source: trunk/src/gui/dialogs/qprintdialog_win.cpp@ 603

Last change on this file since 603 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 9.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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(Q_CC_MINGW) && !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 // we don't have a 'current page' notion in the QPrinter API yet.
132 // Neither do we support more than one page range, so limit those
133 // options
134 pd->Flags |= PD_NOCURRENTPAGE;
135 pd->nStartPage = START_PAGE_GENERAL;
136 pd->nPageRanges = 1;
137 pd->nMaxPageRanges = 1;
138
139 if (d->ep->printToFile)
140 pd->Flags |= PD_PRINTTOFILE;
141 Q_ASSERT(parent != 0 && parent->testAttribute(Qt::WA_WState_Created));
142 pd->hwndOwner = parent->window()->winId();
143 pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage());
144 pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1;
145 pd->nCopies = d->ep->num_copies;
146}
147
148static void qt_win_read_back_PRINTDLGEX(PRINTDLGEX *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d)
149{
150 if (pd->Flags & PD_SELECTION) {
151 pdlg->setPrintRange(QPrintDialog::Selection);
152 pdlg->setFromTo(0, 0);
153 } else if (pd->Flags & PD_PAGENUMS) {
154 pdlg->setPrintRange(QPrintDialog::PageRange);
155 pdlg->setFromTo(pd->lpPageRanges[0].nFromPage, pd->lpPageRanges[0].nToPage);
156 } else {
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
173static 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
182QPrintDialog::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}
190
191QPrintDialog::QPrintDialog(QWidget *parent)
192 : QAbstractPrintDialog( *(new QPrintDialogPrivate), 0, parent)
193{
194 Q_D(QPrintDialog);
195 if (!warnIfNotNative(d->printer))
196 return;
197 d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
198}
199
200QPrintDialog::~QPrintDialog()
201{
202}
203
204int QPrintDialog::exec()
205{
206 if (!warnIfNotNative(printer()))
207 return 0;
208
209 Q_D(QPrintDialog);
210 return d->openWindowsPrintDialogModally();
211}
212
213int QPrintDialogPrivate::openWindowsPrintDialogModally()
214{
215 Q_Q(QPrintDialog);
216 QWidget *parent = q->parentWidget();
217 if (parent)
218 parent = parent->window();
219 else
220 parent = QApplication::activeWindow();
221
222 // If there is no window, fall back to the print dialog itself
223 if (parent == 0)
224 parent = q;
225
226 QWidget modal_widget;
227 modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
228 modal_widget.setParent(parent, Qt::Window);
229 QApplicationPrivate::enterModal(&modal_widget);
230
231 HGLOBAL *tempDevNames = ep->createDevNames();
232
233 bool done;
234 bool result;
235 bool doPrinting;
236
237 PRINTPAGERANGE pageRange;
238 PRINTDLGEX pd;
239 memset(&pd, 0, sizeof(PRINTDLGEX));
240 pd.lStructSize = sizeof(PRINTDLGEX);
241 pd.lpPageRanges = &pageRange;
242 qt_win_setup_PRINTDLGEX(&pd, parent, q, this, tempDevNames);
243
244 do {
245 done = true;
246 doPrinting = false;
247 result = (PrintDlgEx(&pd) == S_OK);
248 if (result && (pd.dwResultAction == PD_RESULT_PRINT
249 || pd.dwResultAction == PD_RESULT_APPLY))
250 {
251 doPrinting = (pd.dwResultAction == PD_RESULT_PRINT);
252 if ((pd.Flags & PD_PAGENUMS)
253 && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage))
254 {
255 pd.lpPageRanges[0].nFromPage = 1;
256 pd.lpPageRanges[0].nToPage = 1;
257 done = false;
258 }
259 if (pd.hDC == 0)
260 result = false;
261 }
262
263 if (!done) {
264 QMessageBox::warning(0, QPrintDialog::tr("Print"),
265 QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."),
266 QPrintDialog::tr("OK"));
267 }
268 } while (!done);
269
270 QApplicationPrivate::leaveModal(&modal_widget);
271
272 qt_win_eatMouseMove();
273
274 // write values back...
275 if (result && (pd.dwResultAction == PD_RESULT_PRINT
276 || pd.dwResultAction == PD_RESULT_APPLY))
277 {
278 qt_win_read_back_PRINTDLGEX(&pd, q, this);
279 // update printer validity
280 printer->d_func()->validPrinter = !ep->name.isEmpty();
281 }
282
283 // Cleanup...
284 GlobalFree(tempDevNames);
285
286 q->done(result && doPrinting);
287
288 return result && doPrinting;
289}
290
291void QPrintDialog::setVisible(bool visible)
292{
293 Q_D(QPrintDialog);
294
295 // its always modal, so we cannot hide a native print dialog
296 if (!visible)
297 return;
298
299 if (!warnIfNotNative(d->printer))
300 return;
301
302 (void)d->openWindowsPrintDialogModally();
303 return;
304}
305
306QT_END_NAMESPACE
307
308#include "moc_qprintdialog.cpp"
309
310#endif // QT_NO_PRINTDIALOG
Note: See TracBrowser for help on using the repository browser.