Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qprintdialog_win.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtPrintSupport/qtprintsupportglobal.h>
5
6#include "qprintdialog.h"
7
8#include <qwidget.h>
9#include <qapplication.h>
10#include <qmessagebox.h>
11#include <private/qapplication_p.h>
12
14#include <private/qprintengine_win_p.h>
16
17#if !defined(PD_NOCURRENTPAGE)
18#define PD_NOCURRENTPAGE 0x00800000
19#define PD_RESULT_PRINT 1
20#define PD_RESULT_APPLY 2
21#define START_PAGE_GENERAL 0XFFFFFFFF
22#endif
23
25
26using namespace Qt::StringLiterals;
27
28//extern void qt_win_eatMouseMove();
29
31{
32 Q_DECLARE_PUBLIC(QPrintDialog)
33public:
35 : engine(0), ep(0)
36 {
37 }
38
40
43};
44
45static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWindow *parentWindow,
46 QPrintDialog *pdlg,
47 QPrintDialogPrivate *d, HGLOBAL *tempDevNames)
48{
49 DEVMODE *devMode = d->ep->devMode;
50
51 if (devMode) {
52 int size = sizeof(DEVMODE) + devMode->dmDriverExtra;
53 pd->hDevMode = GlobalAlloc(GHND, size);
54 {
55 void *dest = GlobalLock(pd->hDevMode);
56 memcpy(dest, devMode, size);
57 GlobalUnlock(pd->hDevMode);
58 }
59 } else {
60 pd->hDevMode = NULL;
61 }
62 pd->hDevNames = tempDevNames;
63
64 pd->Flags = PD_RETURNDC;
65 pd->Flags |= PD_USEDEVMODECOPIESANDCOLLATE;
66
67 if (!pdlg->testOption(QPrintDialog::PrintSelection))
68 pd->Flags |= PD_NOSELECTION;
69 if (pdlg->testOption(QPrintDialog::PrintPageRange)) {
70 pd->nMinPage = pdlg->minPage();
71 pd->nMaxPage = pdlg->maxPage();
72 }
73
74 if (!pdlg->testOption(QPrintDialog::PrintToFile))
75 pd->Flags |= PD_DISABLEPRINTTOFILE;
76
77 if (pdlg->testOption(QPrintDialog::PrintSelection) && pdlg->printRange() == QPrintDialog::Selection)
78 pd->Flags |= PD_SELECTION;
79 else if (pdlg->testOption(QPrintDialog::PrintPageRange) && pdlg->printRange() == QPrintDialog::PageRange)
80 pd->Flags |= PD_PAGENUMS;
81 else if (pdlg->testOption(QPrintDialog::PrintCurrentPage) && pdlg->printRange() == QPrintDialog::CurrentPage)
82 pd->Flags |= PD_CURRENTPAGE;
83 else
84 pd->Flags |= PD_ALLPAGES;
85
86 // As stated by MSDN, to enable collate option when minpage==maxpage==0
87 // set the PD_NOPAGENUMS flag
88 if (pd->nMinPage==0 && pd->nMaxPage==0)
89 pd->Flags |= PD_NOPAGENUMS;
90
91 // Disable Current Page option if not required as default is Enabled
92 if (!pdlg->testOption(QPrintDialog::PrintCurrentPage))
93 pd->Flags |= PD_NOCURRENTPAGE;
94
95 // Default to showing the General tab first
96 pd->nStartPage = START_PAGE_GENERAL;
97
98 // We don't support more than one page range in the QPrinter API yet.
99 pd->nPageRanges = 1;
100 pd->nMaxPageRanges = 1;
101
102 if (d->ep->printToFile)
103 pd->Flags |= PD_PRINTTOFILE;
104
105 WId wId = parentWindow ? parentWindow->winId() : 0;
106 //QTBUG-118899 PrintDlg needs valid window handle in hwndOwner
107 //So in case there is no valid handle in the application,
108 //use the desktop as valid handle.
109 pd->hwndOwner = wId != 0 ? HWND(wId) : GetDesktopWindow();
110 pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage());
111 pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1;
112 pd->nCopies = d->printer->copyCount();
113}
114
116{
117 if (pd->Flags & PD_SELECTION) {
118 pdlg->setPrintRange(QPrintDialog::Selection);
119 pdlg->printer()->setPageRanges(QPageRanges());
120 } else if (pd->Flags & PD_PAGENUMS) {
121 pdlg->setPrintRange(QPrintDialog::PageRange);
122 pdlg->setFromTo(pd->lpPageRanges[0].nFromPage, pd->lpPageRanges[0].nToPage);
123 } else if (pd->Flags & PD_CURRENTPAGE) {
124 pdlg->setPrintRange(QPrintDialog::CurrentPage);
125 pdlg->printer()->setPageRanges(QPageRanges());
126 } else { // PD_ALLPAGES
127 pdlg->setPrintRange(QPrintDialog::AllPages);
128 pdlg->printer()->setPageRanges(QPageRanges());
129 }
130
131 d->ep->printToFile = (pd->Flags & PD_PRINTTOFILE) != 0;
132
133 d->engine->setGlobalDevMode(pd->hDevNames, pd->hDevMode);
134
135 if (d->ep->printToFile && d->ep->fileName.isEmpty())
136 d->ep->fileName = "FILE:"_L1;
137 else if (!d->ep->printToFile && d->ep->fileName == "FILE:"_L1)
138 d->ep->fileName.clear();
139}
140
141static bool warnIfNotNative(QPrinter *printer)
142{
143 if (printer->outputFormat() != QPrinter::NativeFormat) {
144 qWarning("QPrintDialog: Cannot be used on non-native printers");
145 return false;
146 }
147 return true;
148}
149
151 : QAbstractPrintDialog( *(new QPrintDialogPrivate), printer, parent)
152{
153 Q_D(QPrintDialog);
154 if (!warnIfNotNative(d->printer))
155 return;
156 d->engine = static_cast<QWin32PrintEngine *>(d->printer->printEngine());
157 d->ep = static_cast<QWin32PrintEngine *>(d->printer->printEngine())->d_func();
159}
160
162 : QAbstractPrintDialog( *(new QPrintDialogPrivate), 0, parent)
163{
164 Q_D(QPrintDialog);
165 if (!warnIfNotNative(d->printer))
166 return;
167 d->engine = static_cast<QWin32PrintEngine *>(d->printer->printEngine());
168 d->ep = static_cast<QWin32PrintEngine *>(d->printer->printEngine())->d_func();
170}
171
173{
174}
175
177{
178 if (!warnIfNotNative(printer()))
179 return 0;
180
181 Q_D(QPrintDialog);
182 return d->openWindowsPrintDialogModally();
183}
184
186{
187 Q_Q(QPrintDialog);
188 QWindow *parentWindow = q->windowHandle() ? q->windowHandle()->transientParent() : nullptr;
189 if (!parentWindow) {
190 QWidget *parent = q->parentWidget();
191 if (parent)
192 parent = parent->window();
193 else
195
196 // If there is no window, fall back to the print dialog itself
197 if (!parent)
198 parent = q;
199
200 parentWindow = parent->windowHandle();
201 }
202
203 q->QDialog::setVisible(true);
204
205 HGLOBAL *tempDevNames = engine->createGlobalDevNames();
206
207 bool done;
208 bool result;
209 bool doPrinting;
210
211 PRINTPAGERANGE pageRange;
212 PRINTDLGEX pd;
213 memset(&pd, 0, sizeof(PRINTDLGEX));
214 pd.lStructSize = sizeof(PRINTDLGEX);
215 pd.lpPageRanges = &pageRange;
216 qt_win_setup_PRINTDLGEX(&pd, parentWindow, q, this, tempDevNames);
217
218 do {
219 done = true;
220 doPrinting = false;
221 result = (PrintDlgEx(&pd) == S_OK);
222 if (result && (pd.dwResultAction == PD_RESULT_PRINT
223 || pd.dwResultAction == PD_RESULT_APPLY))
224 {
225 doPrinting = (pd.dwResultAction == PD_RESULT_PRINT);
226 if ((pd.Flags & PD_PAGENUMS)
227 && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage))
228 {
229 pd.lpPageRanges[0].nFromPage = 1;
230 pd.lpPageRanges[0].nToPage = 1;
231 done = false;
232 }
233 if (pd.hDC == 0)
234 result = false;
235 }
236
237 if (!done) {
238 QMessageBox::warning(nullptr,
239 QPrintDialog::tr("Print"),
240 QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."));
241 }
242 } while (!done);
243
244 q->QDialog::setVisible(false);
245
246// qt_win_eatMouseMove();
247
248 // write values back...
249 if (result && (pd.dwResultAction == PD_RESULT_PRINT
250 || pd.dwResultAction == PD_RESULT_APPLY))
251 {
253 // update printer validity
254 printer->d_func()->validPrinter = !printer->printerName().isEmpty();
255 }
256
257 // Cleanup...
258 GlobalFree(tempDevNames);
259
260 q->done(result && doPrinting);
261
262 return result && doPrinting;
263}
264
265void QPrintDialog::setVisible(bool visible)
266{
267 Q_D(QPrintDialog);
268
269 // its always modal, so we cannot hide a native print dialog
270 if (!visible)
271 return;
272
273 if (!warnIfNotNative(d->printer))
274 return;
275
276 (void)d->openWindowsPrintDialogModally();
277 return;
278}
279
281
282#include "moc_qprintdialog.cpp"
The QAbstractPrintDialog class provides a base implementation for print dialogs used to configure pri...
QPrinter * printer() const
Returns the printer that this printer dialog operates on.
static QWidget * activeWindow()
Returns the application top-level window that has the keyboard input focus, or \nullptr if no applica...
void setVisible(bool visible) override
\reimp
Definition qdialog.cpp:744
static StandardButton warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
QObject * parent
Definition qobject.h:73
The QPageRanges class represents a collection of page ranges.
Definition qpageranges.h:21
QWin32PrintEnginePrivate * ep
QWin32PrintEngine * engine
The QPrintDialog class provides a dialog for specifying the printer's configuration.
int exec() override
\reimp
~QPrintDialog()
Destroys the print dialog.
QPrintDialog(QPrinter *printer, QWidget *parent=nullptr)
Constructs a new modal printer dialog for the given printer with the given parent.
\reentrant
Definition qprinter.h:28
@ NativeFormat
Definition qprinter.h:69
QString printerName() const
Returns the printer name.
Definition qprinter.cpp:621
OutputFormat outputFormat() const
Definition qprinter.cpp:570
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
bool visible
whether the widget is visible
Definition qwidget.h:144
HGLOBAL * createGlobalDevNames()
\inmodule QtGui
Definition qwindow.h:63
Combined button and popup list for selecting options.
@ WA_DontShowOnScreen
Definition qnamespace.h:383
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
#define qWarning
Definition qlogging.h:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
static bool warnIfNotNative(QPrinter *printer)
#define START_PAGE_GENERAL
static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWindow *parentWindow, QPrintDialog *pdlg, QPrintDialogPrivate *d, HGLOBAL *tempDevNames)
#define PD_RESULT_PRINT
#define PD_NOCURRENTPAGE
static void qt_win_read_back_PRINTDLGEX(PRINTDLGEX *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d)
#define PD_RESULT_APPLY
app setAttribute(Qt::AA_DontShowIconsInMenus)