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
6QT_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.
13static 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
32static 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
40namespace QPrintUtils {
41
42QPrint::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
51QByteArray 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
60int 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
69QPrint::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
78QByteArray 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
87QPrint::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
113QPrint::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
123QPrint::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
132int 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
143QPrint::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
159QT_END_NAMESPACE
160

source code of qtbase/src/printsupport/kernel/qprint.cpp