1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QT_NO_PRINTDIALOG
44 #include "qprintdialog.h"
47 #include <qapplication.h>
48 #include <qmessagebox.h>
49 #include <private/qapplication_p.h>
51 #include "qabstractprintdialog_p.h"
52 #include "../kernel/qprintengine_win_p.h"
53 #include "../kernel/qprinter_p.h"
55 #if !defined(PD_NOCURRENTPAGE)
56 #define PD_NOCURRENTPAGE 0x00800000
57 #define PD_RESULT_PRINT 1
58 #define PD_RESULT_APPLY 2
59 #define START_PAGE_GENERAL 0XFFFFFFFF
64 //extern void qt_win_eatMouseMove();
66 class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
68 Q_DECLARE_PUBLIC(QPrintDialog)
75 int openWindowsPrintDialogModally();
77 QWin32PrintEnginePrivate *ep;
80 static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWidget *parent,
82 QPrintDialogPrivate *d, HGLOBAL *tempDevNames)
84 DEVMODE *devMode = d->ep->devMode;
87 int size = sizeof(DEVMODE) + devMode->dmDriverExtra;
88 pd->hDevMode = GlobalAlloc(GHND, size);
90 void *dest = GlobalLock(pd->hDevMode);
91 memcpy(dest, devMode, size);
92 GlobalUnlock(pd->hDevMode);
97 pd->hDevNames = tempDevNames;
99 pd->Flags = PD_RETURNDC;
100 pd->Flags |= PD_USEDEVMODECOPIESANDCOLLATE;
102 if (!pdlg->isOptionEnabled(QPrintDialog::PrintSelection))
103 pd->Flags |= PD_NOSELECTION;
104 if (pdlg->isOptionEnabled(QPrintDialog::PrintPageRange)) {
105 pd->nMinPage = pdlg->minPage();
106 pd->nMaxPage = pdlg->maxPage();
109 if(!pdlg->isOptionEnabled(QPrintDialog::PrintToFile))
110 pd->Flags |= PD_DISABLEPRINTTOFILE;
112 if (pdlg->printRange() == QPrintDialog::Selection)
113 pd->Flags |= PD_SELECTION;
114 else if (pdlg->printRange() == QPrintDialog::PageRange)
115 pd->Flags |= PD_PAGENUMS;
117 pd->Flags |= PD_ALLPAGES;
119 // As stated by MSDN, to enable collate option when minpage==maxpage==0
120 // set the PD_NOPAGENUMS flag
121 if (pd->nMinPage==0 && pd->nMaxPage==0)
122 pd->Flags |= PD_NOPAGENUMS;
124 // Disable Current Page option if not required as default is Enabled
125 if (!pdlg->isOptionEnabled(QPrintDialog::PrintCurrentPage))
126 pd->Flags |= PD_NOCURRENTPAGE;
128 // Default to showing the General tab first
129 pd->nStartPage = START_PAGE_GENERAL;
131 // We don't support more than one page range in the QPrinter API yet.
133 pd->nMaxPageRanges = 1;
135 if (d->ep->printToFile)
136 pd->Flags |= PD_PRINTTOFILE;
138 QWindow *parentWindow = parent->windowHandle();
139 pd->hwndOwner = parentWindow ? (HWND)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", parentWindow) : 0;
140 pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage());
141 pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1;
142 pd->nCopies = d->ep->num_copies;
145 static void qt_win_read_back_PRINTDLGEX(PRINTDLGEX *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d)
147 if (pd->Flags & PD_SELECTION) {
148 pdlg->setPrintRange(QPrintDialog::Selection);
149 pdlg->setFromTo(0, 0);
150 } else if (pd->Flags & PD_PAGENUMS) {
151 pdlg->setPrintRange(QPrintDialog::PageRange);
152 pdlg->setFromTo(pd->lpPageRanges[0].nFromPage, pd->lpPageRanges[0].nToPage);
153 } else if (pd->Flags & PD_CURRENTPAGE) {
154 pdlg->setPrintRange(QPrintDialog::CurrentPage);
155 pdlg->setFromTo(0, 0);
156 } else { // PD_ALLPAGES
157 pdlg->setPrintRange(QPrintDialog::AllPages);
158 pdlg->setFromTo(0, 0);
161 d->ep->printToFile = (pd->Flags & PD_PRINTTOFILE) != 0;
163 d->ep->readDevnames(pd->hDevNames);
164 d->ep->readDevmode(pd->hDevMode);
165 d->ep->updateCustomPaperSize();
167 if (d->ep->printToFile && d->ep->fileName.isEmpty())
168 d->ep->fileName = d->ep->port;
169 else if (!d->ep->printToFile && d->ep->fileName == QLatin1String("FILE:"))
170 d->ep->fileName.clear();
173 static bool warnIfNotNative(QPrinter *printer)
175 if (printer->outputFormat() != QPrinter::NativeFormat) {
176 qWarning("QPrintDialog: Cannot be used on non-native printers");
182 QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
183 : QAbstractPrintDialog( *(new QPrintDialogPrivate), printer, parent)
186 if (!warnIfNotNative(d->printer))
188 d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
189 setAttribute(Qt::WA_DontShowOnScreen);
192 QPrintDialog::QPrintDialog(QWidget *parent)
193 : QAbstractPrintDialog( *(new QPrintDialogPrivate), 0, parent)
196 if (!warnIfNotNative(d->printer))
198 d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
199 setAttribute(Qt::WA_DontShowOnScreen);
202 QPrintDialog::~QPrintDialog()
206 int QPrintDialog::exec()
208 if (!warnIfNotNative(printer()))
212 return d->openWindowsPrintDialogModally();
215 int QPrintDialogPrivate::openWindowsPrintDialogModally()
218 QWidget *parent = q->parentWidget();
220 parent = parent->window();
222 parent = QApplication::activeWindow();
224 // If there is no window, fall back to the print dialog itself
228 q->QDialog::setVisible(true);
230 HGLOBAL *tempDevNames = ep->createDevNames();
236 PRINTPAGERANGE pageRange;
238 memset(&pd, 0, sizeof(PRINTDLGEX));
239 pd.lStructSize = sizeof(PRINTDLGEX);
240 pd.lpPageRanges = &pageRange;
241 qt_win_setup_PRINTDLGEX(&pd, parent, q, this, tempDevNames);
246 result = (PrintDlgEx(&pd) == S_OK);
247 if (result && (pd.dwResultAction == PD_RESULT_PRINT
248 || pd.dwResultAction == PD_RESULT_APPLY))
250 doPrinting = (pd.dwResultAction == PD_RESULT_PRINT);
251 if ((pd.Flags & PD_PAGENUMS)
252 && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage))
254 pd.lpPageRanges[0].nFromPage = 1;
255 pd.lpPageRanges[0].nToPage = 1;
263 QMessageBox::warning(0, QPrintDialog::tr("Print"),
264 QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."),
265 QPrintDialog::tr("OK"));
269 q->QDialog::setVisible(false);
271 // qt_win_eatMouseMove();
273 // write values back...
274 if (result && (pd.dwResultAction == PD_RESULT_PRINT
275 || pd.dwResultAction == PD_RESULT_APPLY))
277 qt_win_read_back_PRINTDLGEX(&pd, q, this);
278 // update printer validity
279 printer->d_func()->validPrinter = !ep->name.isEmpty();
283 GlobalFree(tempDevNames);
285 q->done(result && doPrinting);
287 return result && doPrinting;
290 void QPrintDialog::setVisible(bool visible)
294 // its always modal, so we cannot hide a native print dialog
298 if (!warnIfNotNative(d->printer))
301 (void)d->openWindowsPrintDialogModally();
307 #include "moc_qprintdialog.cpp"
309 #endif // QT_NO_PRINTDIALOG