summaryrefslogtreecommitdiffstats
path: root/src/plugins/printsupport
diff options
context:
space:
mode:
authorJohn Layt <jlayt@kde.org>2013-12-12 18:44:27 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-17 13:45:37 +0100
commit6826912f605f31c8e13bfd84127fd6676602d5f1 (patch)
tree5d7fb3137f42ff664b4a9be42114b43f701d4434 /src/plugins/printsupport
parent3588f05f1010c5ab9663682c71a3e6fe549603a9 (diff)
QPlatformPrintDevice - Add CUPS implementation
Add support to the CUPS print plugin for the new QPlatformPrintDevice class. Note this is called QPpdPrintDevicePrivate as it uses the CUPS PPD support which is deprecated from CUPS 1.6 onwards. A different plugin will be implemented for the CUPS 1.6 support. Change-Id: I26d005f90842d9c6262341171ef157536d28cc5d Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/plugins/printsupport')
-rw-r--r--src/plugins/printsupport/cups/cups.pro4
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport.cpp41
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport_p.h7
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.cpp499
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.h125
5 files changed, 676 insertions, 0 deletions
diff --git a/src/plugins/printsupport/cups/cups.pro b/src/plugins/printsupport/cups/cups.pro
index f617738a94..cdbb08b10a 100644
--- a/src/plugins/printsupport/cups/cups.pro
+++ b/src/plugins/printsupport/cups/cups.pro
@@ -6,13 +6,17 @@ load(qt_plugin)
QT += core-private gui-private printsupport printsupport-private
+LIBS_PRIVATE += -lcups
+
INCLUDEPATH += ../../../printsupport/kernel
SOURCES += main.cpp \
+ qppdprintdevice.cpp \
qcupsprintersupport.cpp \
qcupsprintengine.cpp
HEADERS += qcupsprintersupport_p.h \
+ qppdprintdevice.h \
qcupsprintengine_p.h
OTHER_FILES += cups.json
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
index b9f0c394f8..0db448f4bf 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -44,7 +45,9 @@
#ifndef QT_NO_PRINTER
#include "qcupsprintengine_p.h"
+#include "qppdprintdevice.h"
#include <private/qprinterinfo_p.h>
+#include <private/qprintdevice_p.h>
#include <QtPrintSupport/QPrinterInfo>
@@ -80,6 +83,44 @@ QPaintEngine *QCupsPrinterSupport::createPaintEngine(QPrintEngine *engine, QPrin
return static_cast<QCupsPrintEngine *>(engine);
}
+QPrintDevice QCupsPrinterSupport::createPrintDevice(const QString &id)
+{
+ return QPlatformPrinterSupport::createPrintDevice(new QPpdPrintDevice(id));
+}
+
+QStringList QCupsPrinterSupport::availablePrintDeviceIds() const
+{
+ QStringList list;
+ cups_dest_t *dests;
+ int count = cupsGetDests(&dests);
+ for (int i = 0; i < count; ++i) {
+ QString printerId = QString::fromLocal8Bit(dests[i].name);
+ if (dests[i].instance)
+ printerId += QLatin1Char('/') + QString::fromLocal8Bit(dests[i].instance);
+ list.append(printerId);
+ }
+ cupsFreeDests(count, dests);
+ return list;
+}
+
+QString QCupsPrinterSupport::defaultPrintDeviceId() const
+{
+ QString printerId;
+ cups_dest_t *dests;
+ int count = cupsGetDests(&dests);
+ for (int i = 0; i < count; ++i) {
+ if (dests[i].is_default) {
+ printerId = QString::fromLocal8Bit(dests[i].name);
+ if (dests[i].instance) {
+ printerId += QLatin1Char('/') + QString::fromLocal8Bit(dests[i].instance);
+ break;
+ }
+ }
+ }
+ cupsFreeDests(count, dests);
+ return printerId;
+}
+
QList<QPrinter::PaperSize> QCupsPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const
{
return QCUPSSupport::getCupsPrinterPaperSizes(printerIndex(printerInfo));
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
index d42c0d2630..9ae4a2cd58 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -66,8 +67,14 @@ public:
virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode);
virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode);
+
+ QPrintDevice createPrintDevice(const QString &id) Q_DECL_OVERRIDE;
+ QStringList availablePrintDeviceIds() const Q_DECL_OVERRIDE;
+ QString defaultPrintDeviceId() const Q_DECL_OVERRIDE;
+
virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
virtual QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &) const;
+
virtual QList<QPrinterInfo> availablePrinters();
virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const;
virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const;
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp
new file mode 100644
index 0000000000..fb2d34ed26
--- /dev/null
+++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp
@@ -0,0 +1,499 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qppdprintdevice.h"
+
+#include <QtCore/QMimeDatabase>
+#include <qdebug.h>
+
+#ifndef QT_LINUXBASE // LSB merges everything into cups.h
+#include <cups/language.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QPpdPrintDevice::QPpdPrintDevice()
+ : QPlatformPrintDevice(),
+ m_cupsDest(0),
+ m_ppd(0)
+{
+}
+
+QPpdPrintDevice::QPpdPrintDevice(const QString &id)
+ : QPlatformPrintDevice(id),
+ m_cupsDest(0),
+ m_ppd(0)
+{
+ if (!id.isEmpty()) {
+
+ // TODO For now each dest is an individual device
+ QStringList parts = id.split(QLatin1Char('/'));
+ m_cupsName = parts.at(0).toUtf8();
+ if (parts.size() > 1)
+ m_cupsInstance = parts.at(1).toUtf8();
+ loadPrinter();
+
+ if (m_cupsDest && m_ppd) {
+ m_name = printerOption("printer-info");
+ m_location = printerOption("printer-location");
+ m_makeAndModel = printerOption("printer-make-and-model");
+ cups_ptype_e type = printerTypeFlags();
+ m_isRemote = type & CUPS_PRINTER_REMOTE;
+ // Note this is if the hardware does multiple copies, not if Cups can
+ m_supportsMultipleCopies = type & CUPS_PRINTER_COPIES;
+ // Note this is if the hardware does collation, not if Cups can
+ m_supportsCollateCopies = type & CUPS_PRINTER_COLLATE;
+
+ // Custom Page Size support
+ // Cups cups_ptype_e CUPS_PRINTER_VARIABLE
+ // 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]);
+ }
+ }
+}
+
+QPpdPrintDevice::QPpdPrintDevice(const QPpdPrintDevice &other)
+ : QPlatformPrintDevice(other),
+ m_cupsDest(0),
+ m_ppd(0)
+{
+ m_cupsName = other.m_cupsName;
+ m_cupsInstance = other.m_cupsInstance;
+ loadPrinter();
+}
+
+QPpdPrintDevice::~QPpdPrintDevice()
+{
+ if (m_ppd)
+ ppdClose(m_ppd);
+ if (m_cupsDest)
+ cupsFreeDests(1, m_cupsDest);
+ m_cupsDest = 0;
+ m_ppd = 0;
+}
+
+QPpdPrintDevice &QPpdPrintDevice::operator=(const QPpdPrintDevice &other)
+{
+ m_cupsName = other.m_cupsName;
+ m_cupsInstance = other.m_cupsInstance;
+ if (other.m_cupsDest && other.m_ppd)
+ loadPrinter();
+ return *this;
+}
+
+bool QPpdPrintDevice::operator==(const QPpdPrintDevice &other) const
+{
+ return (m_id == other.m_id);
+}
+
+bool QPpdPrintDevice::isValid() const
+{
+ return m_cupsDest && m_ppd;
+}
+
+bool QPpdPrintDevice::isDefault() const
+{
+ return printerTypeFlags() & CUPS_PRINTER_DEFAULT;
+}
+
+QPrint::DeviceState QPpdPrintDevice::state() const
+{
+ // 3 = idle, 4 = printing, 5 = stopped
+ // More details available from printer-state-message and printer-state-reasons
+ int state = printerOption(QStringLiteral("printer-state")).toInt();
+ if (state == 3)
+ return QPrint::Idle;
+ else if (state == 4)
+ return QPrint::Active;
+ else
+ return QPrint::Error;
+}
+
+void QPpdPrintDevice::loadPageSizes() const
+{
+ m_pageSizes.clear();
+ m_printableMargins.clear();
+
+ ppd_option_t *pageSizes = ppdFindOption(m_ppd, "PageSize");
+ if (pageSizes) {
+ for (int i = 0; i < pageSizes->num_choices; ++i) {
+ const ppd_size_t *ppdSize = ppdPageSize(m_ppd, pageSizes->choices[i].choice);
+ if (ppdSize) {
+ // Returned size is in points
+ QString key = QString::fromUtf8(ppdSize->name);
+ QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
+ QString name = QString::fromUtf8(pageSizes->choices[i].text);
+ if (!size.isEmpty()) {
+ QPageSize ps = createPageSize(key, size, name);
+ if (ps.isValid()) {
+ m_pageSizes.append(ps);
+ m_printableMargins.insert(key, QMarginsF(ppdSize->left, ppdSize->length - ppdSize->top,
+ ppdSize->width - ppdSize->right, ppdSize->bottom));
+ }
+ }
+ }
+ }
+ m_havePageSizes = true;
+ }
+}
+
+QPageSize QPpdPrintDevice::defaultPageSize() const
+{
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "PageSize");
+ if (defaultChoice) {
+ ppd_size_t *ppdSize = ppdPageSize(m_ppd, defaultChoice->choice);
+ if (ppdSize) {
+ // Returned size is in points
+ QString key = QString::fromUtf8(ppdSize->name);
+ QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
+ QString name = QString::fromUtf8(defaultChoice->text);
+ return createPageSize(key, size, name);
+ }
+ }
+ return QPageSize();
+}
+
+QMarginsF QPpdPrintDevice::printableMargins(const QPageSize &pageSize,
+ QPageLayout::Orientation orientation,
+ int resolution) const
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(resolution)
+ if (!m_havePageSizes)
+ loadPageSizes();
+ // TODO Orientation?
+ if (m_printableMargins.contains(pageSize.key()))
+ return m_printableMargins.value(pageSize.key());
+ return m_customMargins;
+}
+
+void QPpdPrintDevice::loadResolutions() const
+{
+ m_resolutions.clear();
+
+ // Try load standard PPD options first
+ ppd_option_t *resolutions = ppdFindOption(m_ppd, "Resolution");
+ if (resolutions) {
+ for (int i = 0; i < resolutions->num_choices; ++i) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ // If no result, try just the default
+ if (m_resolutions.size() == 0) {
+ resolutions = ppdFindOption(m_ppd, "DefaultResolution");
+ if (resolutions) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ // If still no result, then try HP's custom options
+ if (m_resolutions.size() == 0) {
+ resolutions = ppdFindOption(m_ppd, "HPPrintQuality");
+ if (resolutions) {
+ for (int i = 0; i < resolutions->num_choices; ++i) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ }
+ if (m_resolutions.size() == 0) {
+ resolutions = ppdFindOption(m_ppd, "DefaultHPPrintQuality");
+ if (resolutions) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ m_haveResolutions = true;
+}
+
+int QPpdPrintDevice::defaultResolution() const
+{
+ // Try load standard PPD option first
+ ppd_option_t *resolution = ppdFindOption(m_ppd, "DefaultResolution");
+ if (resolution) {
+ int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
+ if (res > 0)
+ return res;
+ }
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "Resolution");
+ if (defaultChoice) {
+ int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
+ if (res > 0)
+ return res;
+ }
+ // If still no result, then try HP's custom options
+ resolution = ppdFindOption(m_ppd, "DefaultHPPrintQuality");
+ if (resolution) {
+ int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
+ if (res > 0)
+ return res;
+ }
+ defaultChoice = ppdFindMarkedChoice(m_ppd, "HPPrintQuality");
+ if (defaultChoice) {
+ int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
+ if (res > 0)
+ return res;
+ }
+ // Otherwise return a sensible default.
+ // TODO What is sensible? 150? 300?
+ return 72;
+}
+
+void QPpdPrintDevice::loadInputSlots() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // TODO Deal with concatenated names like Tray1Manual or Tray1_Man,
+ // will currently show as CustomInputSlot
+ // TODO Deal with separate ManualFeed key
+ // Try load standard PPD options first
+ m_inputSlots.clear();
+ if (m_ppd) {
+ ppd_option_t *inputSlots = ppdFindOption(m_ppd, "InputSlot");
+ if (inputSlots) {
+ for (int i = 0; i < inputSlots->num_choices; ++i)
+ m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i]));
+ }
+ // If no result, try just the default
+ if (m_inputSlots.size() == 0) {
+ inputSlots = ppdFindOption(m_ppd, "DefaultInputSlot");
+ if (inputSlots)
+ m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[0]));
+ }
+ }
+ // If still no result, just use Auto
+ if (m_inputSlots.size() == 0)
+ m_inputSlots.append(QPlatformPrintDevice::defaultInputSlot());
+ m_haveInputSlots = true;
+}
+
+QPrint::InputSlot QPpdPrintDevice::defaultInputSlot() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *inputSlot = ppdFindOption(m_ppd, "DefaultInputSlot");
+ if (inputSlot)
+ return QPrintUtils::ppdChoiceToInputSlot(inputSlot->choices[0]);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "InputSlot");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToInputSlot(*defaultChoice);
+ }
+ // Otherwise return Auto
+ return QPlatformPrintDevice::defaultInputSlot();
+}
+
+void QPpdPrintDevice::loadOutputBins() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ m_outputBins.clear();
+ if (m_ppd) {
+ ppd_option_t *outputBins = ppdFindOption(m_ppd, "OutputBin");
+ if (outputBins) {
+ for (int i = 0; i < outputBins->num_choices; ++i)
+ m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i]));
+ }
+ // If no result, try just the default
+ if (m_outputBins.size() == 0) {
+ outputBins = ppdFindOption(m_ppd, "DefaultOutputBin");
+ if (outputBins)
+ m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[0]));
+ }
+ }
+ // If still no result, just use Auto
+ if (m_outputBins.size() == 0)
+ m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
+ m_haveOutputBins = true;
+}
+
+QPrint::OutputBin QPpdPrintDevice::defaultOutputBin() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *outputBin = ppdFindOption(m_ppd, "DefaultOutputBin");
+ if (outputBin)
+ return QPrintUtils::ppdChoiceToOutputBin(outputBin->choices[0]);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "OutputBin");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToOutputBin(*defaultChoice);
+ }
+ // Otherwise return AutoBin
+ return QPlatformPrintDevice::defaultOutputBin();
+}
+
+void QPpdPrintDevice::loadDuplexModes() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD options first
+ m_duplexModes.clear();
+ if (m_ppd) {
+ ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex");
+ if (duplexModes) {
+ for (int i = 0; i < duplexModes->num_choices; ++i)
+ 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)
+ m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice));
+ }
+ }
+ // If still no result, or not added in PPD, then add None
+ if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone))
+ m_duplexModes.append(QPrint::DuplexNone);
+ m_haveDuplexModes = true;
+}
+
+QPrint::DuplexMode QPpdPrintDevice::defaultDuplexMode() const
+{
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *inputSlot = ppdFindOption(m_ppd, "DefaultDuplex");
+ if (inputSlot)
+ return QPrintUtils::ppdChoiceToDuplexMode(inputSlot->choices[0].choice);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "Duplex");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToDuplexMode(defaultChoice->choice);
+ }
+ // Otherwise return None
+ return QPrint::DuplexNone;
+}
+
+void QPpdPrintDevice::loadColorModes() const
+{
+ // Cups cups_ptype_e CUPS_PRINTER_BW CUPS_PRINTER_COLOR
+ // Cups ppd_file_t color_device
+ // PPD ColorDevice
+ m_colorModes.clear();
+ cups_ptype_e type = printerTypeFlags();
+ if (type & CUPS_PRINTER_BW)
+ m_colorModes.append(QPrint::GrayScale);
+ if (type & CUPS_PRINTER_COLOR)
+ m_colorModes.append(QPrint::Color);
+ m_haveColorModes = true;
+}
+
+QPrint::ColorMode QPpdPrintDevice::defaultColorMode() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Not a proper option, usually only know if supports color or not, but some
+ // users known to abuse ColorModel to always force GrayScale.
+ if (m_ppd && supportedColorModes().contains(QPrint::Color)) {
+ ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel");
+ if (!colorModel)
+ colorModel = ppdFindOption(m_ppd, "ColorModel");
+ if (!colorModel || (colorModel && !qstrcmp(colorModel->defchoice, "Gray")))
+ return QPrint::Color;
+ }
+ return QPrint::GrayScale;
+}
+
+void QPpdPrintDevice::loadMimeTypes() const
+{
+ // TODO No CUPS api? Need to manually load CUPS mime.types file?
+ // For now hard-code most common support types
+ QMimeDatabase db;
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("application/pdf")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("application/postscript")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/gif")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/png")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/jpeg")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/tiff")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("text/html")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("text/plain")));
+ m_haveMimeTypes = true;
+}
+
+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);
+ if (m_cupsDest) {
+ const char *ppdFile = cupsGetPPD(m_cupsName);
+ if (ppdFile)
+ m_ppd = ppdOpenFile(ppdFile);
+ unlink(ppdFile);
+ if (m_ppd) {
+ ppdMarkDefaults(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);
+}
+
+cups_ptype_e QPpdPrintDevice::printerTypeFlags() const
+{
+ return static_cast<cups_ptype_e>(printerOption("printer-type").toUInt());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h
new file mode 100644
index 0000000000..cdea40dd6d
--- /dev/null
+++ b/src/plugins/printsupport/cups/qppdprintdevice.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPPDPRINTDEVICE_H
+#define QPPDPRINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qfeatures.h> // Some feature dependencies might define QT_NO_PRINTER
+#ifndef QT_NO_PRINTER
+
+#include <qpa/qplatformprintdevice.h>
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPpdPrintDevice : public QPlatformPrintDevice
+{
+public:
+ QPpdPrintDevice();
+ explicit QPpdPrintDevice(const QString &id);
+ QPpdPrintDevice(const QPpdPrintDevice &other);
+ virtual ~QPpdPrintDevice();
+
+ QPpdPrintDevice &operator=(const QPpdPrintDevice &other);
+
+ QPpdPrintDevice *clone();
+
+ bool operator==(const QPpdPrintDevice &other) const;
+
+ bool isValid() const Q_DECL_OVERRIDE;
+ bool isDefault() const Q_DECL_OVERRIDE;
+
+ QPrint::DeviceState state() const Q_DECL_OVERRIDE;
+
+ QPageSize defaultPageSize() const Q_DECL_OVERRIDE;
+
+ QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ int resolution) const Q_DECL_OVERRIDE;
+
+ int defaultResolution() const Q_DECL_OVERRIDE;
+
+ QPrint::InputSlot defaultInputSlot() const Q_DECL_OVERRIDE;
+
+ QPrint::OutputBin defaultOutputBin() const Q_DECL_OVERRIDE;
+
+ QPrint::DuplexMode defaultDuplexMode() const Q_DECL_OVERRIDE;
+
+ QPrint::ColorMode defaultColorMode() const Q_DECL_OVERRIDE;
+
+protected:
+ void loadPageSizes() const Q_DECL_OVERRIDE;
+ void loadResolutions() const Q_DECL_OVERRIDE;
+ void loadInputSlots() const Q_DECL_OVERRIDE;
+ void loadOutputBins() const Q_DECL_OVERRIDE;
+ void loadDuplexModes() const Q_DECL_OVERRIDE;
+ void loadColorModes() const Q_DECL_OVERRIDE;
+ void loadMimeTypes() const Q_DECL_OVERRIDE;
+
+private:
+ void loadPrinter();
+ QString printerOption(const QString &key) const;
+ cups_ptype_e printerTypeFlags() const;
+
+ cups_dest_t *m_cupsDest;
+ ppd_file_t *m_ppd;
+ QByteArray m_cupsName;
+ QByteArray m_cupsInstance;
+ QMarginsF m_customMargins;
+ mutable QHash<QString, QMarginsF> m_printableMargins;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+#endif // QPPDPRINTDEVICE_H