1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qprint_p.h" |
5 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | #ifndef QT_NO_PRINTER |
9 | |
10 | // Note: PPD standard does not define a standard set of InputSlot keywords, |
11 | // it is a free form text field left to the PPD writer to decide, |
12 | // but it does suggest some names for consistency with the Windows enum. |
13 | static const InputSlotMap inputSlotMap[] = { |
14 | { .id: QPrint::Upper, DMBIN_UPPER, .key: "Upper" }, |
15 | { .id: QPrint::Lower, DMBIN_LOWER, .key: "Lower" }, |
16 | { .id: QPrint::Middle, DMBIN_MIDDLE, .key: "Middle" }, |
17 | { .id: QPrint::Manual, DMBIN_MANUAL, .key: "Manual" }, |
18 | { .id: QPrint::Envelope, DMBIN_ENVELOPE, .key: "Envelope" }, |
19 | { .id: QPrint::EnvelopeManual, DMBIN_ENVMANUAL, .key: "EnvelopeManual" }, |
20 | { .id: QPrint::Auto, DMBIN_AUTO, .key: "Auto" }, |
21 | { .id: QPrint::Tractor, DMBIN_TRACTOR, .key: "Tractor" }, |
22 | { .id: QPrint::SmallFormat, DMBIN_SMALLFMT, .key: "AnySmallFormat" }, |
23 | { .id: QPrint::LargeFormat, DMBIN_LARGEFMT, .key: "AnyLargeFormat" }, |
24 | { .id: QPrint::LargeCapacity, DMBIN_LARGECAPACITY, .key: "LargeCapacity" }, |
25 | { .id: QPrint::Cassette, DMBIN_CASSETTE, .key: "Cassette" }, |
26 | { .id: QPrint::FormSource, DMBIN_FORMSOURCE, .key: "FormSource" }, |
27 | { .id: QPrint::Manual, DMBIN_MANUAL, .key: "ManualFeed" }, |
28 | { .id: QPrint::OnlyOne, DMBIN_ONLYONE, .key: "OnlyOne" }, // = QPrint::Upper |
29 | { .id: QPrint::CustomInputSlot, DMBIN_USER, .key: "" } // Must always be last row |
30 | }; |
31 | |
32 | static const OutputBinMap outputBinMap[] = { |
33 | { .id: QPrint::AutoOutputBin, .key: "" }, // Not a PPD defined value, internal use only |
34 | { .id: QPrint::UpperBin, .key: "Upper" }, |
35 | { .id: QPrint::LowerBin, .key: "Lower" }, |
36 | { .id: QPrint::RearBin, .key: "Rear" }, |
37 | { .id: QPrint::CustomOutputBin, .key: "" } // Must always be last row |
38 | }; |
39 | |
40 | namespace QPrintUtils { |
41 | |
42 | QPrint::InputSlotId inputSlotKeyToInputSlotId(const QByteArray &key) |
43 | { |
44 | for (int i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) { |
45 | if (inputSlotMap[i].key == key) |
46 | return inputSlotMap[i].id; |
47 | } |
48 | return QPrint::CustomInputSlot; |
49 | } |
50 | |
51 | QByteArray inputSlotIdToInputSlotKey(QPrint::InputSlotId id) |
52 | { |
53 | for (int i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) { |
54 | if (inputSlotMap[i].id == id) |
55 | return QByteArray(inputSlotMap[i].key); |
56 | } |
57 | return QByteArray(); |
58 | } |
59 | |
60 | int inputSlotIdToWindowsId(QPrint::InputSlotId id) |
61 | { |
62 | for (int i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) { |
63 | if (inputSlotMap[i].id == id) |
64 | return inputSlotMap[i].windowsId; |
65 | } |
66 | return 0; |
67 | } |
68 | |
69 | QPrint::OutputBinId outputBinKeyToOutputBinId(const QByteArray &key) |
70 | { |
71 | for (int i = 0; outputBinMap[i].id != QPrint::CustomOutputBin; ++i) { |
72 | if (outputBinMap[i].key == key) |
73 | return outputBinMap[i].id; |
74 | } |
75 | return QPrint::CustomOutputBin; |
76 | } |
77 | |
78 | QByteArray outputBinIdToOutputBinKey(QPrint::OutputBinId id) |
79 | { |
80 | for (int i = 0; outputBinMap[i].id != QPrint::CustomOutputBin; ++i) { |
81 | if (outputBinMap[i].id == id) |
82 | return QByteArray(outputBinMap[i].key); |
83 | } |
84 | return QByteArray(); |
85 | } |
86 | |
87 | QPrint::InputSlot paperBinToInputSlot(int windowsId, const QString &name) |
88 | { |
89 | QPrint::InputSlot slot; |
90 | slot.name = name; |
91 | int i; |
92 | for (i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) { |
93 | if (inputSlotMap[i].windowsId == windowsId) { |
94 | slot.key = inputSlotMap[i].key; |
95 | slot.id = inputSlotMap[i].id; |
96 | slot.windowsId = inputSlotMap[i].windowsId; |
97 | return slot; |
98 | } |
99 | } |
100 | slot.key = inputSlotMap[i].key; |
101 | slot.id = inputSlotMap[i].id; |
102 | slot.windowsId = windowsId; |
103 | return slot; |
104 | } |
105 | |
106 | #if (defined Q_OS_MACOS) || (defined Q_OS_UNIX && QT_CONFIG(cups)) |
107 | |
108 | // PPD utilities shared by CUPS and Mac plugins requiring CUPS headers |
109 | // May turn into a proper internal QPpd class if enough shared between Mac and CUPS, |
110 | // but where would it live? Not in base module as don't want to link to CUPS. |
111 | // May have to have two copies in plugins to keep in sync. |
112 | |
113 | QPrint::InputSlot ppdChoiceToInputSlot(const ppd_choice_t &choice) |
114 | { |
115 | QPrint::InputSlot input; |
116 | input.key = choice.choice; |
117 | input.name = QString::fromUtf8(utf8: choice.text); |
118 | input.id = inputSlotKeyToInputSlotId(key: input.key); |
119 | input.windowsId = inputSlotMap[input.id].windowsId; |
120 | return input; |
121 | } |
122 | |
123 | QPrint::OutputBin ppdChoiceToOutputBin(const ppd_choice_t &choice) |
124 | { |
125 | QPrint::OutputBin output; |
126 | output.key = choice.choice; |
127 | output.name = QString::fromUtf8(utf8: choice.text); |
128 | output.id = outputBinKeyToOutputBinId(key: output.key); |
129 | return output; |
130 | } |
131 | |
132 | int parsePpdResolution(const QByteArray &value) |
133 | { |
134 | if (value.isEmpty()) |
135 | return -1; |
136 | // value can be in form 600dpi or 600x600dpi |
137 | QByteArray result = value.split(sep: 'x').at(i: 0); |
138 | if (result.endsWith(bv: "dpi" )) |
139 | result.chop(n: 3); |
140 | return result.toInt(); |
141 | } |
142 | |
143 | QPrint::DuplexMode ppdChoiceToDuplexMode(const QByteArray &choice) |
144 | { |
145 | if (choice == "DuplexTumble" ) |
146 | return QPrint::DuplexShortSide; |
147 | else if (choice == "DuplexNoTumble" ) |
148 | return QPrint::DuplexLongSide; |
149 | else // None or SimplexTumble or SimplexNoTumble |
150 | return QPrint::DuplexNone; |
151 | } |
152 | |
153 | #endif // Mac and CUPS PPD Utilities |
154 | |
155 | } |
156 | |
157 | #endif // QT_NO_PRINTER |
158 | |
159 | QT_END_NAMESPACE |
160 | |