Qt 4.8
qpagesetupdialog_mac.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
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 
52 
54 
55 @interface QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) : NSObject {
57 }
58 - (id)initWithMacPrintEngine:(QMacPrintEnginePrivate *)printEngine;
59 - (void)pageLayoutDidEnd:(NSPageLayout *)pageLayout
60  returnCode:(int)returnCode contextInfo:(void *)contextInfo;
61 @end
62 
63 @implementation QT_MANGLE_NAMESPACE(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 
89 
91 extern void macStopInterceptWindowTitle();
92 
94 {
96 
97 public:
99 #ifndef QT_MAC_USE_COCOA
100  ,upp(0)
101 #else
102  ,pageLayout(0)
103 #endif
104  {}
105 
107 #ifndef QT_MAC_USE_COCOA
108  if (upp) {
109  DisposePMSheetDoneUPP(upp);
110  upp = 0;
111  }
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 
141 #ifndef QT_MAC_USE_COCOA
142  PMSheetDoneUPP upp;
144 #else
145  NSPageLayout *pageLayout;
146 #endif
147 };
148 
149 #ifndef QT_MAC_USE_COCOA
152 {
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);
166  Boolean accepted;
167  PMSessionPageSetupDialog(ep->session, ep->format, &accepted);
168  QApplicationPrivate::leaveModal(&modal_widg);
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)
175  PMSessionUseSheets(ep->session, qt_mac_window_for(q->parentWidget()), upp);
176  Boolean unused;
177  PMSessionPageSetupDialog(ep->session, ep->format, &unused);
178  }
179 }
180 
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 {
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 
213  pageLayout = [NSPageLayout pageLayout];
214  // Keep a copy to this since we plan on using it for a bit.
215  [pageLayout retain];
216  QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) *delegate = [[QT_MANGLE_NAMESPACE(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 
231 }
232 
233 void QPageSetupDialogPrivate::closeCocoaPageLayout()
234 {
235  // NSPageLayout can change the session behind our back and then our
236  // d->ep->session object will become a dangling pointer. Update it
237  // based on the "current" session
238  ep->session = static_cast<PMPrintSession>([ep->printInfo PMPrintSession]);
239 
240  [pageLayout release];
241  pageLayout = 0;
242 }
243 #endif
244 
246  : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), printer, parent)
247 {
249  d->ep = static_cast<QMacPrintEngine *>(d->printer->paintEngine())->d_func();
250 }
251 
254 {
256  d->ep = static_cast<QMacPrintEngine *>(d->printer->paintEngine())->d_func();
257 }
258 
260 {
262 
263  if (d->printer->outputFormat() != QPrinter::NativeFormat)
264  return;
265 
266 #ifndef QT_MAC_USE_COCOA
267  bool isCurrentlyVisible = d->sheetCallbackMap.contains(d->ep->session);
268 #else
269  bool isCurrentlyVisible = (d->pageLayout != 0);
270 #endif
271  if (!visible == !isCurrentlyVisible)
272  return;
273 
274  if (visible) {
275 #ifndef QT_MAC_USE_COCOA
276  d->openCarbonPageLayout(parentWidget() ? Qt::WindowModal
278 #else
279  d->openCocoaPageLayout(parentWidget() ? Qt::WindowModal
280  : Qt::ApplicationModal);
281 #endif
282  return;
283  } else {
284 #ifndef QT_MAC_USE_COCOA
285  d->closeCarbonPageLayout();
286 #else
287  if (d->pageLayout) {
288  d->closeCocoaPageLayout();
289  return;
290  }
291 #endif
292  }
293 }
294 
296 {
298 
299  if (d->printer->outputFormat() != QPrinter::NativeFormat)
300  return Rejected;
301 
302 #ifndef QT_MAC_USE_COCOA
303  d->openCarbonPageLayout(Qt::ApplicationModal);
304  d->closeCarbonPageLayout();
305 #else
307  d->openCocoaPageLayout(Qt::ApplicationModal);
308  d->closeCocoaPageLayout();
309 #endif
310  return result();
311 }
312 
314 
315 #endif /* QT_NO_PRINTDIALOG */
double d
Definition: qnumeric_p.h:62
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define it(className, varName)
void macStartInterceptWindowTitle(QWidget *window)
struct OpaqueWindowPtr * WindowRef
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
T & value() const
Returns a modifiable reference to the current item&#39;s value.
Definition: qhash.h:348
The QAbstractPageSetupDialog class provides a base for implementations of page setup dialogs...
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define Q_D(Class)
Definition: qglobal.h:2482
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
OSWindowRef qt_mac_window_for(const QWidget *)
Definition: qwidget_mac.mm:484
void setObjectName(const QString &name)
Definition: qobject.cpp:1112
#define Q_Q(Class)
Definition: qglobal.h:2483
QPageSetupDialog(QPrinter *printer, QWidget *parent=0)
Constructs a page setup dialog that configures printer with parent as the parent widget.
void done(int result)
Reimplemented Function
NSWindow * window
The QPageSetupDialog class provides a configuration dialog for the page-related options on a printer...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QMacPrintEnginePrivate * pe
bool visible
whether the widget is visible
Definition: qwidget.h:191
The QPrinter class is a paint device that paints on a printer.
Definition: qprinter.h:66
Q_CORE_EXPORT void qWarning(const char *,...)
static QHash< PMPrintSession, QPageSetupDialogPrivate * > sheetCallbackMap
QMacPrintEnginePrivate * ep
static void pageSetupDialogSheetDoneCallback(PMPrintSession printSession, WindowRef, Boolean accepted)
void openCarbonPageLayout(Qt::WindowModality modality)
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
#define QT_MANGLE_NAMESPACE(name)
Definition: qglobal.h:106
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
int result() const
In general returns the modal dialog&#39;s result code, Accepted or Rejected.
Definition: qdialog.cpp:458
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
Definition: qhash.h:330
static const QMetaObjectPrivate * priv(const uint *data)
static bool native_modal_dialog_active
void macStopInterceptWindowTitle()
#define QT_USE_NAMESPACE
This macro expands to using QT_NAMESPACE if QT_NAMESPACE is defined and nothing otherwise.
Definition: qglobal.h:88
void createWinId()
Definition: qwidget.cpp:2626
static void leaveModal(QWidget *)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
WindowModality
Definition: qnamespace.h:1683
static void enterModal(QWidget *)
virtual void setVisible(bool visible)
Reimplemented Function