summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm265
1 files changed, 151 insertions, 114 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index a70ba3749f..91fb52eb6d 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -128,14 +128,18 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
- (void)finishOffWithCode:(NSInteger)code;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSFontPanelDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
-- (id)initWithDialogHelper:
- (QCocoaFontDialogHelper *)helper
+@implementation QNSFontPanelDelegate
+
+- (id)init
{
self = [super init];
mFontPanel = [NSFontPanel sharedFontPanel];
- mHelper = helper;
+ mHelper = 0;
+ mStolenContentView = 0;
+ mOkButton = 0;
+ mCancelButton = 0;
mResultCode = NSCancelButton;
mDialogIsExecuting = false;
mResultSet = false;
@@ -145,13 +149,32 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mFontPanel setRestorable:NO];
#endif
+ [mFontPanel setDelegate:self];
+ [[NSFontManager sharedFontManager] setDelegate:self];
+
+ [mFontPanel retain];
+ return self;
+}
+
+- (void)dealloc
+{
+ [self restoreOriginalContentView];
+ [mFontPanel setDelegate:nil];
+ [[NSFontManager sharedFontManager] setDelegate:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [super dealloc];
+}
+
+- (void)setDialogHelper:(QCocoaFontDialogHelper *)helper
+{
+ mHelper = helper;
+
[mFontPanel setTitle:QCFString::toNSString(helper->options()->windowTitle())];
if (mHelper->options()->testOption(QFontDialogOptions::NoButtons)) {
- mStolenContentView = 0;
- mOkButton = 0;
- mCancelButton = 0;
- } else {
+ [self restoreOriginalContentView];
+ } else if (!mStolenContentView) {
// steal the font panel's contents view
mStolenContentView = [mFontPanel contentView];
[mStolenContentView retain];
@@ -176,14 +199,22 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mCancelButton setAction:@selector(onCancelClicked)];
[mCancelButton setTarget:self];
}
+}
- [mFontPanel retain];
- return self;
+- (void)closePanel
+{
+ [mFontPanel close];
}
-- (void)dealloc
+- (void)windowDidResize:(NSNotification *)notification
{
- if (mOkButton) {
+ Q_UNUSED(notification);
+ [self relayout];
+}
+
+- (void)restoreOriginalContentView
+{
+ if (mStolenContentView) {
NSView *ourContentView = [mFontPanel contentView];
// return stolen stuff to its rightful owner
@@ -192,28 +223,17 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mOkButton release];
[mCancelButton release];
[ourContentView release];
+ mOkButton = 0;
+ mCancelButton = 0;
+ mStolenContentView = 0;
}
-
- [mFontPanel setDelegate:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
- [super dealloc];
-}
-
-- (void)closePanel
-{
- [mFontPanel close];
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (mOkButton)
- [self relayout];
}
- (void)relayout
{
+ if (!mOkButton)
+ return;
+
[self relayoutToContentSize:[[mStolenContentView superview] frame].size];
}
@@ -289,30 +309,32 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
NSFont *panelFont = [fontManager convertFont:selectedFont];
mQtFont = qfontForCocoaFont(panelFont, mQtFont);
- emit mHelper->currentFontChanged(mQtFont);
+ if (mHelper)
+ emit mHelper->currentFontChanged(mQtFont);
}
- (void)showModelessPanel
{
mDialogIsExecuting = false;
+ mResultSet = false;
[mFontPanel makeKeyAndOrderFront:mFontPanel];
}
- (BOOL)runApplicationModalPanel
{
mDialogIsExecuting = true;
- [mFontPanel setDelegate:self];
// Call processEvents in case the event dispatcher has been interrupted, and needs to do
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
[NSApp runModalForWindow:mFontPanel];
+ mDialogIsExecuting = false;
return (mResultCode == NSOKButton);
}
-- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode
+- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mResultCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected);
+ return (mResultCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (BOOL)windowShouldClose:(id)window
@@ -324,7 +346,8 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[self finishOffWithCode:NSCancelButton];
} else {
mResultSet = true;
- emit mHelper->reject();
+ if (mHelper)
+ emit mHelper->reject();
}
return true;
}
@@ -359,27 +382,101 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
QT_BEGIN_NAMESPACE
-QCocoaFontDialogHelper::QCocoaFontDialogHelper() :
- mDelegate(0)
+class QCocoaFontPanel
+{
+public:
+ QCocoaFontPanel()
+ {
+ mDelegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc] init];
+ }
+
+ ~QCocoaFontPanel()
+ {
+ [mDelegate release];
+ }
+
+ void init(QCocoaFontDialogHelper *helper)
+ {
+ [mDelegate setDialogHelper:helper];
+ }
+
+ void cleanup(QCocoaFontDialogHelper *helper)
+ {
+ if (mDelegate->mHelper == helper)
+ mDelegate->mHelper = 0;
+ }
+
+ bool exec()
+ {
+ // Note: 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.
+ return [mDelegate runApplicationModalPanel];
+ }
+
+ bool show(Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_UNUSED(parent);
+ if (windowModality != Qt::WindowModal)
+ [mDelegate showModelessPanel];
+ // no need to show a Qt::WindowModal dialog here, because it's necessary to call exec() in that case
+ return true;
+ }
+
+ void hide()
+ {
+ [mDelegate closePanel];
+ }
+
+ QFont currentFont() const
+ {
+ return mDelegate->mQtFont;
+ }
+
+ void setCurrentFont(const QFont &font)
+ {
+ NSFontManager *mgr = [NSFontManager sharedFontManager];
+ const NSFont *nsFont = 0;
+
+ int weight = 5;
+ NSFontTraitMask mask = 0;
+ if (font.style() == QFont::StyleItalic) {
+ mask |= NSItalicFontMask;
+ }
+ if (font.weight() == QFont::Bold) {
+ weight = 9;
+ mask |= NSBoldFontMask;
+ }
+
+ QFontInfo fontInfo(font);
+ nsFont = [mgr fontWithFamily:QCFString::toNSString(fontInfo.family())
+ traits:mask
+ weight:weight
+ size:fontInfo.pointSize()];
+
+ [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
+ mDelegate->mQtFont = font;
+ }
+
+private:
+ QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *mDelegate;
+};
+
+Q_GLOBAL_STATIC(QCocoaFontPanel, sharedFontPanel)
+
+QCocoaFontDialogHelper::QCocoaFontDialogHelper()
{
}
QCocoaFontDialogHelper::~QCocoaFontDialogHelper()
{
- if (!mDelegate)
- return;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate) release];
- mDelegate = 0;
+ sharedFontPanel()->cleanup(this);
}
void QCocoaFontDialogHelper::exec()
{
- // Note: 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.
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- if ([delegate runApplicationModalPanel])
+ if (sharedFontPanel()->exec())
emit accept();
else
emit reject();
@@ -387,86 +484,26 @@ void QCocoaFontDialogHelper::exec()
bool QCocoaFontDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent)
{
- if (windowModality == Qt::WindowModal) {
- // Cocoa's shared font panel cannot be shown as a sheet
- return false;
- }
- return showCocoaFontPanel(windowModality, parent);
+ if (windowModality == Qt::WindowModal)
+ windowModality = Qt::ApplicationModal;
+ sharedFontPanel()->init(this);
+ return sharedFontPanel()->show(windowModality, parent);
}
void QCocoaFontDialogHelper::hide()
{
- if (!mDelegate)
- return;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mFontPanel close];
+ sharedFontPanel()->hide();
}
void QCocoaFontDialogHelper::setCurrentFont(const QFont &font)
{
- NSFontManager *mgr = [NSFontManager sharedFontManager];
- const NSFont *nsFont = 0;
-
- int weight = 5;
- NSFontTraitMask mask = 0;
- if (font.style() == QFont::StyleItalic) {
- mask |= NSItalicFontMask;
- }
- if (font.weight() == QFont::Bold) {
- weight = 9;
- mask |= NSBoldFontMask;
- }
-
- QFontInfo fontInfo(font);
- nsFont = [mgr fontWithFamily:QCFString::toNSString(fontInfo.family())
- traits:mask
- weight:weight
- size:fontInfo.pointSize()];
-
- if (!mDelegate)
- createNSFontPanelDelegate();
-
- [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
- static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mQtFont = font;
+ sharedFontPanel()->init(this);
+ sharedFontPanel()->setCurrentFont(font);
}
QFont QCocoaFontDialogHelper::currentFont() const
{
- if (!mDelegate)
- return QFont();
- return reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mQtFont;
-}
-
-void QCocoaFontDialogHelper::createNSFontPanelDelegate()
-{
- if (mDelegate)
- return;
-
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc]
- initWithDialogHelper:this];
-
- mDelegate = delegate;
-}
-
-bool QCocoaFontDialogHelper::showCocoaFontPanel(Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_UNUSED(parent);
- createNSFontPanelDelegate();
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- if (windowModality == Qt::NonModal)
- [delegate showModelessPanel];
- // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel()
- return true;
-}
-
-bool QCocoaFontDialogHelper::hideCocoaFontPanel()
-{
- if (!mDelegate){
- return false;
- } else {
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- [delegate closePanel];
- return true;
- }
+ return sharedFontPanel()->currentFont();
}
QT_END_NAMESPACE