Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qpagesetupdialog_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// Qt-Security score:significant reason:default
4
6
7#include <qapplication.h>
8
9#include <private/qprintengine_win_p.h>
11#include "qprinter.h"
12#include <qpa/qplatformwindow_p.h>
13
15
16QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
17 : QDialog(*(new QPageSetupDialogPrivate(printer)), parent)
18{
19 setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
20 setAttribute(Qt::WA_DontShowOnScreen);
21}
22
23QPageSetupDialog::QPageSetupDialog(QWidget *parent)
24 : QDialog(*(new QPageSetupDialogPrivate(nullptr)), parent)
25{
26 setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
27 setAttribute(Qt::WA_DontShowOnScreen);
28}
29
30int QPageSetupDialog::exec()
31{
32 Q_D(QPageSetupDialog);
33
34 if (d->printer->outputFormat() != QPrinter::NativeFormat)
35 return Rejected;
36
37 QWin32PrintEngine *engine = static_cast<QWin32PrintEngine*>(d->printer->paintEngine());
38 QWin32PrintEnginePrivate *ep = static_cast<QWin32PrintEnginePrivate *>(engine->d_ptr.data());
39
40 PAGESETUPDLG psd;
41 memset(&psd, 0, sizeof(PAGESETUPDLG));
42 psd.lStructSize = sizeof(PAGESETUPDLG);
43
44 // we need a temp DEVMODE struct if we don't have a global DEVMODE
45 HGLOBAL hDevMode = nullptr;
46 int devModeSize = 0;
47 if (!engine->globalDevMode()) {
48 devModeSize = sizeof(DEVMODE) + ep->devMode->dmDriverExtra;
49 hDevMode = GlobalAlloc(GHND, devModeSize);
50 if (hDevMode) {
51 void *dest = GlobalLock(hDevMode);
52 memcpy(dest, ep->devMode, devModeSize);
53 GlobalUnlock(hDevMode);
54 }
55 psd.hDevMode = hDevMode;
56 } else {
57 psd.hDevMode = engine->globalDevMode();
58 }
59
60 HGLOBAL *tempDevNames = engine->createGlobalDevNames();
61 psd.hDevNames = tempDevNames;
62
63 QWidget *parent = parentWidget();
64 parent = parent ? parent->window() : QApplication::activeWindow();
65 Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created));
66
67 QWindow *parentWindow = parent ? parent->windowHandle() : nullptr;
68 auto *windowInterface = parentWindow
69 ? parentWindow->nativeInterface<QNativeInterface::Private::QWindowsWindow>()
70 : nullptr;
71 psd.hwndOwner = windowInterface ? windowInterface->handle() : nullptr;
72 psd.Flags = PSD_MARGINS;
73 QPageLayout layout = d->printer->pageLayout();
74 switch (layout.units()) {
75 case QPageLayout::Millimeter:
76 case QPageLayout::Inch:
77 break;
78 case QPageLayout::Point:
79 case QPageLayout::Pica:
80 case QPageLayout::Didot:
81 case QPageLayout::Cicero:
82 layout.setUnits(QLocale::system().measurementSystem() == QLocale::MetricSystem ? QPageLayout::Millimeter
83 : QPageLayout::Inch);
84 break;
85 }
86 qreal multiplier = 1.0;
87 if (layout.units() == QPageLayout::Millimeter) {
88 psd.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
89 multiplier = 100.0;
90 } else { // QPageLayout::Inch)
91 psd.Flags |= PSD_INTHOUSANDTHSOFINCHES;
92 multiplier = 1000.0;
93 }
94 psd.rtMargin.left = layout.margins().left() * multiplier;
95 psd.rtMargin.top = layout.margins().top() * multiplier;
96 psd.rtMargin.right = layout.margins().right() * multiplier;
97 psd.rtMargin.bottom = layout.margins().bottom() * multiplier;
98
99 QDialog::setVisible(true);
100 bool result = PageSetupDlg(&psd);
101 QDialog::setVisible(false);
102 if (result) {
103 engine->setGlobalDevMode(psd.hDevNames, psd.hDevMode);
104 QPageSize pageSize;
105 // try to read orientation and paper size ID from the dialog's devmode struct
106 if (psd.hDevMode) {
107 DEVMODE *rDevmode = reinterpret_cast<DEVMODE*>(GlobalLock(psd.hDevMode));
108 if (rDevmode->dmFields & DM_ORIENTATION) {
109 layout.setOrientation(rDevmode->dmOrientation == DMORIENT_PORTRAIT
110 ? QPageLayout::Portrait : QPageLayout::Landscape);
111 }
112 if (rDevmode->dmFields & DM_PAPERSIZE)
113 pageSize = QPageSize::id(rDevmode->dmPaperSize);
114 GlobalUnlock(rDevmode);
115 }
116 // fall back to use our own matching, and assume that paper that's wider than long means landscape
117 if (!pageSize.isValid() || pageSize.id() == QPageSize::Custom) {
118 QSizeF unitSize(psd.ptPaperSize.x / multiplier, psd.ptPaperSize.y / multiplier);
119 if (unitSize.width() > unitSize.height()) {
120 layout.setOrientation(QPageLayout::Landscape);
121 unitSize.transpose();
122 } else {
123 layout.setOrientation(QPageLayout::Portrait);
124 }
125 pageSize = QPageSize(unitSize, layout.units() == QPageLayout::Inch
126 ? QPageSize::Inch : QPageSize::Millimeter);
127 }
128 layout.setPageSize(pageSize, layout.minimumMargins());
129
130 const QMarginsF margins(psd.rtMargin.left, psd.rtMargin.top, psd.rtMargin.right, psd.rtMargin.bottom);
131 layout.setMargins(margins / multiplier, QPageLayout::OutOfBoundsPolicy::Clamp);
132 d->printer->setPageLayout(layout);
133
134 // copy from our temp DEVMODE struct
135 if (!engine->globalDevMode() && hDevMode) {
136 // Make sure memory is allocated
137 if (ep->ownsDevMode && ep->devMode)
138 free(ep->devMode);
139 ep->devMode = reinterpret_cast<DEVMODE *>(malloc(devModeSize));
140 QWin32PrintEnginePrivate::initializeDevMode(ep->devMode);
141 ep->ownsDevMode = true;
142
143 // Copy
144 void *src = GlobalLock(hDevMode);
145 memcpy(ep->devMode, src, devModeSize);
146 GlobalUnlock(hDevMode);
147 }
148 }
149
150 if (!engine->globalDevMode() && hDevMode)
151 GlobalFree(hDevMode);
152 GlobalFree(tempDevNames);
153 done(result);
154 return result;
155}
156
157void QPageSetupDialog::setVisible(bool visible)
158{
159 if (!visible)
160 return;
161 exec();
162}
163
164QT_END_NAMESPACE
Combined button and popup list for selecting options.