diff options
Diffstat (limited to 'src/plugins/printsupport/cups')
5 files changed, 113 insertions, 55 deletions
diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp index 6c29a99705..c9683eb99d 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine.cpp +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -104,7 +104,11 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v break; case PPK_QPageLayout: { QPageLayout pageLayout = value.value<QPageLayout>(); - if (pageLayout.isValid() && (d->m_printDevice.isValidPageLayout(pageLayout, d->resolution) || d->m_printDevice.supportsCustomPageSizes())) { + if (pageLayout.isValid() && (d->m_printDevice.isValidPageLayout(pageLayout, d->resolution) + || d->m_printDevice.supportsCustomPageSizes() + || d->m_printDevice.supportedPageSizes().isEmpty())) { + // supportedPageSizes().isEmpty() because QPageSetupWidget::initPageSizes says + // "If no available printer page sizes, populate with all page sizes" d->m_pageLayout = pageLayout; d->setPageSize(pageLayout.pageSize()); } @@ -132,6 +136,9 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const case PPK_CupsOptions: ret = d->cupsOptions; break; + case PPK_Duplex: + ret = d->duplex; + break; default: ret = QPdfPrintEngine::property(key); break; @@ -140,7 +147,9 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const } -QCupsPrintEnginePrivate::QCupsPrintEnginePrivate(QPrinter::PrinterMode m) : QPdfPrintEnginePrivate(m) +QCupsPrintEnginePrivate::QCupsPrintEnginePrivate(QPrinter::PrinterMode m) + : QPdfPrintEnginePrivate(m) + , duplex(QPrint::DuplexNone) { } diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h index d5363bb8cc..2a1a83b9d7 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine_p.h +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -99,6 +99,7 @@ private: QPrintDevice m_printDevice; QStringList cupsOptions; QString cupsTempFile; + QPrint::DuplexMode duplex; }; QT_END_NAMESPACE diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp index a9c992a2e1..56191c4dec 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp +++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp @@ -47,6 +47,13 @@ #include <QtPrintSupport/QPrinterInfo> +#include <QGuiApplication> +#include <QDialog> +#include <QDialogButtonBox> +#include <QFormLayout> +#include <QLabel> +#include <QLineEdit> + #include <cups/ppd.h> #ifndef QT_LINUXBASE // LSB merges everything into cups.h # include <cups/language.h> @@ -54,9 +61,74 @@ QT_BEGIN_NAMESPACE +static const char *getPasswordCB(const char */*prompt*/, http_t *http, const char */*method*/, const char *resource, void */*user_data*/) +{ + // cups doesn't free the const char * we return so keep around + // the last password so we don't leak memory if called multiple times. + static QByteArray password; + + // prompt is always "Password for %s on %s? " but we can't use it since we allow the user to change the user. + // That is fine because cups always calls cupsUser after calling this callback. + // We build our own prompt with the hostname (if not localhost) and the resource that is being used + + char hostname[HTTP_MAX_HOST]; + httpGetHostname(http, hostname, HTTP_MAX_HOST); + + const QString username = QString::fromLocal8Bit(cupsUser()); + + QDialog dialog; + dialog.setWindowTitle(QCoreApplication::translate("QCupsPrinterSupport", "Authentication Needed")); + + QFormLayout *layout = new QFormLayout(&dialog); + layout->setSizeConstraint(QLayout::SetFixedSize); + + QLineEdit *usernameLE = new QLineEdit(); + usernameLE->setText(username); + + QLineEdit *passwordLE = new QLineEdit(); + passwordLE->setEchoMode(QLineEdit::Password); + + QString resourceString = QString::fromLocal8Bit(resource); + if (resourceString.startsWith(QStringLiteral("/printers/"))) + resourceString = resourceString.mid(QStringLiteral("/printers/").length()); + + QLabel *label = new QLabel(); + if (hostname == QStringLiteral("localhost")) { + label->setText(QCoreApplication::translate("QCupsPrinterSupport", "Authentication needed to use %1.").arg(resourceString)); + } else { + label->setText(QCoreApplication::translate("QCupsPrinterSupport", "Authentication needed to use %1 on %2.").arg(resourceString).arg(hostname)); + label->setWordWrap(true); + } + + layout->addRow(label); + layout->addRow(new QLabel(QCoreApplication::translate("QCupsPrinterSupport", "Username:")), usernameLE); + layout->addRow(new QLabel(QCoreApplication::translate("QCupsPrinterSupport", "Password:")), passwordLE); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + layout->addRow(buttonBox); + + QObject::connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + QObject::connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + + passwordLE->setFocus(); + + if (dialog.exec() != QDialog::Accepted) + return nullptr; + + if (usernameLE->text() != username) + cupsSetUser(usernameLE->text().toLocal8Bit().constData()); + + password = passwordLE->text().toLocal8Bit(); + + return password.constData(); +} + QCupsPrinterSupport::QCupsPrinterSupport() : QPlatformPrinterSupport() { + // Only show password dialog if GUI application + if (qobject_cast<QGuiApplication*>(QCoreApplication::instance())) + cupsSetPasswordCB2(getPasswordCB, nullptr /* user_data */ ); } QCupsPrinterSupport::~QCupsPrinterSupport() diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 340b1a1ff4..d2ddc4144f 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -50,13 +50,6 @@ QT_BEGIN_NAMESPACE -QPpdPrintDevice::QPpdPrintDevice() - : QPlatformPrintDevice(), - m_cupsDest(0), - m_ppd(0) -{ -} - QPpdPrintDevice::QPpdPrintDevice(const QString &id) : QPlatformPrintDevice(id), m_cupsDest(0), @@ -69,9 +62,26 @@ QPpdPrintDevice::QPpdPrintDevice(const QString &id) m_cupsName = parts.at(0).toUtf8(); if (parts.size() > 1) m_cupsInstance = parts.at(1).toUtf8(); - loadPrinter(); - if (m_cupsDest && m_ppd) { + // Get the print instance and PPD file + m_cupsDest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, m_cupsName, m_cupsInstance.isNull() ? nullptr : m_cupsInstance.constData()); + if (m_cupsDest) { + const char *ppdFile = cupsGetPPD(m_cupsName); + if (ppdFile) { + m_ppd = ppdOpenFile(ppdFile); + unlink(ppdFile); + } + if (m_ppd) { + ppdMarkDefaults(m_ppd); + cupsMarkOptions(m_ppd, m_cupsDest->num_options, m_cupsDest->options); + ppdLocalize(m_ppd); + + m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]); + m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]); + m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3], + m_ppd->custom_margins[2], m_ppd->custom_margins[1]); + } + m_name = printerOption("printer-info"); m_location = printerOption("printer-location"); m_makeAndModel = printerOption("printer-make-and-model"); @@ -87,10 +97,6 @@ QPpdPrintDevice::QPpdPrintDevice(const QString &id) // Cups ppd_file_t variable_sizes custom_min custom_max // PPD MaxMediaWidth MaxMediaHeight m_supportsCustomPageSizes = type & CUPS_PRINTER_VARIABLE; - m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]); - m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]); - m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3], - m_ppd->custom_margins[2], m_ppd->custom_margins[1]); } } } @@ -107,7 +113,7 @@ QPpdPrintDevice::~QPpdPrintDevice() bool QPpdPrintDevice::isValid() const { - return m_cupsDest && m_ppd; + return m_cupsDest; } bool QPpdPrintDevice::isDefault() const @@ -152,8 +158,8 @@ void QPpdPrintDevice::loadPageSizes() const } } } - m_havePageSizes = true; } + m_havePageSizes = true; } QPageSize QPpdPrintDevice::defaultPageSize() const @@ -359,14 +365,18 @@ void QPpdPrintDevice::loadDuplexModes() const ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex"); if (duplexModes) { m_duplexModes.reserve(duplexModes->num_choices); - for (int i = 0; i < duplexModes->num_choices; ++i) - m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice)); + for (int i = 0; i < duplexModes->num_choices; ++i) { + if (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[i].choice) == 0) { + m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice)); + } + } } // If no result, try just the default if (m_duplexModes.size() == 0) { duplexModes = ppdFindOption(m_ppd, "DefaultDuplex"); - if (duplexModes) + if (duplexModes && (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[0].choice) == 0)) { m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice)); + } } } // If still no result, or not added in PPD, then add None @@ -417,7 +427,7 @@ QPrint::ColorMode QPpdPrintDevice::defaultColorMode() const ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel"); if (!colorModel) colorModel = ppdFindOption(m_ppd, "ColorModel"); - if (!colorModel || (colorModel && !qstrcmp(colorModel->defchoice, "Gray"))) + if (!colorModel || qstrcmp(colorModel->defchoice, "Gray") != 0) return QPrint::Color; } return QPrint::GrayScale; @@ -481,38 +491,6 @@ void QPpdPrintDevice::loadMimeTypes() const } #endif -void QPpdPrintDevice::loadPrinter() -{ - // Just to be safe, check if existing printer needs closing - if (m_ppd) { - ppdClose(m_ppd); - m_ppd = 0; - } - if (m_cupsDest) { - cupsFreeDests(1, m_cupsDest); - m_cupsDest = 0; - } - - // Get the print instance and PPD file - m_cupsDest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, m_cupsName, m_cupsInstance.isNull() ? nullptr : m_cupsInstance.constData()); - if (m_cupsDest) { - const char *ppdFile = cupsGetPPD(m_cupsName); - if (ppdFile) { - m_ppd = ppdOpenFile(ppdFile); - unlink(ppdFile); - } - if (m_ppd) { - ppdMarkDefaults(m_ppd); - cupsMarkOptions(m_ppd, m_cupsDest->num_options, m_cupsDest->options); - ppdLocalize(m_ppd); - } else { - cupsFreeDests(1, m_cupsDest); - m_cupsDest = 0; - m_ppd = 0; - } - } -} - QString QPpdPrintDevice::printerOption(const QString &key) const { return cupsGetOption(key.toUtf8(), m_cupsDest->num_options, m_cupsDest->options); diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h index 9867083bd7..90f90d6788 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.h +++ b/src/plugins/printsupport/cups/qppdprintdevice.h @@ -65,7 +65,6 @@ QT_BEGIN_NAMESPACE class QPpdPrintDevice : public QPlatformPrintDevice { public: - QPpdPrintDevice(); explicit QPpdPrintDevice(const QString &id); virtual ~QPpdPrintDevice(); @@ -105,7 +104,6 @@ protected: #endif private: - void loadPrinter(); QString printerOption(const QString &key) const; cups_ptype_e printerTypeFlags() const; |