summaryrefslogtreecommitdiffstats
path: root/src/printsupport/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/printsupport/kernel')
-rw-r--r--src/printsupport/kernel/kernel.pri34
-rw-r--r--src/printsupport/kernel/qcups.cpp446
-rw-r--r--src/printsupport/kernel/qcups_p.h133
-rw-r--r--src/printsupport/kernel/qpaintengine_alpha.cpp516
-rw-r--r--src/printsupport/kernel/qpaintengine_alpha_p.h135
-rw-r--r--src/printsupport/kernel/qpaintengine_preview.cpp223
-rw-r--r--src/printsupport/kernel/qpaintengine_preview_p.h106
-rw-r--r--src/printsupport/kernel/qplatformprintersupport_qpa.cpp133
-rw-r--r--src/printsupport/kernel/qplatformprintersupport_qpa.h84
-rw-r--r--src/printsupport/kernel/qplatformprintplugin.cpp72
-rw-r--r--src/printsupport/kernel/qplatformprintplugin_qpa.h94
-rw-r--r--src/printsupport/kernel/qprintengine.h119
-rw-r--r--src/printsupport/kernel/qprintengine_pdf.cpp666
-rw-r--r--src/printsupport/kernel/qprintengine_pdf_p.h165
-rw-r--r--src/printsupport/kernel/qprinter.cpp2264
-rw-r--r--src/printsupport/kernel/qprinter.h279
-rw-r--r--src/printsupport/kernel/qprinter_p.h131
-rw-r--r--src/printsupport/kernel/qprinterinfo.cpp205
-rw-r--r--src/printsupport/kernel/qprinterinfo.h91
-rw-r--r--src/printsupport/kernel/qprinterinfo_p.h108
-rw-r--r--src/printsupport/kernel/qprinterinfo_unix.cpp857
-rw-r--r--src/printsupport/kernel/qprinterinfo_unix_p.h130
22 files changed, 6991 insertions, 0 deletions
diff --git a/src/printsupport/kernel/kernel.pri b/src/printsupport/kernel/kernel.pri
new file mode 100644
index 0000000000..3868d9e212
--- /dev/null
+++ b/src/printsupport/kernel/kernel.pri
@@ -0,0 +1,34 @@
+HEADERS += \
+ $$PWD/qpaintengine_alpha_p.h \
+ $$PWD/qpaintengine_preview_p.h \
+ $$PWD/qprintengine.h \
+ $$PWD/qprinter.h \
+ $$PWD/qprinter_p.h \
+ $$PWD/qprinterinfo.h \
+ $$PWD/qprinterinfo_p.h \
+ $$PWD/qplatformprintplugin_qpa.h \
+ $$PWD/qplatformprintersupport_qpa.h
+
+SOURCES += \
+ $$PWD/qpaintengine_alpha.cpp \
+ $$PWD/qpaintengine_preview.cpp \
+ $$PWD/qprintengine_pdf.cpp \
+ $$PWD/qprinter.cpp \
+ $$PWD/qprinterinfo.cpp \
+ $$PWD/qplatformprintplugin.cpp \
+ $$PWD/qplatformprintersupport_qpa.cpp
+
+unix:!symbian {
+ HEADERS += \
+ $$PWD/qprinterinfo_unix_p.h
+ SOURCES += \
+ $$PWD/qprinterinfo_unix.cpp
+}
+
+
+x11|qpa:!win32 {
+ SOURCES += $$PWD/qcups.cpp
+ HEADERS += $$PWD/qcups_p.h
+} else {
+ DEFINES += QT_NO_CUPS QT_NO_LPR
+}
diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp
new file mode 100644
index 0000000000..76050d9d71
--- /dev/null
+++ b/src/printsupport/kernel/qcups.cpp
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 <qdebug.h>
+#include "qcups_p.h"
+#include "qprinterinfo_unix_p.h"
+
+#ifndef QT_NO_CUPS
+
+#ifndef QT_LINUXBASE // LSB merges everything into cups.h
+# include <cups/language.h>
+#endif
+#include <qtextcodec.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef int (*CupsGetDests)(cups_dest_t **dests);
+typedef void (*CupsFreeDests)(int num_dests, cups_dest_t *dests);
+typedef const char* (*CupsGetPPD)(const char *printer);
+typedef int (*CupsMarkOptions)(ppd_file_t *ppd, int num_options, cups_option_t *options);
+typedef ppd_file_t* (*PPDOpenFile)(const char *filename);
+typedef void (*PPDMarkDefaults)(ppd_file_t *ppd);
+typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
+typedef void (*PPDClose)(ppd_file_t *ppd);
+typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
+typedef void (*CupsFreeOptions)(int num_options, cups_option_t *options);
+typedef void (*CupsSetDests)(int num_dests, cups_dest_t *dests);
+typedef cups_lang_t* (*CupsLangGet)(const char *language);
+typedef const char* (*CupsLangEncoding)(cups_lang_t *language);
+typedef int (*CupsAddOption)(const char *name, const char *value, int num_options, cups_option_t **options);
+typedef int (*CupsTempFd)(char *name, int len);
+typedef int (*CupsPrintFile)(const char * name, const char * filename, const char * title, int num_options, cups_option_t * options);
+
+static bool cupsLoaded = false;
+static int qt_cups_num_printers = 0;
+static CupsGetDests _cupsGetDests = 0;
+static CupsFreeDests _cupsFreeDests = 0;
+static CupsGetPPD _cupsGetPPD = 0;
+static PPDOpenFile _ppdOpenFile = 0;
+static PPDMarkDefaults _ppdMarkDefaults = 0;
+static PPDClose _ppdClose = 0;
+static CupsMarkOptions _cupsMarkOptions = 0;
+static PPDMarkOption _ppdMarkOption = 0;
+static CupsFreeOptions _cupsFreeOptions = 0;
+static CupsSetDests _cupsSetDests = 0;
+static CupsLangGet _cupsLangGet = 0;
+static CupsLangEncoding _cupsLangEncoding = 0;
+static CupsAddOption _cupsAddOption = 0;
+static CupsTempFd _cupsTempFd = 0;
+static CupsPrintFile _cupsPrintFile = 0;
+
+static void resolveCups()
+{
+ QLibrary cupsLib(QLatin1String("cups"), 2);
+ if(cupsLib.load()) {
+ _cupsGetDests = (CupsGetDests) cupsLib.resolve("cupsGetDests");
+ _cupsFreeDests = (CupsFreeDests) cupsLib.resolve("cupsFreeDests");
+ _cupsGetPPD = (CupsGetPPD) cupsLib.resolve("cupsGetPPD");
+ _cupsLangGet = (CupsLangGet) cupsLib.resolve("cupsLangGet");
+ _cupsLangEncoding = (CupsLangEncoding) cupsLib.resolve("cupsLangEncoding");
+ _ppdOpenFile = (PPDOpenFile) cupsLib.resolve("ppdOpenFile");
+ _ppdMarkDefaults = (PPDMarkDefaults) cupsLib.resolve("ppdMarkDefaults");
+ _ppdClose = (PPDClose) cupsLib.resolve("ppdClose");
+ _cupsMarkOptions = (CupsMarkOptions) cupsLib.resolve("cupsMarkOptions");
+ _ppdMarkOption = (PPDMarkOption) cupsLib.resolve("ppdMarkOption");
+ _cupsFreeOptions = (CupsFreeOptions) cupsLib.resolve("cupsFreeOptions");
+ _cupsSetDests = (CupsSetDests) cupsLib.resolve("cupsSetDests");
+ _cupsAddOption = (CupsAddOption) cupsLib.resolve("cupsAddOption");
+ _cupsTempFd = (CupsTempFd) cupsLib.resolve("cupsTempFd");
+ _cupsPrintFile = (CupsPrintFile) cupsLib.resolve("cupsPrintFile");
+
+ if (_cupsGetDests && _cupsFreeDests) {
+ cups_dest_t *printers;
+ int num_printers = _cupsGetDests(&printers);
+ if (num_printers)
+ _cupsFreeDests(num_printers, printers);
+ qt_cups_num_printers = num_printers;
+ }
+ }
+ cupsLoaded = true;
+}
+
+// ================ CUPS Support class ========================
+
+QCUPSSupport::QCUPSSupport()
+ :
+ prnCount(0),
+ printers(0),
+ page_sizes(0),
+ currPrinterIndex(0),
+ currPPD(0)
+{
+ if (!cupsLoaded)
+ resolveCups();
+
+ // getting all available printers
+ if (!isAvailable())
+ return;
+
+ prnCount = _cupsGetDests(&printers);
+
+ for (int i = 0; i < prnCount; ++i) {
+ if (printers[i].is_default) {
+ currPrinterIndex = i;
+ setCurrentPrinter(i);
+ break;
+ }
+ }
+
+#ifndef QT_NO_TEXTCODEC
+ cups_lang_t *cupsLang = _cupsLangGet(0);
+ codec = QTextCodec::codecForName(_cupsLangEncoding(cupsLang));
+ if (!codec)
+ codec = QTextCodec::codecForLocale();
+#endif
+}
+
+QCUPSSupport::~QCUPSSupport()
+{
+ if (currPPD)
+ _ppdClose(currPPD);
+ if (prnCount)
+ _cupsFreeDests(prnCount, printers);
+}
+
+int QCUPSSupport::availablePrintersCount() const
+{
+ return prnCount;
+}
+
+const cups_dest_t* QCUPSSupport::availablePrinters() const
+{
+ return printers;
+}
+
+const ppd_file_t* QCUPSSupport::currentPPD() const
+{
+ return currPPD;
+}
+
+const ppd_file_t* QCUPSSupport::setCurrentPrinter(int index)
+{
+ Q_ASSERT(index >= 0 && index <= prnCount);
+ if (index == prnCount)
+ return 0;
+
+ currPrinterIndex = index;
+
+ if (currPPD)
+ _ppdClose(currPPD);
+ currPPD = 0;
+ page_sizes = 0;
+
+ const char *ppdFile = _cupsGetPPD(printers[index].name);
+
+ if (!ppdFile)
+ return 0;
+
+ currPPD = _ppdOpenFile(ppdFile);
+ unlink(ppdFile);
+
+ // marking default options
+ _ppdMarkDefaults(currPPD);
+
+ // marking options explicitly set
+ _cupsMarkOptions(currPPD, printers[currPrinterIndex].num_options, printers[currPrinterIndex].options);
+
+ // getting pointer to page sizes
+ page_sizes = ppdOption("PageSize");
+
+ return currPPD;
+}
+
+int QCUPSSupport::currentPrinterIndex() const
+{
+ return currPrinterIndex;
+}
+
+bool QCUPSSupport::isAvailable()
+{
+ if(!cupsLoaded)
+ resolveCups();
+
+ return _cupsGetDests &&
+ _cupsFreeDests &&
+ _cupsGetPPD &&
+ _ppdOpenFile &&
+ _ppdMarkDefaults &&
+ _ppdClose &&
+ _cupsMarkOptions &&
+ _ppdMarkOption &&
+ _cupsFreeOptions &&
+ _cupsSetDests &&
+ _cupsLangGet &&
+ _cupsLangEncoding &&
+ _cupsAddOption &&
+ (qt_cups_num_printers > 0);
+}
+
+const ppd_option_t* QCUPSSupport::ppdOption(const char *key) const
+{
+ if (currPPD) {
+ for (int gr = 0; gr < currPPD->num_groups; ++gr) {
+ for (int opt = 0; opt < currPPD->groups[gr].num_options; ++opt) {
+ if (qstrcmp(currPPD->groups[gr].options[opt].keyword, key) == 0)
+ return &currPPD->groups[gr].options[opt];
+ }
+ }
+ }
+ return 0;
+}
+
+const cups_option_t* QCUPSSupport::printerOption(const QString &key) const
+{
+ for (int i = 0; i < printers[currPrinterIndex].num_options; ++i) {
+ if (QLatin1String(printers[currPrinterIndex].options[i].name) == key)
+ return &printers[currPrinterIndex].options[i];
+ }
+ return 0;
+}
+
+const ppd_option_t* QCUPSSupport::pageSizes() const
+{
+ return page_sizes;
+}
+
+int QCUPSSupport::markOption(const char* name, const char* value)
+{
+ return _ppdMarkOption(currPPD, name, value);
+}
+
+void QCUPSSupport::saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions)
+{
+ int oldOptionCount = printers[currPrinterIndex].num_options;
+ cups_option_t* oldOptions = printers[currPrinterIndex].options;
+
+ int newOptionCount = 0;
+ cups_option_t* newOptions = 0;
+
+ // copying old options that are not on the new list
+ for (int i = 0; i < oldOptionCount; ++i) {
+ bool contains = false;
+ for (int j = 0; j < options.count(); ++j) {
+ if (qstrcmp(options.at(j)->keyword, oldOptions[i].name) == 0) {
+ contains = true;
+ break;
+ }
+ }
+
+ if (!contains) {
+ newOptionCount = _cupsAddOption(oldOptions[i].name, oldOptions[i].value, newOptionCount, &newOptions);
+ }
+ }
+
+ // we can release old option list
+ _cupsFreeOptions(oldOptionCount, oldOptions);
+
+ // adding marked options
+ for (int i = 0; i < markedOptions.count(); ++i) {
+ const char* name = markedOptions.at(i);
+ ++i;
+ newOptionCount = _cupsAddOption(name, markedOptions.at(i), newOptionCount, &newOptions);
+ }
+
+ // placing the new option list
+ printers[currPrinterIndex].num_options = newOptionCount;
+ printers[currPrinterIndex].options = newOptions;
+
+ // saving new default values
+ _cupsSetDests(prnCount, printers);
+}
+
+QRect QCUPSSupport::paperRect(const char *choice) const
+{
+ if (!currPPD)
+ return QRect();
+ for (int i = 0; i < currPPD->num_sizes; ++i) {
+ if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
+ return QRect(0, 0, qRound(currPPD->sizes[i].width), qRound(currPPD->sizes[i].length));
+ }
+ return QRect();
+}
+
+QRect QCUPSSupport::pageRect(const char *choice) const
+{
+ if (!currPPD)
+ return QRect();
+ for (int i = 0; i < currPPD->num_sizes; ++i) {
+ if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
+ return QRect(qRound(currPPD->sizes[i].left),
+ qRound(currPPD->sizes[i].length - currPPD->sizes[i].top),
+ qRound(currPPD->sizes[i].right - currPPD->sizes[i].left),
+ qRound(currPPD->sizes[i].top - currPPD->sizes[i].bottom));
+ }
+ return QRect();
+}
+
+QStringList QCUPSSupport::options() const
+{
+ QStringList list;
+ collectMarkedOptions(list);
+ return list;
+}
+
+bool QCUPSSupport::printerHasPPD(const char *printerName)
+{
+ if (!isAvailable())
+ return false;
+ const char *ppdFile = _cupsGetPPD(printerName);
+ if (ppdFile)
+ unlink(ppdFile);
+ return (ppdFile != 0);
+}
+
+QString QCUPSSupport::unicodeString(const char *s)
+{
+#ifndef QT_NO_TEXTCODEC
+ return codec->toUnicode(s);
+#else
+ return QLatin1String(s);
+#endif
+}
+
+void QCUPSSupport::collectMarkedOptions(QStringList& list, const ppd_group_t* group) const
+{
+ if (group == 0) {
+ if (!currPPD)
+ return;
+ for (int i = 0; i < currPPD->num_groups; ++i) {
+ collectMarkedOptions(list, &currPPD->groups[i]);
+ collectMarkedOptionsHelper(list, &currPPD->groups[i]);
+ }
+ } else {
+ for (int i = 0; i < group->num_subgroups; ++i)
+ collectMarkedOptionsHelper(list, &group->subgroups[i]);
+ }
+}
+
+void QCUPSSupport::collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const
+{
+ for (int i = 0; i < group->num_options; ++i) {
+ for (int j = 0; j < group->options[i].num_choices; ++j) {
+ if (group->options[i].choices[j].marked == 1 && qstrcmp(group->options[i].choices[j].choice, group->options[i].defchoice) != 0)
+ list << QString::fromLocal8Bit(group->options[i].keyword) << QString::fromLocal8Bit(group->options[i].choices[j].choice);
+ }
+ }
+}
+
+QPair<int, QString> QCUPSSupport::tempFd()
+{
+ char filename[512];
+ int fd = _cupsTempFd(filename, 512);
+ return QPair<int, QString>(fd, QString::fromLocal8Bit(filename));
+}
+
+// Prints the given file and returns a job id.
+int QCUPSSupport::printFile(const char * printerName, const char * filename, const char * title,
+ int num_options, cups_option_t * options)
+{
+ return _cupsPrintFile(printerName, filename, title, num_options, options);
+}
+
+QCUPSSupport::Printer::Printer(const QString &n) : name(n), isDefault(false), cupsPrinterIndex(-1)
+{
+}
+
+QList<QCUPSSupport::Printer> QCUPSSupport::availableUnixPrinters()
+{
+ QList<Printer> printers;
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::isAvailable()) {
+ QCUPSSupport cups;
+ int cupsPrinterCount = cups.availablePrintersCount();
+ const cups_dest_t* cupsPrinters = cups.availablePrinters();
+ for (int i = 0; i < cupsPrinterCount; ++i) {
+ QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
+ if (cupsPrinters[i].instance)
+ printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
+
+ Printer p(printerName);
+ if (cupsPrinters[i].is_default)
+ p.isDefault = true;
+ p.cupsPrinterIndex = i;
+ printers.append(p);
+ }
+ } else
+#endif
+ {
+ QList<QPrinterDescription> 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;
+}
+
+QList<QPrinter::PaperSize> QCUPSSupport::getCupsPrinterPaperSizes(int cupsPrinterIndex)
+{
+ return qt_getCupsPrinterPaperSizes(cupsPrinterIndex);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_CUPS
diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h
new file mode 100644
index 0000000000..cb7a79e486
--- /dev/null
+++ b/src/printsupport/kernel/qcups_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QCUPS_P_H
+#define QCUPS_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 "QtCore/qstring.h"
+#include "QtCore/qstringlist.h"
+#include "QtCore/qpair.h"
+#include "QtPrintSupport/qprinter.h"
+
+#ifndef QT_NO_CUPS
+#include <QtCore/qlibrary.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_TYPEINFO(cups_option_t, Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE);
+
+class Q_PRINTSUPPORT_EXPORT QCUPSSupport
+{
+public:
+ struct Printer
+ {
+ Printer(const QString &name = QString());
+
+ QString name;
+ bool isDefault;
+ int cupsPrinterIndex;
+ };
+ QCUPSSupport();
+ ~QCUPSSupport();
+
+ static bool isAvailable();
+ static int cupsVersion() { return isAvailable() ? CUPS_VERSION_MAJOR*10000+CUPS_VERSION_MINOR*100+CUPS_VERSION_PATCH : 0; }
+ int availablePrintersCount() const;
+ const cups_dest_t* availablePrinters() const;
+ int currentPrinterIndex() const;
+ const ppd_file_t* setCurrentPrinter(int index);
+
+ const ppd_file_t* currentPPD() const;
+ const ppd_option_t* ppdOption(const char *key) const;
+
+ const cups_option_t* printerOption(const QString &key) const;
+ const ppd_option_t* pageSizes() const;
+
+ int markOption(const char* name, const char* value);
+ void saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions);
+
+ QRect paperRect(const char *choice) const;
+ QRect pageRect(const char *choice) const;
+
+ QStringList options() const;
+
+ static bool printerHasPPD(const char *printerName);
+
+ QString unicodeString(const char *s);
+
+ QPair<int, QString> tempFd();
+ int printFile(const char * printerName, const char * filename, const char * title,
+ int num_options, cups_option_t * options);
+
+ static QList<Printer> availableUnixPrinters();
+ static QList<QPrinter::PaperSize> getCupsPrinterPaperSizes(int cupsPrinterIndex);
+
+private:
+ void collectMarkedOptions(QStringList& list, const ppd_group_t* group = 0) const;
+ void collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const;
+
+ int prnCount;
+ cups_dest_t *printers;
+ const ppd_option_t* page_sizes;
+ int currPrinterIndex;
+ ppd_file_t *currPPD;
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec *codec;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_CUPS
+
+#endif
diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp
new file mode 100644
index 0000000000..beda2c7144
--- /dev/null
+++ b/src/printsupport/kernel/qpaintengine_alpha.cpp
@@ -0,0 +1,516 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 <qglobal.h>
+
+#ifndef QT_NO_PRINTER
+#include <qdebug.h>
+#include "private/qpaintengine_alpha_p.h"
+
+#include "private/qpicture_p.h"
+#include "private/qfont_p.h"
+#include "QtGui/qpicture.h"
+
+QT_BEGIN_NAMESPACE
+
+QAlphaPaintEngine::QAlphaPaintEngine(QAlphaPaintEnginePrivate &data, PaintEngineFeatures devcaps)
+ : QPaintEngine(data, devcaps)
+{
+
+}
+
+QAlphaPaintEngine::~QAlphaPaintEngine()
+{
+
+}
+
+bool QAlphaPaintEngine::begin(QPaintDevice *pdev)
+{
+ Q_D(QAlphaPaintEngine);
+
+ d->m_continueCall = true;
+ if (d->m_pass != 0) {
+ return true;
+ }
+
+ d->m_savedcaps = gccaps;
+ d->m_pdev = pdev;
+
+ d->m_alphaPen = false;
+ d->m_alphaBrush = false;
+ d->m_alphaOpacity = false;
+ d->m_hasalpha = false;
+ d->m_advancedPen = false;
+ d->m_advancedBrush = false;
+ d->m_complexTransform = false;
+ d->m_emulateProjectiveTransforms = false;
+
+ // clear alpha region
+ d->m_alphargn = QRegion();
+ d->m_cliprgn = QRegion();
+ d->m_pen = QPen();
+ d->m_transform = QTransform();
+
+ flushAndInit();
+
+ return true;
+}
+
+bool QAlphaPaintEngine::end()
+{
+ Q_D(QAlphaPaintEngine);
+
+ d->m_continueCall = true;
+ if (d->m_pass != 0) {
+ return true;
+ }
+
+ flushAndInit(false);
+ return true;
+}
+
+void QAlphaPaintEngine::updateState(const QPaintEngineState &state)
+{
+ Q_D(QAlphaPaintEngine);
+
+ DirtyFlags flags = state.state();
+ if (flags & QPaintEngine::DirtyTransform) {
+ d->m_transform = state.transform();
+ d->m_complexTransform = (d->m_transform.type() > QTransform::TxScale);
+ d->m_emulateProjectiveTransforms = !(d->m_savedcaps & QPaintEngine::PerspectiveTransform)
+ && !(d->m_savedcaps & QPaintEngine::AlphaBlend)
+ && (d->m_transform.type() >= QTransform::TxProject);
+ }
+ if (flags & QPaintEngine::DirtyPen) {
+ d->m_pen = state.pen();
+ if (d->m_pen.style() == Qt::NoPen) {
+ d->m_advancedPen = false;
+ d->m_alphaPen = false;
+ } else {
+ d->m_advancedPen = (d->m_pen.brush().style() != Qt::SolidPattern);
+ d->m_alphaPen = !d->m_pen.brush().isOpaque();
+ }
+ }
+
+ if (d->m_pass != 0) {
+ d->m_continueCall = true;
+ return;
+ }
+ d->m_continueCall = false;
+
+ if (flags & QPaintEngine::DirtyOpacity) {
+ d->m_alphaOpacity = (state.opacity() != 1.0f);
+ }
+
+ if (flags & QPaintEngine::DirtyBrush) {
+ if (state.brush().style() == Qt::NoBrush) {
+ d->m_advancedBrush = false;
+ d->m_alphaBrush = false;
+ } else {
+ d->m_advancedBrush = (state.brush().style() != Qt::SolidPattern);
+ d->m_alphaBrush = !state.brush().isOpaque();
+ }
+ }
+
+
+ d->m_hasalpha = d->m_alphaOpacity || d->m_alphaBrush || d->m_alphaPen;
+
+ if (d->m_picengine)
+ d->m_picengine->updateState(state);
+}
+
+void QAlphaPaintEngine::drawPath(const QPainterPath &path)
+{
+ Q_D(QAlphaPaintEngine);
+
+ QRectF tr = d->addPenWidth(path);
+
+ if (d->m_pass == 0) {
+ d->m_continueCall = false;
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
+ d->addAlphaRect(tr);
+ }
+ if (d->m_picengine)
+ d->m_picengine->drawPath(path);
+ } else {
+ d->m_continueCall = !d->fullyContained(tr);
+ }
+}
+
+void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
+{
+ Q_D(QAlphaPaintEngine);
+
+ QPolygonF poly;
+ for (int i=0; i<pointCount; ++i)
+ poly.append(points[i]);
+
+ QPainterPath path;
+ path.addPolygon(poly);
+ QRectF tr = d->addPenWidth(path);
+
+ if (d->m_pass == 0) {
+ d->m_continueCall = false;
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
+ d->addAlphaRect(tr);
+ }
+
+ if (d->m_picengine)
+ d->m_picengine->drawPolygon(points, pointCount, mode);
+ } else {
+ d->m_continueCall = !d->fullyContained(tr);
+ }
+}
+
+void QAlphaPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+ Q_D(QAlphaPaintEngine);
+
+ QRectF tr = d->m_transform.mapRect(r);
+ if (d->m_pass == 0) {
+ d->m_continueCall = false;
+ if (pm.hasAlpha() || d->m_alphaOpacity || d->m_complexTransform || pm.isQBitmap()) {
+ d->addAlphaRect(tr);
+ }
+
+ if (d->m_picengine)
+ d->m_picengine->drawPixmap(r, pm, sr);
+
+ } else {
+ d->m_continueCall = !d->fullyContained(tr);
+ }
+}
+
+void QAlphaPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr)
+{
+ Q_D(QAlphaPaintEngine);
+
+ QRectF tr = d->m_transform.mapRect(r);
+ if (d->m_pass == 0) {
+ d->m_continueCall = false;
+ if (image.hasAlphaChannel() || d->m_alphaOpacity || d->m_complexTransform) {
+ d->addAlphaRect(tr);
+ }
+
+ if (d->m_picengine)
+ d->m_picengine->drawImage(r, image, sr);
+
+ } else {
+ d->m_continueCall = !d->fullyContained(tr);
+ }
+}
+
+void QAlphaPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QAlphaPaintEngine);
+
+ QRectF tr(p.x(), p.y() - textItem.ascent(), textItem.width() + 5, textItem.ascent() + textItem.descent() + 5);
+ tr = d->m_transform.mapRect(tr);
+
+ if (d->m_pass == 0) {
+ d->m_continueCall = false;
+ if (d->m_alphaPen || d->m_alphaOpacity || d->m_advancedPen) {
+ d->addAlphaRect(tr);
+ }
+ if (d->m_picengine) {
+ d->m_picengine->drawTextItem(p, textItem);
+ }
+ } else {
+ d->m_continueCall = !d->fullyContained(tr);
+ }
+}
+
+void QAlphaPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
+{
+ Q_D(QAlphaPaintEngine);
+
+ QRectF brect = d->m_transform.mapRect(r);
+
+ if (d->m_pass == 0) {
+ d->m_continueCall = false;
+ if (pixmap.hasAlpha() || d->m_alphaOpacity || d->m_complexTransform || pixmap.isQBitmap()) {
+ d->addAlphaRect(brect);
+ }
+ if (d->m_picengine)
+ d->m_picengine->drawTiledPixmap(r, pixmap, s);
+ } else {
+ d->m_continueCall = !d->fullyContained(brect);
+ }
+}
+
+QRegion QAlphaPaintEngine::alphaClipping() const
+{
+ Q_D(const QAlphaPaintEngine);
+ return d->m_cliprgn;
+}
+
+bool QAlphaPaintEngine::continueCall() const
+{
+ Q_D(const QAlphaPaintEngine);
+ return d->m_continueCall;
+}
+
+void QAlphaPaintEngine::flushAndInit(bool init)
+{
+ Q_D(QAlphaPaintEngine);
+ Q_ASSERT(d->m_pass == 0);
+
+ if (d->m_pic) {
+ d->m_picpainter->end();
+
+ // set clip region
+ d->m_alphargn = d->m_alphargn.intersected(QRect(0, 0, d->m_pdev->width(), d->m_pdev->height()));
+
+ // just use the bounding rect if it's a complex region..
+ QVector<QRect> rects = d->m_alphargn.rects();
+ if (rects.size() > 10) {
+ QRect br = d->m_alphargn.boundingRect();
+ d->m_alphargn = QRegion(br);
+ rects.clear();
+ rects.append(br);
+ }
+
+ d->m_cliprgn = d->m_alphargn;
+
+ // now replay the QPicture
+ ++d->m_pass; // we are now doing pass #2
+
+ // reset states
+ gccaps = d->m_savedcaps;
+
+ painter()->save();
+ d->resetState(painter());
+
+ // make sure the output from QPicture is unscaled
+ QTransform mtx;
+ mtx.scale(1.0f / (qreal(d->m_pdev->logicalDpiX()) / qreal(qt_defaultDpiX())),
+ 1.0f / (qreal(d->m_pdev->logicalDpiY()) / qreal(qt_defaultDpiY())));
+ painter()->setTransform(mtx);
+ painter()->drawPicture(0, 0, *d->m_pic);
+
+ d->m_cliprgn = QRegion();
+ d->resetState(painter());
+
+ // fill in the alpha images
+ for (int i=0; i<rects.size(); ++i)
+ d->drawAlphaImage(rects.at(i));
+
+ d->m_alphargn = QRegion();
+
+ painter()->restore();
+
+ --d->m_pass; // pass #2 finished
+
+ cleanUp();
+ }
+
+ if (init) {
+ gccaps = PaintEngineFeatures(AllFeatures & ~QPaintEngine::ObjectBoundingModeGradients);
+
+ d->m_pic = new QPicture();
+ d->m_pic->d_ptr->in_memory_only = true;
+ d->m_picpainter = new QPainter(d->m_pic);
+ d->m_picengine = d->m_picpainter->paintEngine();
+
+ // When newPage() is called and the m_picpainter is recreated
+ // we have to copy the current state of the original printer
+ // painter back to the m_picpainter
+ d->m_picpainter->setPen(painter()->pen());
+ d->m_picpainter->setBrush(painter()->brush());
+ d->m_picpainter->setBrushOrigin(painter()->brushOrigin());
+ d->m_picpainter->setFont(painter()->font());
+ d->m_picpainter->setOpacity(painter()->opacity());
+ d->m_picpainter->setTransform(painter()->combinedTransform());
+ d->m_picengine->syncState();
+ }
+}
+
+void QAlphaPaintEngine::cleanUp()
+{
+ Q_D(QAlphaPaintEngine);
+
+ delete d->m_picpainter;
+ delete d->m_pic;
+
+ d->m_picpainter = 0;
+ d->m_pic = 0;
+ d->m_picengine = 0;
+}
+
+QAlphaPaintEnginePrivate::QAlphaPaintEnginePrivate()
+ : m_pass(0),
+ m_pic(0),
+ m_picengine(0),
+ m_picpainter(0),
+ m_hasalpha(false),
+ m_alphaPen(false),
+ m_alphaBrush(false),
+ m_alphaOpacity(false),
+ m_advancedPen(false),
+ m_advancedBrush(false),
+ m_complexTransform(false)
+{
+
+}
+
+QAlphaPaintEnginePrivate::~QAlphaPaintEnginePrivate()
+{
+ delete m_picpainter;
+ delete m_pic;
+}
+
+QRectF QAlphaPaintEnginePrivate::addPenWidth(const QPainterPath &path)
+{
+ QPainterPath tmp = path;
+
+ if (m_pen.style() == Qt::NoPen)
+ return (path.controlPointRect() * m_transform).boundingRect();
+ if (m_pen.isCosmetic())
+ tmp = path * m_transform;
+
+ QPainterPathStroker stroker;
+ if (m_pen.widthF() == 0.0f)
+ stroker.setWidth(1.0);
+ else
+ stroker.setWidth(m_pen.widthF());
+ stroker.setJoinStyle(m_pen.joinStyle());
+ stroker.setCapStyle(m_pen.capStyle());
+ tmp = stroker.createStroke(tmp);
+ if (m_pen.isCosmetic())
+ return tmp.controlPointRect();
+
+ return (tmp.controlPointRect() * m_transform).boundingRect();
+}
+
+QRect QAlphaPaintEnginePrivate::toRect(const QRectF &rect) const
+{
+ QRect r;
+ r.setLeft(int(rect.left()));
+ r.setTop(int(rect.top()));
+ r.setRight(int(rect.right() + 1));
+ r.setBottom(int(rect.bottom() + 1));
+ return r;
+}
+
+void QAlphaPaintEnginePrivate::addAlphaRect(const QRectF &rect)
+{
+ m_alphargn |= toRect(rect);
+}
+
+void QAlphaPaintEnginePrivate::drawAlphaImage(const QRectF &rect)
+{
+ Q_Q(QAlphaPaintEngine);
+
+ qreal dpiX = qMax(m_pdev->logicalDpiX(), 300);
+ qreal dpiY = qMax(m_pdev->logicalDpiY(), 300);
+ qreal xscale = (dpiX / m_pdev->logicalDpiX());
+ qreal yscale = (dpiY / m_pdev->logicalDpiY());
+
+ QTransform picscale;
+ picscale.scale(xscale, yscale);
+
+ const int tileSize = 2048;
+ QSize size((int(rect.width() * xscale)), int(rect.height() * yscale));
+ int divw = (size.width() / tileSize);
+ int divh = (size.height() / tileSize);
+ divw += 1;
+ divh += 1;
+
+ int incx = int(rect.width() / divw);
+ int incy = int(rect.height() / divh);
+
+ for (int y=0; y<divh; ++y) {
+ int ypos = int((incy * y) + rect.y());
+ int height = int((y == (divh - 1)) ? (rect.height() - (incy * y)) : incy) + 1;
+
+ for (int x=0; x<divw; ++x) {
+ int xpos = int((incx * x) + rect.x());
+ int width = int((x == (divw - 1)) ? (rect.width() - (incx * x)) : incx) + 1;
+
+ QSize imgsize((int)(width * xscale), (int)(height * yscale));
+ QImage img(imgsize, QImage::Format_RGB32);
+ img.fill(0xffffffff);
+
+ QPainter imgpainter(&img);
+ imgpainter.setTransform(picscale);
+ QPointF picpos(qreal(-xpos), qreal(-ypos));
+ imgpainter.drawPicture(picpos, *m_pic);
+ imgpainter.end();
+
+ q->painter()->setTransform(QTransform());
+ QRect r(xpos, ypos, width, height);
+ q->painter()->drawImage(r, img);
+ }
+ }
+}
+
+bool QAlphaPaintEnginePrivate::fullyContained(const QRectF &rect) const
+{
+ QRegion r(toRect(rect));
+ return (m_cliprgn.intersected(r) == r);
+}
+
+void QAlphaPaintEnginePrivate::resetState(QPainter *p)
+{
+ p->setPen(QPen());
+ p->setBrush(QBrush());
+ p->setBrushOrigin(0,0);
+ p->setBackground(QBrush());
+ p->setFont(QFont());
+ p->setTransform(QTransform());
+ // The view transform is already recorded and included in the
+ // picture we're about to replay. If we don't turn if off,
+ // the view matrix will be applied twice.
+ p->setViewTransformEnabled(false);
+ p->setClipRegion(QRegion(), Qt::NoClip);
+ p->setClipPath(QPainterPath(), Qt::NoClip);
+ p->setClipping(false);
+ p->setOpacity(1.0f);
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qpaintengine_alpha_p.h b/src/printsupport/kernel/qpaintengine_alpha_p.h
new file mode 100644
index 0000000000..5694e2a5bc
--- /dev/null
+++ b/src/printsupport/kernel/qpaintengine_alpha_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPAINTENGINE_ALPHA_P_H
+#define QPAINTENGINE_ALPHA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QT_NO_PRINTER
+#include "private/qpaintengine_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAlphaPaintEnginePrivate;
+
+class QAlphaPaintEngine : public QPaintEngine
+{
+ Q_DECLARE_PRIVATE(QAlphaPaintEngine)
+public:
+ ~QAlphaPaintEngine();
+
+ virtual bool begin(QPaintDevice *pdev);
+ virtual bool end();
+
+ virtual void updateState(const QPaintEngineState &state);
+
+ virtual void drawPath(const QPainterPath &path);
+
+ virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+
+ virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ virtual void drawImage(const QRectF &r, const QImage &image, const QRectF &sr);
+ virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
+ virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+
+protected:
+ QAlphaPaintEngine(QAlphaPaintEnginePrivate &data, PaintEngineFeatures devcaps = 0);
+ QRegion alphaClipping() const;
+ bool continueCall() const;
+ void flushAndInit(bool init = true);
+ void cleanUp();
+};
+
+class QAlphaPaintEnginePrivate : public QPaintEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QAlphaPaintEngine)
+public:
+ QAlphaPaintEnginePrivate();
+ ~QAlphaPaintEnginePrivate();
+
+ int m_pass;
+ QPicture *m_pic;
+ QPaintEngine *m_picengine;
+ QPainter *m_picpainter;
+
+ QPaintEngine::PaintEngineFeatures m_savedcaps;
+ QPaintDevice *m_pdev;
+
+ QRegion m_alphargn;
+ QRegion m_cliprgn;
+
+ bool m_hasalpha;
+ bool m_alphaPen;
+ bool m_alphaBrush;
+ bool m_alphaOpacity;
+ bool m_advancedPen;
+ bool m_advancedBrush;
+ bool m_complexTransform;
+ bool m_emulateProjectiveTransforms;
+ bool m_continueCall;
+
+ QTransform m_transform;
+ QPen m_pen;
+
+ void addAlphaRect(const QRectF &rect);
+ QRectF addPenWidth(const QPainterPath &path);
+ void drawAlphaImage(const QRectF &rect);
+ QRect toRect(const QRectF &rect) const;
+ bool fullyContained(const QRectF &rect) const;
+
+ void resetState(QPainter *p);
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPAINTENGINE_ALPHA_P_H
diff --git a/src/printsupport/kernel/qpaintengine_preview.cpp b/src/printsupport/kernel/qpaintengine_preview.cpp
new file mode 100644
index 0000000000..3cf06f5770
--- /dev/null
+++ b/src/printsupport/kernel/qpaintengine_preview.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 <private/qpaintengine_preview_p.h>
+#include <private/qpainter_p.h>
+#include <private/qpaintengine_p.h>
+#include <private/qpicture_p.h>
+
+#include <QtPrintSupport/qprintengine.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpicture.h>
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+QT_BEGIN_NAMESPACE
+
+class QPreviewPaintEnginePrivate : public QPaintEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QPreviewPaintEngine)
+public:
+ QPreviewPaintEnginePrivate() : state(QPrinter::Idle) {}
+ ~QPreviewPaintEnginePrivate() {}
+
+ QList<const QPicture *> pages;
+ QPaintEngine *engine;
+ QPainter *painter;
+ QPrinter::PrinterState state;
+
+ QPaintEngine *proxy_paint_engine;
+ QPrintEngine *proxy_print_engine;
+};
+
+
+QPreviewPaintEngine::QPreviewPaintEngine()
+ : QPaintEngine(*(new QPreviewPaintEnginePrivate), PaintEngineFeatures(AllFeatures & ~ObjectBoundingModeGradients))
+{
+ Q_D(QPreviewPaintEngine);
+ d->proxy_print_engine = 0;
+ d->proxy_paint_engine = 0;
+}
+
+QPreviewPaintEngine::~QPreviewPaintEngine()
+{
+ Q_D(QPreviewPaintEngine);
+
+ qDeleteAll(d->pages);
+}
+
+bool QPreviewPaintEngine::begin(QPaintDevice *)
+{
+ Q_D(QPreviewPaintEngine);
+
+ qDeleteAll(d->pages);
+ d->pages.clear();
+
+ QPicture *page = new QPicture;
+ page->d_func()->in_memory_only = true;
+ d->painter = new QPainter(page);
+ d->engine = d->painter->paintEngine();
+ d->pages.append(page);
+ d->state = QPrinter::Active;
+ return true;
+}
+
+bool QPreviewPaintEngine::end()
+{
+ Q_D(QPreviewPaintEngine);
+
+ delete d->painter;
+ d->painter = 0;
+ d->engine = 0;
+ d->state = QPrinter::Idle;
+ return true;
+}
+
+void QPreviewPaintEngine::updateState(const QPaintEngineState &state)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->updateState(state);
+}
+
+void QPreviewPaintEngine::drawPath(const QPainterPath &path)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawPath(path);
+}
+
+void QPreviewPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawPolygon(points, pointCount, mode);
+}
+
+void QPreviewPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawTextItem(p, textItem);
+}
+
+void QPreviewPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawPixmap(r, pm, sr);
+}
+
+void QPreviewPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawTiledPixmap(r, pm, p);
+}
+
+bool QPreviewPaintEngine::newPage()
+{
+ Q_D(QPreviewPaintEngine);
+
+ QPicture *page = new QPicture;
+ page->d_func()->in_memory_only = true;
+ QPainter *tmp_painter = new QPainter(page);
+ QPaintEngine *tmp_engine = tmp_painter->paintEngine();
+
+ // copy the painter state from the original painter
+ Q_ASSERT(painter()->d_func()->state && tmp_painter->d_func()->state);
+ *tmp_painter->d_func()->state = *painter()->d_func()->state;
+
+ // composition modes aren't supported on a QPrinter and yields a
+ // warning, so ignore it for now
+ tmp_engine->setDirty(DirtyFlags(AllDirty & ~DirtyCompositionMode));
+ tmp_engine->syncState();
+
+ delete d->painter;
+ d->painter = tmp_painter;
+ d->pages.append(page);
+ d->engine = tmp_engine;
+ return true;
+}
+
+bool QPreviewPaintEngine::abort()
+{
+ Q_D(QPreviewPaintEngine);
+ end();
+ qDeleteAll(d->pages);
+ d->state = QPrinter::Aborted;
+
+ return true;
+}
+
+QList<const QPicture *> QPreviewPaintEngine::pages()
+{
+ Q_D(QPreviewPaintEngine);
+ return d->pages;
+}
+
+void QPreviewPaintEngine::setProxyEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine)
+{
+ Q_D(QPreviewPaintEngine);
+ d->proxy_print_engine = printEngine;
+ d->proxy_paint_engine = paintEngine;
+}
+
+void QPreviewPaintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
+{
+ Q_D(QPreviewPaintEngine);
+ d->proxy_print_engine->setProperty(key, value);
+}
+
+QVariant QPreviewPaintEngine::property(PrintEnginePropertyKey key) const
+{
+ Q_D(const QPreviewPaintEngine);
+ return d->proxy_print_engine->property(key);
+}
+
+int QPreviewPaintEngine::metric(QPaintDevice::PaintDeviceMetric id) const
+{
+ Q_D(const QPreviewPaintEngine);
+ return d->proxy_print_engine->metric(id);
+}
+
+QPrinter::PrinterState QPreviewPaintEngine::printerState() const
+{
+ Q_D(const QPreviewPaintEngine);
+ return d->state;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/printsupport/kernel/qpaintengine_preview_p.h b/src/printsupport/kernel/qpaintengine_preview_p.h
new file mode 100644
index 0000000000..c2e11313c2
--- /dev/null
+++ b/src/printsupport/kernel/qpaintengine_preview_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPREVIEWPAINTENGINE_P_H
+#define QPREVIEWPAINTENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QPreviewPrinter and friends. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include <QtGui/qpaintengine.h>
+#include <QtPrintSupport/qprintengine.h>
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+
+QT_BEGIN_NAMESPACE
+
+class QPreviewPaintEnginePrivate;
+
+class QPreviewPaintEngine : public QPaintEngine, public QPrintEngine
+{
+ Q_DECLARE_PRIVATE(QPreviewPaintEngine)
+public:
+ QPreviewPaintEngine();
+ ~QPreviewPaintEngine();
+
+ bool begin(QPaintDevice *dev);
+ bool end();
+
+ void updateState(const QPaintEngineState &state);
+
+ void drawPath(const QPainterPath &path);
+ void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+ void drawTextItem(const QPointF &p, const QTextItem &textItem);
+
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p);
+
+ QList<const QPicture *> pages();
+
+ QPaintEngine::Type type() const { return Picture; }
+
+ void setProxyEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine);
+
+ void setProperty(PrintEnginePropertyKey key, const QVariant &value);
+ QVariant property(PrintEnginePropertyKey key) const;
+
+ bool newPage();
+ bool abort();
+
+ int metric(QPaintDevice::PaintDeviceMetric) const;
+
+ QPrinter::PrinterState printerState() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTPREVIEWWIDGET
+
+#endif
diff --git a/src/printsupport/kernel/qplatformprintersupport_qpa.cpp b/src/printsupport/kernel/qplatformprintersupport_qpa.cpp
new file mode 100644
index 0000000000..3c11b3304c
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintersupport_qpa.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 "qplatformprintersupport_qpa.h"
+
+#include <QtPrintSupport/qprinterinfo.h>
+
+#include <private/qprinterinfo_p.h>
+
+#ifndef QT_NO_PRINTER
+
+QT_BEGIN_NAMESPACE
+
+QPlatformPrinterSupport::QPlatformPrinterSupport()
+{
+}
+
+QPlatformPrinterSupport::~QPlatformPrinterSupport()
+{
+}
+
+QPrintEngine *QPlatformPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode)
+{
+ return 0;
+}
+
+QPaintEngine *QPlatformPrinterSupport::createPaintEngine(QPrintEngine *, QPrinter::PrinterMode)
+{
+ return 0;
+}
+
+QList<QPrinter::PaperSize> QPlatformPrinterSupport::supportedPaperSizes(const QPrinterInfo &) const
+{
+ return QList<QPrinter::PaperSize>();
+}
+
+QList<QPrinterInfo> QPlatformPrinterSupport::availablePrinters()
+{
+ return QList<QPrinterInfo>();
+}
+
+QPrinterInfo QPlatformPrinterSupport::defaultPrinter()
+{
+ const QList<QPrinterInfo> printers = availablePrinters();
+ foreach (const QPrinterInfo &printerInfo, printers) {
+ if (printerInfo.isDefault())
+ return printerInfo;
+ }
+ return printers.isEmpty() ? QPrinterInfo() : printers.front();
+}
+
+QPrinterInfo QPlatformPrinterSupport::printerInfo(const QString &printerName, bool isDefault)
+{
+ QPrinterInfo pi = QPrinterInfo(printerName);
+ pi.d_func()->isDefault = isDefault;
+ return pi;
+}
+
+void QPlatformPrinterSupport::setPrinterInfoDefault(QPrinterInfo *p, bool isDefault)
+{
+ p->d_func()->isDefault = isDefault;
+}
+
+bool QPlatformPrinterSupport::printerInfoIsDefault(const QPrinterInfo &p)
+{
+ return p.d_func()->isDefault;
+}
+
+int QPlatformPrinterSupport::printerInfoCupsPrinterIndex(const QPrinterInfo &p)
+{
+ int i = -1;
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (!p.isNull())
+ return i = p.d_func()->cupsPrinterIndex;
+#endif
+#endif
+ Q_UNUSED(p)
+ return i;
+}
+
+void QPlatformPrinterSupport::setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index)
+{
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ p->d_func()->cupsPrinterIndex = index;
+#endif
+#endif
+ Q_UNUSED(p)
+ Q_UNUSED(index)
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qplatformprintersupport_qpa.h b/src/printsupport/kernel/qplatformprintersupport_qpa.h
new file mode 100644
index 0000000000..800713c5bb
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintersupport_qpa.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPLATFORMPRINTINGSUPPORT_H
+#define QPLATFORMPRINTINGSUPPORT_H
+
+#include <QtPrintSupport/qprinter.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+
+class QPrintEngine;
+
+class Q_PRINTSUPPORT_EXPORT QPlatformPrinterSupport
+{
+public:
+ QPlatformPrinterSupport();
+ virtual ~QPlatformPrinterSupport();
+
+ virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode);
+ virtual QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode);
+ virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
+
+ virtual QList<QPrinterInfo> availablePrinters();
+ virtual QPrinterInfo defaultPrinter();
+
+protected:
+ static QPrinterInfo printerInfo(const QString &printerName, bool isDefault = false);
+ 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
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMPRINTINGSUPPORT_H
diff --git a/src/printsupport/kernel/qplatformprintplugin.cpp b/src/printsupport/kernel/qplatformprintplugin.cpp
new file mode 100644
index 0000000000..8b3c75127e
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintplugin.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 "qplatformprintplugin_qpa.h"
+#include "private/qfactoryloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QPlatformPrinterSupportFactoryInterface_iid, QLatin1String("/printsupport"), Qt::CaseInsensitive))
+#endif
+
+QPlatformPrinterSupportPlugin::QPlatformPrinterSupportPlugin(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin()
+{
+}
+
+QPlatformPrinterSupport *QPlatformPrinterSupportPlugin::get()
+{
+ QStringList k = loader()->keys();
+ if (k.isEmpty())
+ return 0;
+ QPlatformPrinterSupportPlugin *plugin = qobject_cast<QPlatformPrinterSupportPlugin *>(loader()->instance(k.first()));
+ if (!plugin)
+ return 0;
+ return plugin->create(k.first());
+}
+
+QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qplatformprintplugin_qpa.h b/src/printsupport/kernel/qplatformprintplugin_qpa.h
new file mode 100644
index 0000000000..831a0546b0
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintplugin_qpa.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPLATFORMPRINTERSUPPORTPLUGIN_H
+#define QPLATFORMPRINTERSUPPORTPLUGIN_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 <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformPrinterSupport;
+
+struct QPlatformPrinterSupportFactoryInterface : public QFactoryInterface
+{
+ virtual QPlatformPrinterSupport *create(const QString &key) = 0;
+};
+
+#define QPlatformPrinterSupportFactoryInterface_iid "org.qt-project.QPlatformPrinterSupportFactoryInterface"
+
+Q_DECLARE_INTERFACE(QPlatformPrinterSupportFactoryInterface, QPlatformPrinterSupportFactoryInterface_iid)
+
+class Q_PRINTSUPPORT_EXPORT QPlatformPrinterSupportPlugin : public QObject, public QPlatformPrinterSupportFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QPlatformPrinterSupportFactoryInterface:QFactoryInterface)
+public:
+ explicit QPlatformPrinterSupportPlugin(QObject *parent = 0);
+ ~QPlatformPrinterSupportPlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QPlatformPrinterSupport *create(const QString &key) = 0;
+
+ static QPlatformPrinterSupport *get();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMPRINTERSUPPORTPLUGIN_H
diff --git a/src/printsupport/kernel/qprintengine.h b/src/printsupport/kernel/qprintengine.h
new file mode 100644
index 0000000000..782b6ef8bd
--- /dev/null
+++ b/src/printsupport/kernel/qprintengine.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPRINTENGINE_H
+#define QPRINTENGINE_H
+
+#include <QtCore/qvariant.h>
+#include <QtPrintSupport/qprinter.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+
+class Q_PRINTSUPPORT_EXPORT QPrintEngine
+{
+public:
+ virtual ~QPrintEngine() {}
+ enum PrintEnginePropertyKey {
+ PPK_CollateCopies,
+ PPK_ColorMode,
+ PPK_Creator,
+ PPK_DocumentName,
+ PPK_FullPage,
+ PPK_NumberOfCopies,
+ PPK_Orientation,
+ PPK_OutputFileName,
+ PPK_PageOrder,
+ PPK_PageRect,
+ PPK_PageSize,
+ PPK_PaperRect,
+ PPK_PaperSource,
+ PPK_PrinterName,
+ PPK_PrinterProgram,
+ PPK_Resolution,
+ PPK_SelectionOption,
+ PPK_SupportedResolutions,
+
+ PPK_WindowsPageSize,
+ PPK_FontEmbedding,
+ PPK_SuppressSystemPrintStatus,
+
+ PPK_Duplex,
+
+ PPK_PaperSources,
+ PPK_CustomPaperSize,
+ PPK_PageMargins,
+ PPK_CopyCount,
+ PPK_SupportsMultipleCopies,
+ PPK_PaperSize = PPK_PageSize,
+
+ PPK_CustomBase = 0xff00
+ };
+
+ virtual void setProperty(PrintEnginePropertyKey key, const QVariant &value) = 0;
+ virtual QVariant property(PrintEnginePropertyKey key) const = 0;
+
+ virtual bool newPage() = 0;
+ virtual bool abort() = 0;
+
+ virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0;
+
+ virtual QPrinter::PrinterState printerState() const = 0;
+
+#ifdef Q_WS_WIN
+ virtual HDC getPrinterDC() const { return 0; }
+ virtual void releasePrinterDC(HDC) const { }
+#endif
+
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPRINTENGINE_H
diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp
new file mode 100644
index 0000000000..c8ce2cfa0f
--- /dev/null
+++ b/src/printsupport/kernel/qprintengine_pdf.cpp
@@ -0,0 +1,666 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 <QtPrintSupport/qprintengine.h>
+
+#include <qiodevice.h>
+#include <qfile.h>
+#include <qdebug.h>
+#include <qbuffer.h>
+#include "private/qcups_p.h"
+#include "qprinterinfo.h"
+
+#ifndef QT_NO_PRINTER
+#include <limits.h>
+#include <math.h>
+
+#include "qprintengine_pdf_p.h"
+
+#ifdef Q_OS_UNIX
+#include "private/qcore_unix_p.h" // overrides QT_OPEN
+#endif
+
+#ifdef Q_OS_WIN
+#include <io.h> // _close.
+#endif
+
+QT_BEGIN_NAMESPACE
+
+//#define FONT_DUMP
+
+extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size);
+
+#define Q_MM(n) int((n * 720 + 127) / 254)
+#define Q_IN(n) int(n * 72)
+
+static const char * const psToStr[QPrinter::NPageSize+1] =
+{
+ "A4", "B5", "Letter", "Legal", "Executive",
+ "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1",
+ "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E",
+ "DLE", "Folio", "Ledger", "Tabloid", 0
+};
+
+QPdf::PaperSize QPdf::paperSize(QPrinter::PaperSize paperSize)
+{
+ QSizeF s = qt_paperSizeToQSizeF(paperSize);
+ PaperSize p = { Q_MM(s.width()), Q_MM(s.height()) };
+ return p;
+}
+
+const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize)
+{
+ return psToStr[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()
+{
+}
+
+bool QPdfPrintEngine::begin(QPaintDevice *pdev)
+{
+ Q_D(QPdfPrintEngine);
+
+ if (!d->openPrintDevice()) {
+ state = QPrinter::Error;
+ return false;
+ }
+ state = QPrinter::Active;
+
+ return QPdfEngine::begin(pdev);
+}
+
+bool QPdfPrintEngine::end()
+{
+ Q_D(QPdfPrintEngine);
+
+ QPdfEngine::end();
+
+ d->closePrintDevice();
+ state = QPrinter::Idle;
+
+ return true;
+}
+
+bool QPdfPrintEngine::newPage()
+{
+ return QPdfEngine::newPage();
+}
+
+int QPdfPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
+{
+ return QPdfEngine::metric(m);
+}
+
+void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
+{
+ Q_D(QPdfPrintEngine);
+
+ switch (int(key)) {
+ case PPK_CollateCopies:
+ d->collate = value.toBool();
+ break;
+ case PPK_ColorMode:
+ d->grayscale = (QPrinter::ColorMode(value.toInt()) == QPrinter::GrayScale);
+ break;
+ case PPK_Creator:
+ d->creator = value.toString();
+ break;
+ case PPK_DocumentName:
+ d->title = value.toString();
+ break;
+ case PPK_FullPage:
+ d->fullPage = value.toBool();
+ break;
+ case PPK_CopyCount: // fallthrough
+ case PPK_NumberOfCopies:
+ d->copies = value.toInt();
+ break;
+ case PPK_Orientation:
+ d->landscape = (QPrinter::Orientation(value.toInt()) == QPrinter::Landscape);
+ break;
+ case PPK_OutputFileName:
+ d->outputFileName = value.toString();
+ break;
+ case PPK_PageOrder:
+ d->pageOrder = QPrinter::PageOrder(value.toInt());
+ break;
+ case PPK_PaperSize:
+ d->printerPaperSize = QPrinter::PaperSize(value.toInt());
+ d->updatePaperSize();
+ break;
+ case PPK_PaperSource:
+ d->paperSource = QPrinter::PaperSource(value.toInt());
+ break;
+ case PPK_PrinterName:
+ d->printerName = value.toString();
+ break;
+ case PPK_PrinterProgram:
+ d->printProgram = value.toString();
+ break;
+ case PPK_Resolution:
+ d->resolution = value.toInt();
+ break;
+ case PPK_SelectionOption:
+ d->selectionOption = value.toString();
+ break;
+ case PPK_FontEmbedding:
+ d->embedFonts = value.toBool();
+ break;
+ case PPK_Duplex:
+ d->duplex = static_cast<QPrinter::DuplexMode> (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();
+ d->updatePaperSize();
+ break;
+ case PPK_PageMargins:
+ {
+ QList<QVariant> margins(value.toList());
+ Q_ASSERT(margins.size() == 4);
+ d->leftMargin = margins.at(0).toReal();
+ d->topMargin = margins.at(1).toReal();
+ d->rightMargin = margins.at(2).toReal();
+ d->bottomMargin = margins.at(3).toReal();
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
+{
+ Q_D(const QPdfPrintEngine);
+
+ QVariant ret;
+ switch (int(key)) {
+ case PPK_CollateCopies:
+ ret = d->collate;
+ break;
+ case PPK_ColorMode:
+ ret = d->grayscale ? QPrinter::GrayScale : QPrinter::Color;
+ break;
+ case PPK_Creator:
+ ret = d->creator;
+ break;
+ case PPK_DocumentName:
+ ret = d->title;
+ break;
+ case PPK_FullPage:
+ ret = d->fullPage;
+ break;
+ case PPK_CopyCount:
+ 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;
+ break;
+ case PPK_NumberOfCopies:
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::isAvailable())
+ ret = 1;
+ else
+#endif
+ ret = d->copies;
+ break;
+ case PPK_Orientation:
+ ret = d->landscape ? QPrinter::Landscape : QPrinter::Portrait;
+ break;
+ case PPK_OutputFileName:
+ ret = d->outputFileName;
+ break;
+ case PPK_PageOrder:
+ ret = d->pageOrder;
+ break;
+ case PPK_PaperSize:
+ ret = d->paperSize;
+ break;
+ case PPK_PaperSource:
+ ret = d->paperSource;
+ break;
+ case PPK_PrinterName:
+ ret = d->printerName;
+ break;
+ case PPK_PrinterProgram:
+ ret = d->printProgram;
+ break;
+ case PPK_Resolution:
+ ret = d->resolution;
+ break;
+ case PPK_SupportedResolutions:
+ ret = QList<QVariant>() << 72;
+ break;
+ case PPK_PaperRect:
+ ret = d->paperRect();
+ break;
+ case PPK_PageRect:
+ ret = d->pageRect();
+ break;
+ case PPK_SelectionOption:
+ ret = d->selectionOption;
+ break;
+ case PPK_FontEmbedding:
+ ret = d->embedFonts;
+ break;
+ 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;
+ case PPK_PageMargins:
+ {
+ QList<QVariant> margins;
+ margins << d->leftMargin << d->topMargin
+ << d->rightMargin << d->bottomMargin;
+ ret = margins;
+ break;
+ }
+ default:
+ break;
+ }
+ return ret;
+}
+
+
+#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)
+ return false;
+
+ if (!outputFileName.isEmpty()) {
+ QFile *file = new QFile(outputFileName);
+ if (! file->open(QFile::WriteOnly|QFile::Truncate)) {
+ delete file;
+ return false;
+ }
+ outDevice = file;
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ } else if (QCUPSSupport::isAvailable()) {
+ QCUPSSupport cups;
+ QPair<int, QString> 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<QFile *>(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<QByteArray> lprhack;
+ QList<QByteArray> 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<char *>(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<QFile *>(outDevice)->open(fd, QIODevice::WriteOnly);
+#endif
+ }
+
+ return true;
+}
+
+void QPdfPrintEnginePrivate::closePrintDevice()
+{
+ if (outDevice) {
+ outDevice->close();
+ if (fd >= 0)
+ #if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400
+ ::_close(fd);
+ #else
+ ::close(fd);
+ #endif
+ fd = -1;
+ 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<QPair<QByteArray, QByteArray> > options;
+ QVector<cups_option_t> 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<QByteArray, QByteArray>("media", cupsStringPageSize.toLocal8Bit()));
+ }
+
+ if (copies > 1) {
+ options.append(QPair<QByteArray, QByteArray>("copies", QString::number(copies).toLocal8Bit()));
+ }
+
+ if (collate) {
+ options.append(QPair<QByteArray, QByteArray>("Collate", "True"));
+ }
+
+ if (duplex != QPrinter::DuplexNone) {
+ switch(duplex) {
+ case QPrinter::DuplexNone: break;
+ case QPrinter::DuplexAuto:
+ if (!landscape)
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
+ else
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
+ break;
+ case QPrinter::DuplexLongSide:
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
+ break;
+ case QPrinter::DuplexShortSide:
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
+ break;
+ }
+ }
+
+ if (QCUPSSupport::cupsVersion() >= 10300 && landscape) {
+ options.append(QPair<QByteArray, QByteArray>("landscape", ""));
+ }
+
+ QStringList::const_iterator it = cupsOptions.constBegin();
+ while (it != cupsOptions.constEnd()) {
+ options.append(QPair<QByteArray, QByteArray>((*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
+}
+
+
+
+QPdfPrintEnginePrivate::QPdfPrintEnginePrivate(QPrinter::PrinterMode m)
+ : QPdfEnginePrivate(),
+ duplex(QPrinter::DuplexNone),
+ collate(false),
+ copies(1),
+ pageOrder(QPrinter::FirstPageFirst),
+ paperSource(QPrinter::Auto),
+ printerPaperSize(QPrinter::A4),
+ fd(-1)
+{
+ resolution = 72;
+ if (m == QPrinter::HighResolution)
+ resolution = 1200;
+ else if (m == QPrinter::ScreenResolution)
+ resolution = qt_defaultDpi();
+}
+
+QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate()
+{
+}
+
+
+void QPdfPrintEnginePrivate::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/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h
new file mode 100644
index 0000000000..483cde9af9
--- /dev/null
+++ b/src/printsupport/kernel/qprintengine_pdf_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPRINTENGINE_PDF_P_H
+#define QPRINTENGINE_PDF_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 "QtCore/qmap.h"
+#include "QtGui/qmatrix.h"
+#include "QtCore/qstring.h"
+#include "QtCore/qvector.h"
+#include "QtGui/qpaintengine.h"
+#include "QtGui/qpainterpath.h"
+#include "QtCore/qdatastream.h"
+
+#include "private/qfontengine_p.h"
+#include "private/qpdf_p.h"
+#include "private/qpaintengine_p.h"
+#include "qprintengine.h"
+
+QT_BEGIN_NAMESPACE
+
+class QImage;
+class QDataStream;
+class QPen;
+class QPointF;
+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 {
+ int width, height; // in postscript points
+ };
+ Q_PRINTSUPPORT_EXPORT PaperSize paperSize(QPrinter::PaperSize paperSize);
+ Q_PRINTSUPPORT_EXPORT const char *paperSizeToString(QPrinter::PaperSize paperSize);
+}
+
+class QPdfPrintEnginePrivate;
+
+class QPdfPrintEngine : public QPdfEngine, public QPrintEngine
+{
+ Q_DECLARE_PRIVATE(QPdfPrintEngine)
+public:
+ QPdfPrintEngine(QPrinter::PrinterMode m);
+ virtual ~QPdfPrintEngine();
+
+ // reimplementations QPaintEngine
+ bool begin(QPaintDevice *pdev);
+ bool end();
+ // end reimplementations QPaintEngine
+
+ // reimplementations QPrintEngine
+ bool abort() {return false;}
+ QPrinter::PrinterState printerState() const {return state;}
+
+ bool newPage();
+ int metric(QPaintDevice::PaintDeviceMetric) const;
+ void setProperty(PrintEnginePropertyKey key, const QVariant &value);
+ QVariant property(PrintEnginePropertyKey key) const;
+ // end reimplementations QPrintEngine
+
+ QPrinter::PrinterState state;
+
+private:
+ Q_DISABLE_COPY(QPdfPrintEngine)
+};
+
+class QPdfPrintEnginePrivate : public QPdfEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QPdfPrintEngine)
+public:
+ QPdfPrintEnginePrivate(QPrinter::PrinterMode m);
+ ~QPdfPrintEnginePrivate();
+
+ bool openPrintDevice();
+ void closePrintDevice();
+
+ void updatePaperSize();
+
+private:
+ Q_DISABLE_COPY(QPdfPrintEnginePrivate)
+
+ QString printerName;
+ QString printProgram;
+ QString selectionOption;
+ QStringList cupsOptions;
+ QString cupsStringPageSize;
+
+ QPrinter::DuplexMode duplex;
+ bool collate;
+ int copies;
+ QPrinter::PageOrder pageOrder;
+ QPrinter::PaperSource paperSource;
+
+ QPrinter::PaperSize printerPaperSize;
+ QRect cupsPaperRect;
+ QRect cupsPageRect;
+ QSizeF customPaperSize; // in postscript points
+
+ int fd;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPRINTENGINE_PDF_P_H
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
new file mode 100644
index 0000000000..ae215945d3
--- /dev/null
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -0,0 +1,2264 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 "qprinter_p.h"
+#include "qprinter.h"
+#include "qprintengine.h"
+#include "qprinterinfo.h"
+#include "qlist.h"
+#include <qcoreapplication.h>
+#include <qfileinfo.h>
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+#include "private/qcups_p.h"
+#endif
+
+#ifndef QT_NO_PRINTER
+
+#include "qplatformprintplugin_qpa.h"
+#include <QtPrintSupport/QPlatformPrinterSupport>
+#include <private/qpagedpaintdevice_p.h>
+
+#if defined (Q_WS_WIN)
+#include <private/qprintengine_win_p.h>
+#elif defined (Q_WS_MAC)
+#include <private/qprintengine_mac_p.h>
+#elif defined (QTOPIA_PRINTENGINE)
+#include <private/qprintengine_qws_p.h>
+#endif
+
+#if defined(Q_WS_X11)
+#include <private/qt_x11_p.h>
+#endif
+
+#ifndef QT_NO_PDF
+#include "qprintengine_pdf_p.h"
+#endif
+
+#include <qpicture.h>
+#include <private/qpaintengine_preview_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#define ABORT_IF_ACTIVE(location) \
+ if (d->printEngine->printerState() == QPrinter::Active) { \
+ qWarning("%s: Cannot be changed while printer is active", location); \
+ return; \
+ }
+
+// NB! This table needs to be in sync with QPrinter::PaperSize
+static const float qt_paperSizes[][2] = {
+ {210, 297}, // A4
+ {176, 250}, // B5
+ {215.9f, 279.4f}, // Letter
+ {215.9f, 355.6f}, // Legal
+ {190.5f, 254}, // Executive
+ {841, 1189}, // A0
+ {594, 841}, // A1
+ {420, 594}, // A2
+ {297, 420}, // A3
+ {148, 210}, // A5
+ {105, 148}, // A6
+ {74, 105}, // A7
+ {52, 74}, // A8
+ {37, 52}, // A8
+ {1000, 1414}, // B0
+ {707, 1000}, // B1
+ {31, 44}, // B10
+ {500, 707}, // B2
+ {353, 500}, // B3
+ {250, 353}, // B4
+ {125, 176}, // B6
+ {88, 125}, // B7
+ {62, 88}, // B8
+ {33, 62}, // B9
+ {163, 229}, // C5E
+ {105, 241}, // US Common
+ {110, 220}, // DLE
+ {210, 330}, // Folio
+ {431.8f, 279.4f}, // Ledger
+ {279.4f, 431.8f} // Tabloid
+};
+
+/// return the multiplier of converting from the unit value to postscript-points.
+Q_PRINTSUPPORT_EXPORT double qt_multiplierForUnit(QPrinter::Unit unit, int resolution)
+{
+ switch(unit) {
+ case QPrinter::Millimeter:
+ return 2.83464566929;
+ case QPrinter::Point:
+ return 1.0;
+ case QPrinter::Inch:
+ return 72.0;
+ case QPrinter::Pica:
+ return 12;
+ case QPrinter::Didot:
+ return 1.065826771;
+ case QPrinter::Cicero:
+ return 12.789921252;
+ case QPrinter::DevicePixel:
+ return 72.0/resolution;
+ }
+ return 1.0;
+}
+
+// not static: it's needed in qpagesetupdialog_unix.cpp
+Q_PRINTSUPPORT_EXPORT QSizeF qt_printerPaperSize(QPrinter::Orientation orientation,
+ QPrinter::PaperSize paperSize,
+ QPrinter::Unit unit,
+ int resolution)
+{
+ int width_index = 0;
+ int height_index = 1;
+ if (orientation == QPrinter::Landscape) {
+ width_index = 1;
+ height_index = 0;
+ }
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution);
+ return QSizeF((qt_paperSizes[paperSize][width_index] * 72 / 25.4) / multiplier,
+ (qt_paperSizes[paperSize][height_index] * 72 / 25.4) / multiplier);
+}
+
+void QPrinterPrivate::createDefaultEngines()
+{
+ QPrinter::OutputFormat realOutputFormat = outputFormat;
+#if defined (Q_OS_UNIX) && ! defined (Q_WS_MAC)
+ if(outputFormat == QPrinter::NativeFormat) {
+ realOutputFormat = QPrinter::PdfFormat;
+ }
+#endif
+
+ switch (realOutputFormat) {
+ case QPrinter::NativeFormat: {
+#if defined (Q_WS_QPA)
+ 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;
+ }
+#elif defined (Q_WS_WIN)
+ QWin32PrintEngine *winEngine = new QWin32PrintEngine(printerMode);
+ paintEngine = winEngine;
+ printEngine = winEngine;
+#elif defined (Q_WS_MAC)
+ QMacPrintEngine *macEngine = new QMacPrintEngine(printerMode);
+ paintEngine = macEngine;
+ printEngine = macEngine;
+#elif defined (Q_OS_UNIX)
+ Q_ASSERT(false);
+#endif
+ }
+ break;
+ case QPrinter::PdfFormat: {
+ QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode);
+ paintEngine = pdfEngine;
+ printEngine = pdfEngine;
+ }
+ break;
+ }
+ use_default_engine = true;
+ had_default_engines = true;
+}
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+QList<const QPicture *> QPrinterPrivate::previewPages() const
+{
+ if (previewEngine)
+ return previewEngine->pages();
+ return QList<const QPicture *>();
+}
+
+void QPrinterPrivate::setPreviewMode(bool enable)
+{
+ Q_Q(QPrinter);
+ if (enable) {
+ if (!previewEngine)
+ previewEngine = new QPreviewPaintEngine;
+ had_default_engines = use_default_engine;
+ use_default_engine = false;
+ realPrintEngine = printEngine;
+ realPaintEngine = paintEngine;
+ q->setEngines(previewEngine, previewEngine);
+ previewEngine->setProxyEngines(realPrintEngine, realPaintEngine);
+ } else {
+ q->setEngines(realPrintEngine, realPaintEngine);
+ use_default_engine = had_default_engines;
+ }
+}
+#endif // QT_NO_PRINTPREVIEWWIDGET
+
+void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey key)
+{
+ for (int c = 0; c < manualSetList.size(); ++c) {
+ if (manualSetList[c] == key) return;
+ }
+ manualSetList.append(key);
+}
+
+
+/*!
+ \class QPrinter
+ \reentrant
+
+ \brief The QPrinter class is a paint device that paints on a printer.
+
+ \ingroup printing
+
+
+ This device represents a series of pages of printed output, and is
+ used in almost exactly the same way as other paint devices such as
+ QWidget and QPixmap.
+ A set of additional functions are provided to manage device-specific
+ features, such as orientation and resolution, and to step through
+ the pages in a document as it is generated.
+
+ 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
+ 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.
+
+ Note that setting parameters like paper size and resolution on an
+ invalid printer is undefined. You can use QPrinter::isValid() to
+ verify this before changing any parameters.
+
+ QPrinter supports a number of parameters, most of which can be
+ changed by the end user through a \l{QPrintDialog}{print dialog}. In
+ general, QPrinter passes these functions onto the underlying QPrintEngine.
+
+ The most important parameters are:
+ \list
+ \i setOrientation() tells QPrinter which page orientation to use.
+ \i setPaperSize() tells QPrinter what paper size to expect from the
+ printer.
+ \i setResolution() tells QPrinter what resolution you wish the
+ printer to provide, in dots per inch (DPI).
+ \i setFullPage() tells QPrinter whether you want to deal with the
+ full page or just with the part the printer can draw on.
+ \i setCopyCount() tells QPrinter how many copies of the document
+ it should print.
+ \endlist
+
+ Many of these functions can only be called before the actual printing
+ begins (i.e., before QPainter::begin() is called). This usually makes
+ sense because, for example, it's not possible to change the number of
+ copies when you are halfway through printing. There are also some
+ settings that the user sets (through the printer dialog) and that
+ applications are expected to obey. See QAbstractPrintDialog's
+ documentation for more details.
+
+ When QPainter::begin() is called, the QPrinter it operates on is prepared for
+ a new page, enabling the QPainter to be used immediately to paint the first
+ page in a document. Once the first page has been painted, newPage() can be
+ called to request a new blank page to paint on, or QPainter::end() can be
+ called to finish printing. The second page and all following pages are
+ prepared using a call to newPage() before they are painted.
+
+ The first page in a document does not need to be preceded by a call to
+ newPage(). You only need to calling newPage() after QPainter::begin() if you
+ need to insert a blank page at the beginning of a printed document.
+ Similarly, calling newPage() after the last page in a document is painted will
+ result in a trailing blank page appended to the end of the printed document.
+
+ If you want to abort the print job, abort() will try its best to
+ stop printing. It may cancel the entire job or just part of it.
+
+ Since QPrinter can print to any QPrintEngine subclass, it is possible to
+ extend printing support to cover new types of printing subsystem by
+ subclassing QPrintEngine and reimplementing its interface.
+
+ \sa QPrintDialog, {Printing with Qt}
+*/
+
+/*!
+ \enum QPrinter::PrinterState
+
+ \value Idle
+ \value Active
+ \value Aborted
+ \value Error
+*/
+
+/*!
+ \enum QPrinter::PrinterMode
+
+ This enum describes the mode the printer should work in. It
+ basically presets a certain resolution and working mode.
+
+ \value ScreenResolution Sets the resolution of the print device to
+ the screen resolution. This has the big advantage that the results
+ obtained when painting on the printer will match more or less
+ exactly the visible output on the screen. It is the easiest to
+ use, as font metrics on the screen and on the printer are the
+ same. This is the default value. ScreenResolution will produce a
+ lower quality output than HighResolution and should only be used
+ for drafts.
+
+ \value PrinterResolution This value is deprecated. Is is
+ equivalent to ScreenResolution on Unix and HighResolution on
+ Windows and Mac. Due do the difference between ScreenResolution
+ and HighResolution, use of this value may lead to non-portable
+ printer code.
+
+ \value HighResolution On Windows, sets the printer resolution to that
+ defined for the printer in use. For PDF printing, sets the
+ resolution of the PDF driver to 1200 dpi.
+
+ \note When rendering text on a QPrinter device, it is important
+ to realize that the size of text, when specified in points, is
+ independent of the resolution specified for the device itself.
+ Therefore, it may be useful to specify the font size in pixels
+ when combining text with graphics to ensure that their relative
+ sizes are what you expect.
+*/
+
+/*!
+ \enum QPrinter::Orientation
+
+ This enum type (not to be confused with \c Orientation) is used
+ to specify each page's orientation.
+
+ \value Portrait the page's height is greater than its width.
+
+ \value Landscape the page's width is greater than its height.
+
+ This type interacts with \l QPrinter::PaperSize and
+ QPrinter::setFullPage() to determine the final size of the page
+ available to the application.
+*/
+
+
+/*!
+ \enum QPrinter::PrintRange
+
+ Used to specify the print range selection option.
+
+ \value AllPages All pages should be printed.
+ \value Selection Only the selection should be printed.
+ \value PageRange The specified page range should be printed.
+ \value CurrentPage Only the current page should be printed.
+
+ \sa QAbstractPrintDialog::PrintRange
+*/
+
+/*!
+ \enum QPrinter::PrinterOption
+ \compat
+
+ Use QAbstractPrintDialog::PrintDialogOption instead.
+
+ \value PrintToFile
+ \value PrintSelection
+ \value PrintPageRange
+*/
+
+/*!
+ \enum QPrinter::PaperSize
+ \since 4.4
+
+ This enum type specifies what paper size QPrinter should use.
+ QPrinter does not check that the paper size is available; it just
+ uses this information, together with QPrinter::Orientation and
+ QPrinter::setFullPage(), to determine the printable area.
+
+ The defined sizes (with setFullPage(true)) are:
+
+ \value A0 841 x 1189 mm
+ \value A1 594 x 841 mm
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.69 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1000 x 1414 mm
+ \value B1 707 x 1000 mm
+ \value B2 500 x 707 mm
+ \value B3 353 x 500 mm
+ \value B4 250 x 353 mm
+ \value B5 176 x 250 mm, 6.93 x 9.84 inches
+ \value B6 125 x 176 mm
+ \value B7 88 x 125 mm
+ \value B8 62 x 88 mm
+ \value B9 33 x 62 mm
+ \value B10 31 x 44 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 190.5 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 431.8 x 279.4 mm
+ \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
+ \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
+ \value Tabloid 279.4 x 431.8 mm
+ \value Custom Unknown, or a user defined size.
+
+ With setFullPage(false) (the default), the metrics will be a bit
+ smaller; how much depends on the printer in use.
+
+ \omitvalue NPageSize
+ \omitvalue NPaperSize
+*/
+
+
+/*!
+ \enum QPrinter::PageOrder
+
+ This enum type is used by QPrinter to tell the application program
+ how to print.
+
+ \value FirstPageFirst the lowest-numbered page should be printed
+ first.
+
+ \value LastPageFirst the highest-numbered page should be printed
+ first.
+*/
+
+/*!
+ \enum QPrinter::ColorMode
+
+ This enum type is used to indicate whether QPrinter should print
+ in color or not.
+
+ \value Color print in color if available, otherwise in grayscale.
+
+ \value GrayScale print in grayscale, even on color printers.
+*/
+
+/*!
+ \enum QPrinter::PaperSource
+
+ This enum type specifies what paper source QPrinter is to use.
+ QPrinter does not check that the paper source is available; it
+ just uses this information to try and set the paper source.
+ Whether it will set the paper source depends on whether the
+ printer has that particular source.
+
+ \warning This is currently only implemented for Windows.
+
+ \value Auto
+ \value Cassette
+ \value Envelope
+ \value EnvelopeManual
+ \value FormSource
+ \value LargeCapacity
+ \value LargeFormat
+ \value Lower
+ \value MaxPageSource
+ \value Middle
+ \value Manual
+ \value OnlyOne
+ \value Tractor
+ \value SmallFormat
+*/
+
+/*!
+ \enum QPrinter::Unit
+ \since 4.4
+
+ This enum type is used to specify the measurement unit for page and
+ paper sizes.
+
+ \value Millimeter
+ \value Point
+ \value Inch
+ \value Pica
+ \value Didot
+ \value Cicero
+ \value DevicePixel
+
+ Note the difference between Point and DevicePixel. The Point unit is
+ defined to be 1/72th of an inch, while the DevicePixel unit is
+ resolution dependant and is based on the actual pixels, or dots, on
+ the printer.
+*/
+
+
+/*
+ \enum QPrinter::PrintRange
+
+ This enum is used to specify which print range the application
+ should use to print.
+
+ \value AllPages All the pages should be printed.
+ \value Selection Only the selection should be printed.
+ \value PageRange Print according to the from page and to page options.
+ \value CurrentPage Only the current page should be printed.
+
+ \sa setPrintRange(), printRange()
+*/
+
+/*
+ \enum QPrinter::PrinterOption
+
+ This enum describes various printer options that appear in the
+ printer setup dialog. It is used to enable and disable these
+ options in the setup dialog.
+
+ \value PrintToFile Describes if print to file should be enabled.
+ \value PrintSelection Describes if printing selections should be enabled.
+ \value PrintPageRange Describes if printing page ranges (from, to) should
+ be enabled
+ \value PrintCurrentPage if Print Current Page option should be enabled
+
+ \sa setOptionEnabled(), isOptionEnabled()
+*/
+
+/*!
+ Creates a new printer object with the given \a mode.
+*/
+QPrinter::QPrinter(PrinterMode mode)
+ : QPagedPaintDevice(),
+ d_ptr(new QPrinterPrivate(this))
+{
+ init(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) {
+ setOutputFormat(QPrinter::PdfFormat);
+ }
+}
+
+/*!
+ \since 4.4
+
+ Creates a new printer object with the given \a printer and \a mode.
+*/
+QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode)
+ : QPagedPaintDevice(),
+ d_ptr(new QPrinterPrivate(this))
+{
+ init(mode);
+ setPrinterName(printer.printerName());
+}
+
+void QPrinter::init(PrinterMode mode)
+{
+#if !defined(Q_WS_X11)
+ if (!QCoreApplication::instance()) {
+#else
+ if (!QCoreApplication::instance() || !X11) {
+#endif
+ qFatal("QPrinter: Must construct a QApplication before a QPaintDevice");
+ return;
+ }
+ Q_D(QPrinter);
+
+ d->printerMode = mode;
+ d->outputFormat = QPrinter::NativeFormat;
+ d->createDefaultEngines();
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ d->previewEngine = 0;
+#endif
+ d->realPrintEngine = 0;
+ d->realPaintEngine = 0;
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::cupsVersion() >= 10200 && QCUPSSupport().currentPPD()) {
+ setOutputFormat(QPrinter::PdfFormat);
+ d->outputFormat = QPrinter::NativeFormat;
+ }
+#endif
+}
+
+/*!
+ This function is used by subclasses of QPrinter to specify custom
+ print and paint engines (\a printEngine and \a paintEngine,
+ respectively).
+
+ QPrinter does not take ownership of the engines, so you need to
+ manage these engine instances yourself.
+
+ Note that changing the engines will reset the printer state and
+ all its properties.
+
+ \sa printEngine() paintEngine() setOutputFormat()
+
+ \since 4.1
+*/
+void QPrinter::setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine)
+{
+ Q_D(QPrinter);
+
+ if (d->use_default_engine)
+ delete d->printEngine;
+
+ d->printEngine = printEngine;
+ d->paintEngine = paintEngine;
+ d->use_default_engine = false;
+}
+
+/*!
+ Destroys the printer object and frees any allocated resources. If
+ the printer is destroyed while a print job is in progress this may
+ or may not affect the print job.
+*/
+QPrinter::~QPrinter()
+{
+ Q_D(QPrinter);
+ if (d->use_default_engine)
+ delete d->printEngine;
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ delete d->previewEngine;
+#endif
+}
+
+/*!
+ \enum QPrinter::OutputFormat
+
+ The OutputFormat enum is used to describe the format QPrinter should
+ use for printing.
+
+ \value NativeFormat QPrinter will print output using a method defined
+ by the platform it is running on. This mode is the default when printing
+ directly to a printer.
+
+ \value PdfFormat QPrinter will generate its output as a searchable PDF file.
+ This mode is the default when printing to a file.
+
+ \sa outputFormat(), setOutputFormat(), setOutputFileName()
+*/
+
+/*!
+ \since 4.1
+
+ Sets the output format for this printer to \a format.
+*/
+void QPrinter::setOutputFormat(OutputFormat format)
+{
+
+#ifndef QT_NO_PDF
+ Q_D(QPrinter);
+ if (d->validPrinter && d->outputFormat == format)
+ return;
+ d->outputFormat = format;
+
+ QPrintEngine *oldPrintEngine = d->printEngine;
+ const bool def_engine = d->use_default_engine;
+ d->printEngine = 0;
+
+ d->createDefaultEngines();
+
+ if (oldPrintEngine) {
+ for (int i = 0; i < d->manualSetList.size(); ++i) {
+ QPrintEngine::PrintEnginePropertyKey key = d->manualSetList[i];
+ QVariant prop;
+ // PPK_NumberOfCopies need special treatmeant since it in most cases
+ // will return 1, disregarding the actual value that was set
+ if (key == QPrintEngine::PPK_NumberOfCopies)
+ prop = QVariant(copyCount());
+ else
+ prop = oldPrintEngine->property(key);
+ if (prop.isValid())
+ d->printEngine->setProperty(key, prop);
+ }
+ }
+
+ if (def_engine)
+ delete oldPrintEngine;
+
+ if (d->outputFormat == QPrinter::PdfFormat)
+ d->validPrinter = true;
+#else
+ Q_UNUSED(format);
+#endif
+}
+
+/*!
+ \since 4.1
+
+ Returns the output format for this printer.
+*/
+QPrinter::OutputFormat QPrinter::outputFormat() const
+{
+ Q_D(const QPrinter);
+ return d->outputFormat;
+}
+
+
+
+/*! \internal
+*/
+int QPrinter::devType() const
+{
+ return QInternal::Printer;
+}
+
+/*!
+ Returns the printer name. This value is initially set to the name
+ of the default printer.
+
+ \sa setPrinterName()
+*/
+QString QPrinter::printerName() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PrinterName).toString();
+}
+
+/*!
+ Sets the printer name to \a name.
+
+ \sa printerName(), isValid()
+*/
+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<QPrinterInfo> prnList = QPrinterInfo::availablePrinters();
+ if (name.isEmpty()) {
+ d->validPrinter = d->outputFormat == QPrinter::PdfFormat;
+ } else {
+ d->validPrinter = false;
+ for (int i = 0; i < prnList.size(); ++i) {
+ if (prnList[i].printerName() == name) {
+ d->validPrinter = true;
+ break;
+ }
+ }
+ }
+
+ d->printEngine->setProperty(QPrintEngine::PPK_PrinterName, name);
+ d->addToManualSetList(QPrintEngine::PPK_PrinterName);
+}
+
+
+/*!
+ \since 4.4
+
+ Returns true if the printer currently selected is a valid printer
+ in the system, or a pure PDF printer; otherwise returns false.
+
+ To detect other failures check the output of QPainter::begin() or QPrinter::newPage().
+
+ \snippet doc/src/snippets/printing-qprinter/errors.cpp 0
+
+ \sa setPrinterName()
+*/
+bool QPrinter::isValid() const
+{
+ Q_D(const QPrinter);
+#if defined(Q_WS_X11)
+ if (!qApp || !X11) {
+ return false;
+ }
+#endif
+ return d->validPrinter;
+}
+
+
+/*!
+ \fn bool QPrinter::outputToFile() const
+
+ Returns true if the output should be written to a file, or false
+ if the output should be sent directly to the printer. The default
+ setting is false.
+
+ \sa setOutputToFile(), setOutputFileName()
+*/
+
+
+/*!
+ \fn void QPrinter::setOutputToFile(bool enable)
+
+ Specifies whether the output should be written to a file or sent
+ directly to the printer.
+
+ Will output to a file if \a enable is true, or will output
+ directly to the printer if \a enable is false.
+
+ \sa outputToFile(), setOutputFileName()
+*/
+
+
+/*!
+ \fn QString QPrinter::outputFileName() const
+
+ Returns the name of the output file. By default, this is an empty string
+ (indicating that the printer shouldn't print to file).
+
+ \sa QPrintEngine::PrintEnginePropertyKey
+
+*/
+
+QString QPrinter::outputFileName() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_OutputFileName).toString();
+}
+
+/*!
+ Sets the name of the output file to \a fileName.
+
+ Setting a null or empty name (0 or "") disables printing to a file.
+ Setting a non-empty name enables printing to a file.
+
+ This can change the value of outputFormat().
+ If the file name has the ".pdf" suffix PDF is generated. If the file name
+ has a suffix other than ".pdf", the output format used is the
+ one set with setOutputFormat().
+
+ QPrinter uses Qt's cross-platform PDF print engines
+ respectively. If you can produce this format natively, for example
+ Mac OS X can generate PDF's from its print engine, set the output format
+ back to NativeFormat.
+
+ \sa outputFileName() setOutputToFile() setOutputFormat()
+*/
+
+void QPrinter::setOutputFileName(const QString &fileName)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setOutputFileName");
+
+ QFileInfo fi(fileName);
+ if (!fi.suffix().compare(QLatin1String("pdf"), Qt::CaseInsensitive))
+ setOutputFormat(QPrinter::PdfFormat);
+ else if (fileName.isEmpty())
+ setOutputFormat(QPrinter::NativeFormat);
+
+ d->printEngine->setProperty(QPrintEngine::PPK_OutputFileName, fileName);
+ d->addToManualSetList(QPrintEngine::PPK_OutputFileName);
+}
+
+
+/*!
+ Returns the name of the program that sends the print output to the
+ printer.
+
+ The default is to return an empty string; meaning that QPrinter will try to
+ be smart in a system-dependent way. On X11 only, you can set it to something
+ different to use a specific print program. On the other platforms, this
+ returns an empty string.
+
+ \sa setPrintProgram(), setPrinterSelectionOption()
+*/
+QString QPrinter::printProgram() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PrinterProgram).toString();
+}
+
+
+/*!
+ Sets the name of the program that should do the print job to \a
+ printProg.
+
+ On X11, this function sets the program to call with the PDF
+ output. On other platforms, it has no effect.
+
+ \sa printProgram()
+*/
+void QPrinter::setPrintProgram(const QString &printProg)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setPrintProgram");
+ d->printEngine->setProperty(QPrintEngine::PPK_PrinterProgram, printProg);
+ d->addToManualSetList(QPrintEngine::PPK_PrinterProgram);
+}
+
+
+/*!
+ Returns the document name.
+
+ \sa setDocName(), QPrintEngine::PrintEnginePropertyKey
+*/
+QString QPrinter::docName() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_DocumentName).toString();
+}
+
+
+/*!
+ Sets the document name to \a name.
+
+ On X11, the document name is for example used as the default
+ output filename in QPrintDialog. Note that the document name does
+ not affect the file name if the printer is printing to a file.
+ Use the setOutputFile() function for this.
+
+ \sa docName(), QPrintEngine::PrintEnginePropertyKey
+*/
+void QPrinter::setDocName(const QString &name)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setDocName");
+ d->printEngine->setProperty(QPrintEngine::PPK_DocumentName, name);
+ d->addToManualSetList(QPrintEngine::PPK_DocumentName);
+}
+
+
+/*!
+ Returns the name of the application that created the document.
+
+ \sa setCreator()
+*/
+QString QPrinter::creator() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_Creator).toString();
+}
+
+
+/*!
+ Sets the name of the application that created the document to \a
+ creator.
+
+ This function is only applicable to the X11 version of Qt. If no
+ creator name is specified, the creator will be set to "Qt"
+ followed by some version number.
+
+ \sa creator()
+*/
+void QPrinter::setCreator(const QString &creator)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setCreator");
+ d->printEngine->setProperty(QPrintEngine::PPK_Creator, creator);
+ d->addToManualSetList(QPrintEngine::PPK_Creator);
+}
+
+
+/*!
+ Returns the orientation setting. This is driver-dependent, but is usually
+ QPrinter::Portrait.
+
+ \sa setOrientation()
+*/
+QPrinter::Orientation QPrinter::orientation() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::Orientation(d->printEngine->property(QPrintEngine::PPK_Orientation).toInt());
+}
+
+
+/*!
+ Sets the print orientation to \a orientation.
+
+ The orientation can be either QPrinter::Portrait or
+ QPrinter::Landscape.
+
+ The printer driver reads this setting and prints using the
+ specified orientation.
+
+ On Windows, this option can be changed while printing and will
+ take effect from the next call to newPage().
+
+ On Mac OS X, changing the orientation during a print job has no effect.
+
+ \sa orientation()
+*/
+
+void QPrinter::setOrientation(Orientation orientation)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_Orientation, orientation);
+ d->addToManualSetList(QPrintEngine::PPK_Orientation);
+}
+
+
+/*!
+ \since 4.4
+ Returns the printer paper size. The default value is driver-dependent.
+
+ \sa setPaperSize() pageRect() paperRect()
+*/
+
+QPrinter::PaperSize QPrinter::paperSize() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::PaperSize(d->printEngine->property(QPrintEngine::PPK_PaperSize).toInt());
+}
+
+/*!
+ \since 4.4
+
+ Sets the printer paper size to \a newPaperSize if that size is
+ supported. The result is undefined if \a newPaperSize is not
+ supported.
+
+ The default paper size is driver-dependent.
+
+ This function is useful mostly for setting a default value that
+ the user can override in the print dialog.
+
+ \sa paperSize() PaperSize setFullPage() setResolution() pageRect() paperRect()
+*/
+void QPrinter::setPaperSize(PaperSize newPaperSize)
+{
+ setPageSize(newPaperSize);
+}
+
+/*!
+ \obsolete
+
+ Returns the printer page size. The default value is driver-dependent.
+
+ Use paperSize() instead.
+*/
+QPrinter::PageSize QPrinter::pageSize() const
+{
+ return paperSize();
+}
+
+
+/*!
+ \obsolete
+
+ Sets the printer page size based on \a newPageSize.
+
+ Use setPaperSize() instead.
+*/
+
+void QPrinter::setPageSize(PageSize newPageSize)
+{
+ QPagedPaintDevice::setPageSize(newPageSize);
+
+ Q_D(QPrinter);
+ if (d->paintEngine->type() != QPaintEngine::Pdf)
+ ABORT_IF_ACTIVE("QPrinter::setPaperSize");
+ if (newPageSize < 0 || newPageSize >= NPageSize) {
+ qWarning("QPrinter::setPaperSize: Illegal paper size %d", newPageSize);
+ return;
+ }
+ d->printEngine->setProperty(QPrintEngine::PPK_PaperSize, newPageSize);
+ d->addToManualSetList(QPrintEngine::PPK_PaperSize);
+ d->hasUserSetPageSize = true;
+}
+
+/*!
+ \since 4.4
+
+ Sets the paper size based on \a paperSize in \a unit.
+
+ \sa paperSize()
+*/
+
+void QPrinter::setPaperSize(const QSizeF &paperSize, QPrinter::Unit unit)
+{
+ Q_D(QPrinter);
+ if (d->paintEngine->type() != QPaintEngine::Pdf)
+ ABORT_IF_ACTIVE("QPrinter::setPaperSize");
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution());
+ QSizeF size(paperSize.width() * multiplier * 25.4/72., paperSize.height() * multiplier * 25.4/72.);
+ setPageSizeMM(size);
+}
+
+/*!
+ \reimp
+ */
+void QPrinter::setPageSizeMM(const QSizeF &size)
+{
+ Q_D(QPrinter);
+
+ QPagedPaintDevice::setPageSizeMM(size);
+
+ QSizeF s = size * 72./25.4;
+ d->printEngine->setProperty(QPrintEngine::PPK_CustomPaperSize, s);
+ d->addToManualSetList(QPrintEngine::PPK_CustomPaperSize);
+ d->hasUserSetPageSize = true;
+}
+
+/*!
+ \since 4.4
+
+ Returns the paper size in \a unit.
+
+ \sa setPaperSize()
+*/
+
+QSizeF QPrinter::paperSize(Unit unit) const
+{
+ Q_D(const QPrinter);
+ int res = resolution();
+ const qreal multiplier = qt_multiplierForUnit(unit, res);
+ PaperSize paperType = paperSize();
+ if (paperType == Custom) {
+ QSizeF size = d->printEngine->property(QPrintEngine::PPK_CustomPaperSize).toSizeF();
+ return QSizeF(size.width() / multiplier, size.height() / multiplier);
+ }
+ else {
+ return qt_printerPaperSize(orientation(), paperType, unit, res);
+ }
+}
+
+/*!
+ Sets the page order to \a pageOrder.
+
+ The page order can be QPrinter::FirstPageFirst or
+ QPrinter::LastPageFirst. The application is responsible for
+ reading the page order and printing accordingly.
+
+ This function is mostly useful for setting a default value that
+ the user can override in the print dialog.
+
+ This function is only supported under X11.
+*/
+
+void QPrinter::setPageOrder(PageOrder pageOrder)
+{
+ d->pageOrderAscending = (pageOrder == FirstPageFirst);
+
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setPageOrder");
+ d->printEngine->setProperty(QPrintEngine::PPK_PageOrder, pageOrder);
+ d->addToManualSetList(QPrintEngine::PPK_PageOrder);
+}
+
+
+/*!
+ Returns the current page order.
+
+ The default page order is \c FirstPageFirst.
+*/
+
+QPrinter::PageOrder QPrinter::pageOrder() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::PageOrder(d->printEngine->property(QPrintEngine::PPK_PageOrder).toInt());
+}
+
+
+/*!
+ Sets the printer's color mode to \a newColorMode, which can be
+ either \c Color or \c GrayScale.
+
+ \sa colorMode()
+*/
+
+void QPrinter::setColorMode(ColorMode newColorMode)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setColorMode");
+ d->printEngine->setProperty(QPrintEngine::PPK_ColorMode, newColorMode);
+ d->addToManualSetList(QPrintEngine::PPK_ColorMode);
+}
+
+
+/*!
+ Returns the current color mode.
+
+ \sa setColorMode()
+*/
+QPrinter::ColorMode QPrinter::colorMode() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::ColorMode(d->printEngine->property(QPrintEngine::PPK_ColorMode).toInt());
+}
+
+
+/*!
+ \obsolete
+ Returns the number of copies to be printed. The default value is 1.
+
+ On Windows, Mac OS X and X11 systems that support CUPS, this will always
+ return 1 as these operating systems can internally handle the number
+ of copies.
+
+ On X11, this value will return the number of times the application is
+ required to print in order to match the number specified in the printer setup
+ dialog. This has been done since some printer drivers are not capable of
+ buffering up the copies and in those cases the application must make an
+ explicit call to the print code for each copy.
+
+ Use copyCount() in conjunction with supportsMultipleCopies() instead.
+
+ \sa setNumCopies(), actualNumCopies()
+*/
+
+int QPrinter::numCopies() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_NumberOfCopies).toInt();
+}
+
+
+/*!
+ \obsolete
+ \since 4.6
+
+ Returns the number of copies that will be printed. The default
+ value is 1.
+
+ This function always returns the actual value specified in the print
+ dialog or using setNumCopies().
+
+ Use copyCount() instead.
+
+ \sa setNumCopies(), numCopies()
+*/
+int QPrinter::actualNumCopies() const
+{
+ return copyCount();
+}
+
+
+
+/*!
+ \obsolete
+ Sets the number of copies to be printed to \a numCopies.
+
+ The printer driver reads this setting and prints the specified
+ number of copies.
+
+ Use setCopyCount() instead.
+
+ \sa numCopies()
+*/
+
+void QPrinter::setNumCopies(int numCopies)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setNumCopies");
+ d->printEngine->setProperty(QPrintEngine::PPK_NumberOfCopies, numCopies);
+ d->addToManualSetList(QPrintEngine::PPK_NumberOfCopies);
+}
+
+/*!
+ \since 4.7
+
+ Sets the number of copies to be printed to \a count.
+
+ The printer driver reads this setting and prints the specified number of
+ copies.
+
+ \sa copyCount(), supportsMultipleCopies()
+*/
+
+void QPrinter::setCopyCount(int count)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setCopyCount;");
+ d->printEngine->setProperty(QPrintEngine::PPK_CopyCount, count);
+ d->addToManualSetList(QPrintEngine::PPK_CopyCount);
+}
+
+/*!
+ \since 4.7
+
+ Returns the number of copies that will be printed. The default value is 1.
+
+ \sa setCopyCount(), supportsMultipleCopies()
+*/
+
+int QPrinter::copyCount() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_CopyCount).toInt();
+}
+
+/*!
+ \since 4.7
+
+ Returns true if the printer supports printing multiple copies of the same
+ document in one job; otherwise false is returned.
+
+ On most systems this function will return true. However, on X11 systems
+ that do not support CUPS, this function will return false. That means the
+ application has to handle the number of copies by printing the same
+ document the required number of times.
+
+ \sa setCopyCount(), copyCount()
+*/
+
+bool QPrinter::supportsMultipleCopies() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_SupportsMultipleCopies).toBool();
+}
+
+/*!
+ \since 4.1
+
+ Returns true if collation is turned on when multiple copies is selected.
+ Returns false if it is turned off when multiple copies is selected.
+ When collating is turned off the printing of each individual page will be repeated
+ the numCopies() amount before the next page is started. With collating turned on
+ all pages are printed before the next copy of those pages is started.
+
+ \sa setCollateCopies()
+*/
+bool QPrinter::collateCopies() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_CollateCopies).toBool();
+}
+
+
+/*!
+ \since 4.1
+
+ Sets the default value for collation checkbox when the print
+ dialog appears. If \a collate is true, it will enable
+ setCollateCopiesEnabled(). The default value is false. This value
+ will be changed by what the user presses in the print dialog.
+
+ \sa collateCopies()
+*/
+void QPrinter::setCollateCopies(bool collate)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setCollateCopies");
+ d->printEngine->setProperty(QPrintEngine::PPK_CollateCopies, collate);
+ d->addToManualSetList(QPrintEngine::PPK_CollateCopies);
+}
+
+
+
+/*!
+ If \a fp is true, enables support for painting over the entire page;
+ otherwise restricts painting to the printable area reported by the
+ device.
+
+ By default, full page printing is disabled. In this case, the origin
+ of the QPrinter's coordinate system coincides with the top-left
+ corner of the printable area.
+
+ If full page printing is enabled, the origin of the QPrinter's
+ coordinate system coincides with the top-left corner of the paper
+ itself. In this case, the
+ \l{QPaintDevice::PaintDeviceMetric}{device metrics} will report
+ the exact same dimensions as indicated by \l{PaperSize}. It may not
+ be possible to print on the entire physical page because of the
+ printer's margins, so the application must account for the margins
+ itself.
+
+ \sa fullPage(), setPaperSize(), width(), height(), {Printing with Qt}
+*/
+
+void QPrinter::setFullPage(bool fp)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_FullPage, fp);
+ d->addToManualSetList(QPrintEngine::PPK_FullPage);
+}
+
+
+/*!
+ Returns true if the origin of the printer's coordinate system is
+ at the corner of the page and false if it is at the edge of the
+ printable area.
+
+ See setFullPage() for details and caveats.
+
+ \sa setFullPage() PaperSize
+*/
+
+bool QPrinter::fullPage() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_FullPage).toBool();
+}
+
+
+/*!
+ Requests that the printer prints at \a dpi or as near to \a dpi as
+ possible.
+
+ This setting affects the coordinate system as returned by, for
+ example QPainter::viewport().
+
+ This function must be called before QPainter::begin() to have an effect on
+ all platforms.
+
+ \sa resolution() setPaperSize()
+*/
+
+void QPrinter::setResolution(int dpi)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setResolution");
+ d->printEngine->setProperty(QPrintEngine::PPK_Resolution, dpi);
+ d->addToManualSetList(QPrintEngine::PPK_Resolution);
+}
+
+
+/*!
+ Returns the current assumed resolution of the printer, as set by
+ setResolution() or by the printer driver.
+
+ \sa setResolution()
+*/
+
+int QPrinter::resolution() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_Resolution).toInt();
+}
+
+/*!
+ Sets the paper source setting to \a source.
+
+ Windows only: This option can be changed while printing and will
+ take effect from the next call to newPage()
+
+ \sa paperSource()
+*/
+
+void QPrinter::setPaperSource(PaperSource source)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_PaperSource, source);
+ d->addToManualSetList(QPrintEngine::PPK_PaperSource);
+}
+
+/*!
+ Returns the printer's paper source. This is \c Manual or a printer
+ tray or paper cassette.
+*/
+QPrinter::PaperSource QPrinter::paperSource() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::PaperSource(d->printEngine->property(QPrintEngine::PPK_PaperSource).toInt());
+}
+
+
+/*!
+ \since 4.1
+
+ Enabled or disables font embedding depending on \a enable.
+
+ Currently this option is only supported on X11.
+
+ \sa fontEmbeddingEnabled()
+*/
+void QPrinter::setFontEmbeddingEnabled(bool enable)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_FontEmbedding, enable);
+ d->addToManualSetList(QPrintEngine::PPK_FontEmbedding);
+}
+
+/*!
+ \since 4.1
+
+ Returns true if font embedding is enabled.
+
+ Currently this option is only supported on X11.
+
+ \sa setFontEmbeddingEnabled()
+*/
+bool QPrinter::fontEmbeddingEnabled() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_FontEmbedding).toBool();
+}
+
+/*!
+ \enum QPrinter::DuplexMode
+ \since 4.4
+
+ This enum is used to indicate whether printing will occur on one or both sides
+ of each sheet of paper (simplex or duplex printing).
+
+ \value DuplexNone Single sided (simplex) printing only.
+ \value DuplexAuto The printer's default setting is used to determine whether
+ duplex printing is used.
+ \value DuplexLongSide Both sides of each sheet of paper are used for printing.
+ The paper is turned over its longest edge before the second
+ side is printed
+ \value DuplexShortSide Both sides of each sheet of paper are used for printing.
+ The paper is turned over its shortest edge before the second
+ side is printed
+*/
+
+/*!
+ \since 4.2
+
+ Enables double sided printing if \a doubleSided is true; otherwise disables it.
+
+ Currently this option is only supported on X11.
+*/
+void QPrinter::setDoubleSidedPrinting(bool doubleSided)
+{
+ setDuplex(doubleSided ? DuplexAuto : DuplexNone);
+}
+
+
+/*!
+ \since 4.2
+
+ Returns true if double side printing is enabled.
+
+ Currently this option is only supported on X11.
+*/
+bool QPrinter::doubleSidedPrinting() const
+{
+ return duplex() != DuplexNone;
+}
+
+/*!
+ \since 4.4
+
+ Enables double sided printing based on the \a duplex mode.
+
+ Currently this option is only supported on X11.
+*/
+void QPrinter::setDuplex(DuplexMode duplex)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_Duplex, duplex);
+ d->addToManualSetList(QPrintEngine::PPK_Duplex);
+}
+
+/*!
+ \since 4.4
+
+ Returns the current duplex mode.
+
+ Currently this option is only supported on X11.
+*/
+QPrinter::DuplexMode QPrinter::duplex() const
+{
+ Q_D(const QPrinter);
+ return static_cast <DuplexMode> (d->printEngine->property(QPrintEngine::PPK_Duplex).toInt());
+}
+
+/*!
+ \since 4.4
+
+ Returns the page's rectangle in \a unit; this is usually smaller
+ than the paperRect() since the page normally has margins between
+ its borders and the paper.
+
+ \sa paperSize()
+*/
+QRectF QPrinter::pageRect(Unit unit) const
+{
+ Q_D(const QPrinter);
+ int res = resolution();
+ const qreal multiplier = qt_multiplierForUnit(unit, res);
+ // the page rect is in device pixels
+ QRect devRect(d->printEngine->property(QPrintEngine::PPK_PageRect).toRect());
+ if (unit == DevicePixel)
+ return devRect;
+ QRectF diRect(devRect.x()*72.0/res,
+ devRect.y()*72.0/res,
+ devRect.width()*72.0/res,
+ devRect.height()*72.0/res);
+ return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
+ diRect.width()/multiplier, diRect.height()/multiplier);
+}
+
+
+/*!
+ \since 4.4
+
+ Returns the paper's rectangle in \a unit; this is usually larger
+ than the pageRect().
+
+ \sa pageRect()
+*/
+QRectF QPrinter::paperRect(Unit unit) const
+{
+ Q_D(const QPrinter);
+ int res = resolution();
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution());
+ // the page rect is in device pixels
+ QRect devRect(d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect());
+ if (unit == DevicePixel)
+ return devRect;
+ QRectF diRect(devRect.x()*72.0/res,
+ devRect.y()*72.0/res,
+ devRect.width()*72.0/res,
+ devRect.height()*72.0/res);
+ return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
+ diRect.width()/multiplier, diRect.height()/multiplier);
+}
+
+/*!
+ Returns the page's rectangle; this is usually smaller than the
+ paperRect() since the page normally has margins between its
+ borders and the paper.
+
+ The unit of the returned rectangle is DevicePixel.
+
+ \sa paperSize()
+*/
+QRect QPrinter::pageRect() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PageRect).toRect();
+}
+
+/*!
+ Returns the paper's rectangle; this is usually larger than the
+ pageRect().
+
+ The unit of the returned rectangle is DevicePixel.
+
+ \sa pageRect()
+*/
+QRect QPrinter::paperRect() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect();
+}
+
+
+/*!
+ \since 4.4
+
+ This function sets the \a left, \a top, \a right and \a bottom
+ page margins for this printer. The unit of the margins are
+ specified with the \a unit parameter.
+*/
+void QPrinter::setPageMargins(qreal left, qreal top, qreal right, qreal bottom, QPrinter::Unit unit)
+{
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution()) * 25.4/72.;
+ Margins m = { left*multiplier, right*multiplier, top*multiplier, bottom*multiplier };
+ setMargins(m);
+}
+
+/*!
+ reimp
+ */
+void QPrinter::setMargins(const Margins &m)
+{
+ Q_D(QPrinter);
+
+ const qreal multiplier = 72./25.4;
+ QList<QVariant> margins;
+ margins << (m.left * multiplier) << (m.top * multiplier)
+ << (m.right * multiplier) << (m.bottom * multiplier);
+ d->printEngine->setProperty(QPrintEngine::PPK_PageMargins, margins);
+ d->addToManualSetList(QPrintEngine::PPK_PageMargins);
+ d->hasCustomPageMargins = true;
+}
+
+
+/*!
+ \since 4.4
+
+ Returns the page margins for this printer in \a left, \a top, \a
+ right, \a bottom. The unit of the returned margins are specified
+ with the \a unit parameter.
+*/
+void QPrinter::getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, QPrinter::Unit unit) const
+{
+ Q_D(const QPrinter);
+ Q_ASSERT(left && top && right && bottom);
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution());
+ QList<QVariant> margins(d->printEngine->property(QPrintEngine::PPK_PageMargins).toList());
+ *left = margins.at(0).toReal() / multiplier;
+ *top = margins.at(1).toReal() / multiplier;
+ *right = margins.at(2).toReal() / multiplier;
+ *bottom = margins.at(3).toReal() / multiplier;
+}
+
+/*!
+ \internal
+
+ Returns the metric for the given \a id.
+*/
+int QPrinter::metric(PaintDeviceMetric id) const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->metric(id);
+}
+
+/*!
+ Returns the paint engine used by the printer.
+*/
+QPaintEngine *QPrinter::paintEngine() const
+{
+ Q_D(const QPrinter);
+ return d->paintEngine;
+}
+
+/*!
+ \since 4.1
+
+ Returns the print engine used by the printer.
+*/
+QPrintEngine *QPrinter::printEngine() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine;
+}
+
+#if defined (Q_WS_WIN)
+/*!
+ Sets the page size to be used by the printer under Windows to \a
+ pageSize.
+
+ \warning This function is not portable so you may prefer to use
+ setPaperSize() instead.
+
+ \sa winPageSize()
+*/
+void QPrinter::setWinPageSize(int pageSize)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setWinPageSize");
+ d->printEngine->setProperty(QPrintEngine::PPK_WindowsPageSize, pageSize);
+ d->addToManualSetList(QPrintEngine::PPK_WindowsPageSize);
+}
+
+/*!
+ Returns the page size used by the printer under Windows.
+
+ \warning This function is not portable so you may prefer to use
+ paperSize() instead.
+
+ \sa setWinPageSize()
+*/
+int QPrinter::winPageSize() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_WindowsPageSize).toInt();
+}
+#endif // Q_WS_WIN
+
+/*!
+ Returns a list of the resolutions (a list of dots-per-inch
+ integers) that the printer says it supports.
+
+ For X11 where all printing is directly to PDF, this
+ function will always return a one item list containing only the
+ PDF resolution, i.e., 72 (72 dpi -- but see PrinterMode).
+*/
+QList<int> QPrinter::supportedResolutions() const
+{
+ Q_D(const QPrinter);
+ QList<QVariant> varlist
+ = d->printEngine->property(QPrintEngine::PPK_SupportedResolutions).toList();
+ QList<int> intlist;
+ for (int i=0; i<varlist.size(); ++i)
+ intlist << varlist.at(i).toInt();
+ return intlist;
+}
+
+/*!
+ Tells the printer to eject the current page and to continue
+ printing on a new page. Returns true if this was successful;
+ otherwise returns false.
+
+ Calling newPage() on an inactive QPrinter object will always
+ fail.
+*/
+bool QPrinter::newPage()
+{
+ Q_D(QPrinter);
+ if (d->printEngine->printerState() != QPrinter::Active)
+ return false;
+ return d->printEngine->newPage();
+}
+
+/*!
+ Aborts the current print run. Returns true if the print run was
+ successfully aborted and printerState() will return QPrinter::Aborted; otherwise
+ returns false.
+
+ It is not always possible to abort a print job. For example,
+ all the data has gone to the printer but the printer cannot or
+ will not cancel the job when asked to.
+*/
+bool QPrinter::abort()
+{
+ Q_D(QPrinter);
+ return d->printEngine->abort();
+}
+
+/*!
+ Returns the current state of the printer. This may not always be
+ accurate (for example if the printer doesn't have the capability
+ of reporting its state to the operating system).
+*/
+QPrinter::PrinterState QPrinter::printerState() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->printerState();
+}
+
+
+/*! \fn void QPrinter::margins(uint *top, uint *left, uint *bottom, uint *right) const
+
+ Sets *\a top, *\a left, *\a bottom, *\a right to be the top,
+ left, bottom, and right margins.
+
+ This function has been superseded by paperRect() and pageRect().
+ Use paperRect().top() - pageRect().top() for the top margin,
+ paperRect().left() - pageRect().left() for the left margin,
+ paperRect().bottom() - pageRect().bottom() for the bottom margin,
+ and papaerRect().right() - pageRect().right() for the right
+ margin.
+
+ \oldcode
+ uint rightMargin;
+ uint bottomMargin;
+ printer->margins(0, 0, &bottomMargin, &rightMargin);
+ \newcode
+ int rightMargin = printer->paperRect().right() - printer->pageRect().right();
+ int bottomMargin = printer->paperRect().bottom() - printer->pageRect().bottom();
+ \endcode
+*/
+
+/*! \fn QSize QPrinter::margins() const
+
+ \overload
+
+ Returns a QSize containing the left margin and the top margin.
+
+ This function has been superseded by paperRect() and pageRect().
+ Use paperRect().left() - pageRect().left() for the left margin,
+ and paperRect().top() - pageRect().top() for the top margin.
+
+ \oldcode
+ QSize margins = printer->margins();
+ int leftMargin = margins.width();
+ int topMargin = margins.height();
+ \newcode
+ int leftMargin = printer->paperRect().left() - printer->pageRect().left();
+ int topMargin = printer->paperRect().top() - printer->pageRect().top();
+ \endcode
+*/
+
+/*! \fn bool QPrinter::aborted()
+
+ Use printerState() == QPrinter::Aborted instead.
+*/
+
+#ifdef Q_WS_WIN
+/*!
+ \internal
+*/
+HDC QPrinter::getDC() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->getPrinterDC();
+}
+
+/*!
+ \internal
+*/
+void QPrinter::releaseDC(HDC hdc) const
+{
+ Q_D(const QPrinter);
+ d->printEngine->releasePrinterDC(hdc);
+}
+
+/*!
+ Returns the supported paper sizes for this printer.
+
+ The values will be either a value that matches an entry in the
+ QPrinter::PaperSource enum or a driver spesific value. The driver
+ spesific values are greater than the constant DMBIN_USER declared
+ in wingdi.h.
+
+ \warning This function is only available in windows.
+*/
+
+QList<QPrinter::PaperSource> QPrinter::supportedPaperSources() const
+{
+ Q_D(const QPrinter);
+ QVariant v = d->printEngine->property(QPrintEngine::PPK_PaperSources);
+
+ QList<QVariant> variant_list = v.toList();
+ QList<QPrinter::PaperSource> int_list;
+ for (int i=0; i<variant_list.size(); ++i)
+ int_list << (QPrinter::PaperSource) variant_list.at(i).toInt();
+
+ return int_list;
+}
+
+#endif
+
+/*!
+ \fn QString QPrinter::printerSelectionOption() const
+
+ Returns the printer options selection string. This is useful only
+ if the print command has been explicitly set.
+
+ The default value (an empty string) implies that the printer should
+ be selected in a system-dependent manner.
+
+ Any other value implies that the given value should be used.
+
+ \warning This function is not available on Windows.
+
+ \sa setPrinterSelectionOption()
+*/
+
+/*!
+ \fn void QPrinter::setPrinterSelectionOption(const QString &option)
+
+ Sets the printer to use \a option to select the printer. \a option
+ is null by default (which implies that Qt should be smart enough
+ to guess correctly), but it can be set to other values to use a
+ specific printer selection option.
+
+ If the printer selection option is changed while the printer is
+ active, the current print job may or may not be affected.
+
+ \warning This function is not available on Windows.
+
+ \sa printerSelectionOption()
+*/
+
+#ifndef Q_WS_WIN
+QString QPrinter::printerSelectionOption() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_SelectionOption).toString();
+}
+
+void QPrinter::setPrinterSelectionOption(const QString &option)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_SelectionOption, option);
+ d->addToManualSetList(QPrintEngine::PPK_SelectionOption);
+}
+#endif
+
+/*!
+ \since 4.1
+ \fn int QPrinter::fromPage() const
+
+ Returns the number of the first page in a range of pages to be printed
+ (the "from page" setting). Pages in a document are numbered according to
+ the convention that the first page is page 1.
+
+ By default, this function returns a special value of 0, meaning that
+ the "from page" setting is unset.
+
+ \note If fromPage() and toPage() both return 0, this indicates that
+ \e{the whole document will be printed}.
+
+ \sa setFromTo(), toPage()
+*/
+
+int QPrinter::fromPage() const
+{
+ return d->fromPage;
+}
+
+/*!
+ \since 4.1
+
+ Returns the number of the last page in a range of pages to be printed
+ (the "to page" setting). Pages in a document are numbered according to
+ the convention that the first page is page 1.
+
+ By default, this function returns a special value of 0, meaning that
+ the "to page" setting is unset.
+
+ \note If fromPage() and toPage() both return 0, this indicates that
+ \e{the whole document will be printed}.
+
+ The programmer is responsible for reading this setting and
+ printing accordingly.
+
+ \sa setFromTo(), fromPage()
+*/
+
+int QPrinter::toPage() const
+{
+ return d->toPage;
+}
+
+/*!
+ \since 4.1
+
+ Sets the range of pages to be printed to cover the pages with numbers
+ specified by \a from and \a to, where \a from corresponds to the first
+ page in the range and \a to corresponds to the last.
+
+ \note Pages in a document are numbered according to the convention that
+ the first page is page 1. However, if \a from and \a to are both set to 0,
+ the \e{whole document will be printed}.
+
+ This function is mostly used to set a default value that the user can
+ override in the print dialog when you call setup().
+
+ \sa fromPage(), toPage()
+*/
+
+void QPrinter::setFromTo(int from, int to)
+{
+ if (from > to) {
+ qWarning() << "QPrinter::setFromTo: 'from' must be less than or equal to 'to'";
+ from = to;
+ }
+ d->fromPage = from;
+ d->toPage = to;
+}
+
+/*!
+ \since 4.1
+
+ Sets the print range option in to be \a range.
+*/
+void QPrinter::setPrintRange( PrintRange range )
+{
+ d->printSelectionOnly = (range == Selection);
+
+ Q_D(QPrinter);
+ d->printRange = range;
+}
+
+/*!
+ \since 4.1
+
+ Returns the page range of the QPrinter. After the print setup
+ dialog has been opened, this function returns the value selected
+ by the user.
+
+ \sa setPrintRange()
+*/
+QPrinter::PrintRange QPrinter::printRange() const
+{
+ Q_D(const QPrinter);
+ return d->printRange;
+}
+
+
+/*!
+ \class QPrintEngine
+ \reentrant
+
+ \ingroup printing
+
+ \brief The QPrintEngine class defines an interface for how QPrinter
+ interacts with a given printing subsystem.
+
+ The common case when creating your own print engine is to derive from both
+ QPaintEngine and QPrintEngine. Various properties of a print engine are
+ given with property() and set with setProperty().
+
+ \sa QPaintEngine
+*/
+
+/*!
+ \enum QPrintEngine::PrintEnginePropertyKey
+
+ This enum is used to communicate properties between the print
+ engine and QPrinter. A property may or may not be supported by a
+ given print engine.
+
+ \value PPK_CollateCopies A boolean value indicating whether the
+ printout should be collated or not.
+
+ \value PPK_ColorMode Refers to QPrinter::ColorMode, either color or
+ monochrome.
+
+ \value PPK_Creator A string describing the document's creator.
+
+ \value PPK_Duplex A boolean value indicating whether both sides of
+ the printer paper should be used for the printout.
+
+ \value PPK_DocumentName A string describing the document name in
+ the spooler.
+
+ \value PPK_FontEmbedding A boolean value indicating whether data for
+ the document's fonts should be embedded in the data sent to the
+ printer.
+
+ \value PPK_FullPage A boolean describing if the printer should be
+ full page or not.
+
+ \value PPK_NumberOfCopies Obsolete. An integer specifying the number of
+ copies. Use PPK_CopyCount instead.
+
+ \value PPK_Orientation Specifies a QPrinter::Orientation value.
+
+ \value PPK_OutputFileName The output file name as a string. An
+ empty file name indicates that the printer should not print to a file.
+
+ \value PPK_PageOrder Specifies a QPrinter::PageOrder value.
+
+ \value PPK_PageRect A QRect specifying the page rectangle
+
+ \value PPK_PageSize Obsolete. Use PPK_PaperSize instead.
+
+ \value PPK_PaperRect A QRect specifying the paper rectangle.
+
+ \value PPK_PaperSource Specifies a QPrinter::PaperSource value.
+
+ \value PPK_PaperSources Specifies more than one QPrinter::PaperSource value.
+
+ \value PPK_PaperSize Specifies a QPrinter::PaperSize value.
+
+ \value PPK_PrinterName A string specifying the name of the printer.
+
+ \value PPK_PrinterProgram A string specifying the name of the
+ printer program used for printing,
+
+ \value PPK_Resolution An integer describing the dots per inch for
+ this printer.
+
+ \value PPK_SelectionOption
+
+ \value PPK_SupportedResolutions A list of integer QVariants
+ describing the set of supported resolutions that the printer has.
+
+ \value PPK_SuppressSystemPrintStatus Suppress the built-in dialog for showing
+ printing progress. As of 4.1 this only has effect on Mac OS X where, by default,
+ a status dialog is shown.
+
+ \value PPK_WindowsPageSize An integer specifying a DM_PAPER entry
+ on Windows.
+
+ \value PPK_CustomPaperSize A QSizeF specifying a custom paper size
+ in the QPrinter::Point unit.
+
+ \value PPK_PageMargins A QList<QVariant> containing the left, top,
+ right and bottom margin values.
+
+ \value PPK_CopyCount An integer specifying the number of copies to print.
+
+ \value PPK_SupportsMultipleCopies A boolean value indicating whether or not
+ the printer supports printing multiple copies in one job.
+
+ \value PPK_CustomBase Basis for extension.
+*/
+
+/*!
+ \fn QPrintEngine::~QPrintEngine()
+
+ Destroys the print engine.
+*/
+
+/*!
+ \fn void QPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
+
+ Sets the print engine's property specified by \a key to the given \a value.
+
+ \sa property()
+*/
+
+/*!
+ \fn void QPrintEngine::property(PrintEnginePropertyKey key) const
+
+ Returns the print engine's property specified by \a key.
+
+ \sa setProperty()
+*/
+
+/*!
+ \fn bool QPrintEngine::newPage()
+
+ Instructs the print engine to start a new page. Returns true if
+ the printer was able to create the new page; otherwise returns false.
+*/
+
+/*!
+ \fn bool QPrintEngine::abort()
+
+ Instructs the print engine to abort the printing process. Returns
+ true if successful; otherwise returns false.
+*/
+
+/*!
+ \fn int QPrintEngine::metric(QPaintDevice::PaintDeviceMetric id) const
+
+ Returns the metric for the given \a id.
+*/
+
+/*!
+ \fn QPrinter::PrinterState QPrintEngine::printerState() const
+
+ Returns the current state of the printer being used by the print engine.
+*/
+
+/*!
+ \fn HDC QPrintEngine::getPrinterDC() const
+ \internal
+*/
+
+/*!
+ \fn void QPrintEngine::releasePrinterDC(HDC) const
+ \internal
+*/
+
+/*
+ Returns the dimensions for the given paper size, \a size, in millimeters.
+*/
+QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size)
+{
+ if (size == QPrinter::Custom) return QSizeF(0, 0);
+ return QSizeF(qt_paperSizes[size][0], qt_paperSizes[size][1]);
+}
+
+/*
+ Returns the PaperSize type that matches \a size, where \a size
+ is in millimeters.
+
+ Because dimensions may not always be completely accurate (for
+ example when converting between units), a particular PaperSize
+ will be returned if it matches within -1/+1 millimeters.
+*/
+QPrinter::PaperSize qSizeFTopaperSize(const QSizeF& size)
+{
+ for (int i = 0; i < static_cast<int>(QPrinter::NPageSize); ++i) {
+ if (qt_paperSizes[i][0] >= size.width() - 1 &&
+ qt_paperSizes[i][0] <= size.width() + 1 &&
+ qt_paperSizes[i][1] >= size.height() - 1 &&
+ qt_paperSizes[i][1] <= size.height() + 1) {
+ return QPrinter::PaperSize(i);
+ }
+ }
+
+ return QPrinter::Custom;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h
new file mode 100644
index 0000000000..7d04099a8f
--- /dev/null
+++ b/src/printsupport/kernel/qprinter.h
@@ -0,0 +1,279 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPRINTER_H
+#define QPRINTER_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qpagedpaintdevice.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+
+#if defined(B0)
+#undef B0 // Terminal hang-up. We assume that you do not want that.
+#endif
+
+class QPrinterPrivate;
+class QPaintEngine;
+class QPrintEngine;
+class QPrinterInfo;
+
+class Q_PRINTSUPPORT_EXPORT QPrinter : public QPagedPaintDevice
+{
+ Q_DECLARE_PRIVATE(QPrinter)
+public:
+ enum PrinterMode { ScreenResolution, PrinterResolution, HighResolution };
+
+ explicit QPrinter(PrinterMode mode = ScreenResolution);
+ explicit QPrinter(const QPrinterInfo& printer, PrinterMode mode = ScreenResolution);
+ ~QPrinter();
+
+ int devType() const;
+
+ enum Orientation { Portrait, Landscape };
+
+#ifndef Q_QDOC
+ typedef PageSize PaperSize;
+#else
+ enum PaperSize { A4, B5, Letter, Legal, Executive,
+ A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
+ B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
+ DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom, NPaperSize = Custom };
+#endif
+
+ enum PageOrder { FirstPageFirst,
+ LastPageFirst };
+
+ enum ColorMode { GrayScale,
+ Color };
+
+ enum PaperSource { OnlyOne,
+ Lower,
+ Middle,
+ Manual,
+ Envelope,
+ EnvelopeManual,
+ Auto,
+ Tractor,
+ SmallFormat,
+ LargeFormat,
+ LargeCapacity,
+ Cassette,
+ FormSource,
+ MaxPageSource
+ };
+
+ enum PrinterState { Idle,
+ Active,
+ Aborted,
+ Error };
+
+ enum OutputFormat { NativeFormat, PdfFormat };
+
+ // Keep in sync with QAbstractPrintDialog::PrintRange
+ enum PrintRange { AllPages, Selection, PageRange, CurrentPage };
+
+ enum Unit {
+ Millimeter,
+ Point,
+ Inch,
+ Pica,
+ Didot,
+ Cicero,
+ DevicePixel
+ };
+
+ enum DuplexMode {
+ DuplexNone = 0,
+ DuplexAuto,
+ DuplexLongSide,
+ DuplexShortSide
+ };
+
+ void setOutputFormat(OutputFormat format);
+ OutputFormat outputFormat() const;
+
+ void setPrinterName(const QString &);
+ QString printerName() const;
+
+ bool isValid() const;
+
+ void setOutputFileName(const QString &);
+ QString outputFileName()const;
+
+ void setPrintProgram(const QString &);
+ QString printProgram() const;
+
+ void setDocName(const QString &);
+ QString docName() const;
+
+ void setCreator(const QString &);
+ QString creator() const;
+
+ void setOrientation(Orientation);
+ Orientation orientation() const;
+
+ void setPageSize(PageSize);
+ PageSize pageSize() const;
+
+ void setPageSizeMM(const QSizeF &size);
+
+ void setPaperSize(PaperSize);
+ PaperSize paperSize() const;
+
+ void setPaperSize(const QSizeF &paperSize, Unit unit);
+ QSizeF paperSize(Unit unit) const;
+
+ void setPageOrder(PageOrder);
+ PageOrder pageOrder() const;
+
+ void setResolution(int);
+ int resolution() const;
+
+ void setColorMode(ColorMode);
+ ColorMode colorMode() const;
+
+ void setCollateCopies(bool collate);
+ bool collateCopies() const;
+
+ void setFullPage(bool);
+ bool fullPage() const;
+
+ void setNumCopies(int);
+ int numCopies() const;
+
+ int actualNumCopies() const;
+
+ void setCopyCount(int);
+ int copyCount() const;
+ bool supportsMultipleCopies() const;
+
+ void setPaperSource(PaperSource);
+ PaperSource paperSource() const;
+
+ void setDuplex(DuplexMode duplex);
+ DuplexMode duplex() const;
+
+ QList<int> supportedResolutions() const;
+
+#ifdef Q_WS_WIN
+ QList<PaperSource> supportedPaperSources() const;
+#endif
+
+ void setFontEmbeddingEnabled(bool enable);
+ bool fontEmbeddingEnabled() const;
+
+ void setDoubleSidedPrinting(bool enable);
+ bool doubleSidedPrinting() const;
+
+#ifdef Q_WS_WIN
+ void setWinPageSize(int winPageSize);
+ int winPageSize() const;
+#endif
+
+ QRect paperRect() const;
+ QRect pageRect() const;
+ QRectF paperRect(Unit) const;
+ QRectF pageRect(Unit) const;
+
+#if !defined(Q_WS_WIN) || defined(qdoc)
+ QString printerSelectionOption() const;
+ void setPrinterSelectionOption(const QString &);
+#endif
+
+ bool newPage();
+ bool abort();
+
+ PrinterState printerState() const;
+
+ QPaintEngine *paintEngine() const;
+ QPrintEngine *printEngine() const;
+
+#ifdef Q_WS_WIN
+ HDC getDC() const;
+ void releaseDC(HDC hdc) const;
+#endif
+
+ void setFromTo(int fromPage, int toPage);
+ int fromPage() const;
+ int toPage() const;
+
+ void setPrintRange(PrintRange range);
+ PrintRange printRange() const;
+
+ void setMargins(const Margins &m);
+
+ void setPageMargins(qreal left, qreal top, qreal right, qreal bottom, Unit unit);
+ void getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, Unit unit) const;
+
+protected:
+ int metric(PaintDeviceMetric) const;
+ void setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine);
+
+private:
+ void init(PrinterMode mode);
+
+ Q_DISABLE_COPY(QPrinter)
+
+ QScopedPointer<QPrinterPrivate> d_ptr;
+
+ friend class QPrintDialogPrivate;
+ friend class QAbstractPrintDialog;
+ friend class QAbstractPrintDialogPrivate;
+ friend class QPrintPreviewWidgetPrivate;
+ friend class QTextDocument;
+ friend class QPageSetupWidget;
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPRINTER_H
diff --git a/src/printsupport/kernel/qprinter_p.h b/src/printsupport/kernel/qprinter_p.h
new file mode 100644
index 0000000000..08877f08c5
--- /dev/null
+++ b/src/printsupport/kernel/qprinter_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 QPRINTER_P_H
+#define QPRINTER_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 "QtCore/qglobal.h"
+
+#ifndef QT_NO_PRINTER
+
+#include "QtPrintSupport/qprinter.h"
+#include "QtPrintSupport/qprintengine.h"
+#include "QtCore/qpointer.h"
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPrintEngine;
+class QPreviewPaintEngine;
+class QPicture;
+
+class Q_PRINTSUPPORT_EXPORT QPrinterPrivate
+{
+ Q_DECLARE_PUBLIC(QPrinter)
+public:
+ QPrinterPrivate(QPrinter *printer)
+ : printEngine(0)
+ , paintEngine(0)
+ , q_ptr(printer)
+ , printRange(QPrinter::AllPages)
+ , use_default_engine(true)
+ , validPrinter(false)
+ , hasCustomPageMargins(false)
+ , hasUserSetPageSize(false)
+ {
+ }
+
+ ~QPrinterPrivate() {
+
+ }
+
+ void createDefaultEngines();
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ QList<const QPicture *> previewPages() const;
+ void setPreviewMode(bool);
+#endif
+
+ void addToManualSetList(QPrintEngine::PrintEnginePropertyKey key);
+
+ QPrinter::PrinterMode printerMode;
+ QPrinter::OutputFormat outputFormat;
+ QPrintEngine *printEngine;
+ QPaintEngine *paintEngine;
+
+ QPrintEngine *realPrintEngine;
+ QPaintEngine *realPaintEngine;
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ QPreviewPaintEngine *previewEngine;
+#endif
+
+ QPrinter *q_ptr;
+
+ QPrinter::PrintRange printRange;
+
+ uint use_default_engine : 1;
+ uint had_default_engines : 1;
+
+ uint validPrinter : 1;
+ uint hasCustomPageMargins : 1;
+ uint hasUserSetPageSize : 1;
+
+ // Used to remember which properties have been manually set by the user.
+ QList<QPrintEngine::PrintEnginePropertyKey> manualSetList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPRINTER_P_H
diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp
new file mode 100644
index 0000000000..5be73e76b9
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** 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"
+
+#ifndef QT_NO_PRINTER
+
+#include "qplatformprintplugin_qpa.h"
+#include <QtPrintSupport/QPlatformPrinterSupport>
+
+QT_BEGIN_NAMESPACE
+
+QPrinterInfoPrivate QPrinterInfoPrivate::shared_null;
+
+
+/*!
+ \class QPrinterInfo
+
+ \brief The QPrinterInfo class gives access to information about
+ existing printers.
+
+ \ingroup printing
+
+ Use the static functions to generate a list of QPrinterInfo
+ objects. Each QPrinterInfo object in the list represents a single
+ printer and can be queried for name, supported paper sizes, and
+ whether or not it is the default printer.
+
+ \since 4.4
+*/
+
+/*!
+ \fn QList<QPrinterInfo> QPrinterInfo::availablePrinters()
+
+ Returns a list of available printers on the system.
+*/
+
+/*!
+ \fn QPrinterInfo QPrinterInfo::defaultPrinter()
+
+ Returns the default printer on the system.
+
+ The return value should be checked using isNull() before being
+ used, in case there is no default printer.
+
+ \sa isNull()
+*/
+
+/*!
+ Constructs an empty QPrinterInfo object.
+
+ \sa isNull()
+*/
+QPrinterInfo::QPrinterInfo()
+ : d_ptr(&QPrinterInfoPrivate::shared_null)
+{
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+QPrinterInfo::QPrinterInfo(const QPrinterInfo &other)
+ : d_ptr(new QPrinterInfoPrivate(*other.d_ptr))
+{
+}
+
+/*!
+ Constructs a QPrinterInfo object from \a printer.
+*/
+QPrinterInfo::QPrinterInfo(const QPrinter &printer)
+ : d_ptr(&QPrinterInfoPrivate::shared_null)
+{
+ foreach (const QPrinterInfo &printerInfo, availablePrinters()) {
+ if (printerInfo.printerName() == printer.printerName()) {
+ d_ptr.reset(new QPrinterInfoPrivate(*printerInfo.d_ptr));
+ break;
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+QPrinterInfo::QPrinterInfo(const QString &name)
+ : d_ptr(new QPrinterInfoPrivate(name))
+{
+}
+
+/*!
+ Destroys the QPrinterInfo object. References to the values in the
+ object become invalid.
+*/
+QPrinterInfo::~QPrinterInfo()
+{
+}
+
+/*!
+ Sets the QPrinterInfo object to be equal to \a other.
+*/
+QPrinterInfo &QPrinterInfo::operator=(const QPrinterInfo &other)
+{
+ Q_ASSERT(d_ptr);
+ d_ptr.reset(new QPrinterInfoPrivate(*other.d_ptr));
+ return *this;
+}
+
+/*!
+ Returns the name of the printer.
+
+ \sa QPrinter::setPrinterName()
+*/
+QString QPrinterInfo::printerName() const
+{
+ const Q_D(QPrinterInfo);
+ return d->name;
+}
+
+/*!
+ Returns whether this QPrinterInfo object holds a printer definition.
+
+ An empty QPrinterInfo object could result for example from calling
+ defaultPrinter() when there are no printers on the system.
+*/
+bool QPrinterInfo::isNull() const
+{
+ const Q_D(QPrinterInfo);
+ return d == &QPrinterInfoPrivate::shared_null;
+}
+
+/*!
+ Returns whether this printer is the default printer.
+*/
+bool QPrinterInfo::isDefault() const
+{
+ const Q_D(QPrinterInfo);
+ return d->isDefault;
+}
+
+/*!
+ \fn QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
+ \since 4.4
+
+ Returns a list of supported paper sizes by the printer.
+
+ Not all printer drivers support this query, so the list may be empty.
+ On Mac OS X 10.3, this function always returns an empty list.
+*/
+
+#ifdef Q_WS_QPA
+QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
+{
+ const Q_D(QPrinterInfo);
+ if (!isNull() && !d->hasPaperSizes) {
+ d->paperSizes = QPlatformPrinterSupportPlugin::get()->supportedPaperSizes(*this);
+ d->hasPaperSizes = true;
+ }
+ return d->paperSizes;
+}
+
+QList<QPrinterInfo> QPrinterInfo::availablePrinters()
+{
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (!ps)
+ return QList<QPrinterInfo>();
+ return ps->availablePrinters();
+}
+
+QPrinterInfo QPrinterInfo::defaultPrinter()
+{
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (!ps)
+ return QPrinterInfo();
+ return QPlatformPrinterSupportPlugin::get()->defaultPrinter();
+}
+
+#endif //Q_WS_QPA
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprinterinfo.h b/src/printsupport/kernel/qprinterinfo.h
new file mode 100644
index 0000000000..535c29c4d6
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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_H
+#define QPRINTERINFO_H
+
+#include <QtCore/QList>
+
+#include <QtPrintSupport/QPrinter>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+class QPrinterInfoPrivate;
+class QPrinterInfoPrivateDeleter;
+class Q_PRINTSUPPORT_EXPORT QPrinterInfo
+{
+public:
+ QPrinterInfo();
+ QPrinterInfo(const QPrinterInfo &other);
+ QPrinterInfo(const QPrinter &printer);
+ ~QPrinterInfo();
+
+ QPrinterInfo &operator=(const QPrinterInfo &other);
+
+ QString printerName() const;
+ bool isNull() const;
+ bool isDefault() const;
+ QList<QPrinter::PaperSize> supportedPaperSizes() const;
+
+ static QList<QPrinterInfo> availablePrinters();
+ static QPrinterInfo defaultPrinter();
+
+private:
+ QPrinterInfo(const QString &name);
+
+private:
+ friend class QPlatformPrinterSupport;
+ Q_DECLARE_PRIVATE(QPrinterInfo)
+ QScopedPointer<QPrinterInfoPrivate, QPrinterInfoPrivateDeleter> d_ptr;
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPRINTERINFO_H
diff --git a/src/printsupport/kernel/qprinterinfo_p.h b/src/printsupport/kernel/qprinterinfo_p.h
new file mode 100644
index 0000000000..a3c654e7b7
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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_P_H
+#define QPRINTERINFO_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 "QtCore/qglobal.h"
+
+#ifndef QT_NO_PRINTER
+
+#include "QtCore/qlist.h"
+
+QT_BEGIN_NAMESPACE
+
+class QPrinterInfoPrivate
+{
+public:
+ QPrinterInfoPrivate(const QString& name = QString()) :
+ name(name), isDefault(false)
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ , cupsPrinterIndex(0)
+#endif
+#endif
+ , hasPaperSizes(false)
+ {}
+ ~QPrinterInfoPrivate()
+ {}
+
+ static QPrinterInfoPrivate shared_null;
+
+ QString name;
+ bool isDefault;
+
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ int cupsPrinterIndex;
+#endif
+#endif
+ mutable bool hasPaperSizes;
+ mutable QList<QPrinter::PaperSize> paperSizes;
+};
+
+
+class QPrinterInfoPrivateDeleter
+{
+public:
+ static inline void cleanup(QPrinterInfoPrivate *d)
+ {
+ if (d != &QPrinterInfoPrivate::shared_null)
+ delete d;
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPRINTERINFO_P_H
diff --git a/src/printsupport/kernel/qprinterinfo_unix.cpp b/src/printsupport/kernel/qprinterinfo_unix.cpp
new file mode 100644
index 0000000000..c7dbb7cc32
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo_unix.cpp
@@ -0,0 +1,857 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 <qfile.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qlibrary.h>
+#include <qtextstream.h>
+#include <qcoreapplication.h>
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+# include <private/qcups_p.h>
+# include <cups/cups.h>
+# include <private/qpdf_p.h>
+#endif
+
+#include <private/qprinterinfo_unix_p.h>
+
+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<QPrinterDescription> *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<QPrinterDescription> *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<QPrinterDescription> *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 <name>' (where
+ <name> does not contain any white space). The first such match
+ results in <name> 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<QPrinterDescription> *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",
+ printer.fileName().toAscii().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<QPrinterDescription> *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).toAscii().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<QPrinterDescription> *)data);
+ return 0;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+int qt_retrieveNisPrinters(QList<QPrinterDescription> *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<QPrinterDescription> *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<QPrinterDescription> *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<QPrinterDescription> *printers)
+{
+ QDir lp(QLatin1String("/etc/lp/member"));
+ if (!lp.exists())
+ return;
+ QFileInfoList dirs = lp.entryInfoList();
+ if (dirs.isEmpty())
+ return;
+
+ QString tmp;
+ 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<QPrinterDescription> *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<QPrinterDescription> *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<QPrinterDescription>& 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).toAscii();
+ }
+ }
+ }
+
+ 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<QPrinter::PaperSize> qt_getCupsPrinterPaperSizes(int cupsPrinterIndex)
+{
+ QList<QPrinter::PaperSize> 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));
+ }
+ return result;
+#endif
+}
+
+#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
new file mode 100644
index 0000000000..c12aa39556
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo_unix_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** 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 <QtPrintSupport/qprinter.h>
+#include <QtCore/qstringlist.h>
+
+#ifndef QT_NO_NIS
+# ifndef BOOL_DEFINED
+# define BOOL_DEFINED
+# endif
+
+# include <sys/types.h>
+# include <rpc/rpc.h>
+# include <rpcsvc/ypclnt.h>
+# include <rpcsvc/yp_prot.h>
+#endif // QT_NO_NIS
+
+#ifdef Success
+# undef Success
+#endif
+
+#include <ctype.h>
+
+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<QPrinterDescription> *printers, const QString &name,
+ QString host, QString comment,
+ QStringList aliases = QStringList());
+void qt_parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers);
+
+int qt_parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName);
+QString qt_getDefaultFromHomePrinters();
+void qt_parseEtcLpPrinters(QList<QPrinterDescription> *printers);
+char *qt_parsePrintersConf(QList<QPrinterDescription> *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<QPrinterDescription> *printers);
+#endif // QT_NO_NIS
+char *qt_parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line);
+char *qt_parseNsswitchConf(QList<QPrinterDescription> *printers);
+void qt_parseEtcLpMember(QList<QPrinterDescription> *printers);
+void qt_parseSpoolInterface(QList<QPrinterDescription> *printers);
+void qt_parseQconfig(QList<QPrinterDescription> *printers);
+int qt_getLprPrinters(QList<QPrinterDescription>& printers);
+
+QList<QPrinter::PaperSize> qt_getCupsPrinterPaperSizes(int cupsPrinterIndex);
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+#endif // QPRINTERINFO_UNIX_P_H