source: trunk/src/gui/dialogs/qprintdialog_unix.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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