1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qpagesetupdialog.h"
41 
42 #include <qapplication.h>
43 
44 #include "../kernel/qprintengine_win_p.h"
45 #include "qpagesetupdialog_p.h"
46 #include "qprinter.h"
47 #include <qpa/qplatformnativeinterface.h>
48 
49 QT_BEGIN_NAMESPACE
50 
QPageSetupDialog(QPrinter * printer,QWidget * parent)51 QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
52     : QDialog(*(new QPageSetupDialogPrivate(printer)), parent)
53 {
54     setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
55     setAttribute(Qt::WA_DontShowOnScreen);
56 }
57 
QPageSetupDialog(QWidget * parent)58 QPageSetupDialog::QPageSetupDialog(QWidget *parent)
59     : QDialog(*(new QPageSetupDialogPrivate(0)), parent)
60 {
61     setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
62     setAttribute(Qt::WA_DontShowOnScreen);
63 }
64 
exec()65 int QPageSetupDialog::exec()
66 {
67     Q_D(QPageSetupDialog);
68 
69     if (d->printer->outputFormat() != QPrinter::NativeFormat)
70         return Rejected;
71 
72     QWin32PrintEngine *engine = static_cast<QWin32PrintEngine*>(d->printer->paintEngine());
73     QWin32PrintEnginePrivate *ep = static_cast<QWin32PrintEnginePrivate *>(engine->d_ptr.data());
74 
75     PAGESETUPDLG psd;
76     memset(&psd, 0, sizeof(PAGESETUPDLG));
77     psd.lStructSize = sizeof(PAGESETUPDLG);
78 
79     // we need a temp DEVMODE struct if we don't have a global DEVMODE
80     HGLOBAL hDevMode = 0;
81     int devModeSize = 0;
82     if (!engine->globalDevMode()) {
83         devModeSize = sizeof(DEVMODE) + ep->devMode->dmDriverExtra;
84         hDevMode = GlobalAlloc(GHND, devModeSize);
85         if (hDevMode) {
86             void *dest = GlobalLock(hDevMode);
87             memcpy(dest, ep->devMode, devModeSize);
88             GlobalUnlock(hDevMode);
89         }
90         psd.hDevMode = hDevMode;
91     } else {
92         psd.hDevMode = engine->globalDevMode();
93     }
94 
95     HGLOBAL *tempDevNames = engine->createGlobalDevNames();
96     psd.hDevNames = tempDevNames;
97 
98     QWidget *parent = parentWidget();
99     parent = parent ? parent->window() : QApplication::activeWindow();
100     Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created));
101 
102     QWindow *parentWindow = parent ? parent->windowHandle() : 0;
103     psd.hwndOwner = parentWindow ? (HWND)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", parentWindow) : 0;
104 
105     psd.Flags = PSD_MARGINS;
106     QPageLayout layout = d->printer->pageLayout();
107     switch (layout.units()) {
108     case QPageLayout::Millimeter:
109     case QPageLayout::Inch:
110         break;
111     case QPageLayout::Point:
112     case QPageLayout::Pica:
113     case QPageLayout::Didot:
114     case QPageLayout::Cicero:
115         layout.setUnits(QLocale::system().measurementSystem() == QLocale::MetricSystem ? QPageLayout::Millimeter
116                                                                                        : QPageLayout::Inch);
117         break;
118     }
119     qreal multiplier = 1.0;
120     if (layout.units() == QPageLayout::Millimeter) {
121         psd.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
122         multiplier = 100.0;
123     } else { // QPageLayout::Inch)
124         psd.Flags |= PSD_INTHOUSANDTHSOFINCHES;
125         multiplier = 1000.0;
126     }
127     psd.rtMargin.left   = layout.margins().left() * multiplier;
128     psd.rtMargin.top    = layout.margins().top() * multiplier;
129     psd.rtMargin.right  = layout.margins().right() * multiplier;
130     psd.rtMargin.bottom = layout.margins().bottom() * multiplier;
131 
132     QDialog::setVisible(true);
133     bool result = PageSetupDlg(&psd);
134     QDialog::setVisible(false);
135     if (result) {
136         engine->setGlobalDevMode(psd.hDevNames, psd.hDevMode);
137         d->printer->setPageSize(QPageSize(QSizeF(psd.ptPaperSize.x / multiplier, psd.ptPaperSize.y / multiplier),
138                                 layout.units() == QPageLayout::Inch ? QPageSize::Inch : QPageSize::Millimeter));
139         const QMarginsF margins(psd.rtMargin.left, psd.rtMargin.top, psd.rtMargin.right, psd.rtMargin.bottom);
140         d->printer->setPageMargins(margins / multiplier, layout.units());
141 
142         // copy from our temp DEVMODE struct
143         if (!engine->globalDevMode() && hDevMode) {
144             // Make sure memory is allocated
145             if (ep->ownsDevMode && ep->devMode)
146                 free(ep->devMode);
147             ep->devMode = (DEVMODE *) malloc(devModeSize);
148             ep->ownsDevMode = true;
149 
150             // Copy
151             void *src = GlobalLock(hDevMode);
152             memcpy(ep->devMode, src, devModeSize);
153             GlobalUnlock(hDevMode);
154         }
155     }
156 
157     if (!engine->globalDevMode() && hDevMode)
158         GlobalFree(hDevMode);
159     GlobalFree(tempDevNames);
160     done(result);
161     return result;
162 }
163 
setVisible(bool visible)164 void QPageSetupDialog::setVisible(bool visible)
165 {
166     if (!visible)
167         return;
168     exec();
169 }
170 
171 QT_END_NAMESPACE
172