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