source: trunk/src/gui/dialogs/qpagesetupdialog_mac.mm@ 100

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

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

File size: 10.2 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#include "qpagesetupdialog.h"
43
44#include <qhash.h>
45#include <private/qapplication_p.h>
46#include <private/qprintengine_mac_p.h>
47#include <private/qabstractpagesetupdialog_p.h>
48
49#ifndef QT_NO_PRINTDIALOG
50
51QT_USE_NAMESPACE
52
53@class QCocoaPageLayoutDelegate;
54
55@interface QCocoaPageLayoutDelegate : NSObject {
56 QMacPrintEnginePrivate *pe;
57}
58- (id)initWithMacPrintEngine:(QMacPrintEnginePrivate *)printEngine;
59- (void)pageLayoutDidEnd:(NSPageLayout *)pageLayout
60 returnCode:(int)returnCode contextInfo:(void *)contextInfo;
61@end
62
63@implementation QCocoaPageLayoutDelegate
64- (id)initWithMacPrintEngine:(QMacPrintEnginePrivate *)printEngine;
65{
66 self = [super init];
67 if (self) {
68 pe = printEngine;
69 }
70 return self;
71
72}
73- (void)pageLayoutDidEnd:(NSPageLayout *)pageLayout
74 returnCode:(int)returnCode contextInfo:(void *)contextInfo
75{
76 Q_UNUSED(pageLayout);
77 QPageSetupDialog *dialog = static_cast<QPageSetupDialog *>(contextInfo);
78 if (returnCode == NSOKButton) {
79 PMRect paperRect;
80 PMGetUnadjustedPaperRect(pe->format, &paperRect);
81 pe->customSize = QSizeF(paperRect.right - paperRect.left,
82 paperRect.bottom - paperRect.top);
83 }
84 dialog->done((returnCode == NSOKButton) ? QDialog::Accepted : QDialog::Rejected);
85}
86@end
87
88QT_BEGIN_NAMESPACE
89
90extern void macStartInterceptWindowTitle(QWidget *window);
91extern void macStopInterceptWindowTitle();
92
93class QPageSetupDialogPrivate : public QAbstractPageSetupDialogPrivate
94{
95 Q_DECLARE_PUBLIC(QPageSetupDialog)
96
97public:
98 QPageSetupDialogPrivate() : ep(0)
99#ifndef QT_MAC_USE_COCOA
100 ,upp(0)
101#else
102 ,pageLayout(0)
103#endif
104 {}
105
106 ~QPageSetupDialogPrivate() {
107#ifndef QT_MAC_USE_COCOA
108 if (upp) {
109 DisposePMSheetDoneUPP(upp);
110 upp = 0;
111 }
112 QHash<PMPrintSession, QPageSetupDialogPrivate *>::iterator it = sheetCallbackMap.begin();
113 while (it != sheetCallbackMap.end()) {
114 if (it.value() == this) {
115 it = sheetCallbackMap.erase(it);
116 } else {
117 ++it;
118 }
119 }
120#endif
121 }
122
123#ifndef QT_MAC_USE_COCOA
124 void openCarbonPageLayout(Qt::WindowModality modality);
125 void closeCarbonPageLayout();
126 static void pageSetupDialogSheetDoneCallback(PMPrintSession printSession, WindowRef /*documentWindow*/, Boolean accepted) {
127 QPageSetupDialogPrivate *priv = sheetCallbackMap.value(printSession);
128 if (!priv) {
129 qWarning("%s:%d: QPageSetupDialog::exec: Could not retrieve data structure, "
130 "you most likely now have an infinite modal loop", __FILE__, __LINE__);
131 return;
132 }
133 priv->q_func()->done(accepted ? QDialog::Accepted : QDialog::Rejected);
134 }
135#else
136 void openCocoaPageLayout(Qt::WindowModality modality);
137 void closeCocoaPageLayout();
138#endif
139
140 QMacPrintEnginePrivate *ep;
141#ifndef QT_MAC_USE_COCOA
142 PMSheetDoneUPP upp;
143 static QHash<PMPrintSession, QPageSetupDialogPrivate*> sheetCallbackMap;
144#else
145 NSPageLayout *pageLayout;
146#endif
147};
148
149#ifndef QT_MAC_USE_COCOA
150QHash<PMPrintSession, QPageSetupDialogPrivate*> QPageSetupDialogPrivate::sheetCallbackMap;
151void QPageSetupDialogPrivate::openCarbonPageLayout(Qt::WindowModality modality)
152{
153 Q_Q(QPageSetupDialog);
154 // If someone is reusing a QPrinter object, the end released all our old
155 // information. In this case, we must reinitialize.
156 if (ep->session == 0)
157 ep->initialize();
158
159 sheetCallbackMap.insert(ep->session, this);
160 if (modality == Qt::ApplicationModal) {
161 QWidget modal_widg(0, Qt::Window);
162 modal_widg.setObjectName(QLatin1String(__FILE__ "__modal_dlg"));
163 modal_widg.createWinId();
164 QApplicationPrivate::enterModal(&modal_widg);
165 QApplicationPrivate::native_modal_dialog_active = true;
166 Boolean accepted;
167 PMSessionPageSetupDialog(ep->session, ep->format, &accepted);
168 QApplicationPrivate::leaveModal(&modal_widg);
169 QApplicationPrivate::native_modal_dialog_active = false;
170 pageSetupDialogSheetDoneCallback(ep->session, 0, accepted);
171 } else {
172 // Window Modal means that we use a sheet at the moment, there's no other way to do it correctly.
173 if (!upp)
174 upp = NewPMSheetDoneUPP(QPageSetupDialogPrivate::pageSetupDialogSheetDoneCallback);
175 PMSessionUseSheets(ep->session, qt_mac_window_for(q->parentWidget()), upp);
176 Boolean unused;
177 PMSessionPageSetupDialog(ep->session, ep->format, &unused);
178 }
179}
180
181void QPageSetupDialogPrivate::closeCarbonPageLayout()
182{
183 // if the margins have changed, we have to use the margins from the new
184 // PMFormat object
185 if (q_func()->result() == QDialog::Accepted) {
186 PMPaper paper;
187 PMPaperMargins margins;
188 PMGetPageFormatPaper(ep->format, &paper);
189 PMPaperGetMargins(paper, &margins);
190 ep->leftMargin = margins.left;
191 ep->topMargin = margins.top;
192 ep->rightMargin = margins.right;
193 ep->bottomMargin = margins.bottom;
194
195 PMRect paperRect;
196 PMGetUnadjustedPaperRect(ep->format, &paperRect);
197 ep->customSize = QSizeF(paperRect.right - paperRect.left,
198 paperRect.bottom - paperRect.top);
199 }
200 sheetCallbackMap.remove(ep->session);
201}
202#else
203void QPageSetupDialogPrivate::openCocoaPageLayout(Qt::WindowModality modality)
204{
205 Q_Q(QPageSetupDialog);
206
207 // If someone is reusing a QPrinter object, the end released all our old
208 // information. In this case, we must reinitialize.
209 if (ep->session == 0)
210 ep->initialize();
211
212 macStartInterceptWindowTitle(q);
213 pageLayout = [NSPageLayout pageLayout];
214 // Keep a copy to this since we plan on using it for a bit.
215 [pageLayout retain];
216 QCocoaPageLayoutDelegate *delegate = [[QCocoaPageLayoutDelegate alloc] initWithMacPrintEngine:ep];
217
218 if (modality == Qt::ApplicationModal) {
219 int rval = [pageLayout runModalWithPrintInfo:ep->printInfo];
220 [delegate pageLayoutDidEnd:pageLayout returnCode:rval contextInfo:q];
221 } else {
222 Q_ASSERT(q->parentWidget());
223 [pageLayout beginSheetWithPrintInfo:ep->printInfo
224 modalForWindow:qt_mac_window_for(q->parentWidget())
225 delegate:delegate
226 didEndSelector:@selector(pageLayoutDidEnd:returnCode:contextInfo:)
227 contextInfo:q];
228 }
229
230 macStopInterceptWindowTitle();
231}
232
233void QPageSetupDialogPrivate::closeCocoaPageLayout()
234{
235 [pageLayout release];
236 pageLayout = 0;
237}
238#endif
239
240QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
241 : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), printer, parent)
242{
243 Q_D(QPageSetupDialog);
244 d->ep = static_cast<QMacPrintEngine *>(d->printer->paintEngine())->d_func();
245}
246
247QPageSetupDialog::QPageSetupDialog(QWidget *parent)
248 : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), 0, parent)
249{
250 Q_D(QPageSetupDialog);
251 d->ep = static_cast<QMacPrintEngine *>(d->printer->paintEngine())->d_func();
252}
253
254/*!
255 \reimp
256*/
257void QPageSetupDialog::setVisible(bool visible)
258{
259 Q_D(QPageSetupDialog);
260
261 if (d->printer->outputFormat() != QPrinter::NativeFormat)
262 return;
263
264#ifndef QT_MAC_USE_COCOA
265 bool isCurrentlyVisible = d->sheetCallbackMap.contains(d->ep->session);
266#else
267 bool isCurrentlyVisible = (d->pageLayout != 0);
268#endif
269 if (!visible == !isCurrentlyVisible)
270 return;
271
272 if (visible) {
273#ifndef QT_MAC_USE_COCOA
274 d->openCarbonPageLayout(parentWidget() ? Qt::WindowModal
275 : Qt::ApplicationModal);
276#else
277 d->openCocoaPageLayout(parentWidget() ? Qt::WindowModal
278 : Qt::ApplicationModal);
279#endif
280 return;
281 } else {
282#ifndef QT_MAC_USE_COCOA
283 d->closeCarbonPageLayout();
284#else
285 if (d->pageLayout) {
286 d->closeCocoaPageLayout();
287 return;
288 }
289#endif
290 }
291}
292
293int QPageSetupDialog::exec()
294{
295 Q_D(QPageSetupDialog);
296
297 if (d->printer->outputFormat() != QPrinter::NativeFormat)
298 return Rejected;
299
300#ifndef QT_MAC_USE_COCOA
301 d->openCarbonPageLayout(Qt::ApplicationModal);
302 d->closeCarbonPageLayout();
303#else
304 QMacCocoaAutoReleasePool pool;
305 d->openCocoaPageLayout(Qt::ApplicationModal);
306 d->closeCocoaPageLayout();
307#endif
308 return result();
309}
310
311QT_END_NAMESPACE
312
313#endif QT_NO_PRINTDIALOG
Note: See TracBrowser for help on using the repository browser.