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);
40 if (ppdFile ==
nullptr) {
45 if (cups_dinfo_t *destInfo = cupsCopyDestInfo(CUPS_HTTP_DEFAULT, m_cupsDest)) {
46 cupsFreeDestInfo(destInfo);
47 ppdFile = cupsGetPPD(m_cupsName);
51 m_ppd = ppdOpenFile(ppdFile);
55 ppdMarkDefaults(m_ppd);
56 cupsMarkOptions(m_ppd, m_cupsDest->num_options, m_cupsDest->options);
59 m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]);
60 m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]);
61 m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3],
62 m_ppd->custom_margins[2], m_ppd->custom_margins[1]);
65 m_name = printerOption(
"printer-info");
66 m_location = printerOption(
"printer-location");
67 m_makeAndModel = printerOption(
"printer-make-and-model");
68 cups_ptype_e type = printerTypeFlags();
69 m_isRemote = type & CUPS_PRINTER_REMOTE;
71 m_supportsMultipleCopies = type & CUPS_PRINTER_COPIES;
73 m_supportsCollateCopies = type & CUPS_PRINTER_COLLATE;
79 m_supportsCustomPageSizes = type & CUPS_PRINTER_VARIABLE;
122void QPpdPrintDevice::loadPageSizes()
const
125 m_printableMargins.clear();
127 ppd_option_t *pageSizes = ppdFindOption(m_ppd,
"PageSize");
129 for (
int i = 0; i < pageSizes->num_choices; ++i) {
130 const ppd_size_t *ppdSize = ppdPageSize(m_ppd, pageSizes->choices[i].choice);
133 QString key = QString::fromUtf8(ppdSize->name);
134 QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
135 QString name = QString::fromUtf8(pageSizes->choices[i].text);
136 if (!size.isEmpty()) {
137 QPageSize ps = createPageSize(key, size, name);
139 m_pageSizes.append(ps);
140 m_printableMargins.insert(key, QMarginsF(ppdSize->left, ppdSize->length - ppdSize->top,
141 ppdSize->width - ppdSize->right, ppdSize->bottom));
147 m_havePageSizes =
true;
150QPageSize QPpdPrintDevice::defaultPageSize()
const
152 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"PageSize");
154 ppd_size_t *ppdSize = ppdPageSize(m_ppd, defaultChoice->choice);
157 QString key = QString::fromUtf8(ppdSize->name);
158 QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
159 QString name = QString::fromUtf8(defaultChoice->text);
160 return createPageSize(key, size, name);
166QMarginsF QPpdPrintDevice::printableMargins(
const QPageSize &pageSize,
167 QPageLayout::Orientation orientation,
168 int resolution)
const
170 Q_UNUSED(orientation);
171 Q_UNUSED(resolution);
172 if (!m_havePageSizes)
175 if (m_printableMargins.contains(pageSize.key()))
176 return m_printableMargins.value(pageSize.key());
177 return m_customMargins;
180void QPpdPrintDevice::loadResolutions()
const
182 m_resolutions.clear();
185 ppd_option_t *resolutions = ppdFindOption(m_ppd,
"Resolution");
187 for (
int i = 0; i < resolutions->num_choices; ++i) {
188 int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
190 m_resolutions.append(res);
194 if (m_resolutions.size() == 0) {
195 resolutions = ppdFindOption(m_ppd,
"DefaultResolution");
197 int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
199 m_resolutions.append(res);
203 if (m_resolutions.size() == 0) {
204 resolutions = ppdFindOption(m_ppd,
"HPPrintQuality");
206 for (
int i = 0; i < resolutions->num_choices; ++i) {
207 int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
209 m_resolutions.append(res);
213 if (m_resolutions.size() == 0) {
214 resolutions = ppdFindOption(m_ppd,
"DefaultHPPrintQuality");
216 int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
218 m_resolutions.append(res);
221 m_haveResolutions =
true;
224int QPpdPrintDevice::defaultResolution()
const
227 ppd_option_t *resolution = ppdFindOption(m_ppd,
"DefaultResolution");
229 int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
234 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"Resolution");
236 int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
241 resolution = ppdFindOption(m_ppd,
"DefaultHPPrintQuality");
243 int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
247 defaultChoice = ppdFindMarkedChoice(m_ppd,
"HPPrintQuality");
249 int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
258void QPpdPrintDevice::loadInputSlots()
const
265 m_inputSlots.clear();
267 ppd_option_t *inputSlots = ppdFindOption(m_ppd,
"InputSlot");
269 m_inputSlots.reserve(inputSlots->num_choices);
270 for (
int i = 0; i < inputSlots->num_choices; ++i)
271 m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i]));
274 if (m_inputSlots.size() == 0) {
275 inputSlots = ppdFindOption(m_ppd,
"DefaultInputSlot");
277 m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[0]));
281 if (m_inputSlots.size() == 0)
282 m_inputSlots.append(QPlatformPrintDevice::defaultInputSlot());
283 m_haveInputSlots =
true;
286QPrint::InputSlot QPpdPrintDevice::defaultInputSlot()
const
291 ppd_option_t *inputSlot = ppdFindOption(m_ppd,
"DefaultInputSlot");
293 return QPrintUtils::ppdChoiceToInputSlot(inputSlot->choices[0]);
295 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"InputSlot");
297 return QPrintUtils::ppdChoiceToInputSlot(*defaultChoice);
300 return QPlatformPrintDevice::defaultInputSlot();
303void QPpdPrintDevice::loadOutputBins()
const
306 m_outputBins.clear();
308 ppd_option_t *outputBins = ppdFindOption(m_ppd,
"OutputBin");
310 m_outputBins.reserve(outputBins->num_choices);
311 for (
int i = 0; i < outputBins->num_choices; ++i)
312 m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i]));
315 if (m_outputBins.size() == 0) {
316 outputBins = ppdFindOption(m_ppd,
"DefaultOutputBin");
318 m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[0]));
322 if (m_outputBins.size() == 0)
323 m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
324 m_haveOutputBins =
true;
327QPrint::OutputBin QPpdPrintDevice::defaultOutputBin()
const
332 ppd_option_t *outputBin = ppdFindOption(m_ppd,
"DefaultOutputBin");
334 return QPrintUtils::ppdChoiceToOutputBin(outputBin->choices[0]);
336 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"OutputBin");
338 return QPrintUtils::ppdChoiceToOutputBin(*defaultChoice);
341 return QPlatformPrintDevice::defaultOutputBin();
344void QPpdPrintDevice::loadDuplexModes()
const
348 m_duplexModes.clear();
350 ppd_option_t *duplexModes = ppdFindOption(m_ppd,
"Duplex");
352 m_duplexModes.reserve(duplexModes->num_choices);
353 for (
int i = 0; i < duplexModes->num_choices; ++i) {
354 if (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[i].choice) == 0) {
355 m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice));
360 if (m_duplexModes.size() == 0) {
361 duplexModes = ppdFindOption(m_ppd,
"DefaultDuplex");
362 if (duplexModes && (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[0].choice) == 0)) {
363 m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice));
368 if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone))
369 m_duplexModes.append(QPrint::DuplexNone);
371 if (m_duplexModes.contains(QPrint::DuplexLongSide) && m_duplexModes.contains(QPrint::DuplexShortSide))
372 m_duplexModes.append(QPrint::DuplexAuto);
373 m_haveDuplexModes =
true;
376QPrint::DuplexMode QPpdPrintDevice::defaultDuplexMode()
const
380 ppd_option_t *inputSlot = ppdFindOption(m_ppd,
"DefaultDuplex");
382 return QPrintUtils::ppdChoiceToDuplexMode(inputSlot->choices[0].choice);
384 ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd,
"Duplex");
386 return QPrintUtils::ppdChoiceToDuplexMode(defaultChoice->choice);
389 return QPrint::DuplexNone;
392void QPpdPrintDevice::loadColorModes()
const
397 m_colorModes.clear();
398 cups_ptype_e type = printerTypeFlags();
399 if (type & CUPS_PRINTER_BW)
400 m_colorModes.append(QPrint::GrayScale);
401 if (type & CUPS_PRINTER_COLOR)
402 m_colorModes.append(QPrint::Color);
403 m_haveColorModes =
true;
406QPrint::ColorMode QPpdPrintDevice::defaultColorMode()
const
411 if (m_ppd && supportedColorModes().contains(QPrint::Color)) {
412 ppd_option_t *colorModel = ppdFindOption(m_ppd,
"DefaultColorModel");
414 colorModel = ppdFindOption(m_ppd,
"ColorModel");
415 if (!colorModel || qstrcmp(colorModel->defchoice,
"Gray") != 0)
416 return QPrint::Color;
418 return QPrint::GrayScale;
421QVariant QPpdPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key,
422 const QVariant ¶ms)
const
424 if (key == PDPK_PpdFile)
425 return QVariant::fromValue<ppd_file_t *>(m_ppd);
426 else if (key == PDPK_CupsJobPriority)
427 return printerOption(QStringLiteral(
"job-priority"));
428 else if (key == PDPK_CupsJobSheets)
429 return printerOption(QStringLiteral(
"job-sheets"));
430 else if (key == PDPK_CupsJobBilling)
431 return printerOption(QStringLiteral(
"job-billing"));
432 else if (key == PDPK_CupsJobHoldUntil)
433 return printerOption(QStringLiteral(
"job-hold-until"));
434 if (key == PDPK_OptionValue) {
435 const auto &values = params.toStringList();
436 if (values.size() == 1) {
438 const QString optionValue = printerOption(values.at(0));
439 if (!optionValue.isEmpty())
442 ppd_option_t *option = ppdFindOption(m_ppd, values.at(0).toLatin1());
444 return QString::fromLatin1(option->defchoice);
449 return QPlatformPrintDevice::property(key, params);
452bool QPpdPrintDevice::setProperty(QPrintDevice::PrintDevicePropertyKey key,
const QVariant &value)
454 if (key == PDPK_PpdOption) {
455 const QStringList values = value.toStringList();
456 if (values.size() == 2) {
457 ppdMarkOption(m_ppd, values[0].toLatin1(), values[1].toLatin1());
462 return QPlatformPrintDevice::setProperty(key, value);
465bool QPpdPrintDevice::isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey key,
const QVariant ¶ms)
const
467 if (key == PDPK_PpdChoiceIsInstallableConflict) {
468 const QStringList values = params.toStringList();
469 if (values.size() == 2)
470 return ppdInstallableConflict(m_ppd, values[0].toLatin1(), values[1].toLatin1());
471 }
else if (key == PDPK_PpdCustomOption) {
472 const auto &values = params.toStringList();
473 if (values.size() == 1)
474 return ppdFindCustomOption(m_ppd, values[0].toLatin1()) !=
nullptr;
477 return QPlatformPrintDevice::isFeatureAvailable(key, params);