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

Last change on this file since 122 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department 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
55QT_BEGIN_NAMESPACE
56
57extern void qt_win_eatMouseMove();
58
59class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
60{
61 Q_DECLARE_PUBLIC(QPrintDialog)
62public:
63 QPrintDialogPrivate()
64 : ep(0)
65 {
66 }
67
68 inline void _q_printToFileChanged(int) {}
69 inline void _q_rbPrintRangeToggled(bool) {}
70 inline void _q_printerChanged(int) {}
71 inline void _q_chbPrintLastFirstToggled(bool) {}
72 inline void _q_paperSizeChanged(int) {}
73 inline void _q_btnBrowseClicked() {}
74 inline void _q_btnPropertiesClicked() {}
75 int openWindowsPrintDialogModally();
76
77 QWin32PrintEnginePrivate *ep;
78};
79
80#ifndef Q_OS_WINCE
81// If you change this function, make sure you also change the unicode equivalent
82template <class PrintDialog, class DeviceMode>
83static PrintDialog *qt_win_make_PRINTDLG(QWidget *parent,
84 QPrintDialog *pdlg,
85 QPrintDialogPrivate *d, HGLOBAL *tempDevNames)
86{
87 PrintDialog *pd = new PrintDialog;
88 memset(pd, 0, sizeof(PrintDialog));
89 pd->lStructSize = sizeof(PrintDialog);
90
91 void *devMode = sizeof(DeviceMode) == sizeof(DEVMODEA)
92 ? (void *) d->ep->devModeA()
93 : (void *) d->ep->devModeW();
94
95 if (devMode) {
96 int size = sizeof(DeviceMode) + ((DeviceMode *) devMode)->dmDriverExtra;
97 pd->hDevMode = GlobalAlloc(GHND, size);
98 {
99 void *dest = GlobalLock(pd->hDevMode);
100 memcpy(dest, d->ep->devMode, size);
101 GlobalUnlock(pd->hDevMode);
102 }
103 } else {
104 pd->hDevMode = NULL;
105 }
106 pd->hDevNames = tempDevNames;
107
108 pd->Flags = PD_RETURNDC;
109 pd->Flags |= PD_USEDEVMODECOPIESANDCOLLATE;
110
111 if (!pdlg->isOptionEnabled(QPrintDialog::PrintSelection))
112 pd->Flags |= PD_NOSELECTION;
113 if (pdlg->isOptionEnabled(QPrintDialog::PrintPageRange)) {
114 pd->nMinPage = pdlg->minPage();
115 pd->nMaxPage = pdlg->maxPage();
116 }
117
118 if(!pdlg->isOptionEnabled(QPrintDialog::PrintToFile))
119 pd->Flags |= PD_DISABLEPRINTTOFILE;
120
121 if (pdlg->printRange() == QPrintDialog::Selection)
122 pd->Flags |= PD_SELECTION;
123 else if (pdlg->printRange() == QPrintDialog::PageRange)
124 pd->Flags |= PD_PAGENUMS;
125 else
126 pd->Flags |= PD_ALLPAGES;
127
128 // As stated by MSDN, to enable collate option when minpage==maxpage==0
129 // set the PD_NOPAGENUMS flag
130 if (pd->nMinPage==0 && pd->nMaxPage==0)
131 pd->Flags |= PD_NOPAGENUMS;
132
133 if (d->ep->printToFile)
134 pd->Flags |= PD_PRINTTOFILE;
135 Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created));
136 pd->hwndOwner = parent ? parent->winId() : 0;
137 pd->nFromPage = qMax(pdlg->fromPage(), pdlg->minPage());
138 pd->nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1;
139 pd->nCopies = d->ep->num_copies;
140
141 return pd;
142}
143#endif // Q_OS_WINCE
144
145// If you change this function, make sure you also change the ansi equivalent
146template <typename T>
147static void qt_win_clean_up_PRINTDLG(T **pd)
148{
149 delete *pd;
150 *pd = 0;
151}
152
153
154// If you change this function, make sure you also change the ansi equivalent
155template <typename T>
156static void qt_win_read_back_PRINTDLG(T *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d)
157{
158 if (pd->Flags & PD_SELECTION) {
159 pdlg->setPrintRange(QPrintDialog::Selection);
160 pdlg->setFromTo(0, 0);
161 } else if (pd->Flags & PD_PAGENUMS) {
162 pdlg->setPrintRange(QPrintDialog::PageRange);
163 pdlg->setFromTo(pd->nFromPage, pd->nToPage);
164 } else {
165 pdlg->setPrintRange(QPrintDialog::AllPages);
166 pdlg->setFromTo(0, 0);
167 }
168
169 d->ep->printToFile = (pd->Flags & PD_PRINTTOFILE) != 0;
170
171 d->ep->readDevnames(pd->hDevNames);
172 d->ep->readDevmode(pd->hDevMode);
173 d->ep->updateCustomPaperSize();
174
175 if (d->ep->printToFile && d->ep->fileName.isEmpty())
176 d->ep->fileName = d->ep->port;
177 else if (!d->ep->printToFile && d->ep->fileName == QLatin1String("FILE:"))
178 d->ep->fileName.clear();
179}
180
181static bool warnIfNotNative(QPrinter *printer)
182{
183 if (printer->outputFormat() != QPrinter::NativeFormat) {
184 qWarning("QPrintDialog: Cannot be used on non-native printers");
185 return false;
186 }
187 return true;
188}
189
190QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
191 : QAbstractPrintDialog( *(new QPrintDialogPrivate), printer, parent)
192{
193 Q_D(QPrintDialog);
194 if (!warnIfNotNative(d->printer))
195 return;
196 d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
197}
198
199QPrintDialog::QPrintDialog(QWidget *parent)
200 : QAbstractPrintDialog( *(new QPrintDialogPrivate), 0, parent)
201{
202 Q_D(QPrintDialog);
203 if (!warnIfNotNative(d->printer))
204 return;
205 d->ep = static_cast<QWin32PrintEngine *>(d->printer->paintEngine())->d_func();
206}
207
208QPrintDialog::~QPrintDialog()
209{
210}
211
212int QPrintDialog::exec()
213{
214 if (!warnIfNotNative(printer()))
215 return 0;
216
217 Q_D(QPrintDialog);
218 return d->openWindowsPrintDialogModally();
219}
220
221int QPrintDialogPrivate::openWindowsPrintDialogModally()
222{
223 Q_Q(QPrintDialog);
224 QWidget *parent = q->parentWidget();
225 if (parent)
226 parent = parent->window();
227 else
228 parent = qApp->activeWindow();
229
230 QWidget modal_widget;
231 modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
232 modal_widget.setParent(parent, Qt::Window);
233 QApplicationPrivate::enterModal(&modal_widget);
234
235 HGLOBAL *tempDevNames = ep->createDevNames();
236
237 bool result;
238 bool done;
239 void *pd = QT_WA_INLINE(
240 (void*)(qt_win_make_PRINTDLG<PRINTDLGW, DEVMODEW>(parent, q, this, tempDevNames)),
241 (void*)(qt_win_make_PRINTDLG<PRINTDLGA, DEVMODEA>(parent, q, this, tempDevNames))
242 );
243
244 do {
245 done = true;
246 QT_WA({
247 PRINTDLGW *pdw = reinterpret_cast<PRINTDLGW *>(pd);
248 result = PrintDlgW(pdw);
249 if ((pdw->Flags & PD_PAGENUMS) && (pdw->nFromPage > pdw->nToPage))
250 done = false;
251 if (result && pdw->hDC == 0)
252 result = false;
253 else if (!result)
254 done = true;
255 }, {
256 PRINTDLGA *pda = reinterpret_cast<PRINTDLGA *>(pd);
257 result = PrintDlgA(pda);
258 if ((pda->Flags & PD_PAGENUMS) && (pda->nFromPage > pda->nToPage))
259 done = false;
260 if (result && pda->hDC == 0)
261 result = false;
262 else if (!result)
263 done = true;
264 });
265 if (!done) {
266 QMessageBox::warning(0, QPrintDialog::tr("Print"),
267 QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."),
268 QPrintDialog::tr("OK"));
269 }
270 } while (!done);
271
272 QApplicationPrivate::leaveModal(&modal_widget);
273
274 qt_win_eatMouseMove();
275
276 // write values back...
277 if (result) {
278 QT_WA({
279 PRINTDLGW *pdw = reinterpret_cast<PRINTDLGW *>(pd);
280 qt_win_read_back_PRINTDLG(pdw, q, this);
281 qt_win_clean_up_PRINTDLG(&pdw);
282 }, {
283 PRINTDLGA *pda = reinterpret_cast<PRINTDLGA *>(pd);
284 qt_win_read_back_PRINTDLG(pda, q, this);
285 qt_win_clean_up_PRINTDLG(&pda);
286 });
287 // update printer validity
288 printer->d_func()->validPrinter = !ep->name.isEmpty();
289 }
290
291 // Cleanup...
292 GlobalFree(tempDevNames);
293
294 q->done(result);
295
296 return result;
297}
298
299void QPrintDialog::setVisible(bool visible)
300{
301 Q_D(QPrintDialog);
302
303 // its always modal, so we cannot hide a native print dialog
304 if (!visible)
305 return;
306
307 if (!warnIfNotNative(d->printer))
308 return;
309
310 (void)d->openWindowsPrintDialogModally();
311 return;
312}
313
314QT_END_NAMESPACE
315
316#include "moc_qprintdialog.cpp"
317
318#endif // QT_NO_PRINTDIALOG
Note: See TracBrowser for help on using the repository browser.