src/gui/dialogs/qfontdialog_mac.mm
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
child 30 5dc02b23752f
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     8 **
     8 **
    47 #include <private/qapplication_p.h>
    47 #include <private/qapplication_p.h>
    48 #include <private/qfont_p.h>
    48 #include <private/qfont_p.h>
    49 #include <private/qfontengine_p.h>
    49 #include <private/qfontengine_p.h>
    50 #include <private/qt_cocoa_helpers_mac_p.h>
    50 #include <private/qt_cocoa_helpers_mac_p.h>
    51 #include <private/qt_mac_p.h>
    51 #include <private/qt_mac_p.h>
       
    52 #include <qabstracteventdispatcher.h>
    52 #include <qdebug.h>
    53 #include <qdebug.h>
    53 #import <AppKit/AppKit.h>
    54 #import <AppKit/AppKit.h>
    54 #import <Foundation/Foundation.h>
    55 #import <Foundation/Foundation.h>
    55 
    56 
    56 #if !CGFLOAT_DEFINED
    57 #if !CGFLOAT_DEFINED
   370     if (mPriv) {
   371     if (mPriv) {
   371         if (mModalSession) {
   372         if (mModalSession) {
   372             [NSApp endModalSession:mModalSession];
   373             [NSApp endModalSession:mModalSession];
   373             mModalSession = 0;
   374             mModalSession = 0;
   374         }
   375         }
   375 
   376         // Hack alert!
       
   377         // Since this code path was never intended to be followed when starting from exec
       
   378         // we need to force the dialog to communicate the new font, otherwise the signal
       
   379         // won't get emitted.
       
   380         if(code == NSOKButton)
       
   381             mPriv->sampleEdit->setFont([self qtFont]);
   376         mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected);
   382         mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected);
   377     } else {
   383     } else {
   378         [NSApp stopModalWithCode:code];
   384         [NSApp stopModalWithCode:code];
   379     }
   385     }
   380 }
   386 }
   565             break;
   571             break;
   566         default:
   572         default:
   567             [ourPanel makeKeyAndOrderFront:ourPanel];
   573             [ourPanel makeKeyAndOrderFront:ourPanel];
   568         }
   574         }
   569     }
   575     }
   570 
       
   571     return delegate;
   576     return delegate;
   572 }
   577 }
   573 
   578 
   574 void QFontDialogPrivate::closeCocoaFontPanel(void *delegate)
   579 void QFontDialogPrivate::closeCocoaFontPanel(void *delegate)
   575 {
   580 {
   638 
   643 
   639     [mgr setSelectedFont:nsFont isMultiple:NO];
   644     [mgr setSelectedFont:nsFont isMultiple:NO];
   640     [static_cast<QCocoaFontPanelDelegate *>(delegate) setQtFont:font];
   645     [static_cast<QCocoaFontPanelDelegate *>(delegate) setQtFont:font];
   641 }
   646 }
   642 
   647 
       
   648 void *QFontDialogPrivate::_q_constructNativePanel()
       
   649 {
       
   650     QMacCocoaAutoReleasePool pool;
       
   651 
       
   652     bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists];
       
   653     NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel];
       
   654     [sharedFontPanel setHidesOnDeactivate:false];
       
   655 
       
   656     // hack to ensure that QCocoaApplication's validModesForFontPanel:
       
   657     // implementation is honored
       
   658     if (!sharedFontPanelExisted) {
       
   659         [sharedFontPanel makeKeyAndOrderFront:sharedFontPanel];
       
   660         [sharedFontPanel close];
       
   661     }
       
   662 
       
   663     NSPanel *ourPanel = 0;
       
   664     NSView *stolenContentView = 0;
       
   665     NSButton *okButton = 0;
       
   666     NSButton *cancelButton = 0;
       
   667 
       
   668     CGFloat dialogExtraWidth = 0.0;
       
   669     CGFloat dialogExtraHeight = 0.0;
       
   670 
       
   671     // compute dialogExtra{Width,Height}
       
   672     dialogExtraWidth = 2.0 * DialogSideMargin;
       
   673     dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight
       
   674                         + ButtonBottomMargin;
       
   675 
       
   676     // compute initial contents rectangle
       
   677     NSRect contentRect = [sharedFontPanel contentRectForFrameRect:[sharedFontPanel frame]];
       
   678     contentRect.size.width += dialogExtraWidth;
       
   679     contentRect.size.height += dialogExtraHeight;
       
   680 
       
   681     // create the new panel
       
   682     ourPanel = [[NSPanel alloc] initWithContentRect:contentRect
       
   683                 styleMask:StyleMask
       
   684                     backing:NSBackingStoreBuffered
       
   685                         defer:YES];
       
   686     [ourPanel setReleasedWhenClosed:YES];
       
   687 
       
   688     stolenContentView = [sharedFontPanel contentView];
       
   689 
       
   690     // steal the font panel's contents view
       
   691     [stolenContentView retain];
       
   692     [sharedFontPanel setContentView:0];
       
   693 
       
   694     {
       
   695         // create a new content view and add the stolen one as a subview
       
   696         NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } };
       
   697         NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect];
       
   698         [ourContentView addSubview:stolenContentView];
       
   699 
       
   700         // create OK and Cancel buttons and add these as subviews
       
   701         okButton = macCreateButton("&OK", ourContentView);
       
   702         cancelButton = macCreateButton("Cancel", ourContentView);
       
   703 
       
   704         [ourPanel setContentView:ourContentView];
       
   705         [ourPanel setDefaultButtonCell:[okButton cell]];
       
   706     }
       
   707     // create a delegate and set it
       
   708     QCocoaFontPanelDelegate *delegate =
       
   709             [[QCocoaFontPanelDelegate alloc] initWithFontPanel:sharedFontPanel
       
   710                                              stolenContentView:stolenContentView
       
   711                                                       okButton:okButton
       
   712                                                   cancelButton:cancelButton
       
   713                                                           priv:this
       
   714                                                     extraWidth:dialogExtraWidth
       
   715                                                    extraHeight:dialogExtraHeight];
       
   716     [ourPanel setDelegate:delegate];
       
   717     [[NSFontManager sharedFontManager] setDelegate:delegate];
       
   718 #ifdef QT_MAC_USE_COCOA
       
   719     [[NSFontManager sharedFontManager] setTarget:delegate];
       
   720 #endif
       
   721     setFont(delegate, QApplication::font());
       
   722 
       
   723     {
       
   724         // hack to get correct initial layout
       
   725         NSRect frameRect = [ourPanel frame];
       
   726         frameRect.size.width += 1.0;
       
   727         [ourPanel setFrame:frameRect display:NO];
       
   728         frameRect.size.width -= 1.0;
       
   729         frameRect.size = [delegate windowWillResize:ourPanel toSize:frameRect.size];
       
   730         [ourPanel setFrame:frameRect display:NO];
       
   731         [ourPanel center];
       
   732     }
       
   733     NSString *title = @"Select font";
       
   734     [ourPanel setTitle:title];
       
   735 
       
   736     [delegate setModalSession:[NSApp beginModalSessionForWindow:ourPanel]];
       
   737     return delegate;
       
   738 }
       
   739 
       
   740 void QFontDialogPrivate::mac_nativeDialogModalHelp()
       
   741 {
       
   742     // Copied from QFileDialogPrivate
       
   743     // Do a queued meta-call to open the native modal dialog so it opens after the new
       
   744     // event loop has started to execute (in QDialog::exec). Using a timer rather than
       
   745     // a queued meta call is intentional to ensure that the call is only delivered when
       
   746     // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
       
   747     // running (which is the case if e.g a top-most QEventLoop has been
       
   748     // interrupted, and the second-most event loop has not yet been reactivated (regardless
       
   749     // if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
       
   750     if (nativeDialogInUse) {
       
   751         Q_Q(QFontDialog);
       
   752         QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel()));
       
   753     }
       
   754 }
       
   755 
       
   756 // The problem with the native font dialog is that OS X does not
       
   757 // offer a proper dialog, but a panel (i.e. without Ok and Cancel buttons).
       
   758 // This means we need to "construct" a native dialog by taking the panel
       
   759 // and "adding" the buttons.
       
   760 void QFontDialogPrivate::_q_macRunNativeAppModalPanel()
       
   761 {
       
   762     QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
       
   763     Q_Q(QFontDialog);
       
   764     QCocoaFontPanelDelegate *delegate = (QCocoaFontPanelDelegate *)_q_constructNativePanel();
       
   765     NSWindow *ourPanel = [delegate actualPanel];
       
   766     [ourPanel retain];
       
   767     int rval = [NSApp runModalForWindow:ourPanel];
       
   768     QAbstractEventDispatcher::instance()->interrupt();
       
   769     [ourPanel release];
       
   770     [delegate cleanUpAfterMyself];
       
   771     [delegate release];
       
   772     bool isOk = (rval == NSOKButton);
       
   773     if(isOk)
       
   774         rescode = QDialog::Accepted;
       
   775     else
       
   776         rescode = QDialog::Rejected;
       
   777 }
       
   778 
       
   779 bool QFontDialogPrivate::setVisible_sys(bool visible)
       
   780 {
       
   781     Q_Q(QFontDialog);
       
   782     if (!visible == q->isHidden())
       
   783         return false;
       
   784     return visible;
       
   785 }
       
   786 
   643 QT_END_NAMESPACE
   787 QT_END_NAMESPACE
   644 
   788 
   645 #endif
   789 #endif