summaryrefslogtreecommitdiffstats
path: root/src/gui/dialogs/qfontdialog_mac.mm
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/gui/dialogs/qfontdialog_mac.mm
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/gui/dialogs/qfontdialog_mac.mm')
-rw-r--r--src/gui/dialogs/qfontdialog_mac.mm699
1 files changed, 699 insertions, 0 deletions
diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm
new file mode 100644
index 0000000000..1552ad675f
--- /dev/null
+++ b/src/gui/dialogs/qfontdialog_mac.mm
@@ -0,0 +1,699 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfontdialog_p.h"
+#if !defined(QT_NO_FONTDIALOG) && defined(Q_WS_MAC)
+#include <qapplication.h>
+#include <qdialogbuttonbox.h>
+#include <qlineedit.h>
+#include <private/qapplication_p.h>
+#include <private/qfont_p.h>
+#include <private/qfontengine_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#include <private/qt_mac_p.h>
+#include <qabstracteventdispatcher.h>
+#include <qdebug.h>
+#include <private/qfontengine_coretext_p.h>
+#import <AppKit/AppKit.h>
+#import <Foundation/Foundation.h>
+
+#if !CGFLOAT_DEFINED
+typedef float CGFloat; // Should only not be defined on 32-bit platforms
+#endif
+
+QT_BEGIN_NAMESPACE
+
+extern void macStartInterceptNSPanelCtor();
+extern void macStopInterceptNSPanelCtor();
+extern NSButton *macCreateButton(const char *text, NSView *superview);
+extern bool qt_mac_is_macsheet(const QWidget *w); // qwidget_mac.mm
+
+QT_END_NAMESPACE
+QT_USE_NAMESPACE
+
+// should a priori be kept in sync with qcolordialog_mac.mm
+const CGFloat ButtonMinWidth = 78.0;
+const CGFloat ButtonMinHeight = 32.0;
+const CGFloat ButtonSpacing = 0.0;
+const CGFloat ButtonTopMargin = 0.0;
+const CGFloat ButtonBottomMargin = 7.0;
+const CGFloat ButtonSideMargin = 9.0;
+
+// looks better with some margins
+const CGFloat DialogTopMargin = 7.0;
+const CGFloat DialogSideMargin = 9.0;
+
+const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
+
+@class QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate);
+
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+
+@protocol NSWindowDelegate <NSObject>
+- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
+@end
+
+#endif
+
+@interface QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) : NSObject <NSWindowDelegate> {
+ NSFontPanel *mFontPanel;
+ NSView *mStolenContentView;
+ NSButton *mOkButton;
+ NSButton *mCancelButton;
+ QFontDialogPrivate *mPriv;
+ QFont *mQtFont;
+ BOOL mPanelHackedWithButtons;
+ CGFloat mDialogExtraWidth;
+ CGFloat mDialogExtraHeight;
+ int mReturnCode;
+ BOOL mAppModal;
+}
+- (id)initWithFontPanel:(NSFontPanel *)panel
+ stolenContentView:(NSView *)stolenContentView
+ okButton:(NSButton *)okButton
+ cancelButton:(NSButton *)cancelButton
+ priv:(QFontDialogPrivate *)priv
+ extraWidth:(CGFloat)extraWidth
+ extraHeight:(CGFloat)extraHeight;
+- (void)showModelessPanel;
+- (void)showWindowModalSheet:(QWidget *)docWidget;
+- (void)runApplicationModalPanel;
+- (BOOL)isAppModal;
+- (void)changeFont:(id)sender;
+- (void)changeAttributes:(id)sender;
+- (BOOL)windowShouldClose:(id)window;
+- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
+- (void)relayout;
+- (void)relayoutToContentSize:(NSSize)frameSize;
+- (void)onOkClicked;
+- (void)onCancelClicked;
+- (NSFontPanel *)fontPanel;
+- (NSWindow *)actualPanel;
+- (NSSize)dialogExtraSize;
+- (void)setQtFont:(const QFont &)newFont;
+- (QFont)qtFont;
+- (void)finishOffWithCode:(NSInteger)result;
+- (void)cleanUpAfterMyself;
+- (void)setSubwindowStacking;
+@end
+
+static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
+{
+ QFont newFont;
+ if (cocoaFont) {
+ int pSize = qRound([cocoaFont pointSize]);
+ QString family(qt_mac_NSStringToQString([cocoaFont familyName]));
+ QString typeface(qt_mac_NSStringToQString([cocoaFont fontName]));
+
+ int hyphenPos = typeface.indexOf(QLatin1Char('-'));
+ if (hyphenPos != -1) {
+ typeface.remove(0, hyphenPos + 1);
+ } else {
+ typeface = QLatin1String("Normal");
+ }
+
+ newFont = QFontDatabase().font(family, typeface, pSize);
+ newFont.setUnderline(resolveFont.underline());
+ newFont.setStrikeOut(resolveFont.strikeOut());
+
+ }
+ return newFont;
+}
+
+@implementation QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate)
+- (id)initWithFontPanel:(NSFontPanel *)panel
+ stolenContentView:(NSView *)stolenContentView
+ okButton:(NSButton *)okButton
+ cancelButton:(NSButton *)cancelButton
+ priv:(QFontDialogPrivate *)priv
+ extraWidth:(CGFloat)extraWidth
+ extraHeight:(CGFloat)extraHeight
+{
+ self = [super init];
+ mFontPanel = panel;
+ mStolenContentView = stolenContentView;
+ mOkButton = okButton;
+ mCancelButton = cancelButton;
+ mPriv = priv;
+ mPanelHackedWithButtons = (okButton != 0);
+ mDialogExtraWidth = extraWidth;
+ mDialogExtraHeight = extraHeight;
+ mReturnCode = -1;
+ mAppModal = false;
+
+ if (mPanelHackedWithButtons) {
+ [self relayout];
+
+ [okButton setAction:@selector(onOkClicked)];
+ [okButton setTarget:self];
+
+ [cancelButton setAction:@selector(onCancelClicked)];
+ [cancelButton setTarget:self];
+ }
+
+ mQtFont = new QFont();
+ return self;
+}
+
+- (void)setSubwindowStacking
+{
+#ifdef QT_MAC_USE_COCOA
+ // Stack the native dialog in front of its parent, if any:
+ QFontDialog *q = mPriv->fontDialog();
+ if (!qt_mac_is_macsheet(q)) {
+ if (QWidget *parent = q->parentWidget()) {
+ if (parent->isWindow()) {
+ [qt_mac_window_for(parent)
+ addChildWindow:[mStolenContentView window] ordered:NSWindowAbove];
+ }
+ }
+ }
+#endif
+}
+
+- (void)dealloc
+{
+ delete mQtFont;
+ [super dealloc];
+}
+
+- (void)showModelessPanel
+{
+ mAppModal = false;
+ NSWindow *ourPanel = [mStolenContentView window];
+ [ourPanel makeKeyAndOrderFront:self];
+}
+
+- (void)runApplicationModalPanel
+{
+ QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
+ mAppModal = true;
+ NSWindow *ourPanel = [mStolenContentView window];
+ [ourPanel setReleasedWhenClosed:NO];
+ [NSApp runModalForWindow:ourPanel];
+ QAbstractEventDispatcher::instance()->interrupt();
+
+ if (mReturnCode == NSOKButton)
+ mPriv->fontDialog()->accept();
+ else
+ mPriv->fontDialog()->reject();
+}
+
+- (BOOL)isAppModal
+{
+ return mAppModal;
+}
+
+- (void)showWindowModalSheet:(QWidget *)docWidget
+{
+#ifdef QT_MAC_USE_COCOA
+ NSWindow *window = qt_mac_window_for(docWidget);
+#else
+ WindowRef hiwindowRef = qt_mac_window_for(docWidget);
+ NSWindow *window = [[NSWindow alloc] initWithWindowRef:hiwindowRef];
+ CFRetain(hiwindowRef);
+#endif
+
+ mAppModal = false;
+ NSWindow *ourPanel = [mStolenContentView window];
+ [NSApp beginSheet:ourPanel
+ modalForWindow:window
+ modalDelegate:0
+ didEndSelector:0
+ contextInfo:0 ];
+
+#ifndef QT_MAC_USE_COCOA
+ CFRelease(hiwindowRef);
+#endif
+}
+
+- (void)changeFont:(id)sender
+{
+ NSFont *dummyFont = [NSFont userFontOfSize:12.0];
+ [self setQtFont:qfontForCocoaFont([sender convertFont:dummyFont], *mQtFont)];
+ if (mPriv)
+ mPriv->updateSampleFont(*mQtFont);
+}
+
+- (void)changeAttributes:(id)sender
+{
+ NSDictionary *dummyAttribs = [NSDictionary dictionary];
+ NSDictionary *attribs = [sender convertAttributes:dummyAttribs];
+
+#ifdef QT_MAC_USE_COCOA
+ for (id key in attribs) {
+#else
+ NSEnumerator *enumerator = [attribs keyEnumerator];
+ id key;
+ while((key = [enumerator nextObject])) {
+#endif
+ NSNumber *number = static_cast<NSNumber *>([attribs objectForKey:key]);
+ if ([key isEqual:NSUnderlineStyleAttributeName]) {
+ mQtFont->setUnderline([number intValue] != NSUnderlineStyleNone);
+ } else if ([key isEqual:NSStrikethroughStyleAttributeName]) {
+ mQtFont->setStrikeOut([number intValue] != NSUnderlineStyleNone);
+ }
+ }
+
+ if (mPriv)
+ mPriv->updateSampleFont(*mQtFont);
+}
+
+- (BOOL)windowShouldClose:(id)window
+{
+ Q_UNUSED(window);
+ if (mPanelHackedWithButtons) {
+ [self onCancelClicked];
+ } else {
+ [self finishOffWithCode:NSCancelButton];
+ }
+ return true;
+}
+
+- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
+{
+ if (mFontPanel == window) {
+ proposedFrameSize = [static_cast<id <NSWindowDelegate> >(mFontPanel) windowWillResize:mFontPanel toSize:proposedFrameSize];
+ } else {
+ /*
+ Ugly hack: NSFontPanel rearranges the layout of its main
+ component in windowWillResize:toSize:. So we temporarily
+ restore the stolen content view to its rightful owner,
+ call windowWillResize:toSize:, and steal the content view
+ again.
+ */
+ [mStolenContentView removeFromSuperview];
+ [mFontPanel setContentView:mStolenContentView];
+ NSSize extraSize = [self dialogExtraSize];
+ proposedFrameSize.width -= extraSize.width;
+ proposedFrameSize.height -= extraSize.height;
+ proposedFrameSize = [static_cast<id <NSWindowDelegate> >(mFontPanel) windowWillResize:mFontPanel toSize:proposedFrameSize];
+ NSRect frameRect = { { 0.0, 0.0 }, proposedFrameSize };
+ [mFontPanel setFrame:frameRect display:NO];
+ [mFontPanel setContentView:0];
+ [[window contentView] addSubview:mStolenContentView];
+ proposedFrameSize.width += extraSize.width;
+ proposedFrameSize.height += extraSize.height;
+ }
+ if (mPanelHackedWithButtons) {
+ NSRect frameRect = { { 0.0, 0.0 }, proposedFrameSize };
+ NSRect contentRect = [NSWindow contentRectForFrameRect:frameRect styleMask:[window styleMask]];
+ [self relayoutToContentSize:contentRect.size];
+ }
+ return proposedFrameSize;
+}
+
+- (void)relayout
+{
+ [self relayoutToContentSize:[[mStolenContentView superview] frame].size];
+}
+
+- (void)relayoutToContentSize:(NSSize)frameSize
+{
+ Q_ASSERT(mPanelHackedWithButtons);
+
+ [mOkButton sizeToFit];
+ NSSize okSizeHint = [mOkButton frame].size;
+
+ [mCancelButton sizeToFit];
+ NSSize cancelSizeHint = [mCancelButton frame].size;
+
+ const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth,
+ qMax(okSizeHint.width, cancelSizeHint.width)),
+ CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5));
+ const CGFloat ButtonHeight = qMax(ButtonMinHeight,
+ qMax(okSizeHint.height, cancelSizeHint.height));
+
+ const CGFloat X = DialogSideMargin;
+ const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin;
+
+ NSRect okRect = { { frameSize.width - ButtonSideMargin - ButtonWidth,
+ ButtonBottomMargin },
+ { ButtonWidth, ButtonHeight } };
+ [mOkButton setFrame:okRect];
+ [mOkButton setNeedsDisplay:YES];
+
+ NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth,
+ ButtonBottomMargin },
+ { ButtonWidth, ButtonHeight } };
+ [mCancelButton setFrame:cancelRect];
+ [mCancelButton setNeedsDisplay:YES];
+
+ NSRect stolenCVRect = { { X, Y },
+ { frameSize.width - X - X, frameSize.height - Y - DialogTopMargin } };
+ [mStolenContentView setFrame:stolenCVRect];
+ [mStolenContentView setNeedsDisplay:YES];
+
+ [[mStolenContentView superview] setNeedsDisplay:YES];
+}
+
+- (void)onOkClicked
+{
+ Q_ASSERT(mPanelHackedWithButtons);
+ NSFontManager *fontManager = [NSFontManager sharedFontManager];
+ [self setQtFont:qfontForCocoaFont([fontManager convertFont:[fontManager selectedFont]],
+ *mQtFont)];
+ [self finishOffWithCode:NSOKButton];
+}
+
+- (void)onCancelClicked
+{
+ Q_ASSERT(mPanelHackedWithButtons);
+ [self finishOffWithCode:NSCancelButton];
+}
+
+- (NSFontPanel *)fontPanel
+{
+ return mFontPanel;
+}
+
+- (NSWindow *)actualPanel
+{
+ return [mStolenContentView window];
+}
+
+- (NSSize)dialogExtraSize
+{
+ // this must be recomputed each time, because sometimes the
+ // NSFontPanel has the NSDocModalWindowMask flag set, and sometimes
+ // not -- which affects the frame rect vs. content rect measurements
+
+ // take the different frame rectangles into account for dialogExtra{Width,Height}
+ NSRect someRect = { { 0.0, 0.0 }, { 100000.0, 100000.0 } };
+ NSRect sharedFontPanelContentRect = [mFontPanel contentRectForFrameRect:someRect];
+ NSRect ourPanelContentRect = [NSWindow contentRectForFrameRect:someRect styleMask:StyleMask];
+
+ NSSize result = { mDialogExtraWidth, mDialogExtraHeight };
+ result.width -= ourPanelContentRect.size.width - sharedFontPanelContentRect.size.width;
+ result.height -= ourPanelContentRect.size.height - sharedFontPanelContentRect.size.height;
+ return result;
+}
+
+- (void)setQtFont:(const QFont &)newFont
+{
+ delete mQtFont;
+ mQtFont = new QFont(newFont);
+}
+
+- (QFont)qtFont
+{
+ return *mQtFont;
+}
+
+- (void)finishOffWithCode:(NSInteger)code
+{
+#ifdef QT_MAC_USE_COCOA
+ QFontDialog *q = mPriv->fontDialog();
+ if (QWidget *parent = q->parentWidget()) {
+ if (parent->isWindow()) {
+ [qt_mac_window_for(parent) removeChildWindow:[mStolenContentView window]];
+ }
+ }
+#endif
+
+ if(code == NSOKButton)
+ mPriv->sampleEdit->setFont([self qtFont]);
+
+ if (mAppModal) {
+ mReturnCode = code;
+ [NSApp stopModalWithCode:code];
+ } else {
+ if (code == NSOKButton)
+ mPriv->fontDialog()->accept();
+ else
+ mPriv->fontDialog()->reject();
+ }
+}
+
+- (void)cleanUpAfterMyself
+{
+ if (mPanelHackedWithButtons) {
+ NSView *ourContentView = [mFontPanel contentView];
+
+ // return stolen stuff to its rightful owner
+ [mStolenContentView removeFromSuperview];
+ [mFontPanel setContentView:mStolenContentView];
+
+ [mOkButton release];
+ [mCancelButton release];
+ [ourContentView release];
+ }
+ [mFontPanel setDelegate:nil];
+ [[NSFontManager sharedFontManager] setDelegate:nil];
+#ifdef QT_MAC_USE_COCOA
+ [[NSFontManager sharedFontManager] setTarget:nil];
+#endif
+}
+@end
+
+QT_BEGIN_NAMESPACE
+
+void QFontDialogPrivate::closeCocoaFontPanel()
+{
+ QMacCocoaAutoReleasePool pool;
+ QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *theDelegate = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
+ NSWindow *ourPanel = [theDelegate actualPanel];
+ [ourPanel close];
+ if ([theDelegate isAppModal])
+ [ourPanel release];
+ [theDelegate cleanUpAfterMyself];
+ [theDelegate release];
+ this->delegate = 0;
+ sharedFontPanelAvailable = true;
+}
+
+void QFontDialogPrivate::setFont(void *delegate, const QFont &font)
+{
+ QMacCocoaAutoReleasePool pool;
+ QFontEngine *fe = font.d->engineForScript(QUnicodeTables::Common);
+ NSFontManager *mgr = [NSFontManager sharedFontManager];
+ const NSFont *nsFont = 0;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (qstrcmp(fe->name(), "CoreText") == 0) {
+ nsFont = reinterpret_cast<const NSFont *>(static_cast<QCoreTextFontEngineMulti *>(fe)->ctfont);
+ } else
+#endif
+ {
+ int weight = 5;
+ NSFontTraitMask mask = 0;
+ if (font.style() == QFont::StyleItalic) {
+ mask |= NSItalicFontMask;
+ }
+ if (font.weight() == QFont::Bold) {
+ weight = 9;
+ mask |= NSBoldFontMask;
+ }
+
+ NSFontManager *mgr = [NSFontManager sharedFontManager];
+ QFontInfo fontInfo(font);
+ nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family())
+ traits:mask
+ weight:weight
+ size:fontInfo.pointSize()];
+ }
+
+ [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
+ [static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate) setQtFont:font];
+}
+
+void QFontDialogPrivate::createNSFontPanelDelegate()
+{
+ if (delegate)
+ return;
+
+ sharedFontPanelAvailable = false;
+ QMacCocoaAutoReleasePool pool;
+ bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists];
+ NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel];
+ [sharedFontPanel setHidesOnDeactivate:false];
+
+ // hack to ensure that QCocoaApplication's validModesForFontPanel:
+ // implementation is honored
+ if (!sharedFontPanelExisted) {
+ [sharedFontPanel makeKeyAndOrderFront:sharedFontPanel];
+ [sharedFontPanel close];
+ }
+
+ NSPanel *ourPanel = 0;
+ NSView *stolenContentView = 0;
+ NSButton *okButton = 0;
+ NSButton *cancelButton = 0;
+
+ CGFloat dialogExtraWidth = 0.0;
+ CGFloat dialogExtraHeight = 0.0;
+
+ // compute dialogExtra{Width,Height}
+ dialogExtraWidth = 2.0 * DialogSideMargin;
+ dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight + ButtonBottomMargin;
+
+ // compute initial contents rectangle
+ NSRect contentRect = [sharedFontPanel contentRectForFrameRect:[sharedFontPanel frame]];
+ contentRect.size.width += dialogExtraWidth;
+ contentRect.size.height += dialogExtraHeight;
+
+ // create the new panel
+ ourPanel = [[NSPanel alloc] initWithContentRect:contentRect
+ styleMask:StyleMask
+ backing:NSBackingStoreBuffered
+ defer:YES];
+ [ourPanel setReleasedWhenClosed:YES];
+ stolenContentView = [sharedFontPanel contentView];
+
+ // steal the font panel's contents view
+ [stolenContentView retain];
+ [sharedFontPanel setContentView:0];
+
+ {
+ // create a new content view and add the stolen one as a subview
+ NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } };
+ NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect];
+ [ourContentView addSubview:stolenContentView];
+
+ // create OK and Cancel buttons and add these as subviews
+ okButton = macCreateButton("&OK", ourContentView);
+ cancelButton = macCreateButton("Cancel", ourContentView);
+
+ [ourPanel setContentView:ourContentView];
+ [ourPanel setDefaultButtonCell:[okButton cell]];
+ }
+
+ // create the delegate and set it
+ QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = [[QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) alloc] initWithFontPanel:sharedFontPanel
+ stolenContentView:stolenContentView
+ okButton:okButton
+ cancelButton:cancelButton
+ priv:this
+ extraWidth:dialogExtraWidth
+ extraHeight:dialogExtraHeight];
+ delegate = del;
+ [ourPanel setDelegate:del];
+
+ [[NSFontManager sharedFontManager] setDelegate:del];
+#ifdef QT_MAC_USE_COCOA
+ [[NSFontManager sharedFontManager] setTarget:del];
+#endif
+ setFont(del, q_func()->currentFont());
+
+ {
+ // hack to get correct initial layout
+ NSRect frameRect = [ourPanel frame];
+ frameRect.size.width += 1.0;
+ [ourPanel setFrame:frameRect display:NO];
+ frameRect.size.width -= 1.0;
+ frameRect.size = [del windowWillResize:ourPanel toSize:frameRect.size];
+ [ourPanel setFrame:frameRect display:NO];
+ [ourPanel center];
+ }
+ [del setSubwindowStacking];
+ NSString *title = @"Select font";
+ [ourPanel setTitle:title];
+}
+
+void QFontDialogPrivate::mac_nativeDialogModalHelp()
+{
+ // Copied from QFileDialogPrivate
+ // Do a queued meta-call to open the native modal dialog so it opens after the new
+ // event loop has started to execute (in QDialog::exec). Using a timer rather than
+ // a queued meta call is intentional to ensure that the call is only delivered when
+ // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
+ // running (which is the case if e.g a top-most QEventLoop has been
+ // interrupted, and the second-most event loop has not yet been reactivated (regardless
+ // if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
+ if (nativeDialogInUse) {
+ Q_Q(QFontDialog);
+ QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel()));
+ }
+}
+
+// The problem with the native font dialog is that OS X does not
+// offer a proper dialog, but a panel (i.e. without Ok and Cancel buttons).
+// This means we need to "construct" a native dialog by taking the panel
+// and "adding" the buttons.
+void QFontDialogPrivate::_q_macRunNativeAppModalPanel()
+{
+ createNSFontPanelDelegate();
+ QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
+ [del runApplicationModalPanel];
+}
+
+bool QFontDialogPrivate::showCocoaFontPanel()
+{
+ if (!sharedFontPanelAvailable)
+ return false;
+
+ Q_Q(QFontDialog);
+ QMacCocoaAutoReleasePool pool;
+ createNSFontPanelDelegate();
+ QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate);
+ if (qt_mac_is_macsheet(q))
+ [del showWindowModalSheet:q->parentWidget()];
+ else
+ [del showModelessPanel];
+ return true;
+}
+
+bool QFontDialogPrivate::hideCocoaFontPanel()
+{
+ if (!delegate){
+ // Nothing to do. We return false to leave the question
+ // open regarding whether or not to go native:
+ return false;
+ } else {
+ closeCocoaFontPanel();
+ // Even when we hide it, we are still using a
+ // native dialog, so return true:
+ return true;
+ }
+}
+bool QFontDialogPrivate::setVisible_sys(bool visible)
+{
+ Q_Q(QFontDialog);
+ if (!visible == q->isHidden())
+ return false;
+
+ return visible ? showCocoaFontPanel() : hideCocoaFontPanel();
+}
+
+QT_END_NAMESPACE
+
+#endif