23QPpdPrintDevice::QPpdPrintDevice(
const QString &id)
24 : QPlatformPrintDevice(id),
31 const auto parts = QStringView{id}.split(u'/');
32 m_cupsName = parts.at(0).toUtf8();
34 m_cupsInstance = parts.at(1).toUtf8();
37 m_cupsDest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, m_cupsName, m_cupsInstance.isNull() ?
nullptr : m_cupsInstance.constData());
39 const char *ppdFile = cupsGetPPD(m_cupsName);
41 m_ppd = ppdOpenFile(ppdFile);
45 ppdMarkDefaults(m_ppd);
46 cupsMarkOptions(m_ppd, m_cupsDest->num_options, m_cupsDest->options);
49 m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]);
50 m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]);
51 m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3],
52 m_ppd->custom_margins[2], m_ppd->custom_margins[1]);
55 m_name = printerOption(
"printer-info");
56 m_location = printerOption(
"printer-location");
57 m_makeAndModel = printerOption(
"printer-make-and-model");
58 cups_ptype_e type = printerTypeFlags();
59 m_isRemote = type & CUPS_PRINTER_REMOTE;
61 m_supportsMultipleCopies = type & CUPS_PRINTER_COPIES;
63 m_supportsCollateCopies = type & CUPS_PRINTER_COLLATE;
69 m_supportsCustomPageSizes = type & CUPS_PRINTER_VARIABLE;
112void QPpdPrintDevice::loadPageSizes()
const
115 m_printableMargins.clear();
117 ppd_option_t *pageSizes = ppdFindOption(m_ppd,
"PageSize");
119 for (
int i = 0; i < pageSizes->num_choices; ++i) {
120 const ppd_size_t *ppdSize = ppdPageSize(m_ppd, pageSizes->choices[i].choice);
123 QString key = QString::fromUtf8(ppdSize->name);
124 QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
125 QString name = QString::fromUtf8(pageSizes->choices[i].text);
126 if (!size.isEmpty()) {
127 QPageSize ps = createPageSize(key, size, name);
129 m_pageSizes.append(ps);
130 m_printableMargins.insert(key, QMarginsF(ppdSize->left, ppdSize->length - ppdSize->top,
131 ppdSize->width - ppdSize->right, ppdSize->bottom));
137 m_havePageSizes =
true;
140QPageSize QPpdPrintDevice::defaultPageSize()
const
142 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"PageSize");
144 ppd_size_t *ppdSize = ppdPageSize(m_ppd, defaultChoice->choice);
147 QString key = QString::fromUtf8(ppdSize->name);
148 QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
149 QString name = QString::fromUtf8(defaultChoice->text);
150 return createPageSize(key, size, name);
156QMarginsF QPpdPrintDevice::printableMargins(
const QPageSize &pageSize,
157 QPageLayout::Orientation orientation,
158 int resolution)
const
160 Q_UNUSED(orientation);
161 Q_UNUSED(resolution);
162 if (!m_havePageSizes)
165 if (m_printableMargins.contains(pageSize.key()))
166 return m_printableMargins.value(pageSize.key());
167 return m_customMargins;
170void QPpdPrintDevice::loadResolutions()
const
172 m_resolutions.clear();
175 ppd_option_t *resolutions = ppdFindOption(m_ppd,
"Resolution");
177 for (
int i = 0; i < resolutions->num_choices; ++i) {
178 int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
180 m_resolutions.append(res);
184 if (m_resolutions.size() == 0) {
185 resolutions = ppdFindOption(m_ppd,
"DefaultResolution");
187 int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
189 m_resolutions.append(res);
193 if (m_resolutions.size() == 0) {
194 resolutions = ppdFindOption(m_ppd,
"HPPrintQuality");
196 for (
int i = 0; i < resolutions->num_choices; ++i) {
197 int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
199 m_resolutions.append(res);
203 if (m_resolutions.size() == 0) {
204 resolutions = ppdFindOption(m_ppd,
"DefaultHPPrintQuality");
206 int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
208 m_resolutions.append(res);
211 m_haveResolutions =
true;
214int QPpdPrintDevice::defaultResolution()
const
217 ppd_option_t *resolution = ppdFindOption(m_ppd,
"DefaultResolution");
219 int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
224 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"Resolution");
226 int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
231 resolution = ppdFindOption(m_ppd,
"DefaultHPPrintQuality");
233 int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
237 defaultChoice = ppdFindMarkedChoice(m_ppd,
"HPPrintQuality");
239 int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
248void QPpdPrintDevice::loadInputSlots()
const
255 m_inputSlots.clear();
257 ppd_option_t *inputSlots = ppdFindOption(m_ppd,
"InputSlot");
259 m_inputSlots.reserve(inputSlots->num_choices);
260 for (
int i = 0; i < inputSlots->num_choices; ++i)
261 m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i]));
264 if (m_inputSlots.size() == 0) {
265 inputSlots = ppdFindOption(m_ppd,
"DefaultInputSlot");
267 m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[0]));
271 if (m_inputSlots.size() == 0)
272 m_inputSlots.append(QPlatformPrintDevice::defaultInputSlot());
273 m_haveInputSlots =
true;
276QPrint::InputSlot QPpdPrintDevice::defaultInputSlot()
const
281 ppd_option_t *inputSlot = ppdFindOption(m_ppd,
"DefaultInputSlot");
283 return QPrintUtils::ppdChoiceToInputSlot(inputSlot->choices[0]);
285 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"InputSlot");
287 return QPrintUtils::ppdChoiceToInputSlot(*defaultChoice);
290 return QPlatformPrintDevice::defaultInputSlot();
293void QPpdPrintDevice::loadOutputBins()
const
296 m_outputBins.clear();
298 ppd_option_t *outputBins = ppdFindOption(m_ppd,
"OutputBin");
300 m_outputBins.reserve(outputBins->num_choices);
301 for (
int i = 0; i < outputBins->num_choices; ++i)
302 m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i]));
305 if (m_outputBins.size() == 0) {
306 outputBins = ppdFindOption(m_ppd,
"DefaultOutputBin");
308 m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[0]));
312 if (m_outputBins.size() == 0)
313 m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
314 m_haveOutputBins =
true;
317QPrint::OutputBin QPpdPrintDevice::defaultOutputBin()
const
322 ppd_option_t *outputBin = ppdFindOption(m_ppd,
"DefaultOutputBin");
324 return QPrintUtils::ppdChoiceToOutputBin(outputBin->choices[0]);
326 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"OutputBin");
328 return QPrintUtils::ppdChoiceToOutputBin(*defaultChoice);
331 return QPlatformPrintDevice::defaultOutputBin();
334void QPpdPrintDevice::loadDuplexModes()
const
338 m_duplexModes.clear();
340 ppd_option_t *duplexModes = ppdFindOption(m_ppd,
"Duplex");
342 m_duplexModes.reserve(duplexModes->num_choices);
343 for (
int i = 0; i < duplexModes->num_choices; ++i) {
344 if (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[i].choice) == 0) {
345 m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice));
350 if (m_duplexModes.size() == 0) {
351 duplexModes = ppdFindOption(m_ppd,
"DefaultDuplex");
352 if (duplexModes && (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[0].choice) == 0)) {
353 m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice));
358 if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone))
359 m_duplexModes.append(QPrint::DuplexNone);
361 if (m_duplexModes.contains(QPrint::DuplexLongSide) && m_duplexModes.contains(QPrint::DuplexShortSide))
362 m_duplexModes.append(QPrint::DuplexAuto);
363 m_haveDuplexModes =
true;
366QPrint::DuplexMode QPpdPrintDevice::defaultDuplexMode()
const
370 ppd_option_t *inputSlot = ppdFindOption(m_ppd,
"DefaultDuplex");
372 return QPrintUtils::ppdChoiceToDuplexMode(inputSlot->choices[0].choice);
374 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"Duplex");
376 return QPrintUtils::ppdChoiceToDuplexMode(defaultChoice->choice);
379 return QPrint::DuplexNone;
382void QPpdPrintDevice::loadColorModes()
const
387 m_colorModes.clear();
388 cups_ptype_e type = printerTypeFlags();
389 if (type & CUPS_PRINTER_BW)
390 m_colorModes.append(QPrint::GrayScale);
391 if (type & CUPS_PRINTER_COLOR)
392 m_colorModes.append(QPrint::Color);
393 m_haveColorModes =
true;
396QPrint::ColorMode QPpdPrintDevice::defaultColorMode()
const
401 if (m_ppd && supportedColorModes().contains(QPrint::Color)) {
402 ppd_option_t *colorModel = ppdFindOption(m_ppd,
"DefaultColorModel");
404 colorModel = ppdFindOption(m_ppd,
"ColorModel");
405 if (!colorModel || qstrcmp(colorModel->defchoice,
"Gray") != 0)
406 return QPrint::Color;
408 return QPrint::GrayScale;
411QVariant QPpdPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key)
const
413 if (key == PDPK_PpdFile)
414 return QVariant::fromValue<ppd_file_t *>(m_ppd);
415 else if (key == PDPK_CupsJobPriority)
416 return printerOption(QStringLiteral(
"job-priority"));
417 else if (key == PDPK_CupsJobSheets)
418 return printerOption(QStringLiteral(
"job-sheets"));
419 else if (key == PDPK_CupsJobBilling)
420 return printerOption(QStringLiteral(
"job-billing"));
421 else if (key == PDPK_CupsJobHoldUntil)
422 return printerOption(QStringLiteral(
"job-hold-until"));
424 return QPlatformPrintDevice::property(key);
427bool QPpdPrintDevice::setProperty(QPrintDevice::PrintDevicePropertyKey key,
const QVariant &value)
429 if (key == PDPK_PpdOption) {
430 const QStringList values = value.toStringList();
431 if (values.size() == 2) {
432 ppdMarkOption(m_ppd, values[0].toLatin1(), values[1].toLatin1());
437 return QPlatformPrintDevice::setProperty(key, value);
440bool QPpdPrintDevice::isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey key,
const QVariant ¶ms)
const
442 if (key == PDPK_PpdChoiceIsInstallableConflict) {
443 const QStringList values = params.toStringList();
444 if (values.size() == 2)
445 return ppdInstallableConflict(m_ppd, values[0].toLatin1(), values[1].toLatin1());
448 return QPlatformPrintDevice::isFeatureAvailable(key, params);