source: trunk/src/gui/dialogs/qfontdialog_mac.mm

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 22.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qfontdialog_p.h"
43#if !defined(QT_NO_FONTDIALOG) && defined(Q_WS_MAC)
44#include <qapplication.h>
45#include <qdialogbuttonbox.h>
46#include <qlineedit.h>
47#include <private/qapplication_p.h>
48#include <private/qfont_p.h>
49#include <private/qfontengine_p.h>
50#include <private/qt_cocoa_helpers_mac_p.h>
51#include <private/qt_mac_p.h>
52#include <qabstracteventdispatcher.h>
53#include <qdebug.h>
54#import <AppKit/AppKit.h>
55#import <Foundation/Foundation.h>
56
57#if !CGFLOAT_DEFINED
58typedef float CGFloat; // Should only not be defined on 32-bit platforms
59#endif
60
61QT_BEGIN_NAMESPACE
62
63extern void macStartInterceptNSPanelCtor();
64extern void macStopInterceptNSPanelCtor();
65extern NSButton *macCreateButton(const char *text, NSView *superview);
66extern bool qt_mac_is_macsheet(const QWidget *w); // qwidget_mac.mm
67
68QT_END_NAMESPACE
69QT_USE_NAMESPACE
70
71// should a priori be kept in sync with qcolordialog_mac.mm
72const CGFloat ButtonMinWidth = 78.0;
73const CGFloat ButtonMinHeight = 32.0;
74const CGFloat ButtonSpacing = 0.0;
75const CGFloat ButtonTopMargin = 0.0;
76const CGFloat ButtonBottomMargin = 7.0;
77const CGFloat ButtonSideMargin = 9.0;
78
79// looks better with some margins
80const CGFloat DialogTopMargin = 7.0;
81const CGFloat DialogSideMargin = 9.0;
82
83const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
84
85@class QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate);
86
87
88#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
89
90@protocol NSWindowDelegate <NSObject>
91- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
92@end
93
94#endif
95
96@interface QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) : NSObject <NSWindowDelegate> {
97 NSFontPanel *mFontPanel;
98 NSView *mStolenContentView;
99 NSButton *mOkButton;
100 NSButton *mCancelButton;
101 QFontDialogPrivate *mPriv;
102 QFont *mQtFont;
103 BOOL mPanelHackedWithButtons;
104 CGFloat mDialogExtraWidth;
105 CGFloat mDialogExtraHeight;
106 int mReturnCode;
107 BOOL mAppModal;
108}
109- (id)initWithFontPanel:(NSFontPanel *)panel
110 stolenContentView:(NSView *)stolenContentView
111 okButton:(NSButton *)okButton
112 cancelButton:(NSButton *)cancelButton
113 priv:(QFontDialogPrivate *)priv
114 extraWidth:(CGFloat)extraWidth
115 extraHeight:(CGFloat)extraHeight;
116- (void)showModelessPanel;
117- (void)showWindowModalSheet:(QWidget *)docWidget;
118- (void)runApplicationModalPanel;
119- (BOOL)isAppModal;
120- (void)changeFont:(id)sender;
121- (void)changeAttributes:(id)sender;
122- (BOOL)windowShouldClose:(id)window;
123- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
124- (void)relayout;
125- (void)relayoutToContentSize:(NSSize)frameSize;
126- (void)onOkClicked;
127- (void)onCancelClicked;
128- (NSFontPanel *)fontPanel;
129- (NSWindow *)actualPanel;
130- (NSSize)dialogExtraSize;
131- (void)setQtFont:(const QFont &)newFont;
132- (QFont)qtFont;
133- (void)finishOffWithCode:(NSInteger)result;
134- (void)cleanUpAfterMyself;
135- (void)setSubwindowStacking;
136@end
137
138static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
139{
140 QFont newFont;
141 if (cocoaFont) {
142 int pSize = qRound([cocoaFont pointSize]);
143 QString family(qt_mac_NSStringToQString([cocoaFont familyName]));
144 QString typeface(qt_mac_NSStringToQString([cocoaFont fontName]));
145
146 int hyphenPos = typeface.indexOf(QLatin1Char('-'));
147 if (hyphenPos != -1) {
148 typeface.remove(0, hyphenPos + 1);
149 } else {
150 typeface = QLatin1String("Normal");
151 }
152
153 newFont = QFontDatabase().font(family, typeface, pSize);
154 newFont.setUnderline(resolveFont.underline());
155 newFont.setStrikeOut(resolveFont.strikeOut());
156
157 }
158 return newFont;
159}
160
161@implementation QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate)
162- (id)initWithFontPanel:(NSFontPanel *)panel
163 stolenContentView:(NSView *)stolenContentView
164 okButton:(NSButton *)okButton
165 cancelButton:(NSButton *)cancelButton
166 priv:(QFontDialogPrivate *)priv
167 extraWidth:(CGFloat)extraWidth
168 extraHeight:(CGFloat)extraHeight
169{
170 self = [super init];
171 mFontPanel = panel;
172 mStolenContentView = stolenContentView;
173 mOkButton = okButton;
174 mCancelButton = cancelButton;
175 mPriv = priv;
176 mPanelHackedWithButtons = (okButton != 0);
177 mDialogExtraWidth = extraWidth;
178 mDialogExtraHeight = extraHeight;
179 mReturnCode = -1;
180 mAppModal = false;
181
182 if (mPanelHackedWithButtons) {
183 [self relayout];
184
185 [okButton setAction:@selector(onOkClicked)];
186 [okButton setTarget:self];
187
188 [cancelButton setAction:@selector(onCancelClicked)];
189 [cancelButton setTarget:self];
190 }
191
192 mQtFont = new QFont();
193 return self;
194}
195
196- (void)setSubwindowStacking
197{
198#ifdef QT_MAC_USE_COCOA
199 // Stack the native dialog in front of its parent, if any:
200 QFontDialog *q = mPriv->fontDialog();
201 if (!qt_mac_is_macsheet(q)) {
202 if (QWidget *parent = q->parentWidget()) {
203 if (parent->isWindow()) {
204 [qt_mac_window_for(parent)
205 addChildWindow:[mStolenContentView window] ordered:NSWindowAbove];
206 }
207 }
208 }
209#endif
210}
211
212- (void)dealloc
213{
214 delete mQtFont;
215 [super dealloc];
216}
217
218- (void)showModelessPanel
219{
220 mAppModal = false;
221 NSWindow *ourPanel = [mStolenContentView window];
222 [ourPanel makeKeyAndOrderFront:self];
223}
224
225- (void)runApplicationModalPanel
226{
227 QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
228 mAppModal = true;
229 NSWindow *ourPanel = [mStolenContentView window];
230 [ourPanel setReleasedWhenClosed:NO];
231 [NSApp runModalForWindow:ourPanel];
232 QAbstractEventDispatcher::instance()->interrupt();
233
234 if (mReturnCode == NSOKButton)
235 mPriv->fontDialog()->accept();
236 else
237 mPriv->fontDialog()->reject();
238}
239
240- (BOOL)isAppModal
241{
242 return mAppModal;
243}
244
245- (void)showWindowModalSheet:(QWidget *)docWidget
246{
247#ifdef QT_MAC_USE_COCOA
248 NSWindow *window = qt_mac_window_for(docWidget);
249#else
250 WindowRef hiwindowRef = qt_mac_window_for(docWidget);
251 NSWindow *window = [[NSWindow alloc] initWithWindowRef:hiwindowRef];
252 CFRetain(hiwindowRef);
253#endif
254
255 mAppModal = false;
256 NSWindow *ourPanel = [mStolenContentView window];
257 [NSApp beginSheet:ourPanel
258 modalForWindow:window
259 modalDelegate:0
260 didEndSelector:0
261 contextInfo:0 ];
262
263#ifndef QT_MAC_USE_COCOA
264 CFRelease(hiwindowRef);
265#endif
266}
267
268- (void)changeFont:(id)sender
269{
270 NSFont *dummyFont = [NSFont userFontOfSize:12.0];
271 [self setQtFont:qfontForCocoaFont([sender convertFont:dummyFont], *mQtFont)];
272 if (mPriv)
273 mPriv->updateSampleFont(*mQtFont);
274}
275
276- (void)changeAttributes:(id)sender
277{
278 NSDictionary *dummyAttribs = [NSDictionary dictionary];
279 NSDictionary *attribs = [sender convertAttributes:dummyAttribs];
280
281#ifdef QT_MAC_USE_COCOA
282 for (id key in attribs) {
283#else
284 NSEnumerator *enumerator = [attribs keyEnumerator];
285 id key;
286 while((key = [enumerator nextObject])) {
287#endif
288 NSNumber *number = static_cast<NSNumber *>([attribs objectForKey:key]);
289 if ([key isEqual:NSUnderlineStyleAttributeName]) {
290 mQtFont->setUnderline([number intValue] != NSUnderlineStyleNone);
291 } else if ([key isEqual:NSStrikethroughStyleAttributeName]) {
292 mQtFont->setStrikeOut([number intValue] != NSUnderlineStyleNone);
293 }
294 }
295
296 if (mPriv)
297 mPriv->updateSampleFont(*mQtFont);
298}
299
300- (BOOL)windowShouldClose:(id)window
301{
302 Q_UNUSED(window);
303 if (mPanelHackedWithButtons) {
304 [self onCancelClicked];
305 } else {
306 [self finishOffWithCode:NSCancelButton];
307 }
308 return true;
309}
310
311- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
312{
313 if (mFontPanel == window) {
314 proposedFrameSize = [static_cast<id <NSWindowDelegate> >(mFontPanel) windowWillResize:mFontPanel toSize:proposedFrameSize];
315 } else {
316 /*
317 Ugly hack: NSFontPanel rearranges the layout of its main
318 component in windowWillResize:toSize:. So we temporarily
319 restore the stolen content view to its rightful owner,
320 call windowWillResize:toSize:, and steal the content view
321 again.
322 */
323 [mStolenContentView removeFromSuperview];
324 [mFontPanel setContentView:mStolenContentView];
325 NSSize extraSize = [self dialogExtraSize];
326 proposedFrameSize.width -= extraSize.width;
327 proposedFrameSize.height -= extraSize.height;
328 proposedFrameSize = [static_cast<id <NSWindowDelegate> >(mFontPanel) windowWillResize:mFontPanel toSize:proposedFrameSize];
329 NSRect frameRect = { { 0.0, 0.0 }, proposedFrameSize };
330 [mFontPanel setFrame:frameRect display:NO];
331 [mFontPanel setContentView:0];
332 [[window contentView] addSubview:mStolenContentView];
333 proposedFrameSize.width += extraSize.width;
334 proposedFrameSize.height += extraSize.height;
335 }
336 if (mPanelHackedWithButtons) {
337 NSRect frameRect = { { 0.0, 0.0 }, proposedFrameSize };
338 NSRect contentRect = [NSWindow contentRectForFrameRect:frameRect styleMask:[window styleMask]];
339 [self relayoutToContentSize:contentRect.size];
340 }
341 return proposedFrameSize;
342}
343
344- (void)relayout
345{
346 [self relayoutToContentSize:[[mStolenContentView superview] frame].size];
347}
348
349- (void)relayoutToContentSize:(NSSize)frameSize;
350{
351 Q_ASSERT(mPanelHackedWithButtons);
352
353 [mOkButton sizeToFit];
354 NSSize okSizeHint = [mOkButton frame].size;
355
356 [mCancelButton sizeToFit];
357 NSSize cancelSizeHint = [mCancelButton frame].size;
358
359 const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth,
360 qMax(okSizeHint.width, cancelSizeHint.width)),
361 CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5));
362 const CGFloat ButtonHeight = qMax(ButtonMinHeight,
363 qMax(okSizeHint.height, cancelSizeHint.height));
364
365 const CGFloat X = DialogSideMargin;
366 const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin;
367
368 NSRect okRect = { { frameSize.width - ButtonSideMargin - ButtonWidth,
369 ButtonBottomMargin },
370 { ButtonWidth, ButtonHeight } };
371 [mOkButton setFrame:okRect];
372 [mOkButton setNeedsDisplay:YES];
373
374 NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth,
375 ButtonBottomMargin },
376 { ButtonWidth, ButtonHeight } };
377 [mCancelButton setFrame:cancelRect];
378 [mCancelButton setNeedsDisplay:YES];
379
380 NSRect stolenCVRect = { { X, Y },
381 { frameSize.width - X - X, frameSize.height - Y - DialogTopMargin } };
382 [mStolenContentView setFrame:stolenCVRect];
383 [mStolenContentView setNeedsDisplay:YES];
384
385 [[mStolenContentView superview] setNeedsDisplay:YES];
386}
387
388- (void)onOkClicked
389{
390 Q_ASSERT(mPanelHackedWithButtons);
391 NSFontManager *fontManager = [NSFontManager sharedFontManager];
392 [self setQtFont:qfontForCocoaFont([fontManager convertFont:[fontManager selectedFont]],
393 *mQtFont)];
394 [self finishOffWithCode:NSOKButton];
395}
396
397- (void)onCancelClicked
398{
399 Q_ASSERT(mPanelHackedWithButtons);
400 [self finishOffWithCode:NSCancelButton];
401}
402
403- (NSFontPanel *)fontPanel
404{
405 return mFontPanel;
406}
407
408- (NSWindow *)actualPanel
409{
410 return [mStolenContentView window];
411}
412
413- (NSSize)dialogExtraSize
414{
415 // this must be recomputed each time, because sometimes the
416 // NSFontPanel has the NSDocModalWindowMask flag set, and sometimes
417 // not -- which affects the frame rect vs. content rect measurements
418
419 // take the different frame rectangles into account for dialogExtra{Width,Height}
420 NSRect someRect = { { 0.0, 0.0 }, { 100000.0, 100000.0 } };
421 NSRect sharedFontPanelContentRect = [mFontPanel contentRectForFrameRect:someRect];
422 NSRect ourPanelContentRect = [NSWindow contentRectForFrameRect:someRect styleMask:StyleMask];
423
424 NSSize result = { mDialogExtraWidth, mDialogExtraHeight };
425 result.width -= ourPanelContentRect.size.width - sharedFontPanelContentRect.size.width;
426 result.height -= ourPanelContentRect.size.height - sharedFontPanelContentRect.size.height;
427 return result;
428}
429
430- (void)setQtFont:(const QFont &)newFont
431{
432 delete mQtFont;
433 mQtFont = new QFont(newFont);
434}
435
436- (QFont)qtFont
437{
438 return *mQtFont;
439}
440
441- (void)finishOffWithCode:(NSInteger)code
442{
443#ifdef QT_MAC_USE_COCOA
444 QFontDialog *q = mPriv->fontDialog();
445 if (QWidget *parent = q->parentWidget()) {
446 if (parent->isWindow()) {
447 [qt_mac_window_for(parent) removeChildWindow:[mStolenContentView window]];
448 }
449 }
450#endif
451
452 if(code == NSOKButton)
453 mPriv->sampleEdit->setFont([self qtFont]);
454
455 if (mAppModal) {
456 mReturnCode = code;
457 [NSApp stopModalWithCode:code];
458 } else {
459 if (code == NSOKButton)
460 mPriv->fontDialog()->accept();
461 else
462 mPriv->fontDialog()->reject();
463 }
464}
465
466- (void)cleanUpAfterMyself
467{
468 if (mPanelHackedWithButtons) {
469 NSView *ourContentView = [mFontPanel contentView];
470
471 // return stolen stuff to its rightful owner
472 [mStolenContentView removeFromSuperview];
473 [mFontPanel setContentView:mStolenContentView];
474
475 [mOkButton release];
476 [mCancelButton release];
477 [ourContentView release];
478 }
479 [mFontPanel setDelegate:nil];
480 [[NSFontManager sharedFontManager] setDelegate:nil];
481#ifdef QT_MAC_USE_COCOA
482 [[NSFontManager sharedFontManager] setTarget:nil];
483#endif
484}
485@end
486
487QT_BEGIN_NAMESPACE
488
489void QFontDialogPrivate::closeCocoaFontPanel()
490{
491 QMacCocoaAutoReleasePool pool;
492 QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *theDelegate = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
493 NSWindow *ourPanel = [theDelegate actualPanel];
494 [ourPanel close];
495 if ([theDelegate isAppModal])
496 [ourPanel release];
497 [theDelegate cleanUpAfterMyself];
498 [theDelegate release];
499 this->delegate = 0;
500 sharedFontPanelAvailable = true;
501}
502
503void QFontDialogPrivate::setFont(void *delegate, const QFont &font)
504{
505 QMacCocoaAutoReleasePool pool;
506 QFontEngine *fe = font.d->engineForScript(QUnicodeTables::Common);
507 NSFontManager *mgr = [NSFontManager sharedFontManager];
508 NSFont *nsFont = 0;
509
510#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
511 if (qstrcmp(fe->name(), "CoreText") == 0) {
512 nsFont = reinterpret_cast<const NSFont *>(static_cast<QCoreTextFontEngineMulti *>(fe)->ctfont);
513 } else
514#endif
515 {
516 int weight = 5;
517 NSFontTraitMask mask = 0;
518 if (font.style() == QFont::StyleItalic) {
519 mask |= NSItalicFontMask;
520 }
521 if (font.weight() == QFont::Bold) {
522 weight = 9;
523 mask |= NSBoldFontMask;
524 }
525
526 NSFontManager *mgr = [NSFontManager sharedFontManager];
527 QFontInfo fontInfo(font);
528 nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family())
529 traits:mask
530 weight:weight
531 size:fontInfo.pointSize()];
532 }
533
534 [mgr setSelectedFont:nsFont isMultiple:NO];
535 [static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate) setQtFont:font];
536}
537
538void QFontDialogPrivate::createNSFontPanelDelegate()
539{
540 if (delegate)
541 return;
542
543 sharedFontPanelAvailable = false;
544 QMacCocoaAutoReleasePool pool;
545 bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists];
546 NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel];
547 [sharedFontPanel setHidesOnDeactivate:false];
548
549 // hack to ensure that QCocoaApplication's validModesForFontPanel:
550 // implementation is honored
551 if (!sharedFontPanelExisted) {
552 [sharedFontPanel makeKeyAndOrderFront:sharedFontPanel];
553 [sharedFontPanel close];
554 }
555
556 NSPanel *ourPanel = 0;
557 NSView *stolenContentView = 0;
558 NSButton *okButton = 0;
559 NSButton *cancelButton = 0;
560
561 CGFloat dialogExtraWidth = 0.0;
562 CGFloat dialogExtraHeight = 0.0;
563
564 // compute dialogExtra{Width,Height}
565 dialogExtraWidth = 2.0 * DialogSideMargin;
566 dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight + ButtonBottomMargin;
567
568 // compute initial contents rectangle
569 NSRect contentRect = [sharedFontPanel contentRectForFrameRect:[sharedFontPanel frame]];
570 contentRect.size.width += dialogExtraWidth;
571 contentRect.size.height += dialogExtraHeight;
572
573 // create the new panel
574 ourPanel = [[NSPanel alloc] initWithContentRect:contentRect
575 styleMask:StyleMask
576 backing:NSBackingStoreBuffered
577 defer:YES];
578 [ourPanel setReleasedWhenClosed:YES];
579 stolenContentView = [sharedFontPanel contentView];
580
581 // steal the font panel's contents view
582 [stolenContentView retain];
583 [sharedFontPanel setContentView:0];
584
585 {
586 // create a new content view and add the stolen one as a subview
587 NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } };
588 NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect];
589 [ourContentView addSubview:stolenContentView];
590
591 // create OK and Cancel buttons and add these as subviews
592 okButton = macCreateButton("&OK", ourContentView);
593 cancelButton = macCreateButton("Cancel", ourContentView);
594
595 [ourPanel setContentView:ourContentView];
596 [ourPanel setDefaultButtonCell:[okButton cell]];
597 }
598
599 // create the delegate and set it
600 QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = [[QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) alloc] initWithFontPanel:sharedFontPanel
601 stolenContentView:stolenContentView
602 okButton:okButton
603 cancelButton:cancelButton
604 priv:this
605 extraWidth:dialogExtraWidth
606 extraHeight:dialogExtraHeight];
607 delegate = del;
608 [ourPanel setDelegate:del];
609
610 [[NSFontManager sharedFontManager] setDelegate:del];
611#ifdef QT_MAC_USE_COCOA
612 [[NSFontManager sharedFontManager] setTarget:del];
613#endif
614 setFont(del, q_func()->currentFont());
615
616 {
617 // hack to get correct initial layout
618 NSRect frameRect = [ourPanel frame];
619 frameRect.size.width += 1.0;
620 [ourPanel setFrame:frameRect display:NO];
621 frameRect.size.width -= 1.0;
622 frameRect.size = [del windowWillResize:ourPanel toSize:frameRect.size];
623 [ourPanel setFrame:frameRect display:NO];
624 [ourPanel center];
625 }
626 [del setSubwindowStacking];
627 NSString *title = @"Select font";
628 [ourPanel setTitle:title];
629}
630
631void QFontDialogPrivate::mac_nativeDialogModalHelp()
632{
633 // Copied from QFileDialogPrivate
634 // Do a queued meta-call to open the native modal dialog so it opens after the new
635 // event loop has started to execute (in QDialog::exec). Using a timer rather than
636 // a queued meta call is intentional to ensure that the call is only delivered when
637 // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
638 // running (which is the case if e.g a top-most QEventLoop has been
639 // interrupted, and the second-most event loop has not yet been reactivated (regardless
640 // if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
641 if (nativeDialogInUse) {
642 Q_Q(QFontDialog);
643 QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel()));
644 }
645}
646
647// The problem with the native font dialog is that OS X does not
648// offer a proper dialog, but a panel (i.e. without Ok and Cancel buttons).
649// This means we need to "construct" a native dialog by taking the panel
650// and "adding" the buttons.
651void QFontDialogPrivate::_q_macRunNativeAppModalPanel()
652{
653 createNSFontPanelDelegate();
654 QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
655 [del runApplicationModalPanel];
656}
657
658bool QFontDialogPrivate::showCocoaFontPanel()
659{
660 if (!sharedFontPanelAvailable)
661 return false;
662
663 Q_Q(QFontDialog);
664 QMacCocoaAutoReleasePool pool;
665 createNSFontPanelDelegate();
666 QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
667 if (qt_mac_is_macsheet(q))
668 [del showWindowModalSheet:q->parentWidget()];
669 else
670 [del showModelessPanel];
671 return true;
672}
673
674bool QFontDialogPrivate::hideCocoaFontPanel()
675{
676 if (!delegate){
677 // Nothing to do. We return false to leave the question
678 // open regarding whether or not to go native:
679 return false;
680 } else {
681 closeCocoaFontPanel();
682 // Even when we hide it, we are still using a
683 // native dialog, so return true:
684 return true;
685 }
686}
687bool QFontDialogPrivate::setVisible_sys(bool visible)
688{
689 Q_Q(QFontDialog);
690 if (!visible == q->isHidden())
691 return false;
692
693 return visible ? showCocoaFontPanel() : hideCocoaFontPanel();
694}
695
696QT_END_NAMESPACE
697
698#endif
Note: See TracBrowser for help on using the repository browser.