~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/dialogs/qprintdialog_unix.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the dialog module of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#ifndef QT_NO_PRINTDIALOG
 
30
 
 
31
#include "qplatformdefs.h"
 
32
 
 
33
#include <private/qabstractprintdialog_p.h>
 
34
#include "qprintdialog.h"
 
35
 
 
36
#include "qfiledialog.h"
 
37
#include "qdir.h"
 
38
#include "qdesktopwidget.h"
 
39
#include "qfile.h"
 
40
#include "qtextstream.h"
 
41
#include "qcombobox.h"
 
42
#include "qframe.h"
 
43
#include "qlabel.h"
 
44
#include "qlineedit.h"
 
45
#include "qpushbutton.h"
 
46
#include "qprinter.h"
 
47
#include "qlayout.h"
 
48
#include "qbuttongroup.h"
 
49
#include "qradiobutton.h"
 
50
#include "qspinbox.h"
 
51
#include "qapplication.h"
 
52
#include "qstyle.h"
 
53
#include "qstring.h"
 
54
#include "qregexp.h"
 
55
#include "qgroupbox.h"
 
56
#include "qsignalmapper.h"
 
57
#include "qmap.h"
 
58
#include "qabstractitemmodel.h"
 
59
#include "qtreeview.h"
 
60
#include "qheaderview.h"
 
61
 
 
62
#if !defined(QT_NO_CUPS) || !defined(QT_NO_NIS)
 
63
#include "qlibrary.h"
 
64
#endif
 
65
 
 
66
#ifndef QT_NO_NIS
 
67
 
 
68
#ifndef BOOL_DEFINED
 
69
#define BOOL_DEFINED
 
70
#endif
 
71
 
 
72
#include <rpcsvc/ypclnt.h>
 
73
#include <rpcsvc/yp_prot.h>
 
74
 
 
75
#endif // QT_NO_NIS
 
76
 
 
77
#include <ctype.h>
 
78
#include <stdlib.h>
 
79
 
 
80
enum { Success = 's', Unavail = 'u', NotFound = 'n', TryAgain = 't' };
 
81
enum { Continue = 'c', Return = 'r' };
 
82
 
 
83
 
 
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) {}
 
87
    QString name;
 
88
    QString host;
 
89
    QString comment;
 
90
    QStringList aliases;
 
91
    bool samePrinter(const QString& printer) const {
 
92
        return name == printer || aliases.contains(printer);
 
93
    }
 
94
};
 
95
 
 
96
class QPrinterModel : public QAbstractTableModel
 
97
{
 
98
public:
 
99
    QPrinterModel(const QList<QPrinterDescription> &printers, QObject *parent);
 
100
 
 
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;
 
105
 
 
106
    QList<QPrinterDescription> lst;
 
107
};
 
108
 
 
109
QPrinterModel::QPrinterModel(const QList<QPrinterDescription> &printers, QObject *parent)
 
110
    : QAbstractTableModel(parent)
 
111
{
 
112
    lst = printers;
 
113
}
 
114
 
 
115
int QPrinterModel::rowCount(const QModelIndex &) const
 
116
{
 
117
    return lst.count();
 
118
}
 
119
 
 
120
int QPrinterModel::columnCount(const QModelIndex &) const
 
121
{
 
122
    return 3;
 
123
}
 
124
 
 
125
QVariant QPrinterModel::data(const QModelIndex &index, int role) const
 
126
{
 
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()) {
 
131
        case 0:
 
132
            return desc.name;
 
133
        case 1:
 
134
            return desc.host;
 
135
        case 2:
 
136
            return desc.comment;
 
137
        }
 
138
    }
 
139
    return QVariant();
 
140
}
 
141
 
 
142
QVariant QPrinterModel::headerData(int section, Qt::Orientation orientation, int role) const
 
143
{
 
144
    if (orientation == Qt::Horizontal) {
 
145
        const char *name = 0;
 
146
        switch(section) {
 
147
        case 0:
 
148
            name = "Printer";
 
149
            break;
 
150
        case 1:
 
151
            name = "Host";
 
152
            break;
 
153
        case 2:
 
154
            name = "Comment";
 
155
            break;
 
156
        }
 
157
        return qApp->translate("QPrintDialog", name);
 
158
    }
 
159
    return QAbstractTableModel::headerData(section, orientation, role);
 
160
}
 
161
 
 
162
 
 
163
class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
 
164
{
 
165
    Q_DECLARE_PUBLIC(QPrintDialog)
 
166
public:
 
167
    QButtonGroup *printerOrFile;
 
168
 
 
169
    bool outputToFile;
 
170
    QList<QPrinterDescription> printers;
 
171
    QPrinterModel *model;
 
172
    QTreeView *view;
 
173
 
 
174
    QLineEdit *fileName;
 
175
    QPushButton *browse, *ok;
 
176
 
 
177
    QButtonGroup *printRange;
 
178
    QLabel *firstPageLabel;
 
179
    QSpinBox *firstPage;
 
180
    QLabel *lastPageLabel;
 
181
    QSpinBox *lastPage;
 
182
    QRadioButton *printAllButton;
 
183
    QRadioButton *printRangeButton;
 
184
    QRadioButton *printSelectionButton;
 
185
    QRadioButton *printToFileButton;
 
186
    QComboBox *orientationCombo, *sizeCombo;
 
187
 
 
188
    QPrinter::PageSize pageSize;
 
189
    QPrinter::Orientation orientation;
 
190
 
 
191
    QButtonGroup *pageOrder;
 
192
    QRadioButton *firstPageFirst;
 
193
    QRadioButton *lastPageFirst;
 
194
    QPrinter::PageOrder pageOrder2;
 
195
 
 
196
    QButtonGroup *colorMode;
 
197
    QRadioButton *printColor;
 
198
    QRadioButton *printGray;
 
199
    QPrinter::ColorMode colorMode2;
 
200
 
 
201
    QSpinBox *copies;
 
202
    int numCopies;
 
203
 
 
204
    QBoxLayout *customLayout;
 
205
 
 
206
    QPrinter::PageSize indexToPageSize[QPrinter::NPageSize];
 
207
 
 
208
    void init();
 
209
 
 
210
    void browseClicked();
 
211
    void okClicked();
 
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);
 
223
 
 
224
    QGroupBox *setupDestination();
 
225
    QGroupBox *setupOptions();
 
226
    QGroupBox *setupPaper();
 
227
    QGroupBox *setupPrinterSettings();
 
228
 
 
229
    void setPrinter(QPrinter *p, bool pickUpSettings);
 
230
};
 
231
 
 
232
static void isc(QPrintDialogPrivate *d, const QString & text,
 
233
                 QPrinter::PageSize ps);
 
234
 
 
235
 
 
236
 
 
237
static void perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &name,
 
238
                               QString host, QString comment,
 
239
                               QStringList aliases = QStringList())
 
240
{
 
241
    for (int i = 0; i < printers->size(); ++i)
 
242
        if (printers->at(i).samePrinter(name))
 
243
            return;
 
244
 
 
245
    if (host.isEmpty())
 
246
        host = QPrintDialog::tr("locally connected");
 
247
    printers->append(QPrinterDescription(name.simplified(), host.simplified(), comment.simplified(), aliases));
 
248
}
 
249
 
 
250
static void parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers)
 
251
{
 
252
    if (printerDesc.length() < 1)
 
253
        return;
 
254
 
 
255
    printerDesc = printerDesc.simplified();
 
256
    int i = printerDesc.indexOf(':');
 
257
    QString printerName, printerComment, printerHost;
 
258
    QStringList aliases;
 
259
 
 
260
    if (i >= 0) {
 
261
        // have ':' want '|'
 
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(", "));
 
269
        } else {
 
270
            printerName = printerDesc.left(i);
 
271
        }
 
272
        // look for lprng pseudo all printers entry
 
273
        i = printerDesc.indexOf(QRegExp(QLatin1String(": *all *=")));
 
274
        if (i >= 0)
 
275
            printerName = "";
 
276
        // look for signs of this being a remote printer
 
277
        i = printerDesc.indexOf(QRegExp(QLatin1String(": *rm *=")));
 
278
        if (i >= 0) {
 
279
            // point k at the end of remote host name
 
280
            while (printerDesc[i] != '=')
 
281
                i++;
 
282
            while (printerDesc[i] == '=' || printerDesc[i].isSpace())
 
283
                i++;
 
284
            j = i;
 
285
            while (j < (int)printerDesc.length() && printerDesc[j] != ':')
 
286
                j++;
 
287
 
 
288
            // and stuff that into the string
 
289
            printerHost = printerDesc.mid(i, j - i);
 
290
        }
 
291
    }
 
292
    if (printerName.length())
 
293
        perhapsAddPrinter(printers, printerName, printerHost, printerComment,
 
294
                           aliases);
 
295
}
 
296
 
 
297
static int parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName)
 
298
{
 
299
    QFile printcap(fileName);
 
300
    if (!printcap.open(QIODevice::ReadOnly))
 
301
        return NotFound;
 
302
 
 
303
    char *line_ascii = new char[1025];
 
304
    line_ascii[1024] = '\0';
 
305
 
 
306
    QString printerDesc;
 
307
    bool atEnd = false;
 
308
 
 
309
    while (!atEnd) {
 
310
        if (printcap.atEnd() || printcap.readLine(line_ascii, 1024) <= 0)
 
311
            atEnd = true;
 
312
        QString line = line_ascii;
 
313
        line = line.trimmed();
 
314
        if (line.length() >= 1 && line[int(line.length()) - 1] == '\\')
 
315
            line.chop(1);
 
316
        if (line[0] == '#') {
 
317
            if (!atEnd)
 
318
                continue;
 
319
        } else if (line[0] == '|' || line[0] == ':') {
 
320
            printerDesc += line;
 
321
            if (!atEnd)
 
322
                continue;
 
323
        }
 
324
 
 
325
        parsePrinterDesc(printerDesc, printers);
 
326
 
 
327
        // add the first line of the new printer definition
 
328
        printerDesc = line;
 
329
    }
 
330
    delete[] line_ascii;
 
331
    return Success;
 
332
}
 
333
 
 
334
 
 
335
// solaris, not 2.6
 
336
static void parseEtcLpPrinters(QList<QPrinterDescription> *printers)
 
337
{
 
338
    QDir lp(QLatin1String("/etc/lp/printers"));
 
339
    QFileInfoList dirs = lp.entryInfoList();
 
340
    if (dirs.isEmpty())
 
341
        return;
 
342
 
 
343
    QString tmp;
 
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:"));
 
353
            QString printerHost;
 
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;
 
360
                        while (*p != ':')
 
361
                            p++;
 
362
                        p++;
 
363
                        while (isspace((uchar) *p))
 
364
                            p++;
 
365
                        printerHost = QString::fromLocal8Bit(p);
 
366
                        printerHost = printerHost.simplified();
 
367
                    } else if (QString::fromLatin1(line).startsWith(contentType)) {
 
368
                        char *p = line;
 
369
                        while (*p != ':')
 
370
                            p++;
 
371
                        p++;
 
372
                        char *e;
 
373
                        while (*p) {
 
374
                            while (isspace((uchar) *p))
 
375
                                p++;
 
376
                            if (*p) {
 
377
                                char s;
 
378
                                e = p;
 
379
                                while (isalnum((uchar) *e))
 
380
                                    e++;
 
381
                                s = *e;
 
382
                                *e = '\0';
 
383
                                if (!qstrcmp(p, "postscript") ||
 
384
                                     !qstrcmp(p, "any"))
 
385
                                    canPrintPostscript = true;
 
386
                                *e = s;
 
387
                                if (s == ',')
 
388
                                    e++;
 
389
                                p = e;
 
390
                            }
 
391
                        }
 
392
                    }
 
393
                }
 
394
                if (canPrintPostscript)
 
395
                    perhapsAddPrinter(printers, printer.fileName(),
 
396
                                       printerHost, QLatin1String(""));
 
397
            }
 
398
            delete[] line;
 
399
        }
 
400
    }
 
401
}
 
402
 
 
403
 
 
404
// solaris 2.6
 
405
static char *parsePrintersConf(QList<QPrinterDescription> *printers, bool *found = 0)
 
406
{
 
407
    QFile pc(QLatin1String("/etc/printers.conf"));
 
408
    if (!pc.open(QIODevice::ReadOnly)) {
 
409
        if (found)
 
410
            *found = false;
 
411
        return 0;
 
412
    }
 
413
    if (found)
 
414
        *found = true;
 
415
 
 
416
    char *line = new char[1025];
 
417
    line[1024] = '\0';
 
418
 
 
419
    QString printerDesc;
 
420
    int lineLength = 0;
 
421
 
 
422
    char *defaultPrinter = 0;
 
423
 
 
424
    while (!pc.atEnd() &&
 
425
            (lineLength=pc.readLine(line, 1024)) > 0) {
 
426
        if (*line == '#') {
 
427
            *line = '\0';
 
428
            lineLength = 0;
 
429
        }
 
430
        if (lineLength >= 2 && line[lineLength-2] == '\\') {
 
431
            line[lineLength-2] = '\0';
 
432
            printerDesc += QString::fromLocal8Bit(line);
 
433
        } else {
 
434
            printerDesc += QString::fromLocal8Bit(line);
 
435
            printerDesc = printerDesc.simplified();
 
436
            int i = printerDesc.indexOf(':');
 
437
            QString printerName, printerHost, printerComment;
 
438
            QStringList aliases;
 
439
            if (i >= 0) {
 
440
                // have : want |
 
441
                int j = printerDesc.indexOf('|');
 
442
                if (j >= i)
 
443
                    j = -1;
 
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] != '=')
 
449
                        i++;
 
450
                    while (printerDesc[i] == '=' || printerDesc[i].isSpace())
 
451
                        i++;
 
452
                    j = i;
 
453
                    while (j < (int)printerDesc.length() &&
 
454
                            printerDesc[j] != ':' && printerDesc[j] != ',')
 
455
                        j++;
 
456
                    // that's our default printer
 
457
                    defaultPrinter =
 
458
                        qstrdup(printerDesc.mid(i, j-i).toAscii().data());
 
459
                    printerName = "";
 
460
                    printerDesc = "";
 
461
                } else if (printerName == QLatin1String("_all")) {
 
462
                    // skip it.. any other cases we want to skip?
 
463
                    printerName = "";
 
464
                    printerDesc = "";
 
465
                }
 
466
 
 
467
                if (j > 0) {
 
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(", "));
 
472
                }
 
473
                // look for signs of this being a remote printer
 
474
                i = printerDesc.indexOf(
 
475
                    QRegExp(QLatin1String(": *bsdaddr *=")));
 
476
                if (i >= 0) {
 
477
                    // point k at the end of remote host name
 
478
                    while (printerDesc[i] != '=')
 
479
                        i++;
 
480
                    while (printerDesc[i] == '=' || printerDesc[i].isSpace())
 
481
                        i++;
 
482
                    j = i;
 
483
                    while (j < (int)printerDesc.length() &&
 
484
                            printerDesc[j] != ':' && printerDesc[j] != ',')
 
485
                        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] == ',') {
 
490
                        i = ++j;
 
491
                        while (printerDesc[i].isSpace())
 
492
                            i++;
 
493
                        j = i;
 
494
                        while (j < (int)printerDesc.length() &&
 
495
                                printerDesc[j] != ':' && printerDesc[j] != ',')
 
496
                            j++;
 
497
                        if (printerName != printerDesc.mid(i, j-i)) {
 
498
                            printerComment =
 
499
                                QLatin1String("Remote name: ");
 
500
                            printerComment += printerDesc.mid(i, j-i);
 
501
                        }
 
502
                    }
 
503
                }
 
504
            }
 
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
 
511
            printerDesc = "";
 
512
        }
 
513
    }
 
514
    delete[] line;
 
515
    return defaultPrinter;
 
516
}
 
517
 
 
518
#ifndef QT_NO_NIS
 
519
 
 
520
#if defined(Q_C_CALLBACKS)
 
521
extern "C" {
 
522
#endif
 
523
 
 
524
static int pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
 
525
                    char *val, int valLen, char *data)
 
526
{
 
527
    parsePrinterDesc(QString::fromLatin1(val, valLen), (QList<QPrinterDescription> *)data);
 
528
    return 0;
 
529
}
 
530
 
 
531
#if defined(Q_C_CALLBACKS)
 
532
}
 
533
#endif
 
534
 
 
535
static int retrieveNisPrinters(QList<QPrinterDescription> *printers)
 
536
{
 
537
    typedef int (*WildCast)(int, char *, int, char *, int, char *);
 
538
    char printersConfByname[] = "printers.conf.byname";
 
539
    char *domain;
 
540
    int err;
 
541
 
 
542
    QLibrary lib("nsl");
 
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");
 
547
 
 
548
    if (_ypGetDefaultDomain && _ypAll) {
 
549
        err = _ypGetDefaultDomain(&domain);
 
550
        if (err == 0) {
 
551
            ypall_callback cb;
 
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);
 
556
        }
 
557
        if (!err)
 
558
            return Success;
 
559
    }
 
560
    return Unavail;
 
561
}
 
562
 
 
563
#endif // QT_NO_NIS
 
564
 
 
565
static char *parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line)
 
566
{
 
567
#define skipSpaces() \
 
568
    while (isspace((uchar) line[k])) \
 
569
        k++
 
570
 
 
571
    char *defaultPrinter = 0;
 
572
    bool stop = false;
 
573
    int lastStatus = NotFound;
 
574
 
 
575
    int k = 8;
 
576
    skipSpaces();
 
577
    if (line[k] != ':')
 
578
        return 0;
 
579
    k++;
 
580
 
 
581
    char *cp = strchr(line, '#');
 
582
    if (cp != 0)
 
583
        *cp = '\0';
 
584
 
 
585
    while (line[k] != '\0') {
 
586
        if (isspace((uchar) line[k])) {
 
587
            k++;
 
588
        } else if (line[k] == '[') {
 
589
            k++;
 
590
            skipSpaces();
 
591
            while (line[k] != '\0') {
 
592
                char status = tolower(line[k]);
 
593
                char action = '?';
 
594
 
 
595
                while (line[k] != '=' && line[k] != ']' && line[k] != '\0')
 
596
                    k++;
 
597
                if (line[k] == '=') {
 
598
                    k++;
 
599
                    skipSpaces();
 
600
                    action = tolower(line[k]);
 
601
                    while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != ']')
 
602
                        k++;
 
603
                } else if (line[k] == ']') {
 
604
                    k++;
 
605
                    break;
 
606
                }
 
607
                skipSpaces();
 
608
 
 
609
                if (lastStatus == status)
 
610
                    stop = (action == (char) Return);
 
611
            }
 
612
        } else {
 
613
            if (stop)
 
614
                break;
 
615
 
 
616
            QByteArray source;
 
617
            while (!isspace((uchar) line[k]) && line[k] != '[') {
 
618
                source += line[k];
 
619
                k++;
 
620
            }
 
621
 
 
622
            if (source == "user") {
 
623
                lastStatus = parsePrintcap(printers,
 
624
                        QDir::homePath() + "/.printers");
 
625
            } else if (source == "files") {
 
626
                bool found;
 
627
                defaultPrinter = parsePrintersConf(printers, &found);
 
628
                if (found)
 
629
                    lastStatus = Success;
 
630
#ifndef QT_NO_NIS
 
631
            } else if (source == "nis") {
 
632
                lastStatus = retrieveNisPrinters(printers);
 
633
#endif
 
634
            } else {
 
635
                // nisplus, dns, etc., are not implemented yet
 
636
                lastStatus = NotFound;
 
637
            }
 
638
            stop = (lastStatus == Success);
 
639
        }
 
640
    }
 
641
    return defaultPrinter;
 
642
}
 
643
 
 
644
static char *parseNsswitchConf(QList<QPrinterDescription> *printers)
 
645
{
 
646
    QFile nc(QLatin1String("/etc/nsswitch.conf"));
 
647
    if (!nc.open(QIODevice::ReadOnly))
 
648
        return 0;
 
649
 
 
650
    char *defaultPrinter = 0;
 
651
 
 
652
    char *line = new char[1025];
 
653
    line[1024] = '\0';
 
654
 
 
655
    while (!nc.atEnd() &&
 
656
            nc.readLine(line, 1024) > 0) {
 
657
        if (strncmp(line, "printers", 8) == 0) {
 
658
            defaultPrinter = parseNsswitchPrintersEntry(printers, line);
 
659
            delete[] line;
 
660
            return defaultPrinter;
 
661
        }
 
662
    }
 
663
 
 
664
    strcpy(line, "printers: user files nis nisplus xfn");
 
665
    defaultPrinter = parseNsswitchPrintersEntry(printers, line);
 
666
    delete[] line;
 
667
    return defaultPrinter;
 
668
}
 
669
 
 
670
// HP-UX
 
671
static void parseEtcLpMember(QList<QPrinterDescription> *printers)
 
672
{
 
673
    QDir lp(QLatin1String("/etc/lp/member"));
 
674
    if (!lp.exists())
 
675
        return;
 
676
    QFileInfoList dirs = lp.entryInfoList();
 
677
    if (dirs.isEmpty())
 
678
        return;
 
679
 
 
680
    QString tmp;
 
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"),
 
690
                               QLatin1String(""));
 
691
    }
 
692
}
 
693
 
 
694
// IRIX 6.x
 
695
static void parseSpoolInterface(QList<QPrinterDescription> *printers)
 
696
{
 
697
    QDir lp(QLatin1String("/usr/spool/lp/interface"));
 
698
    if (!lp.exists())
 
699
        return;
 
700
    QFileInfoList files = lp.entryInfoList();
 
701
    if(files.isEmpty())
 
702
        return;
 
703
 
 
704
    for (int i = 0; i < files.size(); ++i) {
 
705
        QFileInfo printer = files.at(i);
 
706
 
 
707
        if (!printer.isFile())
 
708
            continue;
 
709
 
 
710
        // parse out some information
 
711
        QFile configFile(printer.filePath());
 
712
        if (!configFile.open(QIODevice::ReadOnly))
 
713
            continue;
 
714
 
 
715
        QByteArray line;
 
716
        line.resize(1025);
 
717
        QString namePrinter;
 
718
        QString hostName;
 
719
        QString hostPrinter;
 
720
        QString printerType;
 
721
 
 
722
        QString nameKey(QLatin1String("NAME="));
 
723
        QString typeKey(QLatin1String("TYPE="));
 
724
        QString hostKey(QLatin1String("HOSTNAME="));
 
725
        QString hostPrinterKey(QLatin1String("HOSTPRINTER="));
 
726
 
 
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();
 
742
            }
 
743
        }
 
744
        configFile.close();
 
745
 
 
746
        printerType = printerType.trimmed();
 
747
        if (printerType.indexOf("postscript", 0, Qt::CaseInsensitive) < 0)
 
748
            continue;
 
749
 
 
750
        int ii = 0;
 
751
        while ((ii = namePrinter.indexOf('"', ii)) >= 0)
 
752
            namePrinter.remove(ii, 1);
 
753
 
 
754
        if (hostName.isEmpty() || hostPrinter.isEmpty()) {
 
755
            perhapsAddPrinter(printers, printer.fileName(),
 
756
                               QLatin1String(""), namePrinter);
 
757
        } else {
 
758
            QString comment;
 
759
            comment = namePrinter;
 
760
            comment += " (";
 
761
            comment += hostPrinter;
 
762
            comment += ")";
 
763
            perhapsAddPrinter(printers, printer.fileName(),
 
764
                               hostName, comment);
 
765
        }
 
766
    }
 
767
}
 
768
 
 
769
 
 
770
// Every unix must have its own.  It's a standard.  Here is AIX.
 
771
static void parseQconfig(QList<QPrinterDescription> *printers)
 
772
{
 
773
    QFile qconfig(QLatin1String("/etc/qconfig"));
 
774
    if (!qconfig.open(QIODevice::ReadOnly))
 
775
        return;
 
776
 
 
777
    QTextStream ts(&qconfig);
 
778
    QString line;
 
779
 
 
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
 
784
 
 
785
    QRegExp newStanza(QLatin1String("^[0-z\\-]*:$"));
 
786
 
 
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
 
793
    // report those).
 
794
 
 
795
    do {
 
796
        line = ts.readLine();
 
797
        bool indented = line[0].isSpace();
 
798
        line = line.simplified();
 
799
 
 
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"))
 
805
                deviceName = value;
 
806
            else if (variable == QLatin1String("host"))
 
807
                remoteHost = value;
 
808
            else if (variable == QLatin1String("up"))
 
809
                up = !(value.toLower() == QLatin1String("false"));
 
810
        } else if (line[0] == '*') { // comment
 
811
            // nothing to do
 
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,
 
817
                                       QString());
 
818
                else if (deviceName.length()) // local printer
 
819
                    perhapsAddPrinter(printers, stanzaName, QString(),
 
820
                                       QString());
 
821
            }
 
822
            line.chop(1);
 
823
            if (line.length() >= 1 && line.length() <= 20)
 
824
                stanzaName = line;
 
825
            up = true;
 
826
            remoteHost.clear();
 
827
            deviceName.clear();
 
828
        } else {
 
829
            // syntax error?  ignore.
 
830
        }
 
831
    } while (!ts.atEnd());
 
832
}
 
833
 
 
834
 
 
835
#ifndef QT_NO_CUPS
 
836
#include <cups/cups.h>
 
837
 
 
838
static char *parseCupsOutput(QList<QPrinterDescription> *printers)
 
839
{
 
840
    char *defaultPrinter = 0;
 
841
    int nd;
 
842
    cups_dest_t *d;
 
843
    QLibrary lib("cups");
 
844
    typedef int (*CupsGetDests)(cups_dest_t **dests);
 
845
    CupsGetDests _cupsGetDests = (CupsGetDests)lib.resolve("cupsGetDests");
 
846
    if (_cupsGetDests) {
 
847
        nd = _cupsGetDests(&d);
 
848
        if (nd < 1)
 
849
            return 0;
 
850
 
 
851
        int n = 0;
 
852
        while (n < nd) {
 
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);
 
857
            n++;
 
858
        }
 
859
    }
 
860
    return defaultPrinter;
 
861
}
 
862
#endif
 
863
 
 
864
QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
 
865
    : QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent)
 
866
{
 
867
    d_func()->init();
 
868
}
 
869
 
 
870
 
 
871
/*! Destroys the object and frees any allocated resources.  Does not
 
872
  delete the associated QPrinter object.
 
873
*/
 
874
 
 
875
QPrintDialog::~QPrintDialog()
 
876
{
 
877
}
 
878
 
 
879
 
 
880
QGroupBox *QPrintDialogPrivate::setupPrinterSettings()
 
881
{
 
882
    Q_Q(QPrintDialog);
 
883
    QGroupBox *g = new QGroupBox(q->tr("Printer settings"), q);
 
884
 
 
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*)));
 
889
 
 
890
    printColor = new QRadioButton(q->tr("Print in color if available"), g);
 
891
    colorMode->addButton(printColor);
 
892
    printColor->setChecked(true);
 
893
    tll->addWidget(printColor);
 
894
 
 
895
    printGray = new QRadioButton(q->tr("Print in grayscale"), g);
 
896
    colorMode->addButton(printGray);
 
897
    tll->addWidget(printGray);
 
898
 
 
899
    return g;
 
900
}
 
901
 
 
902
QGroupBox *QPrintDialogPrivate::setupDestination()
 
903
{
 
904
    Q_Q(QPrintDialog);
 
905
    QGroupBox *g = new QGroupBox(q->tr("Print destination"), q);
 
906
 
 
907
    QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down, g);
 
908
    printerOrFile = new QButtonGroup(q);
 
909
 
 
910
    // printer radio button, list
 
911
    QRadioButton *rb = new QRadioButton(q->tr("Print to printer:"), g);
 
912
    tll->addWidget(rb);
 
913
    printerOrFile->addButton(rb);
 
914
    rb->setChecked(true);
 
915
    outputToFile = false;
 
916
 
 
917
    QBoxLayout *horiz = new QBoxLayout(QBoxLayout::LeftToRight);
 
918
    tll->addLayout(horiz, 3);
 
919
    horiz->addSpacing(19);
 
920
 
 
921
    char *etcLpDefault = 0;
 
922
 
 
923
#ifndef QT_NO_CUPS
 
924
    etcLpDefault = parseCupsOutput(&printers);
 
925
#endif
 
926
    if (printers.size() == 0) {
 
927
        // we only use other schemes when cups fails.
 
928
 
 
929
        parsePrintcap(&printers, QLatin1String("/etc/printcap"));
 
930
        parseEtcLpMember(&printers);
 
931
        parseSpoolInterface(&printers);
 
932
        parseQconfig(&printers);
 
933
 
 
934
        QFileInfo f;
 
935
        f.setFile(QLatin1String("/etc/lp/printers"));
 
936
        if (f.isDir()) {
 
937
            parseEtcLpPrinters(&printers);
 
938
            QFile def(QLatin1String("/etc/lp/default"));
 
939
            if (def.open(QIODevice::ReadOnly)) {
 
940
                if (etcLpDefault)
 
941
                    delete[] etcLpDefault;
 
942
                etcLpDefault = new char[1025];
 
943
                def.readLine(etcLpDefault, 1024);
 
944
                char *p = etcLpDefault;
 
945
                while (p && *p) {
 
946
                    if (!isprint((uchar) *p) || isspace((uchar) *p))
 
947
                        *p = 0;
 
948
                    else
 
949
                        p++;
 
950
                }
 
951
            }
 
952
        }
 
953
 
 
954
        char *def = 0;
 
955
        f.setFile(QLatin1String("/etc/nsswitch.conf"));
 
956
        if (f.isFile()) {
 
957
            def = parseNsswitchConf(&printers);
 
958
        } else {
 
959
            f.setFile(QLatin1String("/etc/printers.conf"));
 
960
            if (f.isFile())
 
961
                def = parsePrintersConf(&printers);
 
962
        }
 
963
 
 
964
        if (def) {
 
965
            if (etcLpDefault)
 
966
                delete[] etcLpDefault;
 
967
            etcLpDefault = def;
 
968
        }
 
969
    }
 
970
 
 
971
    // all printers hopefully known.  try to find a good default
 
972
    QString dollarPrinter;
 
973
    {
 
974
        if (!qgetenv("PRINTER").isEmpty())
 
975
            dollarPrinter = QString::fromLocal8Bit(qgetenv("LPDEST").constData());
 
976
        if (!dollarPrinter.isEmpty())
 
977
            perhapsAddPrinter(&printers, dollarPrinter,
 
978
                               QPrintDialog::tr("unknown"),
 
979
                              QLatin1String(""));
 
980
    }
 
981
 
 
982
 
 
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);
 
988
 
 
989
    // bang the best default into the listview
 
990
    int quality = 0;
 
991
    int best = 0;
 
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]|$)"));
 
995
 
 
996
        QString name = printers.at(i).name;
 
997
        QString comment = printers.at(i).comment;
 
998
        if (quality < 4 && name == dollarPrinter) {
 
999
            best = i;
 
1000
            quality = 4;
 
1001
        } else if (quality < 3 && etcLpDefault &&
 
1002
                    name == QLatin1String(etcLpDefault)) {
 
1003
            best = i;
 
1004
            quality = 3;
 
1005
        } else if (quality < 2 &&
 
1006
                    (name == QLatin1String("ps") ||
 
1007
                     ps.indexIn(comment) != -1)) {
 
1008
            best = i;
 
1009
            quality = 2;
 
1010
        } else if (quality < 1 &&
 
1011
                    (name == QLatin1String("lp") ||
 
1012
                     lp.indexIn(comment) > -1)) {
 
1013
            best = i;
 
1014
            quality = 1;
 
1015
        }
 
1016
    }
 
1017
    view->setCurrentIndex(static_cast<QAbstractTableModel*>(model)->index(best, 0));
 
1018
 
 
1019
    if (etcLpDefault)                 // Avoid purify complaint
 
1020
        delete[] etcLpDefault;
 
1021
 
 
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() +
 
1027
//                                  3 * h);
 
1028
    horiz->addWidget(view, 3);
 
1029
 
 
1030
    // file radio button, edit/browse
 
1031
    printToFileButton = new QRadioButton(q->tr("Print to file:"), g);
 
1032
    tll->addWidget(printToFileButton);
 
1033
    printerOrFile->addButton(printToFileButton);
 
1034
 
 
1035
    horiz = new QBoxLayout(QBoxLayout::LeftToRight);
 
1036
    tll->addLayout(horiz);
 
1037
    horiz->addSpacing(19);
 
1038
 
 
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);
 
1048
 
 
1049
    fileName->setEnabled(false);
 
1050
    browse->setEnabled(false);
 
1051
 
 
1052
    QObject::connect(printerOrFile, SIGNAL(buttonClicked(QAbstractButton*)),
 
1053
             q, SLOT(printerOrFileSelected(QAbstractButton*)));
 
1054
    return g;
 
1055
}
 
1056
 
 
1057
 
 
1058
QGroupBox *QPrintDialogPrivate::setupOptions()
 
1059
{
 
1060
    Q_Q(QPrintDialog);
 
1061
    QGroupBox *g = new QGroupBox(q->tr("Options"), q);
 
1062
 
 
1063
    QBoxLayout *lay = new QBoxLayout(QBoxLayout::LeftToRight, g);
 
1064
    QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down);
 
1065
    lay->addLayout(tll);
 
1066
 
 
1067
    printRange = new QButtonGroup(q);
 
1068
    QObject::connect(printRange, SIGNAL(buttonClicked(QAbstractButton*)), q, SLOT(printRangeSelected(QAbstractButton*)));
 
1069
 
 
1070
    pageOrder = new QButtonGroup(q);
 
1071
    QObject::connect(pageOrder, SIGNAL(buttonClicked(QAbstractButton*)), q, SLOT(pageOrderSelected(QAbstractButton*)));
 
1072
 
 
1073
    printAllButton = new QRadioButton(q->tr("Print all"), g);
 
1074
    printRange->addButton(printAllButton);
 
1075
    tll->addWidget(printAllButton);
 
1076
 
 
1077
    printSelectionButton = new QRadioButton(q->tr("Print selection"), g);
 
1078
    printRange->addButton(printSelectionButton);
 
1079
    tll->addWidget(printSelectionButton);
 
1080
 
 
1081
    printRangeButton = new QRadioButton(q->tr("Print range"), g);
 
1082
    printRange->addButton(printRangeButton);
 
1083
    tll->addWidget(printRangeButton);
 
1084
 
 
1085
    QBoxLayout *horiz = new QBoxLayout(QBoxLayout::LeftToRight);
 
1086
    tll->addLayout(horiz);
 
1087
 
 
1088
    firstPageLabel = new QLabel(q->tr("From page:"), g);
 
1089
    horiz->addSpacing(19);
 
1090
    horiz->addWidget(firstPageLabel);
 
1091
 
 
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)));
 
1098
 
 
1099
    horiz = new QBoxLayout(QBoxLayout::LeftToRight);
 
1100
    tll->addLayout(horiz);
 
1101
 
 
1102
    lastPageLabel = new QLabel(q->tr("To page:"), g);
 
1103
    horiz->addSpacing(19);
 
1104
    horiz->addWidget(lastPageLabel);
 
1105
 
 
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)));
 
1112
 
 
1113
    lay->addSpacing(25);
 
1114
    tll = new QBoxLayout(QBoxLayout::Down);
 
1115
    lay->addLayout(tll);
 
1116
 
 
1117
    // print order
 
1118
    firstPageFirst = new QRadioButton(q->tr("Print first page first"), g);
 
1119
    tll->addWidget(firstPageFirst);
 
1120
    pageOrder->addButton(firstPageFirst);
 
1121
    firstPageFirst->setChecked(true);
 
1122
 
 
1123
    lastPageFirst = new QRadioButton(q->tr("Print last page first"), g);
 
1124
    tll->addWidget(lastPageFirst);
 
1125
    pageOrder->addButton(lastPageFirst);
 
1126
 
 
1127
    tll->addStretch();
 
1128
 
 
1129
    // copies
 
1130
 
 
1131
    horiz = new QBoxLayout(QBoxLayout::LeftToRight);
 
1132
    tll->addLayout(horiz);
 
1133
 
 
1134
    QLabel *l = new QLabel(q->tr("Number of copies:"), g);
 
1135
    horiz->addWidget(l);
 
1136
 
 
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)));
 
1143
 
 
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());
 
1150
 
 
1151
    return g;
 
1152
}
 
1153
 
 
1154
 
 
1155
void isc(QPrintDialogPrivate *ptr, const QString & text, QPrinter::PageSize ps)
 
1156
{
 
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;
 
1162
    }
 
1163
}
 
1164
 
 
1165
QGroupBox *QPrintDialogPrivate::setupPaper()
 
1166
{
 
1167
    Q_Q(QPrintDialog);
 
1168
    QGroupBox *g = new QGroupBox(q->tr("Paper format"), q);
 
1169
 
 
1170
    QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down, g);
 
1171
    pageSize = QPrinter::A4;
 
1172
 
 
1173
    // page orientation
 
1174
    orientationCombo = new QComboBox(g);
 
1175
    orientationCombo->addItem(q->tr("Portrait"));
 
1176
    orientationCombo->addItem(q->tr("Landscape"));
 
1177
    tll->addWidget(orientationCombo);
 
1178
 
 
1179
    orientation = QPrinter::Portrait;
 
1180
 
 
1181
    QObject::connect(orientationCombo, SIGNAL(activated(int)),
 
1182
             q, SLOT(orientSelected(int)));
 
1183
 
 
1184
    // paper size
 
1185
    sizeCombo = new QComboBox(g);
 
1186
    tll->addWidget(sizeCombo);
 
1187
 
 
1188
    int n;
 
1189
    for(n=0; n<QPrinter::NPageSize; n++)
 
1190
        indexToPageSize[n] = QPrinter::A4;
 
1191
 
 
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);
 
1222
 
 
1223
    QObject::connect(sizeCombo, SIGNAL(activated(int)),
 
1224
             q, SLOT(paperSizeSelected(int)));
 
1225
 
 
1226
    return g;
 
1227
}
 
1228
 
 
1229
 
 
1230
void QPrintDialogPrivate::printerOrFileSelected(QAbstractButton *b)
 
1231
{
 
1232
    outputToFile = (b == printToFileButton);
 
1233
    if (outputToFile) {
 
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) != '/')
 
1240
                home += '/';
 
1241
            if (cur.at(cur.length()-1) != '/')
 
1242
                cur += '/';
 
1243
            if (cur.left(home.length()) != home)
 
1244
                cur = home;
 
1245
#ifdef Q_WS_X11
 
1246
            cur += "print.ps";
 
1247
#endif
 
1248
            fileName->setText(cur);
 
1249
            fileName->setCursorPosition(cur.length());
 
1250
            fileName->selectAll();
 
1251
        }
 
1252
        browse->setEnabled(true);
 
1253
        fileName->setEnabled(true);
 
1254
        fileName->setFocus();
 
1255
        view->setEnabled(false);
 
1256
    } else {
 
1257
        ok->setEnabled(printers.count() != 0);
 
1258
        view->setEnabled(true);
 
1259
        if (fileName->hasFocus() || browse->hasFocus())
 
1260
            view->setFocus();
 
1261
        browse->setEnabled(false);
 
1262
        fileName->setEnabled(false);
 
1263
    }
 
1264
}
 
1265
 
 
1266
 
 
1267
void QPrintDialogPrivate::landscapeSelected(int id)
 
1268
{
 
1269
    orientation = (QPrinter::Orientation)id;
 
1270
}
 
1271
 
 
1272
 
 
1273
void QPrintDialogPrivate::paperSizeSelected(int id)
 
1274
{
 
1275
    if (id < QPrinter::NPageSize)
 
1276
        pageSize = QPrinter::PageSize(indexToPageSize[id]);
 
1277
}
 
1278
 
 
1279
 
 
1280
void QPrintDialogPrivate::orientSelected(int id)
 
1281
{
 
1282
    orientation = (QPrinter::Orientation)id;
 
1283
}
 
1284
 
 
1285
 
 
1286
void QPrintDialogPrivate::pageOrderSelected(QAbstractButton *b)
 
1287
{
 
1288
    pageOrder2 = (b == firstPageFirst) ? QPrinter::FirstPageFirst : QPrinter::LastPageFirst;
 
1289
}
 
1290
 
 
1291
 
 
1292
void QPrintDialogPrivate::setNumCopies(int copies)
 
1293
{
 
1294
    numCopies = copies;
 
1295
}
 
1296
 
 
1297
 
 
1298
void QPrintDialogPrivate::browseClicked()
 
1299
{
 
1300
    Q_Q(QPrintDialog);
 
1301
    QString fn = QFileDialog::getSaveFileName(q, QString(), fileName->text(),
 
1302
                                              q->tr("PostScript Files (*.ps);;All Files (*)"));
 
1303
    if (!fn.isNull())
 
1304
        fileName->setText(fn);
 
1305
}
 
1306
 
 
1307
 
 
1308
void QPrintDialogPrivate::okClicked()
 
1309
{
 
1310
    Q_Q(QPrintDialog);
 
1311
    lastPage->interpretText();
 
1312
    firstPage->interpretText();
 
1313
    copies->interpretText();
 
1314
    if (outputToFile) {
 
1315
        printer->setOutputFileName(fileName->text());
 
1316
    } else {
 
1317
        printer->setOutputFileName(QString());
 
1318
        QModelIndex current = view->currentIndex();
 
1319
        if (current.isValid())
 
1320
            printer->setPrinterName(printers.at(current.row()).name);
 
1321
    }
 
1322
 
 
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());
 
1331
    } else {
 
1332
        if (printSelectionButton->isChecked()) {
 
1333
            q->setPrintRange(QPrintDialog::Selection);
 
1334
            q->setFromTo(0, 0);
 
1335
        } else {
 
1336
            q->setPrintRange(QPrintDialog::PageRange);
 
1337
            q->setFromTo(firstPage->value(), lastPage->value());
 
1338
        }
 
1339
    }
 
1340
    q->accept();
 
1341
}
 
1342
 
 
1343
 
 
1344
void QPrintDialogPrivate::printRangeSelected(QAbstractButton *b)
 
1345
{
 
1346
    bool enable = (b == printRangeButton);
 
1347
    firstPage->setEnabled(enable);
 
1348
    lastPage->setEnabled(enable);
 
1349
    firstPageLabel->setEnabled(enable);
 
1350
    lastPageLabel->setEnabled(enable);
 
1351
}
 
1352
 
 
1353
 
 
1354
void QPrintDialogPrivate::setFirstPage(int fp)
 
1355
{
 
1356
    Q_Q(QPrintDialog);
 
1357
    if (printer) {
 
1358
        lastPage->setMinimum(fp);
 
1359
        lastPage->setMaximum(qMax(fp, q->maxPage()));
 
1360
    }
 
1361
}
 
1362
 
 
1363
 
 
1364
void QPrintDialogPrivate::setLastPage(int lp)
 
1365
{
 
1366
    Q_Q(QPrintDialog);
 
1367
    if (printer) {
 
1368
        firstPage->setMinimum(qMin(lp, q->minPage()));
 
1369
        firstPage->setMaximum(lp);
 
1370
    }
 
1371
}
 
1372
 
 
1373
 
 
1374
#ifdef QT3_SUPPORT
 
1375
/*!
 
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.
 
1379
*/
 
1380
void QPrintDialog::addButton(QPushButton *but)
 
1381
{
 
1382
    Q_D(QPrintDialog);
 
1383
    d->customLayout->addWidget(but);
 
1384
}
 
1385
 
 
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
 
1389
{
 
1390
    Q_D(const QPrintDialog);
 
1391
    return d->printer;
 
1392
}
 
1393
 
 
1394
/*!
 
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.
 
1399
*/
 
1400
 
 
1401
void QPrintDialog::setPrinter(QPrinter *p, bool pickUpSettings)
 
1402
{
 
1403
    Q_D(QPrintDialog);
 
1404
    d->setPrinter(p, pickUpSettings);
 
1405
}
 
1406
#endif
 
1407
 
 
1408
void QPrintDialogPrivate::setPrinter(QPrinter *p, bool pickUpSettings)
 
1409
{
 
1410
    Q_Q(QPrintDialog);
 
1411
    printer = p;
 
1412
 
 
1413
    if (p && pickUpSettings) {
 
1414
        // top to botton in the old dialog.
 
1415
        // printer or file
 
1416
        if (!p->outputFileName().isEmpty())
 
1417
            printToFileButton->setChecked(true);
 
1418
 
 
1419
        // printer name
 
1420
        if (!p->printerName().isEmpty()) {
 
1421
            for (int i = 0; i < printers.size(); ++i) {
 
1422
                if (printers.at(i).name == p->printerName()) {
 
1423
                    // ###############
 
1424
//                    printers->setSelected(i, true);
 
1425
                    ok->setEnabled(true);
 
1426
                } else if (fileName->text().isEmpty()) {
 
1427
                    ok->setEnabled(model->rowCount() != 0);
 
1428
                }
 
1429
            }
 
1430
        }
 
1431
 
 
1432
        // print command does not exist any more
 
1433
 
 
1434
        // file name
 
1435
        printToFileButton->setEnabled(q->isOptionEnabled(QPrintDialog::PrintToFile));
 
1436
        fileName->setText(p->outputFileName());
 
1437
 
 
1438
        // orientation
 
1439
        orientationCombo->setCurrentIndex((int)p->orientation());
 
1440
        orientSelected(p->orientation());
 
1441
 
 
1442
        // page size
 
1443
        int n = 0;
 
1444
        while (n < QPrinter::NPageSize &&
 
1445
                indexToPageSize[n] != p->pageSize())
 
1446
            n++;
 
1447
        sizeCombo->setCurrentIndex(n);
 
1448
        paperSizeSelected(n);
 
1449
 
 
1450
        // New stuff (Options)
 
1451
 
 
1452
        // page order
 
1453
        pageOrder2 = p->pageOrder();
 
1454
        if (pageOrder2 == QPrinter::LastPageFirst)
 
1455
            lastPageFirst->setChecked(true);
 
1456
 
 
1457
        // color mode
 
1458
        colorMode2 = p->colorMode();
 
1459
        if (colorMode2 == QPrinter::Color)
 
1460
            printColor->setChecked(true);
 
1461
 
 
1462
        // number of copies
 
1463
        copies->setValue(p->numCopies());
 
1464
        setNumCopies(p->numCopies());
 
1465
    }
 
1466
 
 
1467
    if(p) {
 
1468
        printAllButton->setEnabled(true);
 
1469
        printSelectionButton->setEnabled(q->isOptionEnabled(QPrintDialog::PrintSelection));
 
1470
        printRangeButton->setEnabled(q->isOptionEnabled(QPrintDialog::PrintPageRange));
 
1471
 
 
1472
        switch (q->printRange()) {
 
1473
        case QPrintDialog::AllPages:
 
1474
            printAllButton->click();
 
1475
            break;
 
1476
        case QPrintDialog::Selection:
 
1477
            printSelectionButton->click();
 
1478
            break;
 
1479
        case QPrintDialog::PageRange:
 
1480
            printRangeButton->click();
 
1481
            break;
 
1482
        }
 
1483
    }
 
1484
 
 
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());
 
1495
        }
 
1496
    }
 
1497
}
 
1498
 
 
1499
void QPrintDialogPrivate::colorModeSelected(QAbstractButton *b)
 
1500
{
 
1501
    colorMode2 = (b == printColor) ? QPrinter::Color : QPrinter::GrayScale;
 
1502
}
 
1503
 
 
1504
void QPrintDialogPrivate::fileNameEditChanged(const QString &text)
 
1505
{
 
1506
    if (fileName->isEnabled())
 
1507
        ok->setEnabled(!text.isEmpty());
 
1508
}
 
1509
 
 
1510
int QPrintDialog::exec()
 
1511
{
 
1512
    return QDialog::exec();
 
1513
}
 
1514
 
 
1515
void QPrintDialogPrivate::init()
 
1516
{
 
1517
    Q_Q(QPrintDialog);
 
1518
    numCopies = 1;
 
1519
 
 
1520
    QBoxLayout *tll = new QBoxLayout(QBoxLayout::Down, q);
 
1521
 
 
1522
    // destination
 
1523
    QGroupBox *g;
 
1524
    g = setupDestination();
 
1525
    tll->addWidget(g, 1);
 
1526
 
 
1527
    // printer and paper settings
 
1528
    QBoxLayout *lay = new QBoxLayout(QBoxLayout::LeftToRight);
 
1529
    tll->addLayout(lay);
 
1530
 
 
1531
    g = setupPrinterSettings();
 
1532
    lay->addWidget(g, 1);
 
1533
 
 
1534
    g = setupPaper();
 
1535
    lay->addWidget(g);
 
1536
 
 
1537
    // options
 
1538
    g = setupOptions();
 
1539
    tll->addWidget(g);
 
1540
 
 
1541
    QBoxLayout *l = new QBoxLayout(QBoxLayout::LeftToRight);
 
1542
    customLayout = new QBoxLayout(QBoxLayout::LeftToRight);
 
1543
    tll->addLayout(l);
 
1544
    l->addLayout(customLayout);
 
1545
    l->addStretch();
 
1546
 
 
1547
    // buttons
 
1548
    QBoxLayout *horiz = new QBoxLayout(QBoxLayout::LeftToRight);
 
1549
    tll->addLayout(horiz);
 
1550
 
 
1551
    bool rightalign =
 
1552
        bool(q->style()->styleHint(QStyle::SH_PrintDialog_RightAlignButtons, 0, q));
 
1553
 
 
1554
    if (rightalign)
 
1555
        horiz->addStretch(1);
 
1556
 
 
1557
    ok = new QPushButton(q->tr("OK"), q);
 
1558
    ok->setDefault(true);
 
1559
    horiz->addWidget(ok);
 
1560
    if (! rightalign)
 
1561
        horiz->addStretch(1);
 
1562
 
 
1563
    QPushButton *cancel = new QPushButton(q->tr("Cancel"), q);
 
1564
    horiz->addWidget(cancel);
 
1565
 
 
1566
    q->connect(ok, SIGNAL(clicked()), q, SLOT(okClicked()));
 
1567
    q->connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
 
1568
 
 
1569
    QSize ms(q->minimumSize());
 
1570
    QSize ss(QApplication::desktop()->screenGeometry(q->pos()).size());
 
1571
    if (ms.height() < 512 && ss.height() >= 600)
 
1572
        ms.setHeight(512);
 
1573
    else if (ms.height() < 460 && ss.height() >= 480)
 
1574
        ms.setHeight(460);
 
1575
    q->resize(ms);
 
1576
 
 
1577
    setPrinter(printer, true);
 
1578
    view->setFocus();
 
1579
}
 
1580
 
 
1581
#include "moc_qprintdialog.cpp"
 
1582
#endif