From f70924e9ccc016b979bc74bba156600639184be7 Mon Sep 17 00:00:00 2001 From: John Layt Date: Wed, 9 May 2012 23:47:14 +0100 Subject: QtPrintSupport: Add CUPS printsupport plugin Move CUPS code around to create a new CUPS printsupport plugin, this fixes QPrinterInfo for CUPS which depends on the plugin to work. It QT_NO_CUPS is defined then the plugin is not built and only Print to PDF is supported under Linux. * Move unused genericiunixprintersupport plugin to start new CUPS printsupport plugin * Split QPdfPrintEngine to create QCupsPrintEngine * Remove LPR related code from QPdfPrintEngine * Move CUPS specific code from plugin base class to derived CUPS class * Remove forcing CUPS print engine to use PDF mode as PDF is now Native * Move qt_getCupsPrinterPaperSizes from qprinterinfo_unix to QCUPSSupport * Remove qprinterinfo_unix as no longer used * Remove all QT_NO_LPR uses There is now no CUPS specific code left in printsupport/kernel except QCUPSSupport which is needed for the dialogs. Task-number: QTBUG-23060 Change-Id: Ie8fa4512a2424edc8943068e0fa9fb714cc42db9 Reviewed-by: Teemu Katajisto Reviewed-by: Lars Knoll Reviewed-by: John Layt --- src/corelib/global/qglobal.h | 1 - src/gui/painting/qpdf_p.h | 2 - src/platformsupport/platformsupport.pro | 1 - .../printersupport/genericunix/genericunix.pri | 4 - .../genericunix/qgenericunixprintersupport.cpp | 71 -- .../genericunix/qgenericunixprintersupport_p.h | 59 -- .../printersupport/printersupport.pri | 3 - src/plugins/printsupport/cups/cups.json | 3 + src/plugins/printsupport/cups/cups.pro | 19 + src/plugins/printsupport/cups/main.cpp | 74 ++ src/plugins/printsupport/cups/qcupsprintengine.cpp | 269 +++++++ src/plugins/printsupport/cups/qcupsprintengine_p.h | 114 +++ .../printsupport/cups/qcupsprintersupport.cpp | 99 +++ .../printsupport/cups/qcupsprintersupport_p.h | 70 ++ src/plugins/printsupport/printsupport.pro | 1 + src/printsupport/dialogs/dialogs.pri | 1 + src/printsupport/dialogs/qpagesetupdialog_unix.cpp | 3 +- src/printsupport/dialogs/qprintdialog_unix.cpp | 25 +- src/printsupport/kernel/kernel.pri | 11 +- src/printsupport/kernel/qcups.cpp | 83 +- src/printsupport/kernel/qcups_p.h | 10 + src/printsupport/kernel/qplatformprintersupport.h | 2 - .../kernel/qplatformprintersupport_qpa.cpp | 20 - src/printsupport/kernel/qprintengine_pdf.cpp | 305 +------- src/printsupport/kernel/qprintengine_pdf_p.h | 29 +- src/printsupport/kernel/qprinter.cpp | 61 +- src/printsupport/kernel/qprinterinfo.h | 1 + src/printsupport/kernel/qprinterinfo_unix.cpp | 858 --------------------- src/printsupport/kernel/qprinterinfo_unix_p.h | 130 ---- 29 files changed, 772 insertions(+), 1557 deletions(-) delete mode 100644 src/platformsupport/printersupport/genericunix/genericunix.pri delete mode 100644 src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp delete mode 100644 src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h delete mode 100644 src/platformsupport/printersupport/printersupport.pri create mode 100644 src/plugins/printsupport/cups/cups.json create mode 100644 src/plugins/printsupport/cups/cups.pro create mode 100644 src/plugins/printsupport/cups/main.cpp create mode 100644 src/plugins/printsupport/cups/qcupsprintengine.cpp create mode 100644 src/plugins/printsupport/cups/qcupsprintengine_p.h create mode 100644 src/plugins/printsupport/cups/qcupsprintersupport.cpp create mode 100644 src/plugins/printsupport/cups/qcupsprintersupport_p.h delete mode 100644 src/printsupport/kernel/qprinterinfo_unix.cpp delete mode 100644 src/printsupport/kernel/qprinterinfo_unix_p.h (limited to 'src') diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 911759892b..5abbbe4cf4 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -451,7 +451,6 @@ class QDataStream; #if defined(Q_OS_VXWORKS) # define QT_NO_CRASHHANDLER // no popen # define QT_NO_PROCESS // no exec*, no fork -# define QT_NO_LPR # define QT_NO_SHAREDMEMORY // only POSIX, no SysV and in the end... # define QT_NO_SYSTEMSEMAPHORE // not needed at all in a flat address space #endif diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index b175b574bd..87f400c00a 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -283,8 +283,6 @@ public: QSizeF paperSize; qreal leftMargin, topMargin, rightMargin, bottomMargin; - QString cupsTempFile; - private: #ifdef USE_NATIVE_GRADIENTS int gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject); diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index d035dda166..e55bbe0627 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -31,7 +31,6 @@ include(eventdispatchers/eventdispatchers.pri) include(fb_base/fb_base.pri) include(fontdatabases/fontdatabases.pri) include(glxconvenience/glxconvenience.pri) -#include(printersupport/printersupport.pri) include(inputcontext/inputcontext.pri) include(devicediscovery/devicediscovery.pri) include(services/services.pri) diff --git a/src/platformsupport/printersupport/genericunix/genericunix.pri b/src/platformsupport/printersupport/genericunix/genericunix.pri deleted file mode 100644 index 55534c098e..0000000000 --- a/src/platformsupport/printersupport/genericunix/genericunix.pri +++ /dev/null @@ -1,4 +0,0 @@ -QT += printsupport printsupport-private - -HEADERS += $$PWD/qgenericunixprintersupport_p.h -SOURCES += $$PWD/qgenericunixprintersupport.cpp diff --git a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp deleted file mode 100644 index 2fb9562545..0000000000 --- a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgenericunixprintersupport_p.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -QList QGenericUnixPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const -{ -#ifndef QT_NO_CUPS - return QCUPSSupport::getCupsPrinterPaperSizes(QPlatformPrinterSupport::printerInfoCupsPrinterIndex(printerInfo)); -#else - return QList(); -#endif -} - -QList QGenericUnixPrinterSupport::availablePrinters() -{ - QList printers; -#ifndef QT_NO_CUPS - foreach (const QCUPSSupport::Printer &p, QCUPSSupport::availableUnixPrinters()) { - QPrinterInfo printer(QPlatformPrinterSupport::printerInfo(p.name, p.isDefault)); - QPlatformPrinterSupport::setPrinterInfoCupsPrinterIndex(&printer, p.cupsPrinterIndex); - printers.append(printer); - } -#endif - return printers; -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h deleted file mode 100644 index d6b2d0d080..0000000000 --- a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGENERICUNIXPRINTINGSUPPORT_H -#define QGENERICUNIXPRINTINGSUPPORT_H - -#include - -QT_BEGIN_NAMESPACE - -class QGenericUnixPrinterSupport : public QPlatformPrinterSupport -{ -public: - virtual QList supportedPaperSizes(const QPrinterInfo &) const; - - virtual QList availablePrinters(); -}; - -QT_END_NAMESPACE - -#endif // QGENERICUNIXPRINTINGSUPPORT_H diff --git a/src/platformsupport/printersupport/printersupport.pri b/src/platformsupport/printersupport/printersupport.pri deleted file mode 100644 index 797ac771e7..0000000000 --- a/src/platformsupport/printersupport/printersupport.pri +++ /dev/null @@ -1,3 +0,0 @@ -unix { - include($$PWD/genericunix/genericunix.pri) -} diff --git a/src/plugins/printsupport/cups/cups.json b/src/plugins/printsupport/cups/cups.json new file mode 100644 index 0000000000..f578375d09 --- /dev/null +++ b/src/plugins/printsupport/cups/cups.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "cupsprintersupport" ] +} diff --git a/src/plugins/printsupport/cups/cups.pro b/src/plugins/printsupport/cups/cups.pro new file mode 100644 index 0000000000..e19694cb40 --- /dev/null +++ b/src/plugins/printsupport/cups/cups.pro @@ -0,0 +1,19 @@ +TARGET = cupsprintersupport +load(qt_plugin) +DESTDIR = $$QT.gui.plugins/printsupport + +QT += core-private gui-private printsupport printsupport-private + +INCLUDEPATH += ../../../printsupport/kernel + +SOURCES += main.cpp \ + qcupsprintersupport.cpp \ + qcupsprintengine.cpp + +HEADERS += qcupsprintersupport.h \ + qcupsprintengine_p.h + +OTHER_FILES += cups.json + +target.path += $$[QT_INSTALL_PLUGINS]/printsupport +INSTALLS += target diff --git a/src/plugins/printsupport/cups/main.cpp b/src/plugins/printsupport/cups/main.cpp new file mode 100644 index 0000000000..c705ca3c86 --- /dev/null +++ b/src/plugins/printsupport/cups/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qcupsprintersupport_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +class QCupsPrinterSupportPlugin : public QPlatformPrinterSupportPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.QPlatformPrinterSupportFactoryInterface" FILE "cups.json") + +public: + QStringList keys() const; + QPlatformPrinterSupport *create(const QString &); +}; + +QStringList QCupsPrinterSupportPlugin::keys() const +{ + return QStringList(QStringLiteral("cupsprintersupport")); +} + +QPlatformPrinterSupport *QCupsPrinterSupportPlugin::create(const QString &key) +{ + if (key.compare(key, QStringLiteral("cupsprintersupport"), Qt::CaseInsensitive) == 0) + return new QCupsPrinterSupport; + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp new file mode 100644 index 0000000000..8d350e72ab --- /dev/null +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcupsprintengine_p.h" + +#ifndef QT_NO_PRINTER + +#include +#include +#include +#include +#include "private/qcups_p.h" +#include "qprinterinfo.h" + +#include +#include + +#include "private/qcore_unix_p.h" // overrides QT_OPEN + +QT_BEGIN_NAMESPACE + +QCupsPrintEngine::QCupsPrintEngine(QPrinter::PrinterMode m) + : QPdfPrintEngine(*new QCupsPrintEnginePrivate(m)) +{ + Q_D(QCupsPrintEngine); + + if (QCUPSSupport::isAvailable()) { + QCUPSSupport cups; + const cups_dest_t* printers = cups.availablePrinters(); + int prnCount = cups.availablePrintersCount(); + + for (int i = 0; i < prnCount; ++i) { + if (printers[i].is_default) { + d->printerName = QString::fromLocal8Bit(printers[i].name); + break; + } + } + + } + + state = QPrinter::Idle; +} + +QCupsPrintEngine::~QCupsPrintEngine() +{ +} + +void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) +{ + Q_D(QCupsPrintEngine); + + switch (int(key)) { + case PPK_CupsPageRect: + d->cupsPageRect = value.toRect(); + break; + case PPK_CupsPaperRect: + d->cupsPaperRect = value.toRect(); + break; + case PPK_CupsOptions: + d->cupsOptions = value.toStringList(); + break; + case PPK_CupsStringPageSize: + d->cupsStringPageSize = value.toString(); + break; + default: + QPdfPrintEngine::setProperty(key, value); + break; + } +} + +QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const +{ + Q_D(const QCupsPrintEngine); + + QVariant ret; + switch (int(key)) { + case PPK_SupportsMultipleCopies: + ret = true; + break; + case PPK_NumberOfCopies: + ret = 1; + break; + case PPK_CupsPageRect: + ret = d->cupsPageRect; + break; + case PPK_CupsPaperRect: + ret = d->cupsPaperRect; + break; + case PPK_CupsOptions: + ret = d->cupsOptions; + break; + case PPK_CupsStringPageSize: + ret = d->cupsStringPageSize; + break; + default: + ret = QPdfPrintEngine::property(key); + break; + } + return ret; +} + + +QCupsPrintEnginePrivate::QCupsPrintEnginePrivate(QPrinter::PrinterMode m) : QPdfPrintEnginePrivate(m) +{ +} + +QCupsPrintEnginePrivate::~QCupsPrintEnginePrivate() +{ +} + +bool QCupsPrintEnginePrivate::openPrintDevice() +{ + if (outDevice) + return false; + + if (!outputFileName.isEmpty()) { + QFile *file = new QFile(outputFileName); + if (! file->open(QFile::WriteOnly|QFile::Truncate)) { + delete file; + return false; + } + outDevice = file; + } else if (QCUPSSupport::isAvailable()) { + QCUPSSupport cups; + QPair ret = cups.tempFd(); + if (ret.first < 0) { + qWarning("QPdfPrinter: Could not open temporary file to print"); + return false; + } + cupsTempFile = ret.second; + outDevice = new QFile(); + static_cast(outDevice)->open(ret.first, QIODevice::WriteOnly); + } + + return true; +} + +void QCupsPrintEnginePrivate::closePrintDevice() +{ + QPdfPrintEnginePrivate::closePrintDevice(); + + if (!cupsTempFile.isEmpty()) { + QString tempFile = cupsTempFile; + cupsTempFile.clear(); + QCUPSSupport cups; + + // Set up print options. + QByteArray prnName; + QList > options; + QVector cupsOptStruct; + + if (!printerName.isEmpty()) { + prnName = printerName.toLocal8Bit(); + } else { + QPrinterInfo def = QPrinterInfo::defaultPrinter(); + if (def.isNull()) { + qWarning("Could not determine printer to print to"); + QFile::remove(tempFile); + return; + } + prnName = def.printerName().toLocal8Bit(); + } + + if (!cupsStringPageSize.isEmpty()) + options.append(QPair("media", cupsStringPageSize.toLocal8Bit())); + + if (copies > 1) + options.append(QPair("copies", QString::number(copies).toLocal8Bit())); + + if (collate) + options.append(QPair("Collate", "True")); + + switch (duplex) { + case QPrinter::DuplexNone: + options.append(QPair("sides", "one-sided")); + break; + case QPrinter::DuplexAuto: + if (!landscape) + options.append(QPair("sides", "two-sided-long-edge")); + else + options.append(QPair("sides", "two-sided-short-edge")); + break; + case QPrinter::DuplexLongSide: + options.append(QPair("sides", "two-sided-long-edge")); + break; + case QPrinter::DuplexShortSide: + options.append(QPair("sides", "two-sided-short-edge")); + break; + } + + if (QCUPSSupport::cupsVersion() >= 10300 && landscape) + options.append(QPair("landscape", "")); + + QStringList::const_iterator it = cupsOptions.constBegin(); + while (it != cupsOptions.constEnd()) { + options.append(QPair((*it).toLocal8Bit(), (*(it+1)).toLocal8Bit())); + it += 2; + } + + for (int c = 0; c < options.size(); ++c) { + cups_option_t opt; + opt.name = options[c].first.data(); + opt.value = options[c].second.data(); + cupsOptStruct.append(opt); + } + + // Print the file. + cups_option_t* optPtr = cupsOptStruct.size() ? &cupsOptStruct.first() : 0; + cups.printFile(prnName.constData(), tempFile.toLocal8Bit().constData(), + title.toLocal8Bit().constData(), cupsOptStruct.size(), optPtr); + + QFile::remove(tempFile); + } +} + +void QCupsPrintEnginePrivate::updatePaperSize() +{ + if (printerPaperSize == QPrinter::Custom) { + paperSize = customPaperSize; + } else if (!cupsPaperRect.isNull()) { + QRect r = cupsPaperRect; + paperSize = r.size(); + } else { + QPdf::PaperSize s = QPdf::paperSize(printerPaperSize); + paperSize = QSize(s.width, s.height); + } +} + +QT_END_NAMESPACE + +#endif // QT_NO_PRINTER diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h new file mode 100644 index 0000000000..bbffeaaca2 --- /dev/null +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCUPSPRINTENGINE_P_H +#define QCUPSPRINTENGINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtPrintSupport/qprintengine.h" + +#ifndef QT_NO_PRINTER + +#include +#include + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QCupsPrintEnginePrivate; + +class QCupsPrintEngine : public QPdfPrintEngine +{ + Q_DECLARE_PRIVATE(QCupsPrintEngine) +public: + QCupsPrintEngine(QPrinter::PrinterMode m); + virtual ~QCupsPrintEngine(); + + // reimplementations QPdfPrintEngine + void setProperty(PrintEnginePropertyKey key, const QVariant &value); + QVariant property(PrintEnginePropertyKey key) const; + // end reimplementations QPdfPrintEngine + +private: + Q_DISABLE_COPY(QCupsPrintEngine) +}; + +class QCupsPrintEnginePrivate : public QPdfPrintEnginePrivate +{ + Q_DECLARE_PUBLIC(QCupsPrintEngine) +public: + QCupsPrintEnginePrivate(QPrinter::PrinterMode m); + ~QCupsPrintEnginePrivate(); + + bool openPrintDevice(); + void closePrintDevice(); + + void updatePaperSize(); + +private: + Q_DISABLE_COPY(QCupsPrintEnginePrivate) + + QStringList cupsOptions; + QString cupsStringPageSize; + QRect cupsPaperRect; + QRect cupsPageRect; + QString cupsTempFile; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_PRINTER + +#endif // QCUPSPRINTENGINE_P_H diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp new file mode 100644 index 0000000000..279c26ad72 --- /dev/null +++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcupsprintersupport_p.h" + +#include "qcupsprintengine_p.h" +#include + +#include + +#include "qcups_p.h" + +QT_BEGIN_NAMESPACE + +QCupsPrinterSupport::QCupsPrinterSupport() : QPlatformPrinterSupport() +{ +} + +QCupsPrinterSupport::~QCupsPrinterSupport() +{ +} + +QPrintEngine *QCupsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode) +{ + return new QCupsPrintEngine(printerMode); +} + +QPaintEngine *QCupsPrinterSupport::createPaintEngine(QPrintEngine *engine, QPrinter::PrinterMode printerMode) +{ + Q_UNUSED(printerMode) + return static_cast(engine); +} + +QList QCupsPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const +{ + return QCUPSSupport::getCupsPrinterPaperSizes(printerInfoCupsPrinterIndex(printerInfo)); +} + +QList QCupsPrinterSupport::availablePrinters() +{ + QList printers; + foreach (const QCUPSSupport::Printer &p, QCUPSSupport::availableUnixPrinters()) { + QPrinterInfo printer(p.name); + printer.d_func()->isDefault = p.isDefault; + setPrinterInfoCupsPrinterIndex(&printer, p.cupsPrinterIndex); + printers.append(printer); + } + return printers; +} + +int QCupsPrinterSupport::printerInfoCupsPrinterIndex(const QPrinterInfo &p) +{ + return p.isNull() ? -1 : p.d_func()->cupsPrinterIndex; +} + +void QCupsPrinterSupport::setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index) +{ + p->d_func()->cupsPrinterIndex = index; +} + +QT_END_NAMESPACE diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h new file mode 100644 index 0000000000..81887e3dd8 --- /dev/null +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCUPSPRINTERSUPPORT_H +#define QCUPSPRINTERSUPPORT_H + +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +class QCupsPrinterSupport : public QPlatformPrinterSupport +{ +public: + QCupsPrinterSupport(); + ~QCupsPrinterSupport(); + + virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode); + virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode); + virtual QList supportedPaperSizes(const QPrinterInfo &) const; + + virtual QList availablePrinters(); + +private: + static int printerInfoCupsPrinterIndex(const QPrinterInfo &p); + static void setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index); +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QCUPSPRINTERSUPPORT_H diff --git a/src/plugins/printsupport/printsupport.pro b/src/plugins/printsupport/printsupport.pro index 547ac42c9e..93f3d65bc5 100644 --- a/src/plugins/printsupport/printsupport.pro +++ b/src/plugins/printsupport/printsupport.pro @@ -2,3 +2,4 @@ TEMPLATE = subdirs mac: SUBDIRS += cocoa win32: SUBDIRS += windows +unix:!mac:contains(QT_CONFIG, cups): SUBDIRS += cups diff --git a/src/printsupport/dialogs/dialogs.pri b/src/printsupport/dialogs/dialogs.pri index 2b92f43bec..c9acae7767 100644 --- a/src/printsupport/dialogs/dialogs.pri +++ b/src/printsupport/dialogs/dialogs.pri @@ -21,6 +21,7 @@ win32 { } unix:!mac { + INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/printsupport/cups HEADERS += dialogs/qpagesetupdialog_unix_p.h SOURCES += dialogs/qprintdialog_unix.cpp \ dialogs/qpagesetupdialog_unix.cpp diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index 90fb3ef542..ac8338b739 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -52,11 +52,10 @@ #include #include #include +#include #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) # include -# include -# include #endif diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 9633c1358e..49d523e2eb 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -62,14 +63,11 @@ #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) # include -# include -# include #else # include +# include #endif -#include - QT_BEGIN_NAMESPACE class QOptionTreeItem; @@ -165,7 +163,6 @@ public: Ui::QPrintWidget widget; QAbstractPrintDialog * q; QPrinter *printer; - QList lprPrinters; void updateWidget(); private: @@ -664,14 +661,6 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p) widget.properties->setEnabled(true); } currentPrinterIndex = cups->currentPrinterIndex(); - } else { -#endif - currentPrinterIndex = qt_getLprPrinters(lprPrinters); - // populating printer combo - QList::const_iterator i = lprPrinters.constBegin(); - for(; i != lprPrinters.constEnd(); ++i) - widget.printers->addItem((*i).name); -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) } #endif @@ -783,16 +772,6 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index) } else { if (optionsPane) optionsPane->selectPrinter(0); -#endif - if (lprPrinters.count() > 0) { - QString type = lprPrinters.at(index).name + QLatin1Char('@') + lprPrinters.at(index).host; - if (!lprPrinters.at(index).comment.isEmpty()) - type += QLatin1String(", ") + lprPrinters.at(index).comment; - widget.type->setText(type); - if (propertiesDialog) - propertiesDialog->selectPrinter(); - } -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) } #endif } diff --git a/src/printsupport/kernel/kernel.pri b/src/printsupport/kernel/kernel.pri index 1ab9c3a0eb..e53e02bdc5 100644 --- a/src/printsupport/kernel/kernel.pri +++ b/src/printsupport/kernel/kernel.pri @@ -18,13 +18,6 @@ SOURCES += \ $$PWD/qplatformprintplugin.cpp \ $$PWD/qplatformprintersupport_qpa.cpp -unix:!mac { - HEADERS += \ - $$PWD/qprinterinfo_unix_p.h - SOURCES += \ - $$PWD/qprinterinfo_unix.cpp -} - win32 { HEADERS += \ $$PWD/qprintengine_win_p.h @@ -33,9 +26,7 @@ win32 { LIBS += -lwinspool -lcomdlg32 } -mac|win32 { - DEFINES += QT_NO_CUPS QT_NO_LPR -} else { +unix:!mac:contains(QT_CONFIG, cups): { SOURCES += $$PWD/qcups.cpp HEADERS += $$PWD/qcups_p.h } diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index 1f8bed57ea..8b4356321d 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include #include "qcups_p.h" -#include "qprinterinfo_unix_p.h" #ifndef QT_NO_CUPS @@ -405,7 +404,6 @@ QList QCUPSSupport::availableUnixPrinters() { QList printers; -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) if (QCUPSSupport::isAvailable()) { QCUPSSupport cups; int cupsPrinterCount = cups.availablePrintersCount(); @@ -421,24 +419,83 @@ QList QCUPSSupport::availableUnixPrinters() p.cupsPrinterIndex = i; printers.append(p); } - } else -#endif - { - QList lprPrinters; - int defprn = qt_getLprPrinters(lprPrinters); - // populating printer combo - foreach (const QPrinterDescription &description, lprPrinters) - printers.append(Printer(description.name)); - if (defprn >= 0 && defprn < printers.size()) - printers[defprn].isDefault = true; } return printers; } +// preserve names in ascending order for the binary search +static const struct NamedPaperSize { + const char *const name; + QPrinter::PaperSize size; +} named_sizes_map[QPrinter::NPageSize] = { + { "A0", QPrinter::A0 }, + { "A1", QPrinter::A1 }, + { "A2", QPrinter::A2 }, + { "A3", QPrinter::A3 }, + { "A4", QPrinter::A4 }, + { "A5", QPrinter::A5 }, + { "A6", QPrinter::A6 }, + { "A7", QPrinter::A7 }, + { "A8", QPrinter::A8 }, + { "A9", QPrinter::A9 }, + { "B0", QPrinter::B0 }, + { "B1", QPrinter::B1 }, + { "B10", QPrinter::B10 }, + { "B2", QPrinter::B2 }, + { "B4", QPrinter::B4 }, + { "B5", QPrinter::B5 }, + { "B6", QPrinter::B6 }, + { "B7", QPrinter::B7 }, + { "B8", QPrinter::B8 }, + { "B9", QPrinter::B9 }, + { "C5E", QPrinter::C5E }, + { "Comm10E", QPrinter::Comm10E }, + { "Custom", QPrinter::Custom }, + { "DLE", QPrinter::DLE }, + { "Executive", QPrinter::Executive }, + { "Folio", QPrinter::Folio }, + { "Ledger", QPrinter::Ledger }, + { "Legal", QPrinter::Legal }, + { "Letter", QPrinter::Letter }, + { "Tabloid", QPrinter::Tabloid } +}; + +inline bool operator<(const char *name, const NamedPaperSize &data) +{ return qstrcmp(name, data.name) < 0; } +inline bool operator<(const NamedPaperSize &data, const char *name) +{ return qstrcmp(data.name, name) < 0; } + +static inline QPrinter::PaperSize string2PaperSize(const char *name) +{ + const NamedPaperSize *r = qBinaryFind(named_sizes_map, named_sizes_map + QPrinter::NPageSize, name); + if (r - named_sizes_map != QPrinter::NPageSize) + return r->size; + return QPrinter::Custom; +} + +static inline const char *paperSize2String(QPrinter::PaperSize size) +{ + for (int i = 0; i < QPrinter::NPageSize; ++i) { + if (size == named_sizes_map[i].size) + return named_sizes_map[i].name; + } + return 0; +} + QList QCUPSSupport::getCupsPrinterPaperSizes(int cupsPrinterIndex) { - return qt_getCupsPrinterPaperSizes(cupsPrinterIndex); + QList result; + if (!QCUPSSupport::isAvailable() || cupsPrinterIndex < 0) + return result; + // Find paper sizes from CUPS. + QCUPSSupport cups; + cups.setCurrentPrinter(cupsPrinterIndex); + if (const ppd_option_t* size = cups.pageSizes()) { + for (int j = 0; j < size->num_choices; ++j) + result.append(string2PaperSize(size->choices[j].choice)); + } + return result; } QT_END_NAMESPACE diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index cbf153f347..e68805d3c1 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -61,9 +61,19 @@ #include #include #include +#include "qprintengine.h" QT_BEGIN_NAMESPACE +// HACK! Define these here temporarily so they can be used in the dialogs +// without a circular reference to QCupsPrintEngine in the plugin. +// Move back to qcupsprintengine_p.h in the plugin once all usage +// removed from the dialogs. +#define PPK_CupsOptions QPrintEngine::PrintEnginePropertyKey(0xfe00) +#define PPK_CupsPageRect QPrintEngine::PrintEnginePropertyKey(0xfe01) +#define PPK_CupsPaperRect QPrintEngine::PrintEnginePropertyKey(0xfe02) +#define PPK_CupsStringPageSize QPrintEngine::PrintEnginePropertyKey(0xfe03) + Q_DECLARE_TYPEINFO(cups_option_t, Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE); class Q_PRINTSUPPORT_EXPORT QCUPSSupport diff --git a/src/printsupport/kernel/qplatformprintersupport.h b/src/printsupport/kernel/qplatformprintersupport.h index 37fb9e89de..910eafacb6 100644 --- a/src/printsupport/kernel/qplatformprintersupport.h +++ b/src/printsupport/kernel/qplatformprintersupport.h @@ -81,8 +81,6 @@ public: protected: static void setPrinterInfoDefault(QPrinterInfo *p, bool isDefault); static bool printerInfoIsDefault(const QPrinterInfo &p); - static int printerInfoCupsPrinterIndex(const QPrinterInfo &p); - static void setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index); }; #endif // QT_NO_PRINTER diff --git a/src/printsupport/kernel/qplatformprintersupport_qpa.cpp b/src/printsupport/kernel/qplatformprintersupport_qpa.cpp index d2459dc91d..7bf2b291d0 100644 --- a/src/printsupport/kernel/qplatformprintersupport_qpa.cpp +++ b/src/printsupport/kernel/qplatformprintersupport_qpa.cpp @@ -117,26 +117,6 @@ bool QPlatformPrinterSupport::printerInfoIsDefault(const QPrinterInfo &p) return p.d_func()->isDefault; } -int QPlatformPrinterSupport::printerInfoCupsPrinterIndex(const QPrinterInfo &p) -{ -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - return p.isNull() ? -1 : p.d_func()->cupsPrinterIndex; -#else - Q_UNUSED(p) - return -1; -#endif -} - -void QPlatformPrinterSupport::setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index) -{ -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - p->d_func()->cupsPrinterIndex = index; -#else - Q_UNUSED(p) - Q_UNUSED(index) -#endif -} - /* Converts QSizeF in millimeters to a predefined PaperSize (returns Custom if the size isn't a standard size) diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp index d3140b4621..af1dcecd95 100644 --- a/src/printsupport/kernel/qprintengine_pdf.cpp +++ b/src/printsupport/kernel/qprintengine_pdf.cpp @@ -39,20 +39,19 @@ ** ****************************************************************************/ -#include +#include "qprintengine_pdf_p.h" + +#ifndef QT_NO_PRINTER #include #include #include #include -#include "private/qcups_p.h" #include "qprinterinfo.h" -#ifndef QT_NO_PRINTER #include #include -#include "qprintengine_pdf_p.h" #ifdef Q_OS_UNIX #include "private/qcore_unix_p.h" // overrides QT_OPEN @@ -95,32 +94,12 @@ const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize) QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m) : QPdfEngine(*new QPdfPrintEnginePrivate(m)) { - Q_D(QPdfPrintEngine); -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - if (QCUPSSupport::isAvailable()) { - QCUPSSupport cups; - const cups_dest_t* printers = cups.availablePrinters(); - int prnCount = cups.availablePrintersCount(); - - for (int i = 0; i < prnCount; ++i) { - if (printers[i].is_default) { - d->printerName = QString::fromLocal8Bit(printers[i].name); - break; - } - } - - } else -#endif - { - d->printerName = QString::fromLocal8Bit(qgetenv("PRINTER")); - if (d->printerName.isEmpty()) - d->printerName = QString::fromLocal8Bit(qgetenv("LPDEST")); - if (d->printerName.isEmpty()) - d->printerName = QString::fromLocal8Bit(qgetenv("NPRINTER")); - if (d->printerName.isEmpty()) - d->printerName = QString::fromLocal8Bit(qgetenv("NGPRINTER")); - } + state = QPrinter::Idle; +} +QPdfPrintEngine::QPdfPrintEngine(QPdfPrintEnginePrivate &p) + : QPdfEngine(p) +{ state = QPrinter::Idle; } @@ -221,18 +200,6 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va case PPK_Duplex: d->duplex = static_cast (value.toInt()); break; - case PPK_CupsPageRect: - d->cupsPageRect = value.toRect(); - break; - case PPK_CupsPaperRect: - d->cupsPaperRect = value.toRect(); - break; - case PPK_CupsOptions: - d->cupsOptions = value.toStringList(); - break; - case PPK_CupsStringPageSize: - d->cupsStringPageSize = value.toString(); - break; case PPK_CustomPaperSize: d->printerPaperSize = QPrinter::Custom; d->customPaperSize = value.toSizeF(); @@ -278,20 +245,10 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const ret = d->copies; break; case PPK_SupportsMultipleCopies: -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - if (QCUPSSupport::isAvailable()) - ret = true; - else -#endif - ret = false; + ret = false; break; case PPK_NumberOfCopies: -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - if (QCUPSSupport::isAvailable()) - ret = 1; - else -#endif - ret = d->copies; + ret = d->copies; break; case PPK_Orientation: ret = d->landscape ? QPrinter::Landscape : QPrinter::Portrait; @@ -335,18 +292,6 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const case PPK_Duplex: ret = d->duplex; break; - case PPK_CupsPageRect: - ret = d->cupsPageRect; - break; - case PPK_CupsPaperRect: - ret = d->cupsPaperRect; - break; - case PPK_CupsOptions: - ret = d->cupsOptions; - break; - case PPK_CupsStringPageSize: - ret = d->cupsStringPageSize; - break; case PPK_CustomPaperSize: ret = d->customPaperSize; break; @@ -365,28 +310,6 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const } -#ifndef QT_NO_LPR -static void closeAllOpenFds() -{ - // hack time... getting the maximum number of open - // files, if possible. if not we assume it's the - // larger of 256 and the fd we got - int i; -#if defined(_SC_OPEN_MAX) - i = (int)sysconf(_SC_OPEN_MAX); -#elif defined(_POSIX_OPEN_MAX) - i = (int)_POSIX_OPEN_MAX; -#elif defined(OPEN_MAX) - i = (int)OPEN_MAX; -#else - i = 256; -#endif - // leave stdin/out/err untouched - while(--i > 2) - QT_CLOSE(i); -} -#endif - bool QPdfPrintEnginePrivate::openPrintDevice() { if (outDevice) @@ -399,130 +322,6 @@ bool QPdfPrintEnginePrivate::openPrintDevice() return false; } outDevice = file; -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - } else if (QCUPSSupport::isAvailable()) { - QCUPSSupport cups; - QPair ret = cups.tempFd(); - if (ret.first < 0) { - qWarning("QPdfPrinter: Could not open temporary file to print"); - return false; - } - cupsTempFile = ret.second; - outDevice = new QFile(); - static_cast(outDevice)->open(ret.first, QIODevice::WriteOnly); -#endif -#ifndef QT_NO_LPR - } else { - QString pr; - if (!printerName.isEmpty()) - pr = printerName; - int fds[2]; - if (qt_safe_pipe(fds) != 0) { - qWarning("QPdfPrinter: Could not open pipe to print"); - return false; - } - - pid_t pid = fork(); - if (pid == 0) { // child process - // if possible, exit quickly, so the actual lp/lpr - // becomes a child of init, and ::waitpid() is - // guaranteed not to wait. - if (fork() > 0) { - closeAllOpenFds(); - - // try to replace this process with "true" - this prevents - // global destructors from being called (that could possibly - // do wrong things to the parent process) - (void)execlp("true", "true", (char *)0); - (void)execl("/bin/true", "true", (char *)0); - (void)execl("/usr/bin/true", "true", (char *)0); - ::_exit(0); - } - qt_safe_dup2(fds[0], 0, 0); - - closeAllOpenFds(); - - if (!printProgram.isEmpty()) { - if (!selectionOption.isEmpty()) - pr.prepend(selectionOption); - else - pr.prepend(QLatin1String("-P")); - (void)execlp(printProgram.toLocal8Bit().data(), printProgram.toLocal8Bit().data(), - pr.toLocal8Bit().data(), (char *)0); - } else { - // if no print program has been specified, be smart - // about the option string too. - QList lprhack; - QList lphack; - QByteArray media; - if (!pr.isEmpty() || !selectionOption.isEmpty()) { - if (!selectionOption.isEmpty()) { - QStringList list = selectionOption.split(QLatin1Char(' ')); - for (int i = 0; i < list.size(); ++i) - lprhack.append(list.at(i).toLocal8Bit()); - lphack = lprhack; - } else { - lprhack.append("-P"); - lphack.append("-d"); - } - lprhack.append(pr.toLocal8Bit()); - lphack.append(pr.toLocal8Bit()); - } - lphack.append("-s"); - - char ** lpargs = new char *[lphack.size()+6]; - char lp[] = "lp"; - lpargs[0] = lp; - int i; - for (i = 0; i < lphack.size(); ++i) - lpargs[i+1] = (char *)lphack.at(i).constData(); -#ifndef Q_OS_OSF - if (QPdf::paperSizeToString(printerPaperSize)) { - char dash_o[] = "-o"; - lpargs[++i] = dash_o; - lpargs[++i] = const_cast(QPdf::paperSizeToString(printerPaperSize)); - lpargs[++i] = dash_o; - media = "media="; - media += QPdf::paperSizeToString(printerPaperSize); - lpargs[++i] = media.data(); - } -#endif - lpargs[++i] = 0; - char **lprargs = new char *[lprhack.size()+2]; - char lpr[] = "lpr"; - lprargs[0] = lpr; - for (int i = 0; i < lprhack.size(); ++i) - lprargs[i+1] = (char *)lprhack[i].constData(); - lprargs[lprhack.size() + 1] = 0; - (void)execvp("lp", lpargs); - (void)execvp("lpr", lprargs); - (void)execv("/bin/lp", lpargs); - (void)execv("/bin/lpr", lprargs); - (void)execv("/usr/bin/lp", lpargs); - (void)execv("/usr/bin/lpr", lprargs); - - delete []lpargs; - delete []lprargs; - } - // if we couldn't exec anything, close the fd, - // wait for a second so the parent process (the - // child of the GUI process) has exited. then - // exit. - QT_CLOSE(0); - (void)::sleep(1); - ::_exit(0); - } - // parent process - QT_CLOSE(fds[0]); - fd = fds[1]; - (void)qt_safe_waitpid(pid, 0, 0); - - if (fd < 0) - return false; - - outDevice = new QFile(); - static_cast(outDevice)->open(fd, QIODevice::WriteOnly); -#endif } return true; @@ -542,85 +341,6 @@ void QPdfPrintEnginePrivate::closePrintDevice() delete outDevice; outDevice = 0; } - -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - if (!cupsTempFile.isEmpty()) { - QString tempFile = cupsTempFile; - cupsTempFile.clear(); - QCUPSSupport cups; - - // Set up print options. - QByteArray prnName; - QList > options; - QVector cupsOptStruct; - - if (!printerName.isEmpty()) { - prnName = printerName.toLocal8Bit(); - } else { - QPrinterInfo def = QPrinterInfo::defaultPrinter(); - if (def.isNull()) { - qWarning("Could not determine printer to print to"); - QFile::remove(tempFile); - return; - } - prnName = def.printerName().toLocal8Bit(); - } - - if (!cupsStringPageSize.isEmpty()) { - options.append(QPair("media", cupsStringPageSize.toLocal8Bit())); - } - - if (copies > 1) { - options.append(QPair("copies", QString::number(copies).toLocal8Bit())); - } - - if (collate) { - options.append(QPair("Collate", "True")); - } - - switch (duplex) { - case QPrinter::DuplexNone: - options.append(QPair("sides", "one-sided")); - break; - case QPrinter::DuplexAuto: - if (!landscape) - options.append(QPair("sides", "two-sided-long-edge")); - else - options.append(QPair("sides", "two-sided-short-edge")); - break; - case QPrinter::DuplexLongSide: - options.append(QPair("sides", "two-sided-long-edge")); - break; - case QPrinter::DuplexShortSide: - options.append(QPair("sides", "two-sided-short-edge")); - break; - } - - if (QCUPSSupport::cupsVersion() >= 10300 && landscape) { - options.append(QPair("landscape", "")); - } - - QStringList::const_iterator it = cupsOptions.constBegin(); - while (it != cupsOptions.constEnd()) { - options.append(QPair((*it).toLocal8Bit(), (*(it+1)).toLocal8Bit())); - it += 2; - } - - for (int c = 0; c < options.size(); ++c) { - cups_option_t opt; - opt.name = options[c].first.data(); - opt.value = options[c].second.data(); - cupsOptStruct.append(opt); - } - - // Print the file. - cups_option_t* optPtr = cupsOptStruct.size() ? &cupsOptStruct.first() : 0; - cups.printFile(prnName.constData(), tempFile.toLocal8Bit().constData(), - title.toLocal8Bit().constData(), cupsOptStruct.size(), optPtr); - - QFile::remove(tempFile); - } -#endif } @@ -651,10 +371,7 @@ void QPdfPrintEnginePrivate::updatePaperSize() { if (printerPaperSize == QPrinter::Custom) { paperSize = customPaperSize; - } else if (!cupsPaperRect.isNull()) { - QRect r = cupsPaperRect; - paperSize = r.size(); - } else{ + } else { QPdf::PaperSize s = QPdf::paperSize(printerPaperSize); paperSize = QSize(s.width, s.height); } diff --git a/src/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h index 52ade83b43..ec1c90e363 100644 --- a/src/printsupport/kernel/qprintengine_pdf_p.h +++ b/src/printsupport/kernel/qprintengine_pdf_p.h @@ -79,11 +79,6 @@ class QRegion; class QFile; class QPdfPrintEngine; -#define PPK_CupsOptions QPrintEngine::PrintEnginePropertyKey(0xfe00) -#define PPK_CupsPageRect QPrintEngine::PrintEnginePropertyKey(0xfe01) -#define PPK_CupsPaperRect QPrintEngine::PrintEnginePropertyKey(0xfe02) -#define PPK_CupsStringPageSize QPrintEngine::PrintEnginePropertyKey(0xfe03) - namespace QPdf { struct PaperSize { @@ -95,7 +90,7 @@ namespace QPdf { class QPdfPrintEnginePrivate; -class QPdfPrintEngine : public QPdfEngine, public QPrintEngine +class Q_PRINTSUPPORT_EXPORT QPdfPrintEngine : public QPdfEngine, public QPrintEngine { Q_DECLARE_PRIVATE(QPdfPrintEngine) public: @@ -113,36 +108,40 @@ public: bool newPage(); int metric(QPaintDevice::PaintDeviceMetric) const; - void setProperty(PrintEnginePropertyKey key, const QVariant &value); - QVariant property(PrintEnginePropertyKey key) const; + virtual void setProperty(PrintEnginePropertyKey key, const QVariant &value); + virtual QVariant property(PrintEnginePropertyKey key) const; // end reimplementations QPrintEngine QPrinter::PrinterState state; +protected: + QPdfPrintEngine(QPdfPrintEnginePrivate &p); + private: Q_DISABLE_COPY(QPdfPrintEngine) }; -class QPdfPrintEnginePrivate : public QPdfEnginePrivate +class Q_PRINTSUPPORT_EXPORT QPdfPrintEnginePrivate : public QPdfEnginePrivate { Q_DECLARE_PUBLIC(QPdfPrintEngine) public: QPdfPrintEnginePrivate(QPrinter::PrinterMode m); ~QPdfPrintEnginePrivate(); - bool openPrintDevice(); - void closePrintDevice(); + virtual bool openPrintDevice(); + virtual void closePrintDevice(); - void updatePaperSize(); + virtual void updatePaperSize(); private: Q_DISABLE_COPY(QPdfPrintEnginePrivate) + friend class QCupsPrintEngine; + friend class QCupsPrintEnginePrivate; + QString printerName; QString printProgram; QString selectionOption; - QStringList cupsOptions; - QString cupsStringPageSize; QPrinter::DuplexMode duplex; bool collate; @@ -151,8 +150,6 @@ private: QPrinter::PaperSource paperSource; QPrinter::PaperSize printerPaperSize; - QRect cupsPaperRect; - QRect cupsPageRect; QSizeF customPaperSize; // in postscript points int fd; diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 2fd6f60de5..176d1ad5f6 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -41,19 +41,18 @@ #include "qprinter_p.h" #include "qprinter.h" + +#ifndef QT_NO_PRINTER + +#include +#include + #include "qprintengine.h" #include "qprinterinfo.h" #include "qlist.h" #include #include -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) -#include "private/qcups_p.h" -#endif -#ifndef QT_NO_PRINTER - -#include -#include #include #if defined(Q_WS_X11) @@ -150,32 +149,14 @@ Q_PRINTSUPPORT_EXPORT QSizeF qt_printerPaperSize(QPrinter::Orientation orientati void QPrinterPrivate::createDefaultEngines() { - QPrinter::OutputFormat realOutputFormat = outputFormat; -#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC) - if(outputFormat == QPrinter::NativeFormat) { - realOutputFormat = QPrinter::PdfFormat; - } -#endif - - switch (realOutputFormat) { - case QPrinter::NativeFormat: { - QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); - if (ps) { - printEngine = ps->createNativePrintEngine(printerMode); - paintEngine = ps->createPaintEngine(printEngine, printerMode); - } else { - QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode); - paintEngine = pdfEngine; - printEngine = pdfEngine; - } - } - break; - case QPrinter::PdfFormat: { + QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); + if (outputFormat == QPrinter::NativeFormat && ps) { + printEngine = ps->createNativePrintEngine(printerMode); + paintEngine = ps->createPaintEngine(printEngine, printerMode); + } else { QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode); paintEngine = pdfEngine; printEngine = pdfEngine; - } - break; } use_default_engine = true; had_default_engines = true; @@ -236,7 +217,7 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke When printing directly to a printer on Windows or Mac OS X, QPrinter uses the built-in printer drivers. On X11, QPrinter uses the - \l{Common Unix Printing System (CUPS)} or the standard Unix \l lpr utility + \l{Common Unix Printing System (CUPS)} to send PDF output to the printer. As an alternative, the printProgram() function can be used to specify the command or utility to use instead of the system default. @@ -513,9 +494,7 @@ QPrinter::QPrinter(PrinterMode mode) QPrinterInfo defPrn(QPrinterInfo::defaultPrinter()); if (!defPrn.isNull()) { setPrinterName(defPrn.printerName()); - } else if (QPrinterInfo::availablePrinters().isEmpty() - && d_ptr->paintEngine->type() != QPaintEngine::Windows - && d_ptr->paintEngine->type() != QPaintEngine::MacPrinter) { + } else if (QPrinterInfo::availablePrinters().isEmpty()) { setOutputFormat(QPrinter::PdfFormat); } } @@ -553,13 +532,6 @@ void QPrinterPrivate::init(QPrinter::PrinterMode mode) #endif realPrintEngine = 0; realPaintEngine = 0; - -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - if (QCUPSSupport::cupsVersion() >= 10200 && QCUPSSupport().currentPPD()) { - q_func()->setOutputFormat(QPrinter::PdfFormat); - outputFormat = QPrinter::NativeFormat; - } -#endif } /*! @@ -707,13 +679,6 @@ void QPrinter::setPrinterName(const QString &name) Q_D(QPrinter); ABORT_IF_ACTIVE("QPrinter::setPrinterName"); -#if defined(Q_OS_UNIX) && !defined(QT_NO_CUPS) - if(d->use_default_engine && d->outputFormat == QPrinter::NativeFormat) { - setOutputFormat(QPrinter::PdfFormat); - d->outputFormat = QPrinter::NativeFormat; - } -#endif - QList prnList = QPrinterInfo::availablePrinters(); if (name.isEmpty()) { d->validPrinter = d->outputFormat == QPrinter::PdfFormat; diff --git a/src/printsupport/kernel/qprinterinfo.h b/src/printsupport/kernel/qprinterinfo.h index 634b68ceb0..9370890639 100644 --- a/src/printsupport/kernel/qprinterinfo.h +++ b/src/printsupport/kernel/qprinterinfo.h @@ -85,6 +85,7 @@ private: friend class QPlatformPrinterSupport; friend class QWindowsPrinterSupport; friend class QCocoaPrinterSupport; + friend class QCupsPrinterSupport; Q_DECLARE_PRIVATE(QPrinterInfo) QScopedPointer d_ptr; }; diff --git a/src/printsupport/kernel/qprinterinfo_unix.cpp b/src/printsupport/kernel/qprinterinfo_unix.cpp deleted file mode 100644 index 05908dcf9e..0000000000 --- a/src/printsupport/kernel/qprinterinfo_unix.cpp +++ /dev/null @@ -1,858 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qprinterinfo.h" -#include "qprinterinfo_p.h" - -#include -#include -#include -#include -#include -#include - -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) -# include -# include -# include -#endif - -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PRINTER - -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) -// preserver names in ascending order for the binary search -static const struct NamedPaperSize { - const char *const name; - QPrinter::PaperSize size; -} named_sizes_map[QPrinter::NPageSize] = { - { "A0", QPrinter::A0 }, - { "A1", QPrinter::A1 }, - { "A2", QPrinter::A2 }, - { "A3", QPrinter::A3 }, - { "A4", QPrinter::A4 }, - { "A5", QPrinter::A5 }, - { "A6", QPrinter::A6 }, - { "A7", QPrinter::A7 }, - { "A8", QPrinter::A8 }, - { "A9", QPrinter::A9 }, - { "B0", QPrinter::B0 }, - { "B1", QPrinter::B1 }, - { "B10", QPrinter::B10 }, - { "B2", QPrinter::B2 }, - { "B4", QPrinter::B4 }, - { "B5", QPrinter::B5 }, - { "B6", QPrinter::B6 }, - { "B7", QPrinter::B7 }, - { "B8", QPrinter::B8 }, - { "B9", QPrinter::B9 }, - { "C5E", QPrinter::C5E }, - { "Comm10E", QPrinter::Comm10E }, - { "Custom", QPrinter::Custom }, - { "DLE", QPrinter::DLE }, - { "Executive", QPrinter::Executive }, - { "Folio", QPrinter::Folio }, - { "Ledger", QPrinter::Ledger }, - { "Legal", QPrinter::Legal }, - { "Letter", QPrinter::Letter }, - { "Tabloid", QPrinter::Tabloid } -}; - -inline bool operator<(const char *name, const NamedPaperSize &data) -{ return qstrcmp(name, data.name) < 0; } -inline bool operator<(const NamedPaperSize &data, const char *name) -{ return qstrcmp(data.name, name) < 0; } - -static inline QPrinter::PaperSize string2PaperSize(const char *name) -{ - const NamedPaperSize *r = qBinaryFind(named_sizes_map, named_sizes_map + QPrinter::NPageSize, name); - if (r - named_sizes_map != QPrinter::NPageSize) - return r->size; - return QPrinter::Custom; -} - -static inline const char *paperSize2String(QPrinter::PaperSize size) -{ - for (int i = 0; i < QPrinter::NPageSize; ++i) { - if (size == named_sizes_map[i].size) - return named_sizes_map[i].name; - } - return 0; -} -#endif - -void qt_perhapsAddPrinter(QList *printers, const QString &name, - QString host, QString comment, - QStringList aliases) -{ - for (int i = 0; i < printers->size(); ++i) - if (printers->at(i).samePrinter(name)) - return; - - if (host.isEmpty()) - host = QCoreApplication::translate("QPrinter", "locally connected"); - printers->append(QPrinterDescription(name.simplified(), host.simplified(), comment.simplified(), aliases)); -} - -void qt_parsePrinterDesc(QString printerDesc, QList *printers) -{ - if (printerDesc.length() < 1) - return; - - printerDesc = printerDesc.simplified(); - int i = printerDesc.indexOf(QLatin1Char(':')); - QString printerName, printerComment, printerHost; - QStringList aliases; - - if (i >= 0) { - // have ':' want '|' - int j = printerDesc.indexOf(QLatin1Char('|')); - if (j > 0 && j < i) { - printerName = printerDesc.left(j); - aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|')); - // try extracting a comment from the aliases - printerComment = QCoreApplication::translate("QPrinter", "Aliases: %1") - .arg(aliases.join(QLatin1String(", "))); - } else { - printerName = printerDesc.left(i); - } - // look for lprng pseudo all printers entry - i = printerDesc.indexOf(QRegExp(QLatin1String(": *all *="))); - if (i >= 0) - printerName = QString(); - // look for signs of this being a remote printer - i = printerDesc.indexOf(QRegExp(QLatin1String(": *rm *="))); - if (i >= 0) { - // point k at the end of remote host name - while (printerDesc[i] != QLatin1Char('=')) - i++; - while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace()) - i++; - j = i; - while (j < (int)printerDesc.length() && printerDesc[j] != QLatin1Char(':')) - j++; - - // and stuff that into the string - printerHost = printerDesc.mid(i, j - i); - } - } - if (printerName.length()) - qt_perhapsAddPrinter(printers, printerName, printerHost, printerComment, - aliases); -} - -int qt_parsePrintcap(QList *printers, const QString& fileName) -{ - QFile printcap(fileName); - if (!printcap.open(QIODevice::ReadOnly)) - return NotFound; - - char *line_ascii = new char[1025]; - line_ascii[1024] = '\0'; - - QString printerDesc; - bool atEnd = false; - - while (!atEnd) { - if (printcap.atEnd() || printcap.readLine(line_ascii, 1024) <= 0) - atEnd = true; - QString line = QString::fromLocal8Bit(line_ascii); - line = line.trimmed(); - if (line.length() >= 1 && line[int(line.length()) - 1] == QLatin1Char('\\')) - line.chop(1); - if (line[0] == QLatin1Char('#')) { - if (!atEnd) - continue; - } else if (line[0] == QLatin1Char('|') || line[0] == QLatin1Char(':') - || line.isEmpty()) { - printerDesc += line; - if (!atEnd) - continue; - } - - qt_parsePrinterDesc(printerDesc, printers); - - // add the first line of the new printer definition - printerDesc = line; - } - delete[] line_ascii; - return Success; -} - -/*! - \internal - - Checks $HOME/.printers for a line matching '_default ' (where - does not contain any white space). The first such match - results in being returned. - If no lines match then an empty string is returned. -*/ -QString qt_getDefaultFromHomePrinters() -{ - QFile file(QDir::homePath() + QLatin1String("/.printers")); - if (!file.open(QIODevice::ReadOnly)) - return QString(); - QString all(QLatin1String(file.readAll())); - QStringList words = all.split(QRegExp(QLatin1String("\\W+")), QString::SkipEmptyParts); - const int i = words.indexOf(QLatin1String("_default")); - if (i != -1 && i < words.size() - 1) - return words.at(i + 1); - return QString(); -} - -// solaris, not 2.6 -void qt_parseEtcLpPrinters(QList *printers) -{ - QDir lp(QLatin1String("/etc/lp/printers")); - QFileInfoList dirs = lp.entryInfoList(); - if (dirs.isEmpty()) - return; - - QString tmp; - for (int i = 0; i < dirs.size(); ++i) { - QFileInfo printer = dirs.at(i); - if (printer.isDir()) { - tmp.sprintf("/etc/lp/printers/%s/configuration", - QFile::encodeName(printer.fileName()).data()); - QFile configuration(tmp); - char *line = new char[1025]; - QString remote(QLatin1String("Remote:")); - QString contentType(QLatin1String("Content types:")); - QString printerHost; - bool canPrintPostscript = false; - if (configuration.open(QIODevice::ReadOnly)) { - while (!configuration.atEnd() && - configuration.readLine(line, 1024) > 0) { - if (QString::fromLatin1(line).startsWith(remote)) { - const char *p = line; - while (*p != ':') - p++; - p++; - while (isspace((uchar) *p)) - p++; - printerHost = QString::fromLocal8Bit(p); - printerHost = printerHost.simplified(); - } else if (QString::fromLatin1(line).startsWith(contentType)) { - char *p = line; - while (*p != ':') - p++; - p++; - char *e; - while (*p) { - while (isspace((uchar) *p)) - p++; - if (*p) { - char s; - e = p; - while (isalnum((uchar) *e)) - e++; - s = *e; - *e = '\0'; - if (!qstrcmp(p, "postscript") || - !qstrcmp(p, "any")) - canPrintPostscript = true; - *e = s; - if (s == ',') - e++; - p = e; - } - } - } - } - if (canPrintPostscript) - qt_perhapsAddPrinter(printers, printer.fileName(), - printerHost, QLatin1String("")); - } - delete[] line; - } - } -} - -// solaris 2.6 -char *qt_parsePrintersConf(QList *printers, bool *found) -{ - QFile pc(QLatin1String("/etc/printers.conf")); - if (!pc.open(QIODevice::ReadOnly)) { - if (found) - *found = false; - return 0; - } - if (found) - *found = true; - - char *line = new char[1025]; - line[1024] = '\0'; - - QString printerDesc; - int lineLength = 0; - - char *defaultPrinter = 0; - - while (!pc.atEnd() && - (lineLength=pc.readLine(line, 1024)) > 0) { - if (*line == '#') { - *line = '\0'; - lineLength = 0; - } - if (lineLength >= 2 && line[lineLength-2] == '\\') { - line[lineLength-2] = '\0'; - printerDesc += QString::fromLocal8Bit(line); - } else { - printerDesc += QString::fromLocal8Bit(line); - printerDesc = printerDesc.simplified(); - int i = printerDesc.indexOf(QLatin1Char(':')); - QString printerName, printerHost, printerComment; - QStringList aliases; - if (i >= 0) { - // have : want | - int j = printerDesc.indexOf(QLatin1Char('|')); - if (j >= i) - j = -1; - printerName = printerDesc.mid(0, j < 0 ? i : j); - if (printerName == QLatin1String("_default")) { - i = printerDesc.indexOf( - QRegExp(QLatin1String(": *use *="))); - while (printerDesc[i] != QLatin1Char('=')) - i++; - while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace()) - i++; - j = i; - while (j < (int)printerDesc.length() && - printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(',')) - j++; - // that's our default printer - defaultPrinter = - qstrdup(printerDesc.mid(i, j-i).toLatin1().data()); - printerName = QString(); - printerDesc = QString(); - } else if (printerName == QLatin1String("_all")) { - // skip it.. any other cases we want to skip? - printerName = QString(); - printerDesc = QString(); - } - - if (j > 0) { - // try extracting a comment from the aliases - aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|')); - printerComment = QCoreApplication::translate("QPrinter", "Aliases: %1") - .arg(aliases.join(QLatin1String(", "))); - } - // look for signs of this being a remote printer - i = printerDesc.indexOf( - QRegExp(QLatin1String(": *bsdaddr *="))); - if (i >= 0) { - // point k at the end of remote host name - while (printerDesc[i] != QLatin1Char('=')) - i++; - while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace()) - i++; - j = i; - while (j < (int)printerDesc.length() && - printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(',')) - j++; - // and stuff that into the string - printerHost = printerDesc.mid(i, j-i); - // maybe stick the remote printer name into the comment - if (printerDesc[j] == QLatin1Char(',')) { - i = ++j; - while (printerDesc[i].isSpace()) - i++; - j = i; - while (j < (int)printerDesc.length() && - printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(',')) - j++; - if (printerName != printerDesc.mid(i, j-i)) { - printerComment = - QLatin1String("Remote name: "); - printerComment += printerDesc.mid(i, j-i); - } - } - } - } - if (printerComment == QLatin1String(":")) - printerComment = QString(); // for cups - if (printerName.length()) - qt_perhapsAddPrinter(printers, printerName, printerHost, - printerComment, aliases); - // chop away the line, for processing the next one - printerDesc = QString(); - } - } - delete[] line; - return defaultPrinter; -} - -#ifndef QT_NO_NIS - -#if defined(Q_C_CALLBACKS) -extern "C" { -#endif - -int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */, - char *val, int valLen, char *data) -{ - qt_parsePrinterDesc(QString::fromLatin1(val, valLen), (QList *)data); - return 0; -} - -#if defined(Q_C_CALLBACKS) -} -#endif - -int qt_retrieveNisPrinters(QList *printers) -{ -#ifndef QT_NO_LIBRARY - typedef int (*WildCast)(int, char *, int, char *, int, char *); - char printersConfByname[] = "printers.conf.byname"; - char *domain; - int err; - - QLibrary lib(QLatin1String("nsl")); - typedef int (*ypGetDefaultDomain)(char **); - ypGetDefaultDomain _ypGetDefaultDomain = (ypGetDefaultDomain)lib.resolve("yp_get_default_domain"); - typedef int (*ypAll)(const char *, const char *, const struct ypall_callback *); - ypAll _ypAll = (ypAll)lib.resolve("yp_all"); - - if (_ypGetDefaultDomain && _ypAll) { - err = _ypGetDefaultDomain(&domain); - if (err == 0) { - ypall_callback cb; - // wild cast to support K&R-style system headers - (WildCast &) cb.foreach = (WildCast) qt_pd_foreach; - cb.data = (char *) printers; - err = _ypAll(domain, printersConfByname, &cb); - } - if (!err) - return Success; - } -#endif //QT_NO_LIBRARY - return Unavail; -} - -#endif // QT_NO_NIS - -char *qt_parseNsswitchPrintersEntry(QList *printers, char *line) -{ -#define skipSpaces() \ - while (line[k] != '\0' && isspace((uchar) line[k])) \ - k++ - - char *defaultPrinter = 0; - bool stop = false; - int lastStatus = NotFound; - - int k = 8; - skipSpaces(); - if (line[k] != ':') - return 0; - k++; - - char *cp = strchr(line, '#'); - if (cp != 0) - *cp = '\0'; - - while (line[k] != '\0') { - if (isspace((uchar) line[k])) { - k++; - } else if (line[k] == '[') { - k++; - skipSpaces(); - while (line[k] != '\0') { - char status = tolower(line[k]); - char action = '?'; - - while (line[k] != '=' && line[k] != ']' && line[k] != '\0') - k++; - if (line[k] == '=') { - k++; - skipSpaces(); - action = tolower(line[k]); - while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != ']') - k++; - } else if (line[k] == ']') { - k++; - break; - } - skipSpaces(); - - if (lastStatus == status) - stop = (action == (char) Return); - } - } else { - if (stop) - break; - - QByteArray source; - while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != '[') { - source += line[k]; - k++; - } - - if (source == "user") { - lastStatus = qt_parsePrintcap(printers, - QDir::homePath() + QLatin1String("/.printers")); - } else if (source == "files") { - bool found; - defaultPrinter = qt_parsePrintersConf(printers, &found); - if (found) - lastStatus = Success; -#ifndef QT_NO_NIS - } else if (source == "nis") { - lastStatus = qt_retrieveNisPrinters(printers); -#endif - } else { - // nisplus, dns, etc., are not implemented yet - lastStatus = NotFound; - } - stop = (lastStatus == Success); - } - } - return defaultPrinter; -} - -char *qt_parseNsswitchConf(QList *printers) -{ - QFile nc(QLatin1String("/etc/nsswitch.conf")); - if (!nc.open(QIODevice::ReadOnly)) - return 0; - - char *defaultPrinter = 0; - - char *line = new char[1025]; - line[1024] = '\0'; - - while (!nc.atEnd() && - nc.readLine(line, 1024) > 0) { - if (qstrncmp(line, "printers", 8) == 0) { - defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line); - delete[] line; - return defaultPrinter; - } - } - - strcpy(line, "printers: user files nis nisplus xfn"); - defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line); - delete[] line; - return defaultPrinter; -} - -// HP-UX -void qt_parseEtcLpMember(QList *printers) -{ - QDir lp(QLatin1String("/etc/lp/member")); - if (!lp.exists()) - return; - QFileInfoList dirs = lp.entryInfoList(); - if (dirs.isEmpty()) - return; - - for (int i = 0; i < dirs.size(); ++i) { - QFileInfo printer = dirs.at(i); - // I haven't found any real documentation, so I'm guessing that - // since lpstat uses /etc/lp/member rather than one of the - // other directories, it's the one to use. I did not find a - // decent way to locate aliases and remote printers. - if (printer.isFile()) - qt_perhapsAddPrinter(printers, printer.fileName(), - QCoreApplication::translate("QPrinter", "unknown"), - QLatin1String("")); - } -} - -// IRIX 6.x -void qt_parseSpoolInterface(QList *printers) -{ - QDir lp(QLatin1String("/usr/spool/lp/interface")); - if (!lp.exists()) - return; - QFileInfoList files = lp.entryInfoList(); - if(files.isEmpty()) - return; - - for (int i = 0; i < files.size(); ++i) { - QFileInfo printer = files.at(i); - - if (!printer.isFile()) - continue; - - // parse out some information - QFile configFile(printer.filePath()); - if (!configFile.open(QIODevice::ReadOnly)) - continue; - - QByteArray line; - line.resize(1025); - QString namePrinter; - QString hostName; - QString hostPrinter; - QString printerType; - - QString nameKey(QLatin1String("NAME=")); - QString typeKey(QLatin1String("TYPE=")); - QString hostKey(QLatin1String("HOSTNAME=")); - QString hostPrinterKey(QLatin1String("HOSTPRINTER=")); - - while (!configFile.atEnd() && - (configFile.readLine(line.data(), 1024)) > 0) { - QString uline = QString::fromLocal8Bit(line); - if (uline.startsWith(typeKey) ) { - printerType = uline.mid(nameKey.length()); - printerType = printerType.simplified(); - } else if (uline.startsWith(hostKey)) { - hostName = uline.mid(hostKey.length()); - hostName = hostName.simplified(); - } else if (uline.startsWith(hostPrinterKey)) { - hostPrinter = uline.mid(hostPrinterKey.length()); - hostPrinter = hostPrinter.simplified(); - } else if (uline.startsWith(nameKey)) { - namePrinter = uline.mid(nameKey.length()); - namePrinter = namePrinter.simplified(); - } - } - configFile.close(); - - printerType = printerType.trimmed(); - if (printerType.indexOf(QLatin1String("postscript"), 0, Qt::CaseInsensitive) < 0) - continue; - - int ii = 0; - while ((ii = namePrinter.indexOf(QLatin1Char('"'), ii)) >= 0) - namePrinter.remove(ii, 1); - - if (hostName.isEmpty() || hostPrinter.isEmpty()) { - qt_perhapsAddPrinter(printers, printer.fileName(), - QLatin1String(""), namePrinter); - } else { - QString comment; - comment = namePrinter; - comment += QLatin1String(" ("); - comment += hostPrinter; - comment += QLatin1Char(')'); - qt_perhapsAddPrinter(printers, printer.fileName(), - hostName, comment); - } - } -} - - -// Every unix must have its own. It's a standard. Here is AIX. -void qt_parseQconfig(QList *printers) -{ - QFile qconfig(QLatin1String("/etc/qconfig")); - if (!qconfig.open(QIODevice::ReadOnly)) - return; - - QTextStream ts(&qconfig); - QString line; - - QString stanzaName; // either a queue or a device name - bool up = true; // queue up? default true, can be false - QString remoteHost; // null if local - QString deviceName; // null if remote - - QRegExp newStanza(QLatin1String("^[0-z\\-]*:$")); - - // our basic strategy here is to process each line, detecting new - // stanzas. each time we see a new stanza, we check if the - // previous stanza was a valid queue for a) a remote printer or b) - // a local printer. if it wasn't, we assume that what we see is - // the start of the first stanza, or that the previous stanza was - // a device stanza, or that there is some syntax error (we don't - // report those). - - do { - line = ts.readLine(); - bool indented = line[0].isSpace(); - line = line.simplified(); - - int i = line.indexOf(QLatin1Char('=')); - if (indented && i != -1) { // line in stanza - QString variable = line.left(i).simplified(); - QString value=line.mid(i+1, line.length()).simplified(); - if (variable == QLatin1String("device")) - deviceName = value; - else if (variable == QLatin1String("host")) - remoteHost = value; - else if (variable == QLatin1String("up")) - up = !(value.toLower() == QLatin1String("false")); - } else if (line[0] == QLatin1Char('*')) { // comment - // nothing to do - } else if (ts.atEnd() || // end of file, or beginning of new stanza - (!indented && line.contains(newStanza))) { - if (up && stanzaName.length() > 0 && stanzaName.length() < 21) { - if (remoteHost.length()) // remote printer - qt_perhapsAddPrinter(printers, stanzaName, remoteHost, - QString()); - else if (deviceName.length()) // local printer - qt_perhapsAddPrinter(printers, stanzaName, QString(), - QString()); - } - line.chop(1); - if (line.length() >= 1 && line.length() <= 20) - stanzaName = line; - up = true; - remoteHost.clear(); - deviceName.clear(); - } else { - // syntax error? ignore. - } - } while (!ts.atEnd()); -} - -Q_PRINTSUPPORT_EXPORT int qt_getLprPrinters(QList& printers) -{ - QByteArray etcLpDefault; - qt_parsePrintcap(&printers, QLatin1String("/etc/printcap")); - qt_parseEtcLpMember(&printers); - qt_parseSpoolInterface(&printers); - qt_parseQconfig(&printers); - - QFileInfo f; - f.setFile(QLatin1String("/etc/lp/printers")); - if (f.isDir()) { - qt_parseEtcLpPrinters(&printers); - QFile def(QLatin1String("/etc/lp/default")); - if (def.open(QIODevice::ReadOnly)) { - etcLpDefault.resize(1025); - if (def.readLine(etcLpDefault.data(), 1024) > 0) { - QRegExp rx(QLatin1String("^(\\S+)")); - if (rx.indexIn(QString::fromLatin1(etcLpDefault)) != -1) - etcLpDefault = rx.cap(1).toLatin1(); - } - } - } - - char *def = 0; - f.setFile(QLatin1String("/etc/nsswitch.conf")); - if (f.isFile()) { - def = qt_parseNsswitchConf(&printers); - } else { - f.setFile(QLatin1String("/etc/printers.conf")); - if (f.isFile()) - def = qt_parsePrintersConf(&printers); - } - - if (def) { - etcLpDefault = def; - delete [] def; - } - - QString homePrintersDefault = qt_getDefaultFromHomePrinters(); - - // all printers hopefully known. try to find a good default - QString dollarPrinter; - { - dollarPrinter = QString::fromLocal8Bit(qgetenv("PRINTER")); - if (dollarPrinter.isEmpty()) - dollarPrinter = QString::fromLocal8Bit(qgetenv("LPDEST")); - if (dollarPrinter.isEmpty()) - dollarPrinter = QString::fromLocal8Bit(qgetenv("NPRINTER")); - if (dollarPrinter.isEmpty()) - dollarPrinter = QString::fromLocal8Bit(qgetenv("NGPRINTER")); - if (!dollarPrinter.isEmpty()) - qt_perhapsAddPrinter(&printers, dollarPrinter, - QCoreApplication::translate("QPrinter", "unknown"), - QLatin1String("")); - } - - QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)")); - QRegExp lp(QLatin1String("[^a-z]lp(?:[^a-z]|$)")); - - int quality = 0; - int best = 0; - for (int i = 0; i < printers.size(); ++i) { - QString name = printers.at(i).name; - QString comment = printers.at(i).comment; - if (quality < 5 && name == dollarPrinter) { - best = i; - quality = 5; - } else if (quality < 4 && !homePrintersDefault.isEmpty() && - name == homePrintersDefault) { - best = i; - quality = 4; - } else if (quality < 3 && !etcLpDefault.isEmpty() && - name == QLatin1String(etcLpDefault)) { - best = i; - quality = 3; - } else if (quality < 2 && - (name == QLatin1String("ps") || - ps.indexIn(comment) != -1)) { - best = i; - quality = 2; - } else if (quality < 1 && - (name == QLatin1String("lp") || - lp.indexIn(comment) > -1)) { - best = i; - quality = 1; - } - } - - return best; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -QList qt_getCupsPrinterPaperSizes(int cupsPrinterIndex) -{ - QList result; -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - if (!QCUPSSupport::isAvailable() || cupsPrinterIndex < 0) - return result; - // Find paper sizes from CUPS. - QCUPSSupport cups; - cups.setCurrentPrinter(cupsPrinterIndex); - if (const ppd_option_t* size = cups.pageSizes()) { - for (int j = 0; j < size->num_choices; ++j) - result.append(string2PaperSize(size->choices[j].choice)); - } -#else - Q_UNUSED(cupsPrinterIndex) -#endif - return result; -} - -#endif // QT_NO_PRINTER - -QT_END_NAMESPACE diff --git a/src/printsupport/kernel/qprinterinfo_unix_p.h b/src/printsupport/kernel/qprinterinfo_unix_p.h deleted file mode 100644 index 8e6f3d31db..0000000000 --- a/src/printsupport/kernel/qprinterinfo_unix_p.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPRINTERINFO_UNIX_P_H -#define QPRINTERINFO_UNIX_P_H - -#include -#include - -#ifndef QT_NO_NIS -# ifndef BOOL_DEFINED -# define BOOL_DEFINED -# endif - -# include -# include -# include -# include -#endif // QT_NO_NIS - -#ifdef Success -# undef Success -#endif - -#include - -QT_BEGIN_NAMESPACE - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QT_NO_PRINTER - -struct QPrinterDescription { - QPrinterDescription(const QString &n, const QString &h, const QString &c, const QStringList &a) - : name(n), host(h), comment(c), aliases(a) {} - QString name; - QString host; - QString comment; - QStringList aliases; - bool samePrinter(const QString& printer) const { - return name == printer || aliases.contains(printer); - } -}; - -enum { Success = 's', Unavail = 'u', NotFound = 'n', TryAgain = 't' }; -enum { Continue = 'c', Return = 'r' }; - -void qt_perhapsAddPrinter(QList *printers, const QString &name, - QString host, QString comment, - QStringList aliases = QStringList()); -void qt_parsePrinterDesc(QString printerDesc, QList *printers); - -int qt_parsePrintcap(QList *printers, const QString& fileName); -QString qt_getDefaultFromHomePrinters(); -void qt_parseEtcLpPrinters(QList *printers); -char *qt_parsePrintersConf(QList *printers, bool *found = 0); - -#ifndef QT_NO_NIS -#if defined(Q_C_CALLBACKS) -extern "C" { -#endif -int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */, - char *val, int valLen, char *data); - -#if defined(Q_C_CALLBACKS) -} -#endif -int qt_retrieveNisPrinters(QList *printers); -#endif // QT_NO_NIS -char *qt_parseNsswitchPrintersEntry(QList *printers, char *line); -char *qt_parseNsswitchConf(QList *printers); -void qt_parseEtcLpMember(QList *printers); -void qt_parseSpoolInterface(QList *printers); -void qt_parseQconfig(QList *printers); -int qt_getLprPrinters(QList& printers); - -QList qt_getCupsPrinterPaperSizes(int cupsPrinterIndex); - -#endif // QT_NO_PRINTER - -QT_END_NAMESPACE - -#endif // QPRINTERINFO_UNIX_P_H -- cgit v1.2.3