QtPrintSupport - Cleanup QPrintDialog header
[profile/ivi/qtbase.git] / src / printsupport / dialogs / qprintdialog_unix.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformdefs.h"
43
44 #ifndef QT_NO_PRINTDIALOG
45
46 #include "private/qabstractprintdialog_p.h"
47 #include <QtWidgets/qmessagebox.h>
48 #include "qprintdialog.h"
49 #include "qfiledialog.h"
50 #include <QtCore/qdir.h>
51 #include <QtGui/qevent.h>
52 #include <QtWidgets/qfilesystemmodel.h>
53 #include <QtWidgets/qstyleditemdelegate.h>
54 #include <QtPrintSupport/qprinter.h>
55 #include <private/qprintengine_pdf_p.h>
56
57 #include <QtWidgets/qdialogbuttonbox.h>
58
59 #include "private/qfscompleter_p.h"
60 #include "ui_qprintpropertieswidget.h"
61 #include "ui_qprintsettingsoutput.h"
62 #include "ui_qprintwidget.h"
63
64 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
65 #  include <private/qcups_p.h>
66 #else
67 #  include <QtCore/qlibrary.h>
68 #  include <private/qprintengine_pdf_p.h>
69 #endif
70
71 /*
72
73 Print dialog class declarations
74
75     QPrintDialog:            The main Print Dialog, nothing really held here.
76
77     QUnixPrintWidget:
78     QUnixPrintWidgetPrivate: The real Unix Print Dialog implementation.
79
80                              Directly includes the upper half of the Print Dialog
81                              containing the Printer Selection widgets and
82                              Properties button.
83
84                              Embeds the Properties pop-up dialog from
85                              QPrintPropertiesDialog
86
87                              Embeds the lower half from separate widget class
88                              QPrintDialogPrivate
89
90                              Layout in qprintwidget.ui
91
92     QPrintDialogPrivate:     The lower half of the Print Dialog containing the
93                              Copies and Options tabs that expands when the
94                              Options button is selected.
95
96                              Layout in qprintsettingsoutput.ui
97
98     QPrintPropertiesDialog:  Dialog displayed when clicking on Properties button to
99                              allow editing of Page and Advanced tabs.
100
101                              Layout in qprintpropertieswidget.ui
102
103     QPPDOptionsModel:        Holds the PPD Options for the printer.
104
105     QPPDOptionsEditor:       Edits the PPD Options for the printer.
106
107 */
108
109 QT_BEGIN_NAMESPACE
110
111 class QOptionTreeItem;
112 class QPPDOptionsModel;
113
114 class QPrintPropertiesDialog : public QDialog
115 {
116     Q_OBJECT
117 public:
118     QPrintPropertiesDialog(QAbstractPrintDialog *parent = 0);
119     ~QPrintPropertiesDialog();
120
121 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
122     void setCups(QCUPSSupport *cups) { m_cups = cups; }
123     void addItemToOptions(QOptionTreeItem *parent, QList<const ppd_option_t*>& options, QList<const char*>& markedOptions) const;
124 #endif
125
126     void selectPrinter();
127     void selectPdfPsPrinter(const QPrinter *p);
128
129     /// copy printer properties to the widget
130     void applyPrinterProperties(QPrinter *p);
131     void setupPrinter() const;
132
133 protected:
134     void showEvent(QShowEvent* event);
135
136 private:
137     Ui::QPrintPropertiesWidget widget;
138     QDialogButtonBox *m_buttons;
139 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
140     QCUPSSupport *m_cups;
141     QPPDOptionsModel *m_cupsOptionsModel;
142 #endif
143 };
144
145 class QUnixPrintWidgetPrivate;
146
147 class QUnixPrintWidget : public QWidget
148 {
149     Q_OBJECT
150
151 public:
152     explicit QUnixPrintWidget(QPrinter *printer, QWidget *parent = 0);
153     ~QUnixPrintWidget();
154     void updatePrinter();
155
156 private:
157     friend class QPrintDialogPrivate;
158     friend class QUnixPrintWidgetPrivate;
159     QUnixPrintWidgetPrivate *d;
160     Q_PRIVATE_SLOT(d, void _q_printerChanged(int))
161     Q_PRIVATE_SLOT(d, void _q_btnBrowseClicked())
162     Q_PRIVATE_SLOT(d, void _q_btnPropertiesClicked())
163 };
164
165 class QUnixPrintWidgetPrivate
166 {
167 public:
168     QUnixPrintWidgetPrivate(QUnixPrintWidget *q);
169     ~QUnixPrintWidgetPrivate();
170
171     /// copy printer properties to the widget
172     void applyPrinterProperties(QPrinter *p);
173     bool checkFields();
174     void setupPrinter();
175     void setOptionsPane(QPrintDialogPrivate *pane);
176 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
177     void setCupsProperties();
178 #endif
179
180 // slots
181     void _q_printerChanged(int index);
182     void _q_btnPropertiesClicked();
183     void _q_btnBrowseClicked();
184
185     QUnixPrintWidget * const parent;
186     QPrintPropertiesDialog *propertiesDialog;
187     Ui::QPrintWidget widget;
188     QAbstractPrintDialog * q;
189     QPrinter *printer;
190     void updateWidget();
191
192 private:
193     QPrintDialogPrivate *optionsPane;
194     bool filePrintersAdded;
195 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
196     QCUPSSupport* cups;
197     int cupsPrinterCount;
198     const cups_dest_t* cupsPrinters;
199     const ppd_file_t* cupsPPD;
200 #endif
201 };
202
203 class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
204 {
205     Q_DECLARE_PUBLIC(QPrintDialog)
206     Q_DECLARE_TR_FUNCTIONS(QPrintDialog)
207 public:
208     QPrintDialogPrivate();
209     ~QPrintDialogPrivate();
210
211     void init();
212     /// copy printer properties to the widget
213     void applyPrinterProperties(QPrinter *p);
214
215 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
216     void selectPrinter(QCUPSSupport *cups);
217 #endif
218
219     void _q_chbPrintLastFirstToggled(bool);
220 #ifndef QT_NO_MESSAGEBOX
221     void _q_checkFields();
222 #endif
223     void _q_collapseOrExpandDialog();
224
225     void setupPrinter();
226     void updateWidgets();
227
228     virtual void setTabs(const QList<QWidget*> &tabs);
229
230     Ui::QPrintSettingsOutput options;
231     QUnixPrintWidget *top;
232     QWidget *bottom;
233     QDialogButtonBox *buttons;
234     QPushButton *collapseButton;
235 };
236
237 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
238 class QOptionTreeItem
239 {
240 public:
241     enum ItemType { Root, Group, Option, Choice };
242
243     QOptionTreeItem(ItemType t, int i, const void* p, const char* desc, QOptionTreeItem* pi)
244         : type(t),
245           index(i),
246           ptr(p),
247           description(desc),
248           selected(-1),
249           selDescription(0),
250           parentItem(pi) {}
251
252     ~QOptionTreeItem() {
253         while (!childItems.isEmpty())
254             delete childItems.takeFirst();
255     }
256
257     ItemType type;
258     int index;
259     const void* ptr;
260     const char* description;
261     int selected;
262     const char* selDescription;
263     QOptionTreeItem* parentItem;
264     QList<QOptionTreeItem*> childItems;
265 };
266
267 class QPPDOptionsModel : public QAbstractItemModel
268 {
269     friend class QPPDOptionsEditor;
270 public:
271     QPPDOptionsModel(QCUPSSupport *cups, QObject *parent = 0);
272     ~QPPDOptionsModel();
273
274     int columnCount(const QModelIndex& parent = QModelIndex()) const;
275     int rowCount(const QModelIndex& parent = QModelIndex()) const;
276     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
277     QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
278     QModelIndex parent(const QModelIndex& index) const;
279     Qt::ItemFlags flags(const QModelIndex& index) const;
280     QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
281
282     QOptionTreeItem* rootItem;
283     QCUPSSupport *cups;
284     const ppd_file_t* ppd;
285     void parseItems();
286     void parseGroups(QOptionTreeItem* parent);
287     void parseOptions(QOptionTreeItem* parent);
288     void parseChoices(QOptionTreeItem* parent);
289 };
290
291 class QPPDOptionsEditor : public QStyledItemDelegate
292 {
293     Q_OBJECT
294 public:
295     QPPDOptionsEditor(QObject* parent = 0) : QStyledItemDelegate(parent) {}
296     ~QPPDOptionsEditor() {}
297
298     QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
299     void setEditorData(QWidget* editor, const QModelIndex& index) const;
300     void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
301
302 private slots:
303     void cbChanged(int index);
304
305 };
306
307 #endif
308
309 ////////////////////////////////////////////////////////////////////////////////
310 ////////////////////////////////////////////////////////////////////////////////
311
312 /*
313
314     QPrintPropertiesDialog
315
316     Dialog displayed when clicking on Properties button to allow editing of Page
317     and Advanced tabs.
318
319 */
320
321 QPrintPropertiesDialog::QPrintPropertiesDialog(QAbstractPrintDialog *parent)
322     : QDialog(parent)
323 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
324     , m_cups(0), m_cupsOptionsModel(0)
325 #endif
326 {
327     QVBoxLayout *lay = new QVBoxLayout(this);
328     this->setLayout(lay);
329     QWidget *content = new QWidget(this);
330     widget.setupUi(content);
331     m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
332     lay->addWidget(content);
333     lay->addWidget(m_buttons);
334
335     connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
336     connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
337 }
338
339 QPrintPropertiesDialog::~QPrintPropertiesDialog()
340 {
341 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
342     delete m_cupsOptionsModel;
343 #else
344     delete widget.cupsPropertiesPage;
345 #endif
346 }
347
348 void QPrintPropertiesDialog::applyPrinterProperties(QPrinter *p)
349 {
350     widget.pageSetup->setPrinter(p);
351 }
352
353 void QPrintPropertiesDialog::setupPrinter() const
354 {
355     widget.pageSetup->setupPrinter();
356
357 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
358     QPPDOptionsModel* model = static_cast<QPPDOptionsModel*>(widget.treeView->model());
359     if (model) {
360         QOptionTreeItem* rootItem = model->rootItem;
361         QList<const ppd_option_t*> options;
362         QList<const char*> markedOptions;
363
364         addItemToOptions(rootItem, options, markedOptions);
365         model->cups->saveOptions(options, markedOptions);
366     }
367 #endif
368 }
369
370 void QPrintPropertiesDialog::selectPrinter()
371 {
372 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
373     widget.pageSetup->selectPrinter(m_cups);
374     widget.treeView->setModel(0);
375     if (m_cups && QCUPSSupport::isAvailable()) {
376
377         if (m_cupsOptionsModel == 0) {
378             m_cupsOptionsModel = new QPPDOptionsModel(m_cups);
379
380             widget.treeView->setItemDelegate(new QPPDOptionsEditor(this));
381         } else {
382             // update the model
383             m_cupsOptionsModel->parseItems();
384         }
385
386         if (m_cupsOptionsModel->rowCount() > 0) {
387             widget.treeView->setModel(m_cupsOptionsModel);
388
389             for (int i = 0; i < m_cupsOptionsModel->rowCount(); ++i)
390                 widget.treeView->expand(m_cupsOptionsModel->index(i,0));
391
392             widget.tabs->setTabEnabled(1, true); // enable the advanced tab
393         } else {
394             widget.tabs->setTabEnabled(1, false);
395         }
396
397     } else
398 #endif
399     {
400         widget.cupsPropertiesPage->setEnabled(false);
401         widget.pageSetup->selectPrinter(0);
402     }
403 }
404
405 void QPrintPropertiesDialog::selectPdfPsPrinter(const QPrinter *p)
406 {
407     widget.treeView->setModel(0);
408     widget.pageSetup->selectPdfPsPrinter(p);
409     widget.tabs->setTabEnabled(1, false); // disable the advanced tab
410 }
411
412 void QPrintPropertiesDialog::showEvent(QShowEvent* event)
413 {
414     widget.treeView->resizeColumnToContents(0);
415     event->accept();
416 }
417
418 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
419 void QPrintPropertiesDialog::addItemToOptions(QOptionTreeItem *parent, QList<const ppd_option_t*>& options, QList<const char*>& markedOptions) const
420 {
421     for (int i = 0; i < parent->childItems.count(); ++i) {
422         QOptionTreeItem *itm = parent->childItems.at(i);
423         if (itm->type == QOptionTreeItem::Option) {
424             const ppd_option_t* opt = reinterpret_cast<const ppd_option_t*>(itm->ptr);
425             options << opt;
426             if (qstrcmp(opt->defchoice, opt->choices[itm->selected].choice) != 0) {
427                 markedOptions << opt->keyword << opt->choices[itm->selected].choice;
428             }
429         } else {
430             addItemToOptions(itm, options, markedOptions);
431         }
432     }
433 }
434 #endif
435
436 ////////////////////////////////////////////////////////////////////////////////
437 ////////////////////////////////////////////////////////////////////////////////
438
439 /*
440
441     QPrintDialogPrivate
442
443     The lower half of the Print Dialog containing the Copies and Options
444     tabs that expands when the Options button is selected.
445
446 */
447
448 QPrintDialogPrivate::QPrintDialogPrivate()
449     : top(0), bottom(0), buttons(0), collapseButton(0)
450 {
451 }
452
453 QPrintDialogPrivate::~QPrintDialogPrivate()
454 {
455 }
456
457 void QPrintDialogPrivate::init()
458 {
459     Q_Q(QPrintDialog);
460
461     top = new QUnixPrintWidget(0, q);
462     bottom = new QWidget(q);
463     options.setupUi(bottom);
464     options.color->setIconSize(QSize(32, 32));
465     options.color->setIcon(QIcon(QLatin1String(":/qt-project.org/dialogs/qprintdialog/images/status-color.png")));
466     options.grayscale->setIconSize(QSize(32, 32));
467     options.grayscale->setIcon(QIcon(QLatin1String(":/qt-project.org/dialogs/qprintdialog/images/status-gray-scale.png")));
468     top->d->setOptionsPane(this);
469
470     buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, q);
471     collapseButton = new QPushButton(QPrintDialog::tr("&Options >>"), buttons);
472     buttons->addButton(collapseButton, QDialogButtonBox::ResetRole);
473     bottom->setVisible(false);
474
475     QPushButton *printButton = buttons->button(QDialogButtonBox::Ok);
476     printButton->setText(QPrintDialog::tr("&Print"));
477     printButton->setDefault(true);
478
479     QVBoxLayout *lay = new QVBoxLayout(q);
480     q->setLayout(lay);
481     lay->addWidget(top);
482     lay->addWidget(bottom);
483     lay->addWidget(buttons);
484
485     QPrinter* p = q->printer();
486
487     applyPrinterProperties(p);
488
489 #ifdef QT_NO_MESSAGEBOX
490     QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(accept()));
491 #else
492     QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(_q_checkFields()));
493 #endif
494     QObject::connect(buttons, SIGNAL(rejected()), q, SLOT(reject()));
495
496     QObject::connect(options.reverse, SIGNAL(toggled(bool)),
497                      q, SLOT(_q_chbPrintLastFirstToggled(bool)));
498
499     QObject::connect(collapseButton, SIGNAL(released()), q, SLOT(_q_collapseOrExpandDialog()));
500 }
501
502 void QPrintDialogPrivate::applyPrinterProperties(QPrinter *p)
503 {
504     if (p->colorMode() == QPrinter::Color)
505         options.color->setChecked(true);
506     else
507         options.grayscale->setChecked(true);
508
509     switch(p->duplex()) {
510     case QPrinter::DuplexNone:
511         options.noDuplex->setChecked(true); break;
512     case QPrinter::DuplexLongSide:
513     case QPrinter::DuplexAuto:
514         options.duplexLong->setChecked(true); break;
515     case QPrinter::DuplexShortSide:
516         options.duplexShort->setChecked(true); break;
517     }
518     options.copies->setValue(p->copyCount());
519     options.collate->setChecked(p->collateCopies());
520     options.reverse->setChecked(p->pageOrder() == QPrinter::LastPageFirst);
521     top->d->applyPrinterProperties(p);
522 }
523
524 void QPrintDialogPrivate::_q_chbPrintLastFirstToggled(bool checked)
525 {
526     Q_Q(QPrintDialog);
527     if (checked)
528         q->printer()->setPageOrder(QPrinter::LastPageFirst);
529     else
530         q->printer()->setPageOrder(QPrinter::FirstPageFirst);
531 }
532
533 void QPrintDialogPrivate::_q_collapseOrExpandDialog()
534 {
535     int collapseHeight = 0;
536     Q_Q(QPrintDialog);
537     QWidget *widgetToHide = bottom;
538     if (widgetToHide->isVisible()) {
539         collapseButton->setText(QPrintDialog::tr("&Options >>"));
540         collapseHeight = widgetToHide->y() + widgetToHide->height() - (top->y() + top->height());
541     }
542     else
543         collapseButton->setText(QPrintDialog::tr("&Options <<"));
544     widgetToHide->setVisible(! widgetToHide->isVisible());
545     if (! widgetToHide->isVisible()) { // make it shrink
546         q->layout()->activate();
547         q->resize( QSize(q->width(), q->height() - collapseHeight) );
548     }
549 }
550
551 #ifndef QT_NO_MESSAGEBOX
552 void QPrintDialogPrivate::_q_checkFields()
553 {
554     Q_Q(QPrintDialog);
555     if (top->d->checkFields())
556         q->accept();
557 }
558 #endif // QT_NO_MESSAGEBOX
559
560 void QPrintDialogPrivate::setupPrinter()
561 {
562     Q_Q(QPrintDialog);
563     QPrinter* p = q->printer();
564
565     if (options.duplex->isEnabled()) {
566         if (options.noDuplex->isChecked())
567             p->setDuplex(QPrinter::DuplexNone);
568         else if (options.duplexLong->isChecked())
569             p->setDuplex(QPrinter::DuplexLongSide);
570         else
571             p->setDuplex(QPrinter::DuplexShortSide);
572     }
573
574     p->setColorMode( options.color->isChecked() ? QPrinter::Color : QPrinter::GrayScale );
575
576     // print range
577     if (options.printAll->isChecked()) {
578         p->setPrintRange(QPrinter::AllPages);
579         p->setFromTo(0,0);
580     } else if (options.printSelection->isChecked()) {
581         p->setPrintRange(QPrinter::Selection);
582         p->setFromTo(0,0);
583     } else if (options.printCurrentPage->isChecked()) {
584         p->setPrintRange(QPrinter::CurrentPage);
585         p->setFromTo(0,0);
586     } else if (options.printRange->isChecked()) {
587         p->setPrintRange(QPrinter::PageRange);
588         p->setFromTo(options.from->value(), qMax(options.from->value(), options.to->value()));
589     }
590
591     // copies
592     p->setCopyCount(options.copies->value());
593     p->setCollateCopies(options.collate->isChecked());
594
595     top->d->setupPrinter();
596 }
597
598 void QPrintDialogPrivate::updateWidgets()
599 {
600     Q_Q(QPrintDialog);
601     options.gbPrintRange->setVisible(q->isOptionEnabled(QPrintDialog::PrintPageRange) ||
602                                      q->isOptionEnabled(QPrintDialog::PrintSelection) ||
603                                      q->isOptionEnabled(QPrintDialog::PrintCurrentPage));
604
605     options.printRange->setEnabled(q->isOptionEnabled(QPrintDialog::PrintPageRange));
606     options.printSelection->setVisible(q->isOptionEnabled(QPrintDialog::PrintSelection));
607     options.printCurrentPage->setVisible(q->isOptionEnabled(QPrintDialog::PrintCurrentPage));
608     options.collate->setVisible(q->isOptionEnabled(QPrintDialog::PrintCollateCopies));
609
610     switch (q->printRange()) {
611     case QPrintDialog::AllPages:
612         options.printAll->setChecked(true);
613         break;
614     case QPrintDialog::Selection:
615         options.printSelection->setChecked(true);
616         break;
617     case QPrintDialog::PageRange:
618         options.printRange->setChecked(true);
619         break;
620     case QPrintDialog::CurrentPage:
621         if (q->isOptionEnabled(QPrintDialog::PrintCurrentPage))
622             options.printCurrentPage->setChecked(true);
623         break;
624     default:
625         break;
626     }
627     const int minPage = qMax(1, qMin(q->minPage() , q->maxPage()));
628     const int maxPage = qMax(1, q->maxPage() == INT_MAX ? 9999 : q->maxPage());
629
630     options.from->setMinimum(minPage);
631     options.to->setMinimum(minPage);
632     options.from->setMaximum(maxPage);
633     options.to->setMaximum(maxPage);
634
635     options.from->setValue(q->fromPage());
636     options.to->setValue(q->toPage());
637     top->d->updateWidget();
638 }
639
640 void QPrintDialogPrivate::setTabs(const QList<QWidget*> &tabWidgets)
641 {
642     while(options.tabs->count() > 2)
643         delete options.tabs->widget(2);
644
645     QList<QWidget*>::ConstIterator iter = tabWidgets.begin();
646     while(iter != tabWidgets.constEnd()) {
647         QWidget *tab = *iter;
648         options.tabs->addTab(tab, tab->windowTitle());
649         ++iter;
650     }
651 }
652
653 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
654 void QPrintDialogPrivate::selectPrinter(QCUPSSupport *cups)
655 {
656     options.duplex->setEnabled(cups && cups->ppdOption("Duplex"));
657 }
658 #endif
659
660 ////////////////////////////////////////////////////////////////////////////////
661 ////////////////////////////////////////////////////////////////////////////////
662
663 /*
664
665     QPrintDialog
666
667     The main Print Dialog.
668
669 */
670
671 QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
672     : QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent)
673 {
674     Q_D(QPrintDialog);
675     d->init();
676 }
677
678 /*!
679     Constructs a print dialog with the given \a parent.
680 */
681 QPrintDialog::QPrintDialog(QWidget *parent)
682     : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent)
683 {
684     Q_D(QPrintDialog);
685     d->init();
686 }
687
688 QPrintDialog::~QPrintDialog()
689 {
690 }
691
692 void QPrintDialog::setVisible(bool visible)
693 {
694     Q_D(QPrintDialog);
695
696     if (visible)
697         d->updateWidgets();
698
699     QAbstractPrintDialog::setVisible(visible);
700 }
701
702 int QPrintDialog::exec()
703 {
704     return QDialog::exec();
705 }
706
707 void QPrintDialog::accept()
708 {
709     Q_D(QPrintDialog);
710     d->setupPrinter();
711     QDialog::accept();
712 }
713
714 ////////////////////////////////////////////////////////////////////////////////
715 ////////////////////////////////////////////////////////////////////////////////
716
717 /*
718
719     QUnixPrintWidget && QUnixPrintWidgetPrivate
720
721     The upper half of the Print Dialog containing the Printer Selection widgets
722
723 */
724
725 #if defined (Q_OS_UNIX)
726
727 /*! \internal
728 */
729 QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p)
730     : parent(p), propertiesDialog(0), printer(0), optionsPane(0), filePrintersAdded(false)
731 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
732     , cups(0), cupsPrinterCount(0), cupsPrinters(0), cupsPPD(0)
733 #endif
734 {
735     q = 0;
736     if (parent)
737         q = qobject_cast<QAbstractPrintDialog*> (parent->parent());
738
739     widget.setupUi(parent);
740
741     int currentPrinterIndex = 0;
742 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
743     cups = new QCUPSSupport;
744     if (QCUPSSupport::isAvailable()) {
745         cupsPPD = cups->currentPPD();
746         cupsPrinterCount = cups->availablePrintersCount();
747         cupsPrinters = cups->availablePrinters();
748
749         for (int i = 0; i < cupsPrinterCount; ++i) {
750             QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
751             if (cupsPrinters[i].instance)
752                 printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
753
754             widget.printers->addItem(printerName);
755             if (cupsPrinters[i].is_default)
756                 widget.printers->setCurrentIndex(i);
757         }
758         // the model depends on valid ppd. so before enabling the
759         // properties button we make sure the ppd is in fact valid.
760         if (cupsPrinterCount && cups->currentPPD()) {
761             widget.properties->setEnabled(true);
762         }
763         currentPrinterIndex = cups->currentPrinterIndex();
764     }
765 #endif
766
767 #if !defined(QT_NO_FILESYSTEMMODEL) && !defined(QT_NO_COMPLETER)
768     QFileSystemModel *fsm = new QFileSystemModel(widget.filename);
769     fsm->setRootPath(QDir::homePath());
770     widget.filename->setCompleter(new QCompleter(fsm, widget.filename));
771 #endif
772     _q_printerChanged(currentPrinterIndex);
773
774     QObject::connect(widget.printers, SIGNAL(currentIndexChanged(int)),
775                      parent, SLOT(_q_printerChanged(int)));
776     QObject::connect(widget.fileBrowser, SIGNAL(clicked()), parent, SLOT(_q_btnBrowseClicked()));
777     QObject::connect(widget.properties, SIGNAL(clicked()), parent, SLOT(_q_btnPropertiesClicked()));
778
779     // disable features that QPrinter does not yet support.
780     widget.preview->setVisible(false);
781 }
782
783 void QUnixPrintWidgetPrivate::updateWidget()
784 {
785     const bool printToFile = q == 0 || q->isOptionEnabled(QPrintDialog::PrintToFile);
786     if (printToFile && !filePrintersAdded) {
787         if (widget.printers->count())
788             widget.printers->insertSeparator(widget.printers->count());
789         widget.printers->addItem(QPrintDialog::tr("Print to File (PDF)"));
790         filePrintersAdded = true;
791     }
792     if (!printToFile && filePrintersAdded) {
793         widget.printers->removeItem(widget.printers->count()-1);
794         widget.printers->removeItem(widget.printers->count()-1);
795         if (widget.printers->count())
796             widget.printers->removeItem(widget.printers->count()-1); // remove separator
797         filePrintersAdded = false;
798     }
799     if (printer && filePrintersAdded && (printer->outputFormat() != QPrinter::NativeFormat
800                                          || printer->printerName().isEmpty()))
801     {
802         if (printer->outputFormat() == QPrinter::PdfFormat)
803             widget.printers->setCurrentIndex(widget.printers->count() - 1);
804         widget.filename->setEnabled(true);
805         widget.lOutput->setEnabled(true);
806     }
807
808     widget.filename->setVisible(printToFile);
809     widget.lOutput->setVisible(printToFile);
810     widget.fileBrowser->setVisible(printToFile);
811
812     widget.properties->setVisible(q->isOptionEnabled(QAbstractPrintDialog::PrintShowPageSize));
813 }
814
815 QUnixPrintWidgetPrivate::~QUnixPrintWidgetPrivate()
816 {
817 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
818     delete cups;
819 #endif
820 }
821
822 void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
823 {
824     if (index < 0)
825         return;
826     const int printerCount = widget.printers->count();
827     widget.filename->setEnabled(false);
828     widget.lOutput->setEnabled(false);
829
830     if (filePrintersAdded) {
831         Q_ASSERT(index != printerCount - 2); // separator
832         if (index == printerCount - 1) { // PDF
833             widget.location->setText(QPrintDialog::tr("Local file"));
834             widget.type->setText(QPrintDialog::tr("Write PDF file"));
835             widget.properties->setEnabled(true);
836             widget.filename->setEnabled(true);
837             QString filename = widget.filename->text();
838             QString suffix = QFileInfo(filename).suffix();
839             widget.filename->setText(filename);
840             widget.lOutput->setEnabled(true);
841             if (propertiesDialog)
842                 propertiesDialog->selectPdfPsPrinter(printer);
843 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
844             if (optionsPane)
845                 optionsPane->selectPrinter(0);
846 #endif
847             return;
848         }
849     }
850
851     widget.location->setText(QString());
852 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
853     if (QCUPSSupport::isAvailable()) {
854         cups->setCurrentPrinter(index);
855
856         const cups_option_t *opt = cups->printerOption(QString::fromLatin1("printer-location"));
857         QString location;
858         if (opt)
859             location = QString::fromLocal8Bit(opt->value);
860         widget.location->setText(location);
861
862         cupsPPD = cups->currentPPD();
863         // set printer type line
864         QString type;
865         if (cupsPPD)
866             type = QString::fromLocal8Bit(cupsPPD->manufacturer) + QLatin1String(" - ") + QString::fromLocal8Bit(cupsPPD->modelname);
867         widget.type->setText(type);
868         if (propertiesDialog)
869             propertiesDialog->selectPrinter();
870         if (optionsPane)
871             optionsPane->selectPrinter(cups);
872     } else {
873         if (optionsPane)
874             optionsPane->selectPrinter(0);
875     }
876 #endif
877 }
878
879 void QUnixPrintWidgetPrivate::setOptionsPane(QPrintDialogPrivate *pane)
880 {
881     optionsPane = pane;
882     if (optionsPane)
883         _q_printerChanged(widget.printers->currentIndex());
884 }
885
886 void QUnixPrintWidgetPrivate::_q_btnBrowseClicked()
887 {
888     QString filename = widget.filename->text();
889 #ifndef QT_NO_FILEDIALOG
890     filename = QFileDialog::getSaveFileName(parent, QPrintDialog::tr("Print To File ..."), filename,
891                                             QString(), 0, QFileDialog::DontConfirmOverwrite);
892 #else
893     filename.clear();
894 #endif
895     if (!filename.isEmpty()) {
896         widget.filename->setText(filename);
897         widget.printers->setCurrentIndex(widget.printers->count() - 1); // the pdf one
898     }
899 }
900
901 void QUnixPrintWidgetPrivate::applyPrinterProperties(QPrinter *p)
902 {
903     if (p == 0)
904         return;
905     printer = p;
906     if (p->outputFileName().isEmpty()) {
907         QString home = QDir::homePath();
908         QString cur = QDir::currentPath();
909         if (home.at(home.length()-1) != QLatin1Char('/'))
910             home += QLatin1Char('/');
911         if (cur.at(cur.length()-1) != QLatin1Char('/'))
912             cur += QLatin1Char('/');
913         if (cur.left(home.length()) != home)
914             cur = home;
915 #ifdef Q_WS_X11
916         if (p->docName().isEmpty()) {
917             cur += QLatin1String("print.pdf");
918         } else {
919             QRegExp re(QString::fromLatin1("(.*)\\.\\S+"));
920             if (re.exactMatch(p->docName()))
921                 cur += re.cap(1);
922             else
923                 cur += p->docName();
924             cur += QLatin1String(".pdf");
925         }
926 #endif
927         widget.filename->setText(cur);
928     }
929     else
930         widget.filename->setText( p->outputFileName() );
931     QString printer = p->printerName();
932     if (!printer.isEmpty()) {
933         for (int i = 0; i < widget.printers->count(); ++i) {
934             if (widget.printers->itemText(i) == printer) {
935                 widget.printers->setCurrentIndex(i);
936                 break;
937             }
938         }
939     }
940     // PDF and PS printers are not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget
941
942     if (propertiesDialog)
943         propertiesDialog->applyPrinterProperties(p);
944 }
945
946 #ifndef QT_NO_MESSAGEBOX
947 bool QUnixPrintWidgetPrivate::checkFields()
948 {
949     if (widget.filename->isEnabled()) {
950         QString file = widget.filename->text();
951         QFile f(file);
952         QFileInfo fi(f);
953         bool exists = fi.exists();
954         bool opened = false;
955         if (exists && fi.isDir()) {
956             QMessageBox::warning(q, q->windowTitle(),
957                             QPrintDialog::tr("%1 is a directory.\nPlease choose a different file name.").arg(file));
958             return false;
959         } else if ((exists && !fi.isWritable()) || !(opened = f.open(QFile::Append))) {
960             QMessageBox::warning(q, q->windowTitle(),
961                             QPrintDialog::tr("File %1 is not writable.\nPlease choose a different file name.").arg(file));
962             return false;
963         } else if (exists) {
964             int ret = QMessageBox::question(q, q->windowTitle(),
965                                             QPrintDialog::tr("%1 already exists.\nDo you want to overwrite it?").arg(file),
966                                             QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
967             if (ret == QMessageBox::No)
968                 return false;
969         }
970         if (opened) {
971             f.close();
972             if (!exists)
973                 f.remove();
974         }
975     }
976
977     // Every test passed. Accept the dialog.
978     return true;
979 }
980 #endif // QT_NO_MESSAGEBOX
981
982 void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked()
983 {
984     if (!propertiesDialog) {
985         propertiesDialog = new QPrintPropertiesDialog(q);
986         propertiesDialog->setResult(QDialog::Rejected);
987     }
988
989     if (propertiesDialog->result() == QDialog::Rejected) {
990 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
991         propertiesDialog->setCups(cups);
992 #endif
993         propertiesDialog->applyPrinterProperties(q->printer());
994
995         if (q->isOptionEnabled(QPrintDialog::PrintToFile)
996             && (widget.printers->currentIndex() == widget.printers->count() - 1)) // PDF
997             propertiesDialog->selectPdfPsPrinter(q->printer());
998         else
999             propertiesDialog->selectPrinter();
1000     }
1001     propertiesDialog->exec();
1002 }
1003
1004 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
1005 void QUnixPrintWidgetPrivate::setCupsProperties()
1006 {
1007     if (cups && QCUPSSupport::isAvailable() && cups->pageSizes()) {
1008         QPrintEngine *engine = printer->printEngine();
1009         const ppd_option_t* pageSizes = cups->pageSizes();
1010         QByteArray cupsPageSize;
1011         for (int i = 0; i < pageSizes->num_choices; ++i) {
1012             if (static_cast<int>(pageSizes->choices[i].marked) == 1)
1013                 cupsPageSize = pageSizes->choices[i].choice;
1014         }
1015         engine->setProperty(PPK_CupsStringPageSize, QString::fromLatin1(cupsPageSize));
1016         engine->setProperty(PPK_CupsOptions, cups->options());
1017
1018         QRect pageRect = cups->pageRect(cupsPageSize);
1019         engine->setProperty(PPK_CupsPageRect, pageRect);
1020
1021         QRect paperRect = cups->paperRect(cupsPageSize);
1022         engine->setProperty(PPK_CupsPaperRect, paperRect);
1023
1024         for (int ps = 0; ps < QPrinter::NPageSize; ++ps) {
1025             QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
1026             if (size.width == paperRect.width() && size.height == paperRect.height())
1027                 printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
1028         }
1029     }
1030 }
1031 #endif
1032
1033 void QUnixPrintWidgetPrivate::setupPrinter()
1034 {
1035     const int printerCount = widget.printers->count();
1036     const int index = widget.printers->currentIndex();
1037
1038     if (filePrintersAdded && index == printerCount - 1) { // PDF
1039         printer->setPrinterName(QString());
1040         Q_ASSERT(index != printerCount - 2); // separator
1041         printer->setOutputFormat(QPrinter::PdfFormat);
1042         QString path = widget.filename->text();
1043         if (QDir::isRelativePath(path))
1044             path = QDir::homePath() + QDir::separator() + path;
1045         printer->setOutputFileName(path);
1046     }
1047     else {
1048         printer->setPrinterName(widget.printers->currentText());
1049         printer->setOutputFileName(QString());
1050     }
1051
1052     if (propertiesDialog && propertiesDialog->result() == QDialog::Accepted)
1053         propertiesDialog->setupPrinter();
1054 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
1055     if (!propertiesDialog)
1056         setCupsProperties();
1057 #endif
1058 }
1059
1060 /*! \internal
1061 */
1062 QUnixPrintWidget::QUnixPrintWidget(QPrinter *printer, QWidget *parent)
1063     : QWidget(parent), d(new QUnixPrintWidgetPrivate(this))
1064 {
1065     d->applyPrinterProperties(printer);
1066 }
1067
1068 /*! \internal
1069 */
1070 QUnixPrintWidget::~QUnixPrintWidget()
1071 {
1072     delete d;
1073 }
1074
1075 /*! \internal
1076
1077     Updates the printer with the states held in the QUnixPrintWidget.
1078 */
1079 void QUnixPrintWidget::updatePrinter()
1080 {
1081     d->setupPrinter();
1082 }
1083
1084 ////////////////////////////////////////////////////////////////////////////////
1085 ////////////////////////////////////////////////////////////////////////////////
1086
1087 /*
1088
1089     QPPDOptionsModel
1090
1091     Holds the PPD Options for the printer.
1092
1093 */
1094
1095 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
1096
1097 QPPDOptionsModel::QPPDOptionsModel(QCUPSSupport *c, QObject *parent)
1098     : QAbstractItemModel(parent), rootItem(0), cups(c), ppd(c->currentPPD())
1099 {
1100     parseItems();
1101 }
1102
1103 QPPDOptionsModel::~QPPDOptionsModel()
1104 {
1105 }
1106
1107 int QPPDOptionsModel::columnCount(const QModelIndex&) const
1108 {
1109     return 2;
1110 }
1111
1112 int QPPDOptionsModel::rowCount(const QModelIndex& parent) const
1113 {
1114     QOptionTreeItem* itm;
1115     if (!parent.isValid())
1116         itm = rootItem;
1117     else
1118         itm = reinterpret_cast<QOptionTreeItem*>(parent.internalPointer());
1119
1120     if (itm->type == QOptionTreeItem::Option)
1121         return 0;
1122
1123     return itm->childItems.count();
1124 }
1125
1126 QVariant QPPDOptionsModel::data(const QModelIndex& index, int role) const
1127 {
1128     switch(role) {
1129         case Qt::FontRole: {
1130             QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
1131             if (itm && itm->type == QOptionTreeItem::Group){
1132                 QFont font = QApplication::font();
1133                 font.setBold(true);
1134                 return QVariant(font);
1135             }
1136             return QVariant();
1137         }
1138         break;
1139
1140         case Qt::DisplayRole: {
1141             QOptionTreeItem* itm;
1142             if (!index.isValid())
1143                 itm = rootItem;
1144             else
1145                 itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
1146
1147             if (index.column() == 0)
1148                 return cups->unicodeString(itm->description);
1149             else if (itm->type == QOptionTreeItem::Option && itm->selected > -1)
1150                 return cups->unicodeString(itm->selDescription);
1151             else
1152                 return QVariant();
1153         }
1154         break;
1155
1156         default:
1157             return QVariant();
1158     }
1159     if (role != Qt::DisplayRole)
1160         return QVariant();
1161 }
1162
1163 QModelIndex QPPDOptionsModel::index(int row, int column, const QModelIndex& parent) const
1164 {
1165     QOptionTreeItem* itm;
1166     if (!parent.isValid())
1167         itm = rootItem;
1168     else
1169         itm = reinterpret_cast<QOptionTreeItem*>(parent.internalPointer());
1170
1171     return createIndex(row, column, itm->childItems.at(row));
1172 }
1173
1174
1175 QModelIndex QPPDOptionsModel::parent(const QModelIndex& index) const
1176 {
1177     if (!index.isValid())
1178         return QModelIndex();
1179
1180     QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
1181
1182     if (itm->parentItem && itm->parentItem != rootItem)
1183         return createIndex(itm->parentItem->index, 0, itm->parentItem);
1184     else
1185         return QModelIndex();
1186 }
1187
1188 Qt::ItemFlags QPPDOptionsModel::flags(const QModelIndex& index) const
1189 {
1190     if (!index.isValid() || reinterpret_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Group)
1191         return Qt::ItemIsEnabled;
1192
1193     if (index.column() == 1)
1194         return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
1195
1196     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
1197 }
1198
1199 void QPPDOptionsModel::parseItems()
1200 {
1201     emit layoutAboutToBeChanged();
1202     ppd = cups->currentPPD();
1203     delete rootItem;
1204     rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, "Root Item", 0);
1205     parseGroups(rootItem);
1206     emit layoutChanged();
1207 }
1208
1209 void QPPDOptionsModel::parseGroups(QOptionTreeItem* parent)
1210 {
1211     if (parent->type == QOptionTreeItem::Root) {
1212
1213         const ppd_file_t* ppdFile = reinterpret_cast<const ppd_file_t*>(parent->ptr);
1214
1215         if (ppdFile) {
1216             for (int i = 0; i < ppdFile->num_groups; ++i) {
1217                 QOptionTreeItem* group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppdFile->groups[i], ppdFile->groups[i].text, parent);
1218                 parent->childItems.append(group);
1219                 parseGroups(group); // parse possible subgroups
1220                 parseOptions(group); // parse options
1221             }
1222         }
1223     } else if (parent->type == QOptionTreeItem::Group) {
1224
1225         const ppd_group_t* group = reinterpret_cast<const ppd_group_t*>(parent->ptr);
1226
1227         if (group) {
1228             for (int i = 0; i < group->num_subgroups; ++i) {
1229                 QOptionTreeItem* subgroup = new QOptionTreeItem(QOptionTreeItem::Group, i, &group->subgroups[i], group->subgroups[i].text, parent);
1230                 parent->childItems.append(subgroup);
1231                 parseGroups(subgroup); // parse possible subgroups
1232                 parseOptions(subgroup); // parse options
1233             }
1234         }
1235     }
1236 }
1237
1238 void QPPDOptionsModel::parseOptions(QOptionTreeItem* parent)
1239 {
1240     const ppd_group_t* group = reinterpret_cast<const ppd_group_t*>(parent->ptr);
1241     for (int i = 0; i < group->num_options; ++i) {
1242         QOptionTreeItem* opt = new QOptionTreeItem(QOptionTreeItem::Option, i, &group->options[i], group->options[i].text, parent);
1243         parent->childItems.append(opt);
1244         parseChoices(opt);
1245     }
1246 }
1247
1248 void QPPDOptionsModel::parseChoices(QOptionTreeItem* parent)
1249 {
1250     const ppd_option_t* option = reinterpret_cast<const ppd_option_t*>(parent->ptr);
1251     bool marked = false;
1252     for (int i = 0; i < option->num_choices; ++i) {
1253         QOptionTreeItem* choice = new QOptionTreeItem(QOptionTreeItem::Choice, i, &option->choices[i], option->choices[i].text, parent);
1254         if (static_cast<int>(option->choices[i].marked) == 1) {
1255             parent->selected = i;
1256             parent->selDescription = option->choices[i].text;
1257             marked = true;
1258         } else if (!marked && qstrcmp(option->choices[i].choice, option->defchoice) == 0) {
1259             parent->selected = i;
1260             parent->selDescription = option->choices[i].text;
1261         }
1262         parent->childItems.append(choice);
1263     }
1264 }
1265
1266 QVariant QPPDOptionsModel::headerData(int section, Qt::Orientation, int role) const
1267 {
1268     if (role != Qt::DisplayRole)
1269         return QVariant();
1270
1271     switch(section){
1272         case 0:
1273             return QVariant(QApplication::translate("QPPDOptionsModel", "Name"));
1274         case 1:
1275             return QVariant(QApplication::translate("QPPDOptionsModel", "Value"));
1276         default:
1277             return QVariant();
1278     }
1279 }
1280
1281 ////////////////////////////////////////////////////////////////////////////////
1282 ////////////////////////////////////////////////////////////////////////////////
1283
1284 /*
1285
1286     QPPDOptionsEditor
1287
1288     Edits the PPD Options for the printer.
1289
1290 */
1291
1292 QWidget* QPPDOptionsEditor::createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const
1293 {
1294     if (index.column() == 1 && reinterpret_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Option)
1295         return new QComboBox(parent);
1296     else
1297         return 0;
1298 }
1299
1300 void QPPDOptionsEditor::setEditorData(QWidget* editor, const QModelIndex& index) const
1301 {
1302     if (index.column() != 1)
1303         return;
1304
1305     QComboBox* cb = static_cast<QComboBox*>(editor);
1306     QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
1307
1308     if (itm->selected == -1)
1309         cb->addItem(QString());
1310
1311     for (int i = 0; i < itm->childItems.count(); ++i)
1312         cb->addItem(QString::fromLocal8Bit(itm->childItems.at(i)->description));
1313
1314     if (itm->selected > -1)
1315         cb->setCurrentIndex(itm->selected);
1316
1317     connect(cb, SIGNAL(currentIndexChanged(int)), this, SLOT(cbChanged(int)));
1318 }
1319
1320 void QPPDOptionsEditor::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
1321 {
1322     QComboBox* cb = static_cast<QComboBox*>(editor);
1323     QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
1324
1325     if (itm->selected == cb->currentIndex())
1326         return;
1327
1328     const ppd_option_t* opt = reinterpret_cast<const ppd_option_t*>(itm->ptr);
1329     QPPDOptionsModel* m = static_cast<QPPDOptionsModel*>(model);
1330
1331     if (m->cups->markOption(opt->keyword, opt->choices[cb->currentIndex()].choice) == 0) {
1332         itm->selected = cb->currentIndex();
1333         itm->selDescription = reinterpret_cast<const ppd_option_t*>(itm->ptr)->choices[itm->selected].text;
1334     }
1335 }
1336
1337 void QPPDOptionsEditor::cbChanged(int)
1338 {
1339 /*
1340     emit commitData(static_cast<QWidget*>(sender()));
1341 */
1342 }
1343
1344 ////////////////////////////////////////////////////////////////////////////////
1345 ////////////////////////////////////////////////////////////////////////////////
1346
1347 #endif // !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
1348 #endif // defined (Q_OS_UNIX)
1349
1350 QT_END_NAMESPACE
1351
1352 #include "moc_qprintdialog.cpp"
1353 #include "qprintdialog_unix.moc"
1354 #ifndef Q_OS_MAC
1355 #include "qrc_qprintdialog.cpp"
1356 #endif
1357
1358 #endif // QT_NO_PRINTDIALOG
1359