1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the dialog module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#ifndef QT_NO_PRINTDIALOG
31
#include "qplatformdefs.h"
33
#include <private/qabstractprintdialog_p.h>
34
#include "qprintdialog.h"
36
#include "qfiledialog.h"
38
#include "qdesktopwidget.h"
40
#include "qtextstream.h"
41
#include "qcombobox.h"
44
#include "qlineedit.h"
45
#include "qpushbutton.h"
48
#include "qbuttongroup.h"
49
#include "qradiobutton.h"
51
#include "qapplication.h"
55
#include "qgroupbox.h"
56
#include "qsignalmapper.h"
58
#include "qabstractitemmodel.h"
59
#include "qtreeview.h"
60
#include "qheaderview.h"
62
#if !defined(QT_NO_CUPS) || !defined(QT_NO_NIS)
72
#include <rpcsvc/ypclnt.h>
73
#include <rpcsvc/yp_prot.h>
80
enum { Success = 's', Unavail = 'u', NotFound = 'n', TryAgain = 't' };
81
enum { Continue = 'c', Return = 'r' };
84
struct QPrinterDescription {
85
QPrinterDescription(const QString &n, const QString &h, const QString &c, const QStringList &a)
86
: name(n), host(h), comment(c), aliases(a) {}
91
bool samePrinter(const QString& printer) const {
92
return name == printer || aliases.contains(printer);
96
class QPrinterModel : public QAbstractTableModel
99
QPrinterModel(const QList<QPrinterDescription> &printers, QObject *parent);
101
int rowCount(const QModelIndex &parent = QModelIndex()) const;
102
int columnCount(const QModelIndex &parent = QModelIndex()) const;
103
QVariant data(const QModelIndex &index, int role) const;
104
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
106
QList<QPrinterDescription> lst;
109
QPrinterModel::QPrinterModel(const QList<QPrinterDescription> &printers, QObject *parent)
110
: QAbstractTableModel(parent)
115
int QPrinterModel::rowCount(const QModelIndex &) const
120
int QPrinterModel::columnCount(const QModelIndex &) const
125
QVariant QPrinterModel::data(const QModelIndex &index, int role) const
127
if (index.isValid() && index.row() < (int)lst.count()
128
&& role == Qt::DisplayRole) {
129
const QPrinterDescription &desc = lst.at(index.row());
130
switch(index.column()) {
142
QVariant QPrinterModel::headerData(int section, Qt::Orientation orientation, int role) const
144
if (orientation == Qt::Horizontal) {
145
const char *name = 0;
157
return qApp->translate("QPrintDialog", name);
159
return QAbstractTableModel::headerData(section, orientation, role);
163
class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
165
Q_DECLARE_PUBLIC(QPrintDialog)
167
QButtonGroup *printerOrFile;
170
QList<QPrinterDescription> printers;
171
QPrinterModel *model;
175
QPushButton *browse, *ok;
177
QButtonGroup *printRange;
178
QLabel *firstPageLabel;
180
QLabel *lastPageLabel;
182
QRadioButton *printAllButton;
183
QRadioButton *printRangeButton;
184
QRadioButton *printSelectionButton;
185
QRadioButton *printToFileButton;
186
QComboBox *orientationCombo, *sizeCombo;
188
QPrinter::PageSize pageSize;
189
QPrinter::Orientation orientation;
191
QButtonGroup *pageOrder;
192
QRadioButton *firstPageFirst;
193
QRadioButton *lastPageFirst;
194
QPrinter::PageOrder pageOrder2;
196
QButtonGroup *colorMode;
197
QRadioButton *printColor;
198
QRadioButton *printGray;
199
QPrinter::ColorMode colorMode2;
204
QBoxLayout *customLayout;
206
QPrinter::PageSize indexToPageSize[QPrinter::NPageSize];
210
void browseClicked();
212
void printerOrFileSelected(QAbstractButton *b);
213
void landscapeSelected(int);
214
void paperSizeSelected(int);
215
void orientSelected(int);
216
void pageOrderSelected(QAbstractButton *);
217
void colorModeSelected(QAbstractButton *);
218
void setNumCopies(int);
219
void printRangeSelected(QAbstractButton *);
220
void setFirstPage(int);
221
void setLastPage(int);
222
void fileNameEditChanged(const QString &text);
224
QGroupBox *setupDestination();
225
QGroupBox *setupOptions();
226
QGroupBox *setupPaper();
227
QGroupBox *setupPrinterSettings();
229
void setPrinter(QPrinter *p, bool pickUpSettings);
232
static void isc(QPrintDialogPrivate *d, const QString & text,
233
QPrinter::PageSize ps);
237
static void perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &name,
238
QString host, QString comment,
239
QStringList aliases = QStringList())
241
for (int i = 0; i < printers->size(); ++i)
242
if (printers->at(i).samePrinter(name))
246
host = QPrintDialog::tr("locally connected");
247
printers->append(QPrinterDescription(name.simplified(), host.simplified(), comment.simplified(), aliases));
250
static void parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers)
252
if (printerDesc.length() < 1)
255
printerDesc = printerDesc.simplified();
256
int i = printerDesc.indexOf(':');
257
QString printerName, printerComment, printerHost;
262
int j = printerDesc.indexOf('|');
263
if (j > 0 && j < i) {
264
printerName = printerDesc.left(j);
265
aliases = printerDesc.mid(j + 1, i - j - 1).split('|');
266
// try extracting a comment from the aliases
267
printerComment = QPrintDialog::tr("Aliases: %1")
268
.arg(aliases.join(", "));
270
printerName = printerDesc.left(i);
272
// look for lprng pseudo all printers entry
273
i = printerDesc.indexOf(QRegExp(QLatin1String(": *all *=")));
276
// look for signs of this being a remote printer
277
i = printerDesc.indexOf(QRegExp(QLatin1String(": *rm *=")));
279
// point k at the end of remote host name
280
while (printerDesc[i] != '=')
282
while (printerDesc[i] == '=' || printerDesc[i].isSpace())
285
while (j < (int)printerDesc.length() && printerDesc[j] != ':')
288
// and stuff that into the string
289
printerHost = printerDesc.mid(i, j - i);
292
if (printerName.length())
293
perhapsAddPrinter(printers, printerName, printerHost, printerComment,
297
static int parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName)
299
QFile printcap(fileName);
300
if (!printcap.open(QIODevice::ReadOnly))
303
char *line_ascii = new char[1025];
304
line_ascii[1024] = '\0';
310
if (printcap.atEnd() || printcap.readLine(line_ascii, 1024) <= 0)
312
QString line = line_ascii;
313
line = line.trimmed();
314
if (line.length() >= 1 && line[int(line.length()) - 1] == '\\')
316
if (line[0] == '#') {
319
} else if (line[0] == '|' || line[0] == ':') {
325
parsePrinterDesc(printerDesc, printers);
327
// add the first line of the new printer definition
336
static void parseEtcLpPrinters(QList<QPrinterDescription> *printers)
338
QDir lp(QLatin1String("/etc/lp/printers"));
339
QFileInfoList dirs = lp.entryInfoList();
344
for (int i = 0; i < dirs.size(); ++i) {
345
QFileInfo printer = dirs.at(i);
346
if (printer.isDir()) {
347
tmp.sprintf("/etc/lp/printers/%s/configuration",
348
printer.fileName().toAscii().data());
349
QFile configuration(tmp);
350
char *line = new char[1025];
351
QString remote(QLatin1String("Remote:"));
352
QString contentType(QLatin1String("Content types:"));
354
bool canPrintPostscript = false;
355
if (configuration.open(QIODevice::ReadOnly)) {
356
while (!configuration.atEnd() &&
357
configuration.readLine(line, 1024) > 0) {
358
if (QString::fromLatin1(line).startsWith(remote)) {
359
const char *p = line;
363
while (isspace((uchar) *p))
365
printerHost = QString::fromLocal8Bit(p);
366
printerHost = printerHost.simplified();
367
} else if (QString::fromLatin1(line).startsWith(contentType)) {
374
while (isspace((uchar) *p))
379
while (isalnum((uchar) *e))
383
if (!qstrcmp(p, "postscript") ||
385
canPrintPostscript = true;
394
if (canPrintPostscript)
395
perhapsAddPrinter(printers, printer.fileName(),
396
printerHost, QLatin1String(""));
405
static char *parsePrintersConf(QList<QPrinterDescription> *printers, bool *found = 0)
407
QFile pc(QLatin1String("/etc/printers.conf"));
408
if (!pc.open(QIODevice::ReadOnly)) {
416
char *line = new char[1025];
422
char *defaultPrinter = 0;
424
while (!pc.atEnd() &&
425
(lineLength=pc.readLine(line, 1024)) > 0) {
430
if (lineLength >= 2 && line[lineLength-2] == '\\') {
431
line[lineLength-2] = '\0';
432
printerDesc += QString::fromLocal8Bit(line);
434
printerDesc += QString::fromLocal8Bit(line);
435
printerDesc = printerDesc.simplified();
436
int i = printerDesc.indexOf(':');
437
QString printerName, printerHost, printerComment;
441
int j = printerDesc.indexOf('|');
444
printerName = printerDesc.mid(0, j < 0 ? i : j);
445
if (printerName == QLatin1String("_default")) {
446
i = printerDesc.indexOf(
447
QRegExp(QLatin1String(": *use *=")));
448
while (printerDesc[i] != '=')
450
while (printerDesc[i] == '=' || printerDesc[i].isSpace())
453
while (j < (int)printerDesc.length() &&
454
printerDesc[j] != ':' && printerDesc[j] != ',')
456
// that's our default printer
458
qstrdup(printerDesc.mid(i, j-i).toAscii().data());
461
} else if (printerName == QLatin1String("_all")) {
462
// skip it.. any other cases we want to skip?
468
// try extracting a comment from the aliases
469
aliases = printerDesc.mid(j + 1, i - j - 1).split('|');
470
printerComment = QPrintDialog::tr("Aliases: %1")
471
.arg(aliases.join(", "));
473
// look for signs of this being a remote printer
474
i = printerDesc.indexOf(
475
QRegExp(QLatin1String(": *bsdaddr *=")));
477
// point k at the end of remote host name
478
while (printerDesc[i] != '=')
480
while (printerDesc[i] == '=' || printerDesc[i].isSpace())
483
while (j < (int)printerDesc.length() &&
484
printerDesc[j] != ':' && printerDesc[j] != ',')
486
// and stuff that into the string
487
printerHost = printerDesc.mid(i, j-i);
488
// maybe stick the remote printer name into the comment
489
if (printerDesc[j] == ',') {
491
while (printerDesc[i].isSpace())
494
while (j < (int)printerDesc.length() &&
495
printerDesc[j] != ':' && printerDesc[j] != ',')
497
if (printerName != printerDesc.mid(i, j-i)) {
499
QLatin1String("Remote name: ");
500
printerComment += printerDesc.mid(i, j-i);
505
if (printerComment == ":")
506
printerComment = ""; // for cups
507
if (printerName.length())
508
perhapsAddPrinter(printers, printerName, printerHost,
509
printerComment, aliases);
510
// chop away the line, for processing the next one
515
return defaultPrinter;
520
#if defined(Q_C_CALLBACKS)
524
static int pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
525
char *val, int valLen, char *data)
527
parsePrinterDesc(QString::fromLatin1(val, valLen), (QList<QPrinterDescription> *)data);
531
#if defined(Q_C_CALLBACKS)
535
static int retrieveNisPrinters(QList<QPrinterDescription> *printers)
537
typedef int (*WildCast)(int, char *, int, char *, int, char *);
538
char printersConfByname[] = "printers.conf.byname";
543
typedef int (*ypGetDefaultDomain)(char **);
544
ypGetDefaultDomain _ypGetDefaultDomain = (ypGetDefaultDomain)lib.resolve("yp_get_default_domain");
545
typedef int (*ypAll)(const char *, const char *, const struct ypall_callback *);
546
ypAll _ypAll = (ypAll)lib.resolve("yp_all");
548
if (_ypGetDefaultDomain && _ypAll) {
549
err = _ypGetDefaultDomain(&domain);
552
// wild cast to support K&R-style system headers
553
(WildCast &) cb.foreach = (WildCast) pd_foreach;
554
cb.data = (char *) printers;
555
err = _ypAll(domain, printersConfByname, &cb);
565
static char *parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line)
567
#define skipSpaces() \
568
while (isspace((uchar) line[k])) \
571
char *defaultPrinter = 0;
573
int lastStatus = NotFound;
581
char *cp = strchr(line, '#');
585
while (line[k] != '\0') {
586
if (isspace((uchar) line[k])) {
588
} else if (line[k] == '[') {
591
while (line[k] != '\0') {
592
char status = tolower(line[k]);
595
while (line[k] != '=' && line[k] != ']' && line[k] != '\0')
597
if (line[k] == '=') {
600
action = tolower(line[k]);
601
while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != ']')
603
} else if (line[k] == ']') {
609
if (lastStatus == status)
610
stop = (action == (char) Return);
617
while (!isspace((uchar) line[k]) && line[k] != '[') {
622
if (source == "user") {
623
lastStatus = parsePrintcap(printers,
624
QDir::homePath() + "/.printers");
625
} else if (source == "files") {
627
defaultPrinter = parsePrintersConf(printers, &found);
629
lastStatus = Success;
631
} else if (source == "nis") {
632
lastStatus = retrieveNisPrinters(printers);
635
// nisplus, dns, etc., are not implemented yet
636
lastStatus = NotFound;
638
stop = (lastStatus == Success);
641
return defaultPrinter;
644
static char *parseNsswitchConf(QList<QPrinterDescription> *printers)
646
QFile nc(QLatin1String("/etc/nsswitch.conf"));
647
if (!nc.open(QIODevice::ReadOnly))
650
char *defaultPrinter = 0;
652
char *line = new char[1025];
655
while (!nc.atEnd() &&
656
nc.readLine(line, 1024) > 0) {
657
if (strncmp(line, "printers", 8) == 0) {
658
defaultPrinter = parseNsswitchPrintersEntry(printers, line);
660
return defaultPrinter;
664
strcpy(line, "printers: user files nis nisplus xfn");
665
defaultPrinter = parseNsswitchPrintersEntry(printers, line);
667
return defaultPrinter;
671
static void parseEtcLpMember(QList<QPrinterDescription> *printers)
673
QDir lp(QLatin1String("/etc/lp/member"));
676
QFileInfoList dirs = lp.entryInfoList();
681
for (int i = 0; i < dirs.size(); ++i) {
682
QFileInfo printer = dirs.at(i);
683
// I haven't found any real documentation, so I'm guessing that
684
// since lpstat uses /etc/lp/member rather than one of the
685
// other directories, it's the one to use. I did not find a
686
// decent way to locate aliases and remote printers.
687
if (printer.isFile())
688
perhapsAddPrinter(printers, printer.fileName(),
689
QPrintDialog::tr("unknown"),
695
static void parseSpoolInterface(QList<QPrinterDescription> *printers)
697
QDir lp(QLatin1String("/usr/spool/lp/interface"));
700
QFileInfoList files = lp.entryInfoList();
704
for (int i = 0; i < files.size(); ++i) {
705
QFileInfo printer = files.at(i);
707
if (!printer.isFile())
710
// parse out some information
711
QFile configFile(printer.filePath());
712
if (!configFile.open(QIODevice::ReadOnly))
722
QString nameKey(QLatin1String("NAME="));
723
QString typeKey(QLatin1String("TYPE="));
724
QString hostKey(QLatin1String("HOSTNAME="));
725
QString hostPrinterKey(QLatin1String("HOSTPRINTER="));
727
while (!configFile.atEnd() &&
728
(configFile.readLine(line.data(), 1024)) > 0) {
729
QString uline = line;
730
if (uline.startsWith(typeKey) ) {
731
printerType = line.mid(nameKey.length());
732
printerType = printerType.simplified();
733
} else if (uline.startsWith(hostKey)) {
734
hostName = line.mid(hostKey.length());
735
hostName = hostName.simplified();
736
} else if (uline.startsWith(hostPrinterKey)) {
737
hostPrinter = line.mid(hostPrinterKey.length());
738
hostPrinter = hostPrinter.simplified();
739
} else if (uline.startsWith(nameKey)) {
740
namePrinter = line.mid(nameKey.length());
741
namePrinter = namePrinter.simplified();
746
printerType = printerType.trimmed();
747
if (printerType.indexOf("postscript", 0, Qt::CaseInsensitive) < 0)
751
while ((ii = namePrinter.indexOf('"', ii)) >= 0)
752
namePrinter.remove(ii, 1);
754
if (hostName.isEmpty() || hostPrinter.isEmpty()) {
755
perhapsAddPrinter(printers, printer.fileName(),
756
QLatin1String(""), namePrinter);
759
comment = namePrinter;
761
comment += hostPrinter;
763
perhapsAddPrinter(printers, printer.fileName(),
770
// Every unix must have its own. It's a standard. Here is AIX.
771
static void parseQconfig(QList<QPrinterDescription> *printers)
773
QFile qconfig(QLatin1String("/etc/qconfig"));
774
if (!qconfig.open(QIODevice::ReadOnly))
777
QTextStream ts(&qconfig);
780
QString stanzaName; // either a queue or a device name
781
bool up = true; // queue up? default true, can be false
782
QString remoteHost; // null if local
783
QString deviceName; // null if remote
785
QRegExp newStanza(QLatin1String("^[0-z\\-]*:$"));
787
// our basic strategy here is to process each line, detecting new
788
// stanzas. each time we see a new stanza, we check if the
789
// previous stanza was a valid queue for a) a remote printer or b)
790
// a local printer. if it wasn't, we assume that what we see is
791
// the start of the first stanza, or that the previous stanza was
792
// a device stanza, or that there is some syntax error (we don't
796
line = ts.readLine();
797
bool indented = line[0].isSpace();
798
line = line.simplified();
800
int i = line.indexOf('=');
801
if (indented && i != -1) { // line in stanza
802
QString variable = line.left(i).simplified();
803
QString value=line.mid(i+1, line.length()).simplified();
804
if (variable == QLatin1String("device"))
806
else if (variable == QLatin1String("host"))
808
else if (variable == QLatin1String("up"))
809
up = !(value.toLower() == QLatin1String("false"));
810
} else if (line[0] == '*') { // comment
812
} else if (ts.atEnd() || // end of file, or beginning of new stanza
813
(!indented && line.contains(newStanza))) {
814
if (up && stanzaName.length() > 0 && stanzaName.length() < 21) {
815
if (remoteHost.length()) // remote printer
816
perhapsAddPrinter(printers, stanzaName, remoteHost,
818
else if (deviceName.length()) // local printer
819
perhapsAddPrinter(printers, stanzaName, QString(),
823
if (line.length() >= 1 && line.length() <= 20)
829
// syntax error? ignore.
831
} while (!ts.atEnd());
836
#include <cups/cups.h>
838
static char *parseCupsOutput(QList<QPrinterDescription> *printers)
840
char *defaultPrinter = 0;
843
QLibrary lib("cups");
844
typedef int (*CupsGetDests)(cups_dest_t **dests);
845
CupsGetDests _cupsGetDests = (CupsGetDests)lib.resolve("cupsGetDests");
847
nd = _cupsGetDests(&d);
853
perhapsAddPrinter(printers, d[n].name,
854
QPrintDialog::tr("Unknown Location"), QString());
855
if (d[n].is_default && !defaultPrinter)
856
defaultPrinter = qstrdup(d[n].instance);
860
return defaultPrinter;
864
QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
865
: QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent)
871
/*! Destroys the object and frees any allocated resources. Does not
872
delete the associated QPrinter object.
875
QPrintDialog::~QPrintDialog()
880
QGroupBox *QPrintDialogPrivate::setupPrinterSettings()
883
QGroupBox *g = new QGroupBox(q->tr("Printer settings"), q);
885
QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down, g);
886
colorMode = new QButtonGroup(q);
887
QObject::connect(colorMode, SIGNAL(buttonClicked(QAbstractButton*)),
888
q, SLOT(colorModeSelected(QAbstractButton*)));
890
printColor = new QRadioButton(q->tr("Print in color if available"), g);
891
colorMode->addButton(printColor);
892
printColor->setChecked(true);
893
tll->addWidget(printColor);
895
printGray = new QRadioButton(q->tr("Print in grayscale"), g);
896
colorMode->addButton(printGray);
897
tll->addWidget(printGray);
902
QGroupBox *QPrintDialogPrivate::setupDestination()
905
QGroupBox *g = new QGroupBox(q->tr("Print destination"), q);
907
QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down, g);
908
printerOrFile = new QButtonGroup(q);
910
// printer radio button, list
911
QRadioButton *rb = new QRadioButton(q->tr("Print to printer:"), g);
913
printerOrFile->addButton(rb);
914
rb->setChecked(true);
915
outputToFile = false;
917
QBoxLayout *horiz = new QBoxLayout(QBoxLayout::LeftToRight);
918
tll->addLayout(horiz, 3);
919
horiz->addSpacing(19);
921
char *etcLpDefault = 0;
924
etcLpDefault = parseCupsOutput(&printers);
926
if (printers.size() == 0) {
927
// we only use other schemes when cups fails.
929
parsePrintcap(&printers, QLatin1String("/etc/printcap"));
930
parseEtcLpMember(&printers);
931
parseSpoolInterface(&printers);
932
parseQconfig(&printers);
935
f.setFile(QLatin1String("/etc/lp/printers"));
937
parseEtcLpPrinters(&printers);
938
QFile def(QLatin1String("/etc/lp/default"));
939
if (def.open(QIODevice::ReadOnly)) {
941
delete[] etcLpDefault;
942
etcLpDefault = new char[1025];
943
def.readLine(etcLpDefault, 1024);
944
char *p = etcLpDefault;
946
if (!isprint((uchar) *p) || isspace((uchar) *p))
955
f.setFile(QLatin1String("/etc/nsswitch.conf"));
957
def = parseNsswitchConf(&printers);
959
f.setFile(QLatin1String("/etc/printers.conf"));
961
def = parsePrintersConf(&printers);
966
delete[] etcLpDefault;
971
// all printers hopefully known. try to find a good default
972
QString dollarPrinter;
974
if (!qgetenv("PRINTER").isEmpty())
975
dollarPrinter = QString::fromLocal8Bit(qgetenv("LPDEST").constData());
976
if (!dollarPrinter.isEmpty())
977
perhapsAddPrinter(&printers, dollarPrinter,
978
QPrintDialog::tr("unknown"),
983
model = new QPrinterModel(printers, q);
984
view = new QTreeView(g);
985
view->setModel(model);
986
view->setRootIsDecorated(false);
987
view->header()->setResizeMode(2, QHeaderView::Stretch);
989
// bang the best default into the listview
992
for (int i = 0; i < printers.size(); ++i) {
993
QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)"));
994
QRegExp lp(QLatin1String("[^a-z]lp(?:[^a-z]|$)"));
996
QString name = printers.at(i).name;
997
QString comment = printers.at(i).comment;
998
if (quality < 4 && name == dollarPrinter) {
1001
} else if (quality < 3 && etcLpDefault &&
1002
name == QLatin1String(etcLpDefault)) {
1005
} else if (quality < 2 &&
1006
(name == QLatin1String("ps") ||
1007
ps.indexIn(comment) != -1)) {
1010
} else if (quality < 1 &&
1011
(name == QLatin1String("lp") ||
1012
lp.indexIn(comment) > -1)) {
1017
view->setCurrentIndex(static_cast<QAbstractTableModel*>(model)->index(best, 0));
1019
if (etcLpDefault) // Avoid purify complaint
1020
delete[] etcLpDefault;
1022
// int h = fontMetrics().height();
1023
// if (printers.size())
1024
// h = view->itemViewportRect(model->index(0, 0)).height();
1025
// view->setMinimumSize(view->sizeHint().width(),
1026
// printers->header()->height() +
1028
horiz->addWidget(view, 3);
1030
// file radio button, edit/browse
1031
printToFileButton = new QRadioButton(q->tr("Print to file:"), g);
1032
tll->addWidget(printToFileButton);
1033
printerOrFile->addButton(printToFileButton);
1035
horiz = new QBoxLayout(QBoxLayout::LeftToRight);
1036
tll->addLayout(horiz);
1037
horiz->addSpacing(19);
1039
fileName = new QLineEdit(g);
1040
QObject::connect(fileName, SIGNAL(textChanged(QString)),
1041
q, SLOT(fileNameEditChanged(QString)));
1042
horiz->addWidget(fileName, 1);
1043
browse = new QPushButton(q->tr("Browse..."), g);
1044
browse->setAutoDefault(false);
1045
QObject::connect(browse, SIGNAL(clicked()),
1046
q, SLOT(browseClicked()));
1047
horiz->addWidget(browse);
1049
fileName->setEnabled(false);
1050
browse->setEnabled(false);
1052
QObject::connect(printerOrFile, SIGNAL(buttonClicked(QAbstractButton*)),
1053
q, SLOT(printerOrFileSelected(QAbstractButton*)));
1058
QGroupBox *QPrintDialogPrivate::setupOptions()
1061
QGroupBox *g = new QGroupBox(q->tr("Options"), q);
1063
QBoxLayout *lay = new QBoxLayout(QBoxLayout::LeftToRight, g);
1064
QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down);
1065
lay->addLayout(tll);
1067
printRange = new QButtonGroup(q);
1068
QObject::connect(printRange, SIGNAL(buttonClicked(QAbstractButton*)), q, SLOT(printRangeSelected(QAbstractButton*)));
1070
pageOrder = new QButtonGroup(q);
1071
QObject::connect(pageOrder, SIGNAL(buttonClicked(QAbstractButton*)), q, SLOT(pageOrderSelected(QAbstractButton*)));
1073
printAllButton = new QRadioButton(q->tr("Print all"), g);
1074
printRange->addButton(printAllButton);
1075
tll->addWidget(printAllButton);
1077
printSelectionButton = new QRadioButton(q->tr("Print selection"), g);
1078
printRange->addButton(printSelectionButton);
1079
tll->addWidget(printSelectionButton);
1081
printRangeButton = new QRadioButton(q->tr("Print range"), g);
1082
printRange->addButton(printRangeButton);
1083
tll->addWidget(printRangeButton);
1085
QBoxLayout *horiz = new QBoxLayout(QBoxLayout::LeftToRight);
1086
tll->addLayout(horiz);
1088
firstPageLabel = new QLabel(q->tr("From page:"), g);
1089
horiz->addSpacing(19);
1090
horiz->addWidget(firstPageLabel);
1092
firstPage = new QSpinBox(g);
1093
firstPage->setRange(1, 9999);
1094
firstPage->setValue(1);
1095
horiz->addWidget(firstPage, 1);
1096
QObject::connect(firstPage, SIGNAL(valueChanged(int)),
1097
q, SLOT(setFirstPage(int)));
1099
horiz = new QBoxLayout(QBoxLayout::LeftToRight);
1100
tll->addLayout(horiz);
1102
lastPageLabel = new QLabel(q->tr("To page:"), g);
1103
horiz->addSpacing(19);
1104
horiz->addWidget(lastPageLabel);
1106
lastPage = new QSpinBox(g);
1107
lastPage->setRange(1, 9999);
1108
lastPage->setValue(9999);
1109
horiz->addWidget(lastPage, 1);
1110
QObject::connect(lastPage, SIGNAL(valueChanged(int)),
1111
q, SLOT(setLastPage(int)));
1113
lay->addSpacing(25);
1114
tll = new QBoxLayout(QBoxLayout::Down);
1115
lay->addLayout(tll);
1118
firstPageFirst = new QRadioButton(q->tr("Print first page first"), g);
1119
tll->addWidget(firstPageFirst);
1120
pageOrder->addButton(firstPageFirst);
1121
firstPageFirst->setChecked(true);
1123
lastPageFirst = new QRadioButton(q->tr("Print last page first"), g);
1124
tll->addWidget(lastPageFirst);
1125
pageOrder->addButton(lastPageFirst);
1131
horiz = new QBoxLayout(QBoxLayout::LeftToRight);
1132
tll->addLayout(horiz);
1134
QLabel *l = new QLabel(q->tr("Number of copies:"), g);
1135
horiz->addWidget(l);
1137
copies = new QSpinBox(g);
1138
copies->setRange(1,99);
1139
copies->setValue(1);
1140
horiz->addWidget(copies, 1);
1141
QObject::connect(copies, SIGNAL(valueChanged(int)),
1142
q, SLOT(setNumCopies(int)));
1144
QSize s = firstPageLabel->sizeHint()
1145
.expandedTo(lastPageLabel->sizeHint())
1146
.expandedTo(l->sizeHint());
1147
firstPageLabel->setMinimumSize(s);
1148
lastPageLabel->setMinimumSize(s);
1149
l->setMinimumSize(s.width() + 19, s.height());
1155
void isc(QPrintDialogPrivate *ptr, const QString & text, QPrinter::PageSize ps)
1157
if (ptr && !text.isEmpty() && ps < QPrinter::NPageSize) {
1158
ptr->sizeCombo->addItem(text);
1159
int index = ptr->sizeCombo->count()-1;
1160
if (index >= 0 && index < QPrinter::NPageSize)
1161
ptr->indexToPageSize[index] = ps;
1165
QGroupBox *QPrintDialogPrivate::setupPaper()
1168
QGroupBox *g = new QGroupBox(q->tr("Paper format"), q);
1170
QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down, g);
1171
pageSize = QPrinter::A4;
1174
orientationCombo = new QComboBox(g);
1175
orientationCombo->addItem(q->tr("Portrait"));
1176
orientationCombo->addItem(q->tr("Landscape"));
1177
tll->addWidget(orientationCombo);
1179
orientation = QPrinter::Portrait;
1181
QObject::connect(orientationCombo, SIGNAL(activated(int)),
1182
q, SLOT(orientSelected(int)));
1185
sizeCombo = new QComboBox(g);
1186
tll->addWidget(sizeCombo);
1189
for(n=0; n<QPrinter::NPageSize; n++)
1190
indexToPageSize[n] = QPrinter::A4;
1192
isc(this, q->tr("A0 (841 x 1189 mm)"), QPrinter::A0);
1193
isc(this, q->tr("A1 (594 x 841 mm)"), QPrinter::A1);
1194
isc(this, q->tr("A2 (420 x 594 mm)"), QPrinter::A2);
1195
isc(this, q->tr("A3 (297 x 420 mm)"), QPrinter::A3);
1196
isc(this, q->tr("A4 (210x297 mm, 8.26x11.7 inches)"), QPrinter::A4);
1197
isc(this, q->tr("A5 (148 x 210 mm)"), QPrinter::A5);
1198
isc(this, q->tr("A6 (105 x 148 mm)"), QPrinter::A6);
1199
isc(this, q->tr("A7 (74 x 105 mm)"), QPrinter::A7);
1200
isc(this, q->tr("A8 (52 x 74 mm)"), QPrinter::A8);
1201
isc(this, q->tr("A9 (37 x 52 mm)"), QPrinter::A9);
1202
isc(this, q->tr("B0 (1000 x 1414 mm)"), QPrinter::B0);
1203
isc(this, q->tr("B1 (707 x 1000 mm)"), QPrinter::B1);
1204
isc(this, q->tr("B2 (500 x 707 mm)"), QPrinter::B2);
1205
isc(this, q->tr("B3 (353 x 500 mm)"), QPrinter::B3);
1206
isc(this, q->tr("B4 (250 x 353 mm)"), QPrinter::B4);
1207
isc(this, q->tr("B5 (176 x 250 mm, 6.93x9.84 inches)"), QPrinter::B5);
1208
isc(this, q->tr("B6 (125 x 176 mm)"), QPrinter::B6);
1209
isc(this, q->tr("B7 (88 x 125 mm)"), QPrinter::B7);
1210
isc(this, q->tr("B8 (62 x 88 mm)"), QPrinter::B8);
1211
isc(this, q->tr("B9 (44 x 62 mm)"), QPrinter::B9);
1212
isc(this, q->tr("B10 (31 x 44 mm)"), QPrinter::B10);
1213
isc(this, q->tr("C5E (163 x 229 mm)"), QPrinter::C5E);
1214
isc(this, q->tr("DLE (110 x 220 mm)"), QPrinter::DLE);
1215
isc(this, q->tr("Executive (7.5x10 inches, 191x254 mm)"), QPrinter::Executive);
1216
isc(this, q->tr("Folio (210 x 330 mm)"), QPrinter::Folio);
1217
isc(this, q->tr("Ledger (432 x 279 mm)"), QPrinter::Ledger);
1218
isc(this, q->tr("Legal (8.5x14 inches, 216x356 mm)"), QPrinter::Legal);
1219
isc(this, q->tr("Letter (8.5x11 inches, 216x279 mm)"), QPrinter::Letter);
1220
isc(this, q->tr("Tabloid (279 x 432 mm)"), QPrinter::Tabloid);
1221
isc(this, q->tr("US Common #10 Envelope (105 x 241 mm)"), QPrinter::Comm10E);
1223
QObject::connect(sizeCombo, SIGNAL(activated(int)),
1224
q, SLOT(paperSizeSelected(int)));
1230
void QPrintDialogPrivate::printerOrFileSelected(QAbstractButton *b)
1232
outputToFile = (b == printToFileButton);
1234
ok->setEnabled(true);
1235
fileNameEditChanged(fileName->text());
1236
if (!fileName->isModified() && fileName->text().isEmpty()) {
1237
QString home = QString::fromLocal8Bit(::qgetenv("HOME").constData());
1238
QString cur = QDir::currentPath();
1239
if (home.at(home.length()-1) != '/')
1241
if (cur.at(cur.length()-1) != '/')
1243
if (cur.left(home.length()) != home)
1248
fileName->setText(cur);
1249
fileName->setCursorPosition(cur.length());
1250
fileName->selectAll();
1252
browse->setEnabled(true);
1253
fileName->setEnabled(true);
1254
fileName->setFocus();
1255
view->setEnabled(false);
1257
ok->setEnabled(printers.count() != 0);
1258
view->setEnabled(true);
1259
if (fileName->hasFocus() || browse->hasFocus())
1261
browse->setEnabled(false);
1262
fileName->setEnabled(false);
1267
void QPrintDialogPrivate::landscapeSelected(int id)
1269
orientation = (QPrinter::Orientation)id;
1273
void QPrintDialogPrivate::paperSizeSelected(int id)
1275
if (id < QPrinter::NPageSize)
1276
pageSize = QPrinter::PageSize(indexToPageSize[id]);
1280
void QPrintDialogPrivate::orientSelected(int id)
1282
orientation = (QPrinter::Orientation)id;
1286
void QPrintDialogPrivate::pageOrderSelected(QAbstractButton *b)
1288
pageOrder2 = (b == firstPageFirst) ? QPrinter::FirstPageFirst : QPrinter::LastPageFirst;
1292
void QPrintDialogPrivate::setNumCopies(int copies)
1298
void QPrintDialogPrivate::browseClicked()
1301
QString fn = QFileDialog::getSaveFileName(q, QString(), fileName->text(),
1302
q->tr("PostScript Files (*.ps);;All Files (*)"));
1304
fileName->setText(fn);
1308
void QPrintDialogPrivate::okClicked()
1311
lastPage->interpretText();
1312
firstPage->interpretText();
1313
copies->interpretText();
1315
printer->setOutputFileName(fileName->text());
1317
printer->setOutputFileName(QString());
1318
QModelIndex current = view->currentIndex();
1319
if (current.isValid())
1320
printer->setPrinterName(printers.at(current.row()).name);
1323
printer->setOrientation(orientation);
1324
printer->setPageSize(pageSize);
1325
printer->setPageOrder(pageOrder2);
1326
printer->setColorMode(colorMode2);
1327
printer->setNumCopies(numCopies);
1328
if (printAllButton->isChecked()) {
1329
q->setPrintRange(QPrintDialog::AllPages);
1330
q->setFromTo(q->minPage(), q->maxPage());
1332
if (printSelectionButton->isChecked()) {
1333
q->setPrintRange(QPrintDialog::Selection);
1336
q->setPrintRange(QPrintDialog::PageRange);
1337
q->setFromTo(firstPage->value(), lastPage->value());
1344
void QPrintDialogPrivate::printRangeSelected(QAbstractButton *b)
1346
bool enable = (b == printRangeButton);
1347
firstPage->setEnabled(enable);
1348
lastPage->setEnabled(enable);
1349
firstPageLabel->setEnabled(enable);
1350
lastPageLabel->setEnabled(enable);
1354
void QPrintDialogPrivate::setFirstPage(int fp)
1358
lastPage->setMinimum(fp);
1359
lastPage->setMaximum(qMax(fp, q->maxPage()));
1364
void QPrintDialogPrivate::setLastPage(int lp)
1368
firstPage->setMinimum(qMin(lp, q->minPage()));
1369
firstPage->setMaximum(lp);
1376
Adds the button \a but to the layout of the print dialog. The added
1377
buttons are arranged from the left to the right below the
1378
last groupbox of the printdialog.
1380
void QPrintDialog::addButton(QPushButton *but)
1383
d->customLayout->addWidget(but);
1386
/*! Returns a pointer to the printer this dialog configures, or 0 if
1387
this dialog does not operate on any printer. */
1388
QPrinter *QPrintDialog::printer() const
1390
Q_D(const QPrintDialog);
1395
Sets this dialog to configure printer \a p, or no printer if \a p
1396
is null. If \a pickUpSettings is true, the dialog reads most of
1397
its settings from \a p. If \a pickUpSettings is false (the
1398
default) the dialog keeps its old settings.
1401
void QPrintDialog::setPrinter(QPrinter *p, bool pickUpSettings)
1404
d->setPrinter(p, pickUpSettings);
1408
void QPrintDialogPrivate::setPrinter(QPrinter *p, bool pickUpSettings)
1413
if (p && pickUpSettings) {
1414
// top to botton in the old dialog.
1416
if (!p->outputFileName().isEmpty())
1417
printToFileButton->setChecked(true);
1420
if (!p->printerName().isEmpty()) {
1421
for (int i = 0; i < printers.size(); ++i) {
1422
if (printers.at(i).name == p->printerName()) {
1424
// printers->setSelected(i, true);
1425
ok->setEnabled(true);
1426
} else if (fileName->text().isEmpty()) {
1427
ok->setEnabled(model->rowCount() != 0);
1432
// print command does not exist any more
1435
printToFileButton->setEnabled(q->isOptionEnabled(QPrintDialog::PrintToFile));
1436
fileName->setText(p->outputFileName());
1439
orientationCombo->setCurrentIndex((int)p->orientation());
1440
orientSelected(p->orientation());
1444
while (n < QPrinter::NPageSize &&
1445
indexToPageSize[n] != p->pageSize())
1447
sizeCombo->setCurrentIndex(n);
1448
paperSizeSelected(n);
1450
// New stuff (Options)
1453
pageOrder2 = p->pageOrder();
1454
if (pageOrder2 == QPrinter::LastPageFirst)
1455
lastPageFirst->setChecked(true);
1458
colorMode2 = p->colorMode();
1459
if (colorMode2 == QPrinter::Color)
1460
printColor->setChecked(true);
1463
copies->setValue(p->numCopies());
1464
setNumCopies(p->numCopies());
1468
printAllButton->setEnabled(true);
1469
printSelectionButton->setEnabled(q->isOptionEnabled(QPrintDialog::PrintSelection));
1470
printRangeButton->setEnabled(q->isOptionEnabled(QPrintDialog::PrintPageRange));
1472
switch (q->printRange()) {
1473
case QPrintDialog::AllPages:
1474
printAllButton->click();
1476
case QPrintDialog::Selection:
1477
printSelectionButton->click();
1479
case QPrintDialog::PageRange:
1480
printRangeButton->click();
1485
if (p && q->maxPage()) {
1486
firstPage->setMinimum(q->minPage());
1487
firstPage->setMaximum(q->maxPage());
1488
lastPage->setMinimum(q->minPage());
1489
lastPage->setMaximum(q->maxPage());
1490
if (q->fromPage() || q->toPage()) {
1491
setFirstPage(q->fromPage());
1492
setLastPage(q->toPage());
1493
firstPage->setValue(q->fromPage());
1494
lastPage->setValue(q->toPage());
1499
void QPrintDialogPrivate::colorModeSelected(QAbstractButton *b)
1501
colorMode2 = (b == printColor) ? QPrinter::Color : QPrinter::GrayScale;
1504
void QPrintDialogPrivate::fileNameEditChanged(const QString &text)
1506
if (fileName->isEnabled())
1507
ok->setEnabled(!text.isEmpty());
1510
int QPrintDialog::exec()
1512
return QDialog::exec();
1515
void QPrintDialogPrivate::init()
1520
QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down, q);
1524
g = setupDestination();
1525
tll->addWidget(g, 1);
1527
// printer and paper settings
1528
QBoxLayout *lay = new QBoxLayout(QBoxLayout::LeftToRight);
1529
tll->addLayout(lay);
1531
g = setupPrinterSettings();
1532
lay->addWidget(g, 1);
1541
QBoxLayout *l = new QBoxLayout(QBoxLayout::LeftToRight);
1542
customLayout = new QBoxLayout(QBoxLayout::LeftToRight);
1544
l->addLayout(customLayout);
1548
QBoxLayout *horiz = new QBoxLayout(QBoxLayout::LeftToRight);
1549
tll->addLayout(horiz);
1552
bool(q->style()->styleHint(QStyle::SH_PrintDialog_RightAlignButtons, 0, q));
1555
horiz->addStretch(1);
1557
ok = new QPushButton(q->tr("OK"), q);
1558
ok->setDefault(true);
1559
horiz->addWidget(ok);
1561
horiz->addStretch(1);
1563
QPushButton *cancel = new QPushButton(q->tr("Cancel"), q);
1564
horiz->addWidget(cancel);
1566
q->connect(ok, SIGNAL(clicked()), q, SLOT(okClicked()));
1567
q->connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
1569
QSize ms(q->minimumSize());
1570
QSize ss(QApplication::desktop()->screenGeometry(q->pos()).size());
1571
if (ms.height() < 512 && ss.height() >= 600)
1573
else if (ms.height() < 460 && ss.height() >= 480)
1577
setPrinter(printer, true);
1581
#include "moc_qprintdialog.cpp"