util/src/gui/dialogs/qprintpreviewdialog.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 "qprintpreviewdialog.h"
       
    43 #include "qprintpreviewwidget.h"
       
    44 #include <private/qprinter_p.h>
       
    45 #include "private/qdialog_p.h"
       
    46 
       
    47 #include <QtGui/qaction.h>
       
    48 #include <QtGui/qboxlayout.h>
       
    49 #include <QtGui/qcombobox.h>
       
    50 #include <QtGui/qlabel.h>
       
    51 #include <QtGui/qlineedit.h>
       
    52 #include <QtGui/qpagesetupdialog.h>
       
    53 #include <QtGui/qprinter.h>
       
    54 #include <QtGui/qstyle.h>
       
    55 #include <QtGui/qtoolbutton.h>
       
    56 #include <QtGui/qvalidator.h>
       
    57 #include <QtGui/qfiledialog.h>
       
    58 #include <QtGui/qmainwindow.h>
       
    59 #include <QtGui/qtoolbar.h>
       
    60 #include <QtGui/qformlayout.h>
       
    61 #include <QtCore/QCoreApplication>
       
    62 
       
    63 #include <math.h>
       
    64 
       
    65 #ifndef QT_NO_PRINTPREVIEWDIALOG
       
    66 
       
    67 QT_BEGIN_NAMESPACE
       
    68 
       
    69 namespace {
       
    70 class QPrintPreviewMainWindow : public QMainWindow
       
    71 {
       
    72 public:
       
    73     QPrintPreviewMainWindow(QWidget *parent) : QMainWindow(parent) {}
       
    74     QMenu *createPopupMenu() { return 0; }
       
    75 };
       
    76 
       
    77 class ZoomFactorValidator : public QDoubleValidator
       
    78 {
       
    79 public:
       
    80     ZoomFactorValidator(QObject* parent)
       
    81         : QDoubleValidator(parent) {}
       
    82     ZoomFactorValidator(qreal bottom, qreal top, int decimals, QObject *parent)
       
    83         : QDoubleValidator(bottom, top, decimals, parent) {}
       
    84 
       
    85     State validate(QString &input, int &pos) const
       
    86     {
       
    87         bool replacePercent = false;
       
    88         if (input.endsWith(QLatin1Char('%'))) {
       
    89             input = input.left(input.length() - 1);
       
    90             replacePercent = true;
       
    91         }
       
    92         State state = QDoubleValidator::validate(input, pos);
       
    93         if (replacePercent)
       
    94             input += QLatin1Char('%');
       
    95         const int num_size = 4;
       
    96         if (state == Intermediate) {
       
    97             int i = input.indexOf(QLocale::system().decimalPoint());
       
    98             if ((i == -1 && input.size() > num_size)
       
    99                 || (i != -1 && i > num_size))
       
   100                 return Invalid;
       
   101         }
       
   102         return state;
       
   103     }
       
   104 };
       
   105 
       
   106 class LineEdit : public QLineEdit
       
   107 {
       
   108     Q_OBJECT
       
   109 public:
       
   110     LineEdit(QWidget* parent = 0)
       
   111         : QLineEdit(parent)
       
   112     {
       
   113         setContextMenuPolicy(Qt::NoContextMenu);
       
   114         connect(this, SIGNAL(returnPressed()), SLOT(handleReturnPressed()));
       
   115     }
       
   116 
       
   117 protected:
       
   118     void focusInEvent(QFocusEvent *e)
       
   119     {
       
   120         origText = text();
       
   121         QLineEdit::focusInEvent(e);
       
   122     }
       
   123 
       
   124     void focusOutEvent(QFocusEvent *e)
       
   125     {
       
   126         if (isModified() && !hasAcceptableInput())
       
   127             setText(origText);
       
   128         QLineEdit::focusOutEvent(e);
       
   129     }
       
   130 
       
   131 private slots:
       
   132     void handleReturnPressed()
       
   133     {
       
   134         origText = text();
       
   135     }
       
   136 
       
   137 private:
       
   138     QString origText;
       
   139 };
       
   140 } // anonymous namespace
       
   141 
       
   142 class QPrintPreviewDialogPrivate : public QDialogPrivate
       
   143 {
       
   144     Q_DECLARE_PUBLIC(QPrintPreviewDialog)
       
   145 public:
       
   146     QPrintPreviewDialogPrivate()
       
   147         : printDialog(0), ownPrinter(false),
       
   148           initialized(false) {}
       
   149 
       
   150     // private slots
       
   151     void _q_fit(QAction *action);
       
   152     void _q_zoomIn();
       
   153     void _q_zoomOut();
       
   154     void _q_navigate(QAction *action);
       
   155     void _q_setMode(QAction *action);
       
   156     void _q_pageNumEdited();
       
   157     void _q_print();
       
   158     void _q_pageSetup();
       
   159     void _q_previewChanged();
       
   160     void _q_zoomFactorChanged();
       
   161 
       
   162     void init(QPrinter *printer = 0);
       
   163     void populateScene();
       
   164     void layoutPages();
       
   165     void setupActions();
       
   166     void updateNavActions();
       
   167     void setFitting(bool on);
       
   168     bool isFitting();
       
   169     void updatePageNumLabel();
       
   170     void updateZoomFactor();
       
   171 
       
   172     QPrintDialog *printDialog;
       
   173     QPrintPreviewWidget *preview;
       
   174     QPrinter *printer;
       
   175     bool ownPrinter;
       
   176     bool initialized;
       
   177 
       
   178     // widgets:
       
   179     QLineEdit *pageNumEdit;
       
   180     QLabel *pageNumLabel;
       
   181     QComboBox *zoomFactor;
       
   182 
       
   183     // actions:
       
   184     QActionGroup* navGroup;
       
   185     QAction *nextPageAction;
       
   186     QAction *prevPageAction;
       
   187     QAction *firstPageAction;
       
   188     QAction *lastPageAction;
       
   189 
       
   190     QActionGroup* fitGroup;
       
   191     QAction *fitWidthAction;
       
   192     QAction *fitPageAction;
       
   193 
       
   194     QActionGroup* zoomGroup;
       
   195     QAction *zoomInAction;
       
   196     QAction *zoomOutAction;
       
   197 
       
   198     QActionGroup* orientationGroup;
       
   199     QAction *portraitAction;
       
   200     QAction *landscapeAction;
       
   201 
       
   202     QActionGroup* modeGroup;
       
   203     QAction *singleModeAction;
       
   204     QAction *facingModeAction;
       
   205     QAction *overviewModeAction;
       
   206 
       
   207     QActionGroup *printerGroup;
       
   208     QAction *printAction;
       
   209     QAction *pageSetupAction;
       
   210 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
       
   211     QAction *closeAction;
       
   212 #endif
       
   213 
       
   214     QPointer<QObject> receiverToDisconnectOnClose;
       
   215     QByteArray memberToDisconnectOnClose;
       
   216 };
       
   217 
       
   218 void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
       
   219 {
       
   220     Q_Q(QPrintPreviewDialog);
       
   221 
       
   222     if (_printer) {
       
   223         preview = new QPrintPreviewWidget(_printer, q);
       
   224         printer = _printer;
       
   225     } else {
       
   226         ownPrinter = true;
       
   227         printer = new QPrinter;
       
   228         preview = new QPrintPreviewWidget(printer, q);
       
   229     }
       
   230     QObject::connect(preview, SIGNAL(paintRequested(QPrinter*)), q, SIGNAL(paintRequested(QPrinter*)));
       
   231     QObject::connect(preview, SIGNAL(previewChanged()), q, SLOT(_q_previewChanged()));
       
   232     setupActions();
       
   233 
       
   234     pageNumEdit = new LineEdit;
       
   235     pageNumEdit->setAlignment(Qt::AlignRight);
       
   236     pageNumEdit->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
       
   237     pageNumLabel = new QLabel;
       
   238     QObject::connect(pageNumEdit, SIGNAL(editingFinished()), q, SLOT(_q_pageNumEdited()));
       
   239 
       
   240     zoomFactor = new QComboBox;
       
   241     zoomFactor->setEditable(true);
       
   242     zoomFactor->setMinimumContentsLength(7);
       
   243     zoomFactor->setInsertPolicy(QComboBox::NoInsert);
       
   244     LineEdit *zoomEditor = new LineEdit;
       
   245     zoomEditor->setValidator(new ZoomFactorValidator(1, 1000, 1, zoomEditor));
       
   246     zoomFactor->setLineEdit(zoomEditor);
       
   247     static const short factorsX2[] = { 25, 50, 100, 200, 250, 300, 400, 800, 1600 };
       
   248     for (int i = 0; i < int(sizeof(factorsX2) / sizeof(factorsX2[0])); ++i)
       
   249         zoomFactor->addItem(QPrintPreviewDialog::tr("%1%").arg(factorsX2[i] / 2.0));
       
   250     QObject::connect(zoomFactor->lineEdit(), SIGNAL(editingFinished()),
       
   251                      q, SLOT(_q_zoomFactorChanged()));
       
   252     QObject::connect(zoomFactor, SIGNAL(currentIndexChanged(int)),
       
   253                      q, SLOT(_q_zoomFactorChanged()));
       
   254 
       
   255     QPrintPreviewMainWindow *mw = new QPrintPreviewMainWindow(q);
       
   256     QToolBar *toolbar = new QToolBar(mw);
       
   257     toolbar->addAction(fitWidthAction);
       
   258     toolbar->addAction(fitPageAction);
       
   259     toolbar->addSeparator();
       
   260     toolbar->addWidget(zoomFactor);
       
   261     toolbar->addAction(zoomOutAction);
       
   262     toolbar->addAction(zoomInAction);
       
   263     toolbar->addSeparator();
       
   264     toolbar->addAction(portraitAction);
       
   265     toolbar->addAction(landscapeAction);
       
   266     toolbar->addSeparator();
       
   267     toolbar->addAction(firstPageAction);
       
   268     toolbar->addAction(prevPageAction);
       
   269 
       
   270     // this is to ensure the label text and the editor text are
       
   271     // aligned in all styles - the extra QVBoxLayout is a workaround
       
   272     // for bug in QFormLayout
       
   273     QWidget *pageEdit = new QWidget(toolbar);
       
   274     QVBoxLayout *vboxLayout = new QVBoxLayout;
       
   275     vboxLayout->setContentsMargins(0, 0, 0, 0);
       
   276 #ifdef Q_WS_MAC
       
   277     // We query the widgets about their size and then we fix the size.
       
   278     // This should do the trick for the laying out part...
       
   279     QSize pageNumEditSize, pageNumLabelSize;
       
   280     pageNumEditSize = pageNumEdit->minimumSizeHint();
       
   281     pageNumLabelSize = pageNumLabel->minimumSizeHint();
       
   282     pageNumEdit->resize(pageNumEditSize);
       
   283     pageNumLabel->resize(pageNumLabelSize);
       
   284 #endif
       
   285     QFormLayout *formLayout = new QFormLayout;
       
   286 #ifdef Q_WS_MAC
       
   287     // We have to change the growth policy in Mac.
       
   288     formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
       
   289 #endif
       
   290     formLayout->setWidget(0, QFormLayout::LabelRole, pageNumEdit);
       
   291     formLayout->setWidget(0, QFormLayout::FieldRole, pageNumLabel);
       
   292     vboxLayout->addLayout(formLayout);
       
   293     vboxLayout->setAlignment(Qt::AlignVCenter);
       
   294     pageEdit->setLayout(vboxLayout);
       
   295     toolbar->addWidget(pageEdit);
       
   296 
       
   297     toolbar->addAction(nextPageAction);
       
   298     toolbar->addAction(lastPageAction);
       
   299     toolbar->addSeparator();
       
   300     toolbar->addAction(singleModeAction);
       
   301     toolbar->addAction(facingModeAction);
       
   302     toolbar->addAction(overviewModeAction);
       
   303     toolbar->addSeparator();
       
   304     toolbar->addAction(pageSetupAction);
       
   305     toolbar->addAction(printAction);
       
   306 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
       
   307     toolbar->addAction(closeAction);
       
   308 #endif
       
   309 
       
   310     // Cannot use the actions' triggered signal here, since it doesn't autorepeat
       
   311     QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction));
       
   312     QToolButton *zoomOutButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomOutAction));
       
   313     zoomInButton->setAutoRepeat(true);
       
   314     zoomInButton->setAutoRepeatInterval(200);
       
   315     zoomInButton->setAutoRepeatDelay(200);
       
   316     zoomOutButton->setAutoRepeat(true);
       
   317     zoomOutButton->setAutoRepeatInterval(200);
       
   318     zoomOutButton->setAutoRepeatDelay(200);
       
   319     QObject::connect(zoomInButton, SIGNAL(clicked()), q, SLOT(_q_zoomIn()));
       
   320     QObject::connect(zoomOutButton, SIGNAL(clicked()), q, SLOT(_q_zoomOut()));
       
   321 
       
   322     mw->addToolBar(toolbar);
       
   323     mw->setCentralWidget(preview);
       
   324     // QMainWindows are always created as top levels, force it to be a
       
   325     // plain widget
       
   326     mw->setParent(q, Qt::Widget);
       
   327 
       
   328     QVBoxLayout *topLayout = new QVBoxLayout;
       
   329     topLayout->addWidget(mw);
       
   330     topLayout->setMargin(0);
       
   331     q->setLayout(topLayout);
       
   332 
       
   333     QString caption = QCoreApplication::translate("QPrintPreviewDialog", "Print Preview");
       
   334     if (!printer->docName().isEmpty())
       
   335         caption += QString::fromLatin1(": ") + printer->docName();
       
   336     q->setWindowTitle(caption);
       
   337 
       
   338     if (!printer->isValid()
       
   339 #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
       
   340         || printer->outputFormat() != QPrinter::NativeFormat
       
   341 #endif
       
   342         )
       
   343         pageSetupAction->setEnabled(false);
       
   344     preview->setFocus();
       
   345 }
       
   346 
       
   347 static inline void qt_setupActionIcon(QAction *action, const QLatin1String &name)
       
   348 {
       
   349     QLatin1String imagePrefix(":/trolltech/dialogs/qprintpreviewdialog/images/");
       
   350     QIcon icon;
       
   351     icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
       
   352     icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
       
   353     action->setIcon(icon);
       
   354 }
       
   355 
       
   356 void QPrintPreviewDialogPrivate::setupActions()
       
   357 {
       
   358     Q_Q(QPrintPreviewDialog);
       
   359 
       
   360     // Navigation
       
   361     navGroup = new QActionGroup(q);
       
   362     navGroup->setExclusive(false);
       
   363     nextPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Next page"));
       
   364     prevPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Previous page"));
       
   365     firstPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "First page"));
       
   366     lastPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Last page"));
       
   367     qt_setupActionIcon(nextPageAction, QLatin1String("go-next"));
       
   368     qt_setupActionIcon(prevPageAction, QLatin1String("go-previous"));
       
   369     qt_setupActionIcon(firstPageAction, QLatin1String("go-first"));
       
   370     qt_setupActionIcon(lastPageAction, QLatin1String("go-last"));
       
   371     QObject::connect(navGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_navigate(QAction*)));
       
   372 
       
   373 
       
   374     fitGroup = new QActionGroup(q);
       
   375     fitWidthAction = fitGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Fit width"));
       
   376     fitPageAction = fitGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Fit page"));
       
   377     fitWidthAction->setObjectName(QLatin1String("fitWidthAction"));
       
   378     fitPageAction->setObjectName(QLatin1String("fitPageAction"));
       
   379     fitWidthAction->setCheckable(true);
       
   380     fitPageAction->setCheckable(true);
       
   381     qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
       
   382     qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
       
   383     QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
       
   384 
       
   385     // Zoom
       
   386     zoomGroup = new QActionGroup(q);
       
   387     zoomInAction = zoomGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Zoom in"));
       
   388     zoomOutAction = zoomGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Zoom out"));
       
   389     qt_setupActionIcon(zoomInAction, QLatin1String("zoom-in"));
       
   390     qt_setupActionIcon(zoomOutAction, QLatin1String("zoom-out"));
       
   391 
       
   392     // Portrait/Landscape
       
   393     orientationGroup = new QActionGroup(q);
       
   394     portraitAction = orientationGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Portrait"));
       
   395     landscapeAction = orientationGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Landscape"));
       
   396     portraitAction->setCheckable(true);
       
   397     landscapeAction->setCheckable(true);
       
   398     qt_setupActionIcon(portraitAction, QLatin1String("layout-portrait"));
       
   399     qt_setupActionIcon(landscapeAction, QLatin1String("layout-landscape"));
       
   400     QObject::connect(portraitAction, SIGNAL(triggered(bool)), preview, SLOT(setPortraitOrientation()));
       
   401     QObject::connect(landscapeAction, SIGNAL(triggered(bool)), preview, SLOT(setLandscapeOrientation()));
       
   402 
       
   403     // Display mode
       
   404     modeGroup = new QActionGroup(q);
       
   405     singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
       
   406     facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
       
   407     overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
       
   408     qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
       
   409     qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
       
   410     qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
       
   411     singleModeAction->setObjectName(QLatin1String("singleModeAction"));
       
   412     facingModeAction->setObjectName(QLatin1String("facingModeAction"));
       
   413     overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
       
   414 
       
   415     singleModeAction->setCheckable(true);
       
   416     facingModeAction->setCheckable(true);
       
   417     overviewModeAction->setCheckable(true);
       
   418     QObject::connect(modeGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_setMode(QAction*)));
       
   419 
       
   420     // Print
       
   421     printerGroup = new QActionGroup(q);
       
   422     printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
       
   423     pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
       
   424     qt_setupActionIcon(printAction, QLatin1String("print"));
       
   425     qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
       
   426     QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
       
   427     QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
       
   428 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
       
   429     closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close"));
       
   430     QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject()));
       
   431 #endif
       
   432 
       
   433     // Initial state:
       
   434     fitPageAction->setChecked(true);
       
   435     singleModeAction->setChecked(true);
       
   436     if (preview->orientation() == QPrinter::Portrait)
       
   437         portraitAction->setChecked(true);
       
   438     else
       
   439         landscapeAction->setChecked(true);
       
   440 }
       
   441 
       
   442 
       
   443 bool QPrintPreviewDialogPrivate::isFitting()
       
   444 {
       
   445     return (fitGroup->isExclusive()
       
   446             && (fitWidthAction->isChecked() || fitPageAction->isChecked()));
       
   447 }
       
   448 
       
   449 
       
   450 void QPrintPreviewDialogPrivate::setFitting(bool on)
       
   451 {
       
   452     if (isFitting() == on)
       
   453         return;
       
   454     fitGroup->setExclusive(on);
       
   455     if (on) {
       
   456         QAction* action = fitWidthAction->isChecked() ? fitWidthAction : fitPageAction;
       
   457         action->setChecked(true);
       
   458         if (fitGroup->checkedAction() != action) {
       
   459             // work around exclusitivity problem
       
   460             fitGroup->removeAction(action);
       
   461             fitGroup->addAction(action);
       
   462         }
       
   463     } else {
       
   464         fitWidthAction->setChecked(false);
       
   465         fitPageAction->setChecked(false);
       
   466     }
       
   467 }
       
   468 
       
   469 void QPrintPreviewDialogPrivate::updateNavActions()
       
   470 {
       
   471     int curPage = preview->currentPage();
       
   472     int numPages = preview->pageCount();
       
   473     nextPageAction->setEnabled(curPage < numPages);
       
   474     prevPageAction->setEnabled(curPage > 1);
       
   475     firstPageAction->setEnabled(curPage > 1);
       
   476     lastPageAction->setEnabled(curPage < numPages);
       
   477     pageNumEdit->setText(QString::number(curPage));
       
   478 }
       
   479 
       
   480 void QPrintPreviewDialogPrivate::updatePageNumLabel()
       
   481 {
       
   482     Q_Q(QPrintPreviewDialog);
       
   483 
       
   484     int numPages = preview->pageCount();
       
   485     int maxChars = QString::number(numPages).length();
       
   486     pageNumLabel->setText(QString::fromLatin1("/ %1").arg(numPages));
       
   487     int cyphersWidth = q->fontMetrics().width(QString().fill(QLatin1Char('8'), maxChars));
       
   488     int maxWidth = pageNumEdit->minimumSizeHint().width() + cyphersWidth;
       
   489     pageNumEdit->setMinimumWidth(maxWidth);
       
   490     pageNumEdit->setMaximumWidth(maxWidth);
       
   491     pageNumEdit->setValidator(new QIntValidator(1, numPages, pageNumEdit));
       
   492     // any old one will be deleted later along with its parent pageNumEdit
       
   493 }
       
   494 
       
   495 void QPrintPreviewDialogPrivate::updateZoomFactor()
       
   496 {
       
   497     zoomFactor->lineEdit()->setText(QString().sprintf("%.1f%%", preview->zoomFactor()*100));
       
   498 }
       
   499 
       
   500 void QPrintPreviewDialogPrivate::_q_fit(QAction* action)
       
   501 {
       
   502     setFitting(true);
       
   503     if (action == fitPageAction)
       
   504         preview->fitInView();
       
   505     else
       
   506         preview->fitToWidth();
       
   507 }
       
   508 
       
   509 void QPrintPreviewDialogPrivate::_q_zoomIn()
       
   510 {
       
   511     setFitting(false);
       
   512     preview->zoomIn();
       
   513     updateZoomFactor();
       
   514 }
       
   515 
       
   516 void QPrintPreviewDialogPrivate::_q_zoomOut()
       
   517 {
       
   518     setFitting(false);
       
   519     preview->zoomOut();
       
   520     updateZoomFactor();
       
   521 }
       
   522 
       
   523 void QPrintPreviewDialogPrivate::_q_pageNumEdited()
       
   524 {
       
   525     bool ok = false;
       
   526     int res = pageNumEdit->text().toInt(&ok);
       
   527     if (ok)
       
   528         preview->setCurrentPage(res);
       
   529 }
       
   530 
       
   531 void QPrintPreviewDialogPrivate::_q_navigate(QAction* action)
       
   532 {
       
   533     int curPage = preview->currentPage();
       
   534     if (action == prevPageAction)
       
   535         preview->setCurrentPage(curPage - 1);
       
   536     else if (action == nextPageAction)
       
   537         preview->setCurrentPage(curPage + 1);
       
   538     else if (action == firstPageAction)
       
   539         preview->setCurrentPage(1);
       
   540     else if (action == lastPageAction)
       
   541         preview->setCurrentPage(preview->pageCount());
       
   542     updateNavActions();
       
   543 }
       
   544 
       
   545 void QPrintPreviewDialogPrivate::_q_setMode(QAction* action)
       
   546 {
       
   547     if (action == overviewModeAction) {
       
   548         preview->setViewMode(QPrintPreviewWidget::AllPagesView);
       
   549         setFitting(false);
       
   550         fitGroup->setEnabled(false);
       
   551         navGroup->setEnabled(false);
       
   552         pageNumEdit->setEnabled(false);
       
   553         pageNumLabel->setEnabled(false);
       
   554     } else if (action == facingModeAction) {
       
   555         preview->setViewMode(QPrintPreviewWidget::FacingPagesView);
       
   556     } else {
       
   557         preview->setViewMode(QPrintPreviewWidget::SinglePageView);
       
   558     }
       
   559     if (action == facingModeAction || action == singleModeAction) {
       
   560         fitGroup->setEnabled(true);
       
   561         navGroup->setEnabled(true);
       
   562         pageNumEdit->setEnabled(true);
       
   563         pageNumLabel->setEnabled(true);
       
   564         setFitting(true);
       
   565     }
       
   566 }
       
   567 
       
   568 void QPrintPreviewDialogPrivate::_q_print()
       
   569 {
       
   570     Q_Q(QPrintPreviewDialog);
       
   571 
       
   572 #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
       
   573     if (printer->outputFormat() != QPrinter::NativeFormat) {
       
   574         QString title;
       
   575         QString suffix;
       
   576         if (printer->outputFormat() == QPrinter::PdfFormat) {
       
   577             title = QCoreApplication::translate("QPrintPreviewDialog", "Export to PDF");
       
   578             suffix = QLatin1String(".pdf");
       
   579         } else {
       
   580             title = QCoreApplication::translate("QPrintPreviewDialog", "Export to PostScript");
       
   581             suffix = QLatin1String(".ps");
       
   582         }
       
   583         QString fileName = QFileDialog::getSaveFileName(q, title, printer->outputFileName(),
       
   584                                                         QLatin1Char('*') + suffix);
       
   585         if (!fileName.isEmpty()) {
       
   586             if (QFileInfo(fileName).suffix().isEmpty())
       
   587                 fileName.append(suffix);
       
   588             printer->setOutputFileName(fileName);
       
   589         }
       
   590         if (!printer->outputFileName().isEmpty())
       
   591             preview->print();
       
   592         q->accept();
       
   593         return;
       
   594     }
       
   595 #endif
       
   596 
       
   597     if (!printDialog)
       
   598         printDialog = new QPrintDialog(printer, q);
       
   599     if (printDialog->exec() == QDialog::Accepted) {
       
   600         preview->print();
       
   601         q->accept();
       
   602     }
       
   603 }
       
   604 
       
   605 void QPrintPreviewDialogPrivate::_q_pageSetup()
       
   606 {
       
   607     Q_Q(QPrintPreviewDialog);
       
   608 
       
   609     QPageSetupDialog pageSetup(printer, q);
       
   610     if (pageSetup.exec() == QDialog::Accepted) {
       
   611         // update possible orientation changes
       
   612         if (preview->orientation() == QPrinter::Portrait) {
       
   613             portraitAction->setChecked(true);
       
   614             preview->setPortraitOrientation();
       
   615         }else {
       
   616             landscapeAction->setChecked(true);
       
   617             preview->setLandscapeOrientation();
       
   618         }
       
   619     }
       
   620 }
       
   621 
       
   622 void QPrintPreviewDialogPrivate::_q_previewChanged()
       
   623 {
       
   624     updateNavActions();
       
   625     updatePageNumLabel();
       
   626     updateZoomFactor();
       
   627 }
       
   628 
       
   629 void QPrintPreviewDialogPrivate::_q_zoomFactorChanged()
       
   630 {
       
   631     QString text = zoomFactor->lineEdit()->text();
       
   632     bool ok;
       
   633     qreal factor = text.remove(QLatin1Char('%')).toFloat(&ok);
       
   634     factor = qMax(qreal(1.0), qMin(qreal(1000.0), factor));
       
   635     if (ok) {
       
   636         preview->setZoomFactor(factor/100.0);
       
   637         zoomFactor->setEditText(QString::fromLatin1("%1%").arg(factor));
       
   638         setFitting(false);
       
   639     }
       
   640 }
       
   641 
       
   642 ///////////////////////////////////////////////////////////////////////////
       
   643 
       
   644 /*!
       
   645     \class QPrintPreviewDialog
       
   646     \since 4.4
       
   647 
       
   648     \brief The QPrintPreviewDialog class provides a dialog for
       
   649     previewing and configuring page layouts for printer output.
       
   650 
       
   651     \ingroup standard-dialogs
       
   652     \ingroup printing
       
   653 
       
   654     Using QPrintPreviewDialog in your existing application is
       
   655     straightforward:
       
   656 
       
   657     \list 1
       
   658     \o Create the QPrintPreviewDialog.
       
   659 
       
   660     You can construct a QPrintPreviewDialog with an existing QPrinter
       
   661     object, or you can have QPrintPreviewDialog create one for you,
       
   662     which will be the system default printer.
       
   663 
       
   664     \o Connect the paintRequested() signal to a slot.
       
   665 
       
   666     When the dialog needs to generate a set of preview pages, the
       
   667     paintRequested() signal will be emitted. You can use the exact
       
   668     same code for the actual printing as for having the preview
       
   669     generated, including calling QPrinter::newPage() to start a new
       
   670     page in the preview. Connect a slot to the paintRequested()
       
   671     signal, where you draw onto the QPrinter object that is passed
       
   672     into the slot.
       
   673 
       
   674     \o Call exec().
       
   675 
       
   676     Call QPrintPreviewDialog::exec() to show the preview dialog.
       
   677     \endlist
       
   678 
       
   679 
       
   680     \sa QPrinter, QPrintDialog, QPageSetupDialog, QPrintPreviewWidget
       
   681 */
       
   682 
       
   683 /*!
       
   684     Constructs a QPrintPreviewDialog based on \a printer and with \a
       
   685     parent as the parent widget. The widget flags \a flags are passed on
       
   686     to the QWidget constructor.
       
   687 
       
   688     \sa QWidget::setWindowFlags()
       
   689 */
       
   690 QPrintPreviewDialog::QPrintPreviewDialog(QPrinter* printer, QWidget *parent, Qt::WindowFlags flags)
       
   691     : QDialog(*new QPrintPreviewDialogPrivate, parent, flags)
       
   692 {
       
   693     Q_D(QPrintPreviewDialog);
       
   694     d->init(printer);
       
   695 }
       
   696 
       
   697 /*!
       
   698     \overload
       
   699     \fn QPrintPreviewDialog::QPrintPreviewDialog(QWidget *parent, Qt::WindowFlags flags)
       
   700 
       
   701     This will create an internal QPrinter object, which will use the
       
   702     system default printer.
       
   703 */
       
   704 QPrintPreviewDialog::QPrintPreviewDialog(QWidget *parent, Qt::WindowFlags f)
       
   705     : QDialog(*new QPrintPreviewDialogPrivate, parent, f)
       
   706 {
       
   707     Q_D(QPrintPreviewDialog);
       
   708     d->init();
       
   709 }
       
   710 
       
   711 /*!
       
   712     Destroys the QPrintPreviewDialog.
       
   713 */
       
   714 QPrintPreviewDialog::~QPrintPreviewDialog()
       
   715 {
       
   716     Q_D(QPrintPreviewDialog);
       
   717     if (d->ownPrinter)
       
   718         delete d->printer;
       
   719     delete d->printDialog;
       
   720 }
       
   721 
       
   722 /*!
       
   723     \reimp
       
   724 */
       
   725 void QPrintPreviewDialog::setVisible(bool visible)
       
   726 {
       
   727     Q_D(QPrintPreviewDialog);
       
   728     // this will make the dialog get a decent default size
       
   729     if (visible && !d->initialized) {
       
   730         d->preview->updatePreview();
       
   731         d->initialized = true;
       
   732     }
       
   733     QDialog::setVisible(visible);
       
   734 }
       
   735 
       
   736 /*!
       
   737     \reimp
       
   738 */
       
   739 void QPrintPreviewDialog::done(int result)
       
   740 {
       
   741     Q_D(QPrintPreviewDialog);
       
   742     QDialog::done(result);
       
   743     if (d->receiverToDisconnectOnClose) {
       
   744         disconnect(this, SIGNAL(finished(int)),
       
   745                    d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
       
   746         d->receiverToDisconnectOnClose = 0;
       
   747     }
       
   748     d->memberToDisconnectOnClose.clear();
       
   749 }
       
   750 
       
   751 /*!
       
   752     \overload
       
   753     \since 4.5
       
   754 
       
   755     Opens the dialog and connects its finished(int) signal to the slot specified
       
   756     by \a receiver and \a member.
       
   757 
       
   758     The signal will be disconnected from the slot when the dialog is closed.
       
   759 */
       
   760 void QPrintPreviewDialog::open(QObject *receiver, const char *member)
       
   761 {
       
   762     Q_D(QPrintPreviewDialog);
       
   763     // the int parameter isn't very useful here; we could just as well connect
       
   764     // to reject(), but this feels less robust somehow
       
   765     connect(this, SIGNAL(finished(int)), receiver, member);
       
   766     d->receiverToDisconnectOnClose = receiver;
       
   767     d->memberToDisconnectOnClose = member;
       
   768     QDialog::open();
       
   769 }
       
   770 
       
   771 /*!
       
   772     Returns a pointer to the QPrinter object this dialog is currently
       
   773     operating on.
       
   774 */
       
   775 QPrinter *QPrintPreviewDialog::printer()
       
   776 {
       
   777     Q_D(QPrintPreviewDialog);
       
   778     return d->printer;
       
   779 }
       
   780 
       
   781 /*!
       
   782     \fn void QPrintPreviewDialog::paintRequested(QPrinter *printer)
       
   783 
       
   784     This signal is emitted when the QPrintPreviewDialog needs to generate
       
   785     a set of preview pages.
       
   786 
       
   787     The \a printer instance supplied is the paint device onto which you should
       
   788     paint the contents of each page, using the QPrinter instance in the same way
       
   789     as you would when printing directly.
       
   790 */
       
   791 
       
   792 
       
   793 QT_END_NAMESPACE
       
   794 
       
   795 #include "moc_qprintpreviewdialog.cpp"
       
   796 #include "qprintpreviewdialog.moc"
       
   797 
       
   798 #endif // QT_NO_PRINTPREVIEWDIALOG
       
   799 
       
   800