Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qcups.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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 "qcups_p.h"
5
6#include "qprintdevice_p.h"
7#include "qprintengine.h"
8
10
11using namespace Qt::StringLiterals;
12
14 QCUPSSupport__JobHoldUntil)
16 QCUPSSupport__BannerPage)
19 QCUPSSupport__PagesPerSheetLayout)
21 QCUPSSupport__PagesPerSheet)
22
23static QStringList cupsOptionsList(QPrinter *printer) noexcept
24{
25 return printer->printEngine()->property(PPK_CupsOptions).toStringList();
26}
27
28void setCupsOptions(QPrinter *printer, const QStringList &cupsOptions) noexcept
29{
30 printer->printEngine()->setProperty(PPK_CupsOptions, QVariant(cupsOptions));
31}
32
34{
35 QStringList cupsOptions = cupsOptionsList(printer);
36 if (cupsOptions.contains(option)) {
37 cupsOptions.replace(cupsOptions.indexOf(option) + 1, value);
38 } else {
39 cupsOptions.append(option);
40 cupsOptions.append(value);
41 }
42 setCupsOptions(printer, cupsOptions);
43}
44
46{
47 QStringList cupsOptions = cupsOptionsList(printer);
48 // ### use const_iterator once QList::erase takes them
49 const QStringList::iterator it = std::find(cupsOptions.begin(), cupsOptions.end(), option);
50 if (it != cupsOptions.end()) {
51 Q_ASSERT(it + 1 < cupsOptions.end());
52 cupsOptions.erase(it, it+1);
53 setCupsOptions(printer, cupsOptions);
54 }
55}
56
58{
59 setCupsOptions(printer, QStringList());
60}
61
62static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, QTime holdUntilTime)
63{
64 switch (jobHold) {
66 return QStringLiteral("indefinite");
68 return QStringLiteral("day-time");
70 return QStringLiteral("night");
72 return QStringLiteral("second-shift");
74 return QStringLiteral("third-shift");
76 return QStringLiteral("weekend");
78 if (!holdUntilTime.isNull()) {
79 // CUPS expects the time in UTC, user has entered in local time, so get the UTS equivalent
80 QDateTime localDateTime = QDateTime::currentDateTime();
81 // Check if time is for tomorrow in case of DST change overnight
82 if (holdUntilTime < localDateTime.time())
83 localDateTime = localDateTime.addDays(1);
84 localDateTime.setTime(holdUntilTime);
85 return localDateTime.toUTC().time().toString(u"HH:mm");
86 }
87 // else fall through:
90 return QString();
91 }
92 Q_UNREACHABLE_RETURN(QString());
93}
94
96{
97 if (jobHoldUntil == "indefinite"_L1) {
98 return { QCUPSSupport::Indefinite, QTime() };
99 } else if (jobHoldUntil == "day-time"_L1) {
100 return { QCUPSSupport::DayTime, QTime() };
101 } else if (jobHoldUntil == "night"_L1) {
102 return { QCUPSSupport::Night, QTime() };
103 } else if (jobHoldUntil == "second-shift"_L1) {
104 return { QCUPSSupport::SecondShift, QTime() };
105 } else if (jobHoldUntil == "third-shift"_L1) {
106 return { QCUPSSupport::ThirdShift, QTime() };
107 } else if (jobHoldUntil == "weekend"_L1) {
108 return { QCUPSSupport::Weekend, QTime() };
109 }
110
111
112 QTime parsedTime = QTime::fromString(jobHoldUntil, QStringLiteral("h:m:s"));
113 if (!parsedTime.isValid())
114 parsedTime = QTime::fromString(jobHoldUntil, QStringLiteral("h:m"));
115 if (parsedTime.isValid()) {
116 // CUPS time is in UTC, user expects local time, so get the equivalent
118 dateTimeUtc.setTime(parsedTime);
119 return { QCUPSSupport::SpecificTime, dateTimeUtc.toLocalTime().time() };
120 }
121
122 return { QCUPSSupport::NoHold, QTime() };
123}
124
125ppd_option_t *QCUPSSupport::findPpdOption(const char *optionName, QPrintDevice *printDevice)
126{
127 ppd_file_t *ppd = qvariant_cast<ppd_file_t*>(printDevice->property(PDPK_PpdFile));
128
129 if (ppd) {
130 for (int i = 0; i < ppd->num_groups; ++i) {
131 ppd_group_t *group = &ppd->groups[i];
132
133 for (int i = 0; i < group->num_options; ++i) {
134 ppd_option_t *option = &group->options[i];
135
136 if (qstrcmp(option->keyword, optionName) == 0)
137 return option;
138 }
139 }
140 }
141
142 return nullptr;
143}
144
145void QCUPSSupport::setJobHold(QPrinter *printer, const JobHoldUntil jobHold, QTime holdUntilTime)
146{
147 const QString jobHoldUntilArgument = jobHoldToString(jobHold, holdUntilTime);
148 if (!jobHoldUntilArgument.isEmpty()) {
149 setCupsOption(printer,
150 QStringLiteral("job-hold-until"),
151 jobHoldUntilArgument);
152 } else {
153 clearCupsOption(printer, QStringLiteral("job-hold-until"));
154 }
155}
156
157void QCUPSSupport::setJobBilling(QPrinter *printer, const QString &jobBilling)
158{
159 setCupsOption(printer, QStringLiteral("job-billing"), jobBilling);
160}
161
162void QCUPSSupport::setJobPriority(QPrinter *printer, int priority)
163{
164 setCupsOption(printer, QStringLiteral("job-priority"), QString::number(priority));
165}
166
168{
169 switch (bannerPage) {
170 case QCUPSSupport::NoBanner: return QStringLiteral("none");
171 case QCUPSSupport::Standard: return QStringLiteral("standard");
172 case QCUPSSupport::Unclassified: return QStringLiteral("unclassified");
173 case QCUPSSupport::Confidential: return QStringLiteral("confidential");
174 case QCUPSSupport::Classified: return QStringLiteral("classified");
175 case QCUPSSupport::Secret: return QStringLiteral("secret");
176 case QCUPSSupport::TopSecret: return QStringLiteral("topsecret");
177 }
178 Q_UNREACHABLE_RETURN(QString());
179}
180
182{
183 if (bannerPage == "none"_L1) return QCUPSSupport::NoBanner;
184 else if (bannerPage == "standard"_L1) return QCUPSSupport::Standard;
185 else if (bannerPage == "unclassified"_L1) return QCUPSSupport::Unclassified;
186 else if (bannerPage == "confidential"_L1) return QCUPSSupport::Confidential;
187 else if (bannerPage == "classified"_L1) return QCUPSSupport::Classified;
188 else if (bannerPage == "secret"_L1) return QCUPSSupport::Secret;
189 else if (bannerPage == "topsecret"_L1) return QCUPSSupport::TopSecret;
190
192}
193
195{
197
198 const QStringList parts = jobSheets.split(u',');
199 if (parts.size() == 2) {
200 result.startBannerPage = stringToBannerPage(parts[0]);
201 result.endBannerPage = stringToBannerPage(parts[1]);
202 }
203
204 return result;
205}
206
207void QCUPSSupport::setBannerPages(QPrinter *printer, const BannerPage startBannerPage, const BannerPage endBannerPage)
208{
209 const QString startBanner = bannerPageToString(startBannerPage);
210 const QString endBanner = bannerPageToString(endBannerPage);
211
212 setCupsOption(printer, QStringLiteral("job-sheets"), startBanner + u',' + endBanner);
213}
214
215void QCUPSSupport::setPageSet(QPrinter *printer, const PageSet pageSet)
216{
217 QString pageSetString;
218
219 switch (pageSet) {
220 case OddPages:
221 pageSetString = QStringLiteral("odd");
222 break;
223 case EvenPages:
224 pageSetString = QStringLiteral("even");
225 break;
226 case AllPages:
227 pageSetString = QStringLiteral("all");
228 break;
229 }
230
231 setCupsOption(printer, QStringLiteral("page-set"), pageSetString);
232}
233
235 const PagesPerSheetLayout pagesPerSheetLayout)
236{
237 // WARNING: the following trick (with a [2]-extent) only works as
238 // WARNING: long as there's only one two-digit number in the list
239 // WARNING: and it is the last one (before the "\0")!
240 static const char pagesPerSheetData[][2] = { "1", "2", "4", "6", "9", {'1', '6'}, "\0" };
241 static const char pageLayoutData[][5] = {"lrtb", "lrbt", "rlbt", "rltb", "btlr", "btrl", "tblr", "tbrl"};
242 setCupsOption(printer, QStringLiteral("number-up"), QLatin1StringView(pagesPerSheetData[pagesPerSheet]));
243 setCupsOption(printer, QStringLiteral("number-up-layout"), QLatin1StringView(pageLayoutData[pagesPerSheetLayout]));
244}
245
246void QCUPSSupport::setPageRange(QPrinter *printer, int pageFrom, int pageTo)
247{
248 setPageRange(printer, QStringLiteral("%1-%2").arg(pageFrom).arg(pageTo));
249}
250
251void QCUPSSupport::setPageRange(QPrinter *printer, const QString &pageRange)
252{
253 setCupsOption(printer, QStringLiteral("page-ranges"), pageRange);
254}
255
static void setJobBilling(QPrinter *printer, const QString &jobBilling=QString())
Definition qcups.cpp:157
static JobSheets parseJobSheets(const QString &jobSheets)
Definition qcups.cpp:194
PagesPerSheetLayout
Definition qcups_p.h:89
static void setJobHold(QPrinter *printer, const JobHoldUntil jobHold=NoHold, QTime holdUntilTime=QTime())
Definition qcups.cpp:145
static void setJobPriority(QPrinter *printer, int priority=50)
Definition qcups.cpp:162
static void clearCupsOption(QPrinter *printer, const QString &option)
Definition qcups.cpp:45
static void setPageSet(QPrinter *printer, const PageSet pageSet)
Definition qcups.cpp:215
static void setCupsOption(QPrinter *printer, const QString &option, const QString &value)
static void clearCupsOptions(QPrinter *printer)
Definition qcups.cpp:57
static void setBannerPages(QPrinter *printer, const BannerPage startBannerPage, const BannerPage endBannerPage)
Definition qcups.cpp:207
static ppd_option_t * findPpdOption(const char *optionName, QPrintDevice *printDevice)
Definition qcups.cpp:125
static void setPageRange(QPrinter *printer, int pageFrom, int pageTo)
Definition qcups.cpp:246
static JobHoldUntilWithTime parseJobHoldUntil(const QString &jobHoldUntil)
Definition qcups.cpp:95
static void setPagesPerSheetLayout(QPrinter *printer, const PagesPerSheet pagesPerSheet, const PagesPerSheetLayout pagesPerSheetLayout)
Definition qcups.cpp:234
\inmodule QtCore\reentrant
Definition qdatetime.h:257
static QDateTime currentDateTime()
This is an overloaded member function, provided for convenience. It differs from the above function o...
QDateTime toUTC() const
Returns a copy of this datetime converted to UTC.
void setTime(QTime time)
Sets the time part of this datetime to time.
QTime time() const
Returns the time part of the datetime.
QDateTime toLocalTime() const
Returns a copy of this datetime converted to local time.
static QDateTime currentDateTimeUtc()
QDateTime addDays(qint64 days) const
Returns a QDateTime object containing a datetime ndays days later than the datetime of this object (o...
QVariant property(PrintDevicePropertyKey key) const
\reentrant
Definition qprinter.h:28
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:7956
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
\inmodule QtCore \reentrant
Definition qdatetime.h:189
constexpr bool isNull() const
Returns true if the time is null (i.e., the QTime object was constructed using the default constructo...
Definition qdatetime.h:197
bool isValid() const
Returns true if the time is valid; otherwise returns false.
\inmodule QtCore
Definition qvariant.h:64
QSet< QString >::iterator it
Combined button and popup list for selecting options.
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
#define Q_FALLTHROUGH()
static QCUPSSupport::BannerPage stringToBannerPage(const QString &bannerPage)
Definition qcups.cpp:181
static QString bannerPageToString(const QCUPSSupport::BannerPage bannerPage)
Definition qcups.cpp:167
static QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, QTime holdUntilTime)
Definition qcups.cpp:62
#define PDPK_PpdFile
Definition qcups_p.h:37
#define PPK_CupsOptions
Definition qcups_p.h:35
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG)
Definition qmetatype.h:1363
GLboolean GLuint group
GLuint64EXT * result
[6]
GLuint GLenum option
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int(*) void arg)
#define QStringLiteral(str)