/**************************************************************************** | |
** | |
** 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$ | |
** GNU Lesser General Public License Usage | |
** 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. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $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> | |
#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]; | |
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: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 |