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