1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qprinterinfo.h"
43 #include "qprinterinfo_p.h"
46 #include <qfileinfo.h>
48 #include <qprintdialog.h>
50 #include <qtextstream.h>
52 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
53 # include <private/qcups_p.h>
54 # include <cups/cups.h>
55 # include <private/qpdf_p.h>
58 #include <private/qprinterinfo_unix_p.h>
64 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
65 // preserver names in ascending order for the binary search
66 static const struct NamedPaperSize {
67 const char *const name;
68 QPrinter::PaperSize size;
69 } named_sizes_map[QPrinter::NPageSize] = {
70 { "A0", QPrinter::A0 },
71 { "A1", QPrinter::A1 },
72 { "A2", QPrinter::A2 },
73 { "A3", QPrinter::A3 },
74 { "A4", QPrinter::A4 },
75 { "A5", QPrinter::A5 },
76 { "A6", QPrinter::A6 },
77 { "A7", QPrinter::A7 },
78 { "A8", QPrinter::A8 },
79 { "A9", QPrinter::A9 },
80 { "B0", QPrinter::B0 },
81 { "B1", QPrinter::B1 },
82 { "B10", QPrinter::B10 },
83 { "B2", QPrinter::B2 },
84 { "B4", QPrinter::B4 },
85 { "B5", QPrinter::B5 },
86 { "B6", QPrinter::B6 },
87 { "B7", QPrinter::B7 },
88 { "B8", QPrinter::B8 },
89 { "B9", QPrinter::B9 },
90 { "C5E", QPrinter::C5E },
91 { "Comm10E", QPrinter::Comm10E },
92 { "Custom", QPrinter::Custom },
93 { "DLE", QPrinter::DLE },
94 { "Executive", QPrinter::Executive },
95 { "Folio", QPrinter::Folio },
96 { "Ledger", QPrinter::Ledger },
97 { "Legal", QPrinter::Legal },
98 { "Letter", QPrinter::Letter },
99 { "Tabloid", QPrinter::Tabloid }
102 inline bool operator<(const char *name, const NamedPaperSize &data)
103 { return qstrcmp(name, data.name) < 0; }
104 inline bool operator<(const NamedPaperSize &data, const char *name)
105 { return qstrcmp(data.name, name) < 0; }
107 static inline QPrinter::PaperSize string2PaperSize(const char *name)
109 const NamedPaperSize *r = qBinaryFind(named_sizes_map, named_sizes_map + QPrinter::NPageSize, name);
110 if (r - named_sizes_map != QPrinter::NPageSize)
112 return QPrinter::Custom;
115 static inline const char *paperSize2String(QPrinter::PaperSize size)
117 for (int i = 0; i < QPrinter::NPageSize; ++i) {
118 if (size == named_sizes_map[i].size)
119 return named_sizes_map[i].name;
125 void qt_perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &name,
126 QString host, QString comment,
129 for (int i = 0; i < printers->size(); ++i)
130 if (printers->at(i).samePrinter(name))
133 #ifndef QT_NO_PRINTDIALOG
135 host = QPrintDialog::tr("locally connected");
137 printers->append(QPrinterDescription(name.simplified(), host.simplified(), comment.simplified(), aliases));
140 void qt_parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers)
142 if (printerDesc.length() < 1)
145 printerDesc = printerDesc.simplified();
146 int i = printerDesc.indexOf(QLatin1Char(':'));
147 QString printerName, printerComment, printerHost;
152 int j = printerDesc.indexOf(QLatin1Char('|'));
153 if (j > 0 && j < i) {
154 printerName = printerDesc.left(j);
155 aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|'));
156 #ifndef QT_NO_PRINTDIALOG
157 // try extracting a comment from the aliases
158 printerComment = QPrintDialog::tr("Aliases: %1")
159 .arg(aliases.join(QLatin1String(", ")));
162 printerName = printerDesc.left(i);
164 // look for lprng pseudo all printers entry
165 i = printerDesc.indexOf(QRegExp(QLatin1String(": *all *=")));
167 printerName = QString();
168 // look for signs of this being a remote printer
169 i = printerDesc.indexOf(QRegExp(QLatin1String(": *rm *=")));
171 // point k at the end of remote host name
172 while (printerDesc[i] != QLatin1Char('='))
174 while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
177 while (j < (int)printerDesc.length() && printerDesc[j] != QLatin1Char(':'))
180 // and stuff that into the string
181 printerHost = printerDesc.mid(i, j - i);
184 if (printerName.length())
185 qt_perhapsAddPrinter(printers, printerName, printerHost, printerComment,
189 int qt_parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName)
191 QFile printcap(fileName);
192 if (!printcap.open(QIODevice::ReadOnly))
195 char *line_ascii = new char[1025];
196 line_ascii[1024] = '\0';
202 if (printcap.atEnd() || printcap.readLine(line_ascii, 1024) <= 0)
204 QString line = QString::fromLocal8Bit(line_ascii);
205 line = line.trimmed();
206 if (line.length() >= 1 && line[int(line.length()) - 1] == QLatin1Char('\\'))
208 if (line[0] == QLatin1Char('#')) {
211 } else if (line[0] == QLatin1Char('|') || line[0] == QLatin1Char(':')
218 qt_parsePrinterDesc(printerDesc, printers);
220 // add the first line of the new printer definition
230 Checks $HOME/.printers for a line matching '_default <name>' (where
231 <name> does not contain any white space). The first such match
232 results in <name> being returned.
233 If no lines match then an empty string is returned.
235 QString qt_getDefaultFromHomePrinters()
237 QFile file(QDir::homePath() + QLatin1String("/.printers"));
238 if (!file.open(QIODevice::ReadOnly))
240 QString all(QLatin1String(file.readAll()));
241 QStringList words = all.split(QRegExp(QLatin1String("\\W+")), QString::SkipEmptyParts);
242 const int i = words.indexOf(QLatin1String("_default"));
243 if (i != -1 && i < words.size() - 1)
244 return words.at(i + 1);
249 void qt_parseEtcLpPrinters(QList<QPrinterDescription> *printers)
251 QDir lp(QLatin1String("/etc/lp/printers"));
252 QFileInfoList dirs = lp.entryInfoList();
257 for (int i = 0; i < dirs.size(); ++i) {
258 QFileInfo printer = dirs.at(i);
259 if (printer.isDir()) {
260 tmp.sprintf("/etc/lp/printers/%s/configuration",
261 printer.fileName().toAscii().data());
262 QFile configuration(tmp);
263 char *line = new char[1025];
264 QString remote(QLatin1String("Remote:"));
265 QString contentType(QLatin1String("Content types:"));
267 bool canPrintPostscript = false;
268 if (configuration.open(QIODevice::ReadOnly)) {
269 while (!configuration.atEnd() &&
270 configuration.readLine(line, 1024) > 0) {
271 if (QString::fromLatin1(line).startsWith(remote)) {
272 const char *p = line;
276 while (isspace((uchar) *p))
278 printerHost = QString::fromLocal8Bit(p);
279 printerHost = printerHost.simplified();
280 } else if (QString::fromLatin1(line).startsWith(contentType)) {
287 while (isspace((uchar) *p))
292 while (isalnum((uchar) *e))
296 if (!qstrcmp(p, "postscript") ||
298 canPrintPostscript = true;
307 if (canPrintPostscript)
308 qt_perhapsAddPrinter(printers, printer.fileName(),
309 printerHost, QLatin1String(""));
317 char *qt_parsePrintersConf(QList<QPrinterDescription> *printers, bool *found)
319 QFile pc(QLatin1String("/etc/printers.conf"));
320 if (!pc.open(QIODevice::ReadOnly)) {
328 char *line = new char[1025];
334 char *defaultPrinter = 0;
336 while (!pc.atEnd() &&
337 (lineLength=pc.readLine(line, 1024)) > 0) {
342 if (lineLength >= 2 && line[lineLength-2] == '\\') {
343 line[lineLength-2] = '\0';
344 printerDesc += QString::fromLocal8Bit(line);
346 printerDesc += QString::fromLocal8Bit(line);
347 printerDesc = printerDesc.simplified();
348 int i = printerDesc.indexOf(QLatin1Char(':'));
349 QString printerName, printerHost, printerComment;
353 int j = printerDesc.indexOf(QLatin1Char('|'));
356 printerName = printerDesc.mid(0, j < 0 ? i : j);
357 if (printerName == QLatin1String("_default")) {
358 i = printerDesc.indexOf(
359 QRegExp(QLatin1String(": *use *=")));
360 while (printerDesc[i] != QLatin1Char('='))
362 while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
365 while (j < (int)printerDesc.length() &&
366 printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
368 // that's our default printer
370 qstrdup(printerDesc.mid(i, j-i).toAscii().data());
371 printerName = QString();
372 printerDesc = QString();
373 } else if (printerName == QLatin1String("_all")) {
374 // skip it.. any other cases we want to skip?
375 printerName = QString();
376 printerDesc = QString();
380 // try extracting a comment from the aliases
381 aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|'));
382 #ifndef QT_NO_PRINTDIALOG
383 printerComment = QPrintDialog::tr("Aliases: %1")
384 .arg(aliases.join(QLatin1String(", ")));
387 // look for signs of this being a remote printer
388 i = printerDesc.indexOf(
389 QRegExp(QLatin1String(": *bsdaddr *=")));
391 // point k at the end of remote host name
392 while (printerDesc[i] != QLatin1Char('='))
394 while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
397 while (j < (int)printerDesc.length() &&
398 printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
400 // and stuff that into the string
401 printerHost = printerDesc.mid(i, j-i);
402 // maybe stick the remote printer name into the comment
403 if (printerDesc[j] == QLatin1Char(',')) {
405 while (printerDesc[i].isSpace())
408 while (j < (int)printerDesc.length() &&
409 printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
411 if (printerName != printerDesc.mid(i, j-i)) {
413 QLatin1String("Remote name: ");
414 printerComment += printerDesc.mid(i, j-i);
419 if (printerComment == QLatin1String(":"))
420 printerComment = QString(); // for cups
421 if (printerName.length())
422 qt_perhapsAddPrinter(printers, printerName, printerHost,
423 printerComment, aliases);
424 // chop away the line, for processing the next one
425 printerDesc = QString();
429 return defaultPrinter;
434 #if defined(Q_C_CALLBACKS)
438 int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
439 char *val, int valLen, char *data)
441 qt_parsePrinterDesc(QString::fromLatin1(val, valLen), (QList<QPrinterDescription> *)data);
445 #if defined(Q_C_CALLBACKS)
449 int qt_retrieveNisPrinters(QList<QPrinterDescription> *printers)
451 #ifndef QT_NO_LIBRARY
452 typedef int (*WildCast)(int, char *, int, char *, int, char *);
453 char printersConfByname[] = "printers.conf.byname";
457 QLibrary lib(QLatin1String("nsl"));
458 typedef int (*ypGetDefaultDomain)(char **);
459 ypGetDefaultDomain _ypGetDefaultDomain = (ypGetDefaultDomain)lib.resolve("yp_get_default_domain");
460 typedef int (*ypAll)(const char *, const char *, const struct ypall_callback *);
461 ypAll _ypAll = (ypAll)lib.resolve("yp_all");
463 if (_ypGetDefaultDomain && _ypAll) {
464 err = _ypGetDefaultDomain(&domain);
467 // wild cast to support K&R-style system headers
468 (WildCast &) cb.foreach = (WildCast) qt_pd_foreach;
469 cb.data = (char *) printers;
470 err = _ypAll(domain, printersConfByname, &cb);
475 #endif //QT_NO_LIBRARY
481 char *qt_parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line)
483 #define skipSpaces() \
484 while (line[k] != '\0' && isspace((uchar) line[k])) \
487 char *defaultPrinter = 0;
489 int lastStatus = NotFound;
497 char *cp = strchr(line, '#');
501 while (line[k] != '\0') {
502 if (isspace((uchar) line[k])) {
504 } else if (line[k] == '[') {
507 while (line[k] != '\0') {
508 char status = tolower(line[k]);
511 while (line[k] != '=' && line[k] != ']' && line[k] != '\0')
513 if (line[k] == '=') {
516 action = tolower(line[k]);
517 while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != ']')
519 } else if (line[k] == ']') {
525 if (lastStatus == status)
526 stop = (action == (char) Return);
533 while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != '[') {
538 if (source == "user") {
539 lastStatus = qt_parsePrintcap(printers,
540 QDir::homePath() + QLatin1String("/.printers"));
541 } else if (source == "files") {
543 defaultPrinter = qt_parsePrintersConf(printers, &found);
545 lastStatus = Success;
547 } else if (source == "nis") {
548 lastStatus = qt_retrieveNisPrinters(printers);
551 // nisplus, dns, etc., are not implemented yet
552 lastStatus = NotFound;
554 stop = (lastStatus == Success);
557 return defaultPrinter;
560 char *qt_parseNsswitchConf(QList<QPrinterDescription> *printers)
562 QFile nc(QLatin1String("/etc/nsswitch.conf"));
563 if (!nc.open(QIODevice::ReadOnly))
566 char *defaultPrinter = 0;
568 char *line = new char[1025];
571 while (!nc.atEnd() &&
572 nc.readLine(line, 1024) > 0) {
573 if (qstrncmp(line, "printers", 8) == 0) {
574 defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line);
576 return defaultPrinter;
580 strcpy(line, "printers: user files nis nisplus xfn");
581 defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line);
583 return defaultPrinter;
587 void qt_parseEtcLpMember(QList<QPrinterDescription> *printers)
589 QDir lp(QLatin1String("/etc/lp/member"));
592 QFileInfoList dirs = lp.entryInfoList();
596 #ifdef QT_NO_PRINTDIALOG
600 for (int i = 0; i < dirs.size(); ++i) {
601 QFileInfo printer = dirs.at(i);
602 // I haven't found any real documentation, so I'm guessing that
603 // since lpstat uses /etc/lp/member rather than one of the
604 // other directories, it's the one to use. I did not find a
605 // decent way to locate aliases and remote printers.
606 if (printer.isFile())
607 qt_perhapsAddPrinter(printers, printer.fileName(),
608 QPrintDialog::tr("unknown"),
615 void qt_parseSpoolInterface(QList<QPrinterDescription> *printers)
617 QDir lp(QLatin1String("/usr/spool/lp/interface"));
620 QFileInfoList files = lp.entryInfoList();
624 for (int i = 0; i < files.size(); ++i) {
625 QFileInfo printer = files.at(i);
627 if (!printer.isFile())
630 // parse out some information
631 QFile configFile(printer.filePath());
632 if (!configFile.open(QIODevice::ReadOnly))
642 QString nameKey(QLatin1String("NAME="));
643 QString typeKey(QLatin1String("TYPE="));
644 QString hostKey(QLatin1String("HOSTNAME="));
645 QString hostPrinterKey(QLatin1String("HOSTPRINTER="));
647 while (!configFile.atEnd() &&
648 (configFile.readLine(line.data(), 1024)) > 0) {
649 QString uline = QString::fromLocal8Bit(line);
650 if (uline.startsWith(typeKey) ) {
651 printerType = uline.mid(nameKey.length());
652 printerType = printerType.simplified();
653 } else if (uline.startsWith(hostKey)) {
654 hostName = uline.mid(hostKey.length());
655 hostName = hostName.simplified();
656 } else if (uline.startsWith(hostPrinterKey)) {
657 hostPrinter = uline.mid(hostPrinterKey.length());
658 hostPrinter = hostPrinter.simplified();
659 } else if (uline.startsWith(nameKey)) {
660 namePrinter = uline.mid(nameKey.length());
661 namePrinter = namePrinter.simplified();
666 printerType = printerType.trimmed();
667 if (printerType.indexOf(QLatin1String("postscript"), 0, Qt::CaseInsensitive) < 0)
671 while ((ii = namePrinter.indexOf(QLatin1Char('"'), ii)) >= 0)
672 namePrinter.remove(ii, 1);
674 if (hostName.isEmpty() || hostPrinter.isEmpty()) {
675 qt_perhapsAddPrinter(printers, printer.fileName(),
676 QLatin1String(""), namePrinter);
679 comment = namePrinter;
680 comment += QLatin1String(" (");
681 comment += hostPrinter;
682 comment += QLatin1Char(')');
683 qt_perhapsAddPrinter(printers, printer.fileName(),
690 // Every unix must have its own. It's a standard. Here is AIX.
691 void qt_parseQconfig(QList<QPrinterDescription> *printers)
693 QFile qconfig(QLatin1String("/etc/qconfig"));
694 if (!qconfig.open(QIODevice::ReadOnly))
697 QTextStream ts(&qconfig);
700 QString stanzaName; // either a queue or a device name
701 bool up = true; // queue up? default true, can be false
702 QString remoteHost; // null if local
703 QString deviceName; // null if remote
705 QRegExp newStanza(QLatin1String("^[0-z\\-]*:$"));
707 // our basic strategy here is to process each line, detecting new
708 // stanzas. each time we see a new stanza, we check if the
709 // previous stanza was a valid queue for a) a remote printer or b)
710 // a local printer. if it wasn't, we assume that what we see is
711 // the start of the first stanza, or that the previous stanza was
712 // a device stanza, or that there is some syntax error (we don't
716 line = ts.readLine();
717 bool indented = line[0].isSpace();
718 line = line.simplified();
720 int i = line.indexOf(QLatin1Char('='));
721 if (indented && i != -1) { // line in stanza
722 QString variable = line.left(i).simplified();
723 QString value=line.mid(i+1, line.length()).simplified();
724 if (variable == QLatin1String("device"))
726 else if (variable == QLatin1String("host"))
728 else if (variable == QLatin1String("up"))
729 up = !(value.toLower() == QLatin1String("false"));
730 } else if (line[0] == QLatin1Char('*')) { // comment
732 } else if (ts.atEnd() || // end of file, or beginning of new stanza
733 (!indented && line.contains(newStanza))) {
734 if (up && stanzaName.length() > 0 && stanzaName.length() < 21) {
735 if (remoteHost.length()) // remote printer
736 qt_perhapsAddPrinter(printers, stanzaName, remoteHost,
738 else if (deviceName.length()) // local printer
739 qt_perhapsAddPrinter(printers, stanzaName, QString(),
743 if (line.length() >= 1 && line.length() <= 20)
749 // syntax error? ignore.
751 } while (!ts.atEnd());
754 int qt_getLprPrinters(QList<QPrinterDescription>& printers)
756 QByteArray etcLpDefault;
757 qt_parsePrintcap(&printers, QLatin1String("/etc/printcap"));
758 qt_parseEtcLpMember(&printers);
759 qt_parseSpoolInterface(&printers);
760 qt_parseQconfig(&printers);
763 f.setFile(QLatin1String("/etc/lp/printers"));
765 qt_parseEtcLpPrinters(&printers);
766 QFile def(QLatin1String("/etc/lp/default"));
767 if (def.open(QIODevice::ReadOnly)) {
768 etcLpDefault.resize(1025);
769 if (def.readLine(etcLpDefault.data(), 1024) > 0) {
770 QRegExp rx(QLatin1String("^(\\S+)"));
771 if (rx.indexIn(QString::fromLatin1(etcLpDefault)) != -1)
772 etcLpDefault = rx.cap(1).toAscii();
778 f.setFile(QLatin1String("/etc/nsswitch.conf"));
780 def = qt_parseNsswitchConf(&printers);
782 f.setFile(QLatin1String("/etc/printers.conf"));
784 def = qt_parsePrintersConf(&printers);
792 QString homePrintersDefault = qt_getDefaultFromHomePrinters();
794 // all printers hopefully known. try to find a good default
795 QString dollarPrinter;
797 dollarPrinter = QString::fromLocal8Bit(qgetenv("PRINTER"));
798 if (dollarPrinter.isEmpty())
799 dollarPrinter = QString::fromLocal8Bit(qgetenv("LPDEST"));
800 if (dollarPrinter.isEmpty())
801 dollarPrinter = QString::fromLocal8Bit(qgetenv("NPRINTER"));
802 if (dollarPrinter.isEmpty())
803 dollarPrinter = QString::fromLocal8Bit(qgetenv("NGPRINTER"));
804 #ifndef QT_NO_PRINTDIALOG
805 if (!dollarPrinter.isEmpty())
806 qt_perhapsAddPrinter(&printers, dollarPrinter,
807 QPrintDialog::tr("unknown"),
812 QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)"));
813 QRegExp lp(QLatin1String("[^a-z]lp(?:[^a-z]|$)"));
817 for (int i = 0; i < printers.size(); ++i) {
818 QString name = printers.at(i).name;
819 QString comment = printers.at(i).comment;
820 if (quality < 5 && name == dollarPrinter) {
823 } else if (quality < 4 && !homePrintersDefault.isEmpty() &&
824 name == homePrintersDefault) {
827 } else if (quality < 3 && !etcLpDefault.isEmpty() &&
828 name == QLatin1String(etcLpDefault)) {
831 } else if (quality < 2 &&
832 (name == QLatin1String("ps") ||
833 ps.indexIn(comment) != -1)) {
836 } else if (quality < 1 &&
837 (name == QLatin1String("lp") ||
838 lp.indexIn(comment) > -1)) {
847 /////////////////////////////////////////////////////////////////////////////
848 /////////////////////////////////////////////////////////////////////////////
850 QList<QPrinterInfo> QPrinterInfo::availablePrinters()
852 QList<QPrinterInfo> printers;
854 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
855 if (QCUPSSupport::isAvailable()) {
857 int cupsPrinterCount = cups.availablePrintersCount();
858 const cups_dest_t* cupsPrinters = cups.availablePrinters();
859 for (int i = 0; i < cupsPrinterCount; ++i) {
860 QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
861 if (cupsPrinters[i].instance)
862 printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
864 QPrinterInfo printerInfo(printerName);
865 if (cupsPrinters[i].is_default)
866 printerInfo.d_ptr->isDefault = true;
867 printerInfo.d_ptr->cupsPrinterIndex = i;
868 printers.append(printerInfo);
873 QList<QPrinterDescription> lprPrinters;
874 int defprn = qt_getLprPrinters(lprPrinters);
875 // populating printer combo
876 foreach (const QPrinterDescription &description, lprPrinters)
877 printers.append(QPrinterInfo(description.name));
878 if (defprn >= 0 && defprn < printers.size())
879 printers[defprn].d_ptr->isDefault = true;
885 QPrinterInfo QPrinterInfo::defaultPrinter()
887 QList<QPrinterInfo> printers = availablePrinters();
888 foreach (const QPrinterInfo &printerInfo, printers) {
889 if (printerInfo.isDefault())
893 return printers.value(0);
896 QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
898 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
899 const Q_D(QPrinterInfo);
902 return d->paperSizes;
904 if (!d->hasPaperSizes) {
905 d->hasPaperSizes = true;
907 if (QCUPSSupport::isAvailable()) {
908 // Find paper sizes from CUPS.
910 cups.setCurrentPrinter(d->cupsPrinterIndex);
911 const ppd_option_t* sizes = cups.pageSizes();
913 for (int j = 0; j < sizes->num_choices; ++j)
914 d->paperSizes.append(string2PaperSize(sizes->choices[j].choice));
919 return d->paperSizes;
921 return QList<QPrinter::PaperSize>();
925 #endif // QT_NO_PRINTER