source: trunk/src/gui/dialogs/qprintdialog_win.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: 9.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
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 [email protected].
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 <private/qabstractprintdialog_p.h>
52#include <private/qprintengine_win_p.h>
53#include <private/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
62QT_BEGIN_NAMESPACE
63
64extern void qt_win_eatMouseMove();
65
66class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
67{
68 Q_DECLARE_PUBLIC(QPrintDialog)
69public:
70 QPrintDialogPrivate()
71 : ep(0)
72 {
73 }
74
75 inline void _q_printToFileChanged(int) {}
76 inline void _q_rbPrintRangeToggled(bool) {}
77 inline void _q_printerChanged(int) {}
78 inline void _q_chbPrintLastFirstToggled(bool) {}
79 inline void _q_paperSizeChanged(int) {}
80 inline void _q_btnBrowseClicked() {}
81 inline void _q_btnPropertiesClicked() {}
82 int openWindowsPrintDialogModally();
83
84 QWin32PrintEnginePrivate *ep;
85};
86
87static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWidget *parent,
88 QPrintDialog *pdlg,
89 QPrintDialogPrivate *d, HGLOBAL *tempDevNames)
90{
91 DEVMODE *devMode = d->ep->devMode;
92
93 if (devMode) {
94 int size = sizeof(DEVMODE) + devMode->dmDriverExtra;
95 pd->hDevMode = GlobalAlloc(GHND, size);
96 {
97 void *dest = GlobalLock(pd->hDevMode);
98 memcpy(dest, devMode, size);
99 GlobalUnlock(pd->hDevMode);
100 }
101 } else {
102 pd->hDevMode = NULL;
103 }
104 pd->hDevNames = tempDevNames;
105
106 pd->Flags = PD_RETURNDC;
107 pd->Flags |= PD_USEDEVMODECOPIESANDCOLLATE;
108
109 if (!pdlg->isOptionEnabled(QPrintDialog::PrintSelection))
110 pd->Flags |= PD_NOSELECTION;
111 if (pdlg->isOptionEnabled(QPrintDialog::PrintPageRange)) {
112 pd->nMinPage = pdlg->minPage();
113 pd->nMaxPage = pdlg->maxPage();
114 }
115
116 if(!pdlg->isOptionEnabled(QPrintDialog::PrintToFile))
117 pd->Flags |= PD_DISABLEPRINTTOFILE;
118
119 if (pdlg->printRange() == QPrintDialog::Selection)
120 pd->Flags |= PD_SELECTION;
121 else if (pdlg->printRange() == QPrintDialog::PageRange)
122 pd->Flags |= PD_PAGENUMS;
123 else
124 pd->Flags |= PD_ALLPAGES;
125
126 // As stated by MSDN, to enable collate option when minpage==maxpage==0
127 // set the PD_NOPAGENUMS flag
128 if (pd->nMinPage==0 && pd->nMaxPage==0)
129 pd->Flags |= PD_NOPAGENUMS;
130
131 // Disable Current Page option if not required as default is Enabled
132 if (!pdlg->isOptionEnabled(QPrintDialog::PrintCurrentPage))
133 pd->Flags |= PD_NOCURRENTPAGE;
134
135 // Default to showing the General tab first
136 pd->nStartPage = START_PAGE_GENERAL;
137
138 // We don't support more than one page range in the QPrinter API yet.
139 pd->nPageRanges = 1;
140 pd->nMaxPageRanges = 1;
141
142 if (d->ep->printToFile)
143 pd->Flags |= PD_PRINTTOFILE;
144 Q_ASSERT(parent);
145 pd->hwndOwner = parent->window()->winId();
146 pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage());
147 pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1;
148 pd->nCopies = d->ep->num_copies;
149}
150
151static void qt_win_read_back_PRINTDLGEX(PRINTDLGEX *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d)
152{
153 if (pd->Flags & PD_SELECTION) {
154 pdlg->setPrintRange(QPrintDialog::Selection);
155 pdlg->setFromTo(0, 0);
156 } else if (pd->Flags & PD_PAGENUMS) {
157 pdlg->setPrintRange(QPrintDialog::PageRange);
158 pdlg->setFromTo(pd->lpPageRanges[0].nFromPage, pd->lpPageRanges[0].nToPage);
159 } else if (pd->Flags & PD_CURRENTPAGE) {
160 pdlg->setPrintRange(QPrintDialog::CurrentPage);
161 pdlg->setFromTo(0, 0);
162 } else { // PD_ALLPAGES
163 pdlg->setPrintRange(QPrintDialog::AllPages);
164 pdlg->setFromTo(0, 0);
165 }
166
167 d->ep->printToFile = (pd->Flags & PD_PRINTTOFILE) != 0;
168
169 d->ep->readDevnames(pd->hDevNames);
170 d->ep->readDevmode(pd->hDevMode);
171 d->ep->updateCustomPaperSize();
172
173 if (d->ep->printToFile && d->ep->fileName.isEmpty())
174 d->ep->fileName = d->ep->port;
175 else if (!d->ep->printToFile && d->ep->fileName == QLatin1String("FILE:"))
176 d->ep->fileName.clear();
177}
178
179static bool warnIfNotNative(QPrinter *printer)
180{
181 if (printer->outputFormat() != QPrinter::NativeFormat) {
182 qWarning("QPrintDialog: Cannot be used on non-native printers");
183 return false;
184 }
185 return true;
186}
187
188QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
189 : QAbstractPrintDialog( *(new QPrintDialogPrivate), printer, parent)
190{
191 Q_D(QPrintDialog);
192 if (!warnIfNotNative(d->printer))
193 return;
194 d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
195}
196
197QPrintDialog::QPrintDialog(QWidget *parent)
198 : QAbstractPrintDialog( *(new QPrintDialogPrivate), 0, parent)
199{
200 Q_D(QPrintDialog);
201 if (!warnIfNotNative(d->printer))
202 return;
203 d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
204}
205
206QPrintDialog::~QPrintDialog()
207{
208}
209
210int QPrintDialog::exec()
211{
212 if (!warnIfNotNative(printer()))
213 return 0;
214
215 Q_D(QPrintDialog);
216 return d->openWindowsPrintDialogModally();
217}
218
219int QPrintDialogPrivate::openWindowsPrintDialogModally()
220{
221 Q_Q(QPrintDialog);
222 QWidget *parent = q->parentWidget();
223 if (parent)
224 parent = parent->window();
225 else
226 parent = QApplication::activeWindow();
227
228 // If there is no window, fall back to the print dialog itself
229 if (parent == 0)
230 parent = q;
231
232 QWidget modal_widget;
233 modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
234 modal_widget.setParent(parent, Qt::Window);
235 QApplicationPrivate::enterModal(&modal_widget);
236
237 HGLOBAL *tempDevNames = ep->createDevNames();
238
239 bool done;
240 bool result;
241 bool doPrinting;
242
243 PRINTPAGERANGE pageRange;
244 PRINTDLGEX pd;
245 memset(&pd, 0, sizeof(PRINTDLGEX));
246 pd.lStructSize = sizeof(PRINTDLGEX);
247 pd.lpPageRanges = &pageRange;
248 qt_win_setup_PRINTDLGEX(&pd, parent, q, this, tempDevNames);
249
250 do {
251 done = true;
252 doPrinting = false;
253 result = (PrintDlgEx(&pd) == S_OK);
254 if (result && (pd.dwResultAction == PD_RESULT_PRINT
255 || pd.dwResultAction == PD_RESULT_APPLY))
256 {
257 doPrinting = (pd.dwResultAction == PD_RESULT_PRINT);
258 if ((pd.Flags & PD_PAGENUMS)
259 && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage))
260 {
261 pd.lpPageRanges[0].nFromPage = 1;
262 pd.lpPageRanges[0].nToPage = 1;
263 done = false;
264 }
265 if (pd.hDC == 0)
266 result = false;
267 }
268
269 if (!done) {
270 QMessageBox::warning(0, QPrintDialog::tr("Print"),
271 QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."),
272 QPrintDialog::tr("OK"));
273 }
274 } while (!done);
275
276 QApplicationPrivate::leaveModal(&modal_widget);
277
278 qt_win_eatMouseMove();
279
280 // write values back...
281 if (result && (pd.dwResultAction == PD_RESULT_PRINT
282 || pd.dwResultAction == PD_RESULT_APPLY))
283 {
284 qt_win_read_back_PRINTDLGEX(&pd, q, this);
285 // update printer validity
286 printer->d_func()->validPrinter = !ep->name.isEmpty();
287 }
288
289 // Cleanup...
290 GlobalFree(tempDevNames);
291
292 q->done(result && doPrinting);
293
294 return result && doPrinting;
295}
296
297void QPrintDialog::setVisible(bool visible)
298{
299 Q_D(QPrintDialog);
300
301 // its always modal, so we cannot hide a native print dialog
302 if (!visible)
303 return;
304
305 if (!warnIfNotNative(d->printer))
306 return;
307
308 (void)d->openWindowsPrintDialogModally();
309 return;
310}
311
312QT_END_NAMESPACE
313
314#include "moc_qprintdialog.cpp"
315
316#endif // QT_NO_PRINTDIALOG
Note: See TracBrowser for help on using the repository browser.