QtPrintSupport - Cleanup QPrintDialog header
[profile/ivi/qtbase.git] / src / printsupport / dialogs / qprintdialog_win.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QT_NO_PRINTDIALOG
43
44 #include "qprintdialog.h"
45
46 #include <qwidget.h>
47 #include <qapplication.h>
48 #include <qmessagebox.h>
49 #include <private/qapplication_p.h>
50
51 #include "qabstractprintdialog_p.h"
52 #include "../kernel/qprintengine_win_p.h"
53 #include "../kernel/qprinter_p.h"
54
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
60 #endif
61
62 QT_BEGIN_NAMESPACE
63
64 //extern void qt_win_eatMouseMove();
65
66 class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
67 {
68     Q_DECLARE_PUBLIC(QPrintDialog)
69 public:
70     QPrintDialogPrivate()
71         : ep(0)
72     {
73     }
74
75     int openWindowsPrintDialogModally();
76
77     QWin32PrintEnginePrivate *ep;
78 };
79
80 static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWidget *parent,
81                                     QPrintDialog *pdlg,
82                                     QPrintDialogPrivate *d, HGLOBAL *tempDevNames)
83 {
84     DEVMODE *devMode = d->ep->devMode;
85
86     if (devMode) {
87         int size = sizeof(DEVMODE) + devMode->dmDriverExtra;
88         pd->hDevMode = GlobalAlloc(GHND, size);
89         {
90             void *dest = GlobalLock(pd->hDevMode);
91             memcpy(dest, devMode, size);
92             GlobalUnlock(pd->hDevMode);
93         }
94     } else {
95         pd->hDevMode = NULL;
96     }
97     pd->hDevNames  = tempDevNames;
98
99     pd->Flags = PD_RETURNDC;
100     pd->Flags |= PD_USEDEVMODECOPIESANDCOLLATE;
101
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();
107     }
108
109     if(!pdlg->isOptionEnabled(QPrintDialog::PrintToFile))
110         pd->Flags |= PD_DISABLEPRINTTOFILE;
111
112     if (pdlg->printRange() == QPrintDialog::Selection)
113         pd->Flags |= PD_SELECTION;
114     else if (pdlg->printRange() == QPrintDialog::PageRange)
115         pd->Flags |= PD_PAGENUMS;
116     else
117         pd->Flags |= PD_ALLPAGES;
118
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;
123
124     // Disable Current Page option if not required as default is Enabled
125     if (!pdlg->isOptionEnabled(QPrintDialog::PrintCurrentPage))
126         pd->Flags |= PD_NOCURRENTPAGE;
127
128     // Default to showing the General tab first
129     pd->nStartPage = START_PAGE_GENERAL;
130
131     // We don't support more than one page range in the QPrinter API yet.
132     pd->nPageRanges = 1;
133     pd->nMaxPageRanges = 1;
134
135     if (d->ep->printToFile)
136         pd->Flags |= PD_PRINTTOFILE;
137     Q_ASSERT(parent);
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;
143 }
144
145 static void qt_win_read_back_PRINTDLGEX(PRINTDLGEX *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d)
146 {
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);
159     }
160
161     d->ep->printToFile = (pd->Flags & PD_PRINTTOFILE) != 0;
162
163     d->ep->readDevnames(pd->hDevNames);
164     d->ep->readDevmode(pd->hDevMode);
165     d->ep->updateCustomPaperSize();
166
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();
171 }
172
173 static bool warnIfNotNative(QPrinter *printer)
174 {
175     if (printer->outputFormat() != QPrinter::NativeFormat) {
176         qWarning("QPrintDialog: Cannot be used on non-native printers");
177         return false;
178     }
179     return true;
180 }
181
182 QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
183     : QAbstractPrintDialog( *(new QPrintDialogPrivate), printer, parent)
184 {
185     Q_D(QPrintDialog);
186     if (!warnIfNotNative(d->printer))
187         return;
188     d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
189     setAttribute(Qt::WA_DontShowOnScreen);
190 }
191
192 QPrintDialog::QPrintDialog(QWidget *parent)
193     : QAbstractPrintDialog( *(new QPrintDialogPrivate), 0, parent)
194 {
195     Q_D(QPrintDialog);
196     if (!warnIfNotNative(d->printer))
197         return;
198     d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
199     setAttribute(Qt::WA_DontShowOnScreen);
200 }
201
202 QPrintDialog::~QPrintDialog()
203 {
204 }
205
206 int QPrintDialog::exec()
207 {
208     if (!warnIfNotNative(printer()))
209         return 0;
210
211     Q_D(QPrintDialog);
212     return d->openWindowsPrintDialogModally();
213 }
214
215 int QPrintDialogPrivate::openWindowsPrintDialogModally()
216 {
217     Q_Q(QPrintDialog);
218     QWidget *parent = q->parentWidget();
219     if (parent)
220         parent = parent->window();
221     else
222         parent = QApplication::activeWindow();
223
224     // If there is no window, fall back to the print dialog itself
225     if (parent == 0)
226         parent = q;
227
228     q->QDialog::setVisible(true);
229
230     HGLOBAL *tempDevNames = ep->createDevNames();
231
232     bool done;
233     bool result;
234     bool doPrinting;
235
236     PRINTPAGERANGE pageRange;
237     PRINTDLGEX pd;
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);
242
243     do {
244         done = true;
245         doPrinting = false;
246         result = (PrintDlgEx(&pd) == S_OK);
247         if (result && (pd.dwResultAction == PD_RESULT_PRINT
248                        || pd.dwResultAction == PD_RESULT_APPLY))
249         {
250             doPrinting = (pd.dwResultAction == PD_RESULT_PRINT);
251             if ((pd.Flags & PD_PAGENUMS)
252                 && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage))
253             {
254                 pd.lpPageRanges[0].nFromPage = 1;
255                 pd.lpPageRanges[0].nToPage = 1;
256                 done = false;
257             }
258             if (pd.hDC == 0)
259                 result = false;
260         }
261
262         if (!done) {
263             QMessageBox::warning(0, QPrintDialog::tr("Print"),
264                                  QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."),
265                                  QPrintDialog::tr("OK"));
266         }
267     } while (!done);
268
269     q->QDialog::setVisible(false);
270
271 //    qt_win_eatMouseMove();
272
273     // write values back...
274     if (result && (pd.dwResultAction == PD_RESULT_PRINT
275                    || pd.dwResultAction == PD_RESULT_APPLY))
276     {
277         qt_win_read_back_PRINTDLGEX(&pd, q, this);
278         // update printer validity
279         printer->d_func()->validPrinter = !ep->name.isEmpty();
280     }
281
282     // Cleanup...
283     GlobalFree(tempDevNames);
284
285     q->done(result && doPrinting);
286
287     return result && doPrinting;
288 }
289
290 void QPrintDialog::setVisible(bool visible)
291 {
292     Q_D(QPrintDialog);
293
294     // its always modal, so we cannot hide a native print dialog
295     if (!visible)
296         return;
297
298     if (!warnIfNotNative(d->printer))
299         return;
300
301     (void)d->openWindowsPrintDialogModally();
302     return;
303 }
304
305 QT_END_NAMESPACE
306
307 #include "moc_qprintdialog.cpp"
308
309 #endif // QT_NO_PRINTDIALOG