|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the QtGui module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
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 |
|
51 QT_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 |
|
88 QT_BEGIN_NAMESPACE |
|
89 |
|
90 extern void macStartInterceptWindowTitle(QWidget *window); |
|
91 extern void macStopInterceptWindowTitle(); |
|
92 |
|
93 class QPageSetupDialogPrivate : public QAbstractPageSetupDialogPrivate |
|
94 { |
|
95 Q_DECLARE_PUBLIC(QPageSetupDialog) |
|
96 |
|
97 public: |
|
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 |
|
150 QHash<PMPrintSession, QPageSetupDialogPrivate*> QPageSetupDialogPrivate::sheetCallbackMap; |
|
151 void 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 |
|
181 void 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 |
|
203 void 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 |
|
233 void QPageSetupDialogPrivate::closeCocoaPageLayout() |
|
234 { |
|
235 [pageLayout release]; |
|
236 pageLayout = 0; |
|
237 } |
|
238 #endif |
|
239 |
|
240 QPageSetupDialog::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 |
|
247 QPageSetupDialog::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 void QPageSetupDialog::setVisible(bool visible) |
|
255 { |
|
256 Q_D(QPageSetupDialog); |
|
257 |
|
258 if (d->printer->outputFormat() != QPrinter::NativeFormat) |
|
259 return; |
|
260 |
|
261 #ifndef QT_MAC_USE_COCOA |
|
262 bool isCurrentlyVisible = d->sheetCallbackMap.contains(d->ep->session); |
|
263 #else |
|
264 bool isCurrentlyVisible = (d->pageLayout != 0); |
|
265 #endif |
|
266 if (!visible == !isCurrentlyVisible) |
|
267 return; |
|
268 |
|
269 if (visible) { |
|
270 #ifndef QT_MAC_USE_COCOA |
|
271 d->openCarbonPageLayout(parentWidget() ? Qt::WindowModal |
|
272 : Qt::ApplicationModal); |
|
273 #else |
|
274 d->openCocoaPageLayout(parentWidget() ? Qt::WindowModal |
|
275 : Qt::ApplicationModal); |
|
276 #endif |
|
277 return; |
|
278 } else { |
|
279 #ifndef QT_MAC_USE_COCOA |
|
280 d->closeCarbonPageLayout(); |
|
281 #else |
|
282 if (d->pageLayout) { |
|
283 d->closeCocoaPageLayout(); |
|
284 return; |
|
285 } |
|
286 #endif |
|
287 } |
|
288 } |
|
289 |
|
290 int QPageSetupDialog::exec() |
|
291 { |
|
292 Q_D(QPageSetupDialog); |
|
293 |
|
294 if (d->printer->outputFormat() != QPrinter::NativeFormat) |
|
295 return Rejected; |
|
296 |
|
297 #ifndef QT_MAC_USE_COCOA |
|
298 d->openCarbonPageLayout(Qt::ApplicationModal); |
|
299 d->closeCarbonPageLayout(); |
|
300 #else |
|
301 QMacCocoaAutoReleasePool pool; |
|
302 d->openCocoaPageLayout(Qt::ApplicationModal); |
|
303 d->closeCocoaPageLayout(); |
|
304 #endif |
|
305 return result(); |
|
306 } |
|
307 |
|
308 QT_END_NAMESPACE |
|
309 |
|
310 #endif QT_NO_PRINTDIALOG |