Changeset 846 for trunk/src/gui/dialogs/qfontdialog_mac.mm
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/dialogs/qfontdialog_mac.mm
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 59 59 #endif 60 60 61 QT_BEGIN_NAMESPACE 62 63 extern void macStartInterceptNSPanelCtor(); 64 extern void macStopInterceptNSPanelCtor(); 65 extern NSButton *macCreateButton(const char *text, NSView *superview); 66 extern bool qt_mac_is_macsheet(const QWidget *w); // qwidget_mac.mm 67 68 QT_END_NAMESPACE 61 69 QT_USE_NAMESPACE 62 70 … … 75 83 const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask; 76 84 77 @class Q CocoaFontPanelDelegate;85 @class QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate); 78 86 79 87 … … 86 94 #endif 87 95 88 @interface Q CocoaFontPanelDelegate: NSObject <NSWindowDelegate> {96 @interface QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) : NSObject <NSWindowDelegate> { 89 97 NSFontPanel *mFontPanel; 90 98 NSView *mStolenContentView; … … 96 104 CGFloat mDialogExtraWidth; 97 105 CGFloat mDialogExtraHeight; 98 NSModalSession mModalSession; 106 int mReturnCode; 107 BOOL mAppModal; 99 108 } 100 109 - (id)initWithFontPanel:(NSFontPanel *)panel … … 105 114 extraWidth:(CGFloat)extraWidth 106 115 extraHeight:(CGFloat)extraHeight; 116 - (void)showModelessPanel; 117 - (void)showWindowModalSheet:(QWidget *)docWidget; 118 - (void)runApplicationModalPanel; 119 - (BOOL)isAppModal; 107 120 - (void)changeFont:(id)sender; 108 121 - (void)changeAttributes:(id)sender; 109 - (void)setModalSession:(NSModalSession)session;110 122 - (BOOL)windowShouldClose:(id)window; 111 123 - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize; … … 121 133 - (void)finishOffWithCode:(NSInteger)result; 122 134 - (void)cleanUpAfterMyself; 135 - (void)setSubwindowStacking; 123 136 @end 124 137 … … 146 159 } 147 160 148 @implementation Q CocoaFontPanelDelegate161 @implementation QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) 149 162 - (id)initWithFontPanel:(NSFontPanel *)panel 150 163 stolenContentView:(NSView *)stolenContentView … … 164 177 mDialogExtraWidth = extraWidth; 165 178 mDialogExtraHeight = extraHeight; 166 mModalSession = 0; 179 mReturnCode = -1; 180 mAppModal = false; 167 181 168 182 if (mPanelHackedWithButtons) { … … 175 189 [cancelButton setTarget:self]; 176 190 } 191 177 192 mQtFont = new QFont(); 178 193 return self; 179 194 } 180 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 181 212 - (void)dealloc 182 213 { 183 214 delete mQtFont; 184 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 185 266 } 186 267 … … 215 296 if (mPriv) 216 297 mPriv->updateSampleFont(*mQtFont); 217 }218 219 - (void)setModalSession:(NSModalSession)session220 {221 Q_ASSERT(!mModalSession);222 mModalSession = session;223 298 } 224 299 … … 283 358 284 359 const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth, 285 qMax(okSizeHint.width, cancelSizeHint.width)), 286 CGFloat((frameSize.width - 2.0 * ButtonSideMargin 287 - ButtonSpacing) * 0.5)); 360 qMax(okSizeHint.width, cancelSizeHint.width)), 361 CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5)); 288 362 const CGFloat ButtonHeight = qMax(ButtonMinHeight, 289 363 qMax(okSizeHint.height, cancelSizeHint.height)); … … 318 392 [self setQtFont:qfontForCocoaFont([fontManager convertFont:[fontManager selectedFont]], 319 393 *mQtFont)]; 320 [[mStolenContentView window] close];321 394 [self finishOffWithCode:NSOKButton]; 322 395 } … … 325 398 { 326 399 Q_ASSERT(mPanelHackedWithButtons); 327 [[mStolenContentView window] close];328 400 [self finishOffWithCode:NSCancelButton]; 329 401 } … … 369 441 - (void)finishOffWithCode:(NSInteger)code 370 442 { 371 if (mPriv) { 372 if (mModalSession) { 373 [NSApp endModalSession:mModalSession]; 374 mModalSession = 0; 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]]; 375 448 } 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]); 382 mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); 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]; 383 458 } else { 384 [NSApp stopModalWithCode:code]; 459 if (code == NSOKButton) 460 mPriv->fontDialog()->accept(); 461 else 462 mPriv->fontDialog()->reject(); 385 463 } 386 464 } … … 409 487 QT_BEGIN_NAMESPACE 410 488 411 extern void macStartInterceptNSPanelCtor(); 412 extern void macStopInterceptNSPanelCtor(); 413 extern NSButton *macCreateButton(const char *text, NSView *superview); 414 415 void *QFontDialogPrivate::openCocoaFontPanel(const QFont &initial, 416 QWidget *parent, const QString &title, QFontDialog::FontDialogOptions options, 417 QFontDialogPrivate *priv) 418 { 419 Q_UNUSED(parent); // we would use the parent if only NSFontPanel could be a sheet 489 void QFontDialogPrivate::closeCocoaFontPanel() 490 { 420 491 QMacCocoaAutoReleasePool pool; 421 422 /* 423 The standard Cocoa font panel has no OK or Cancel button and 424 is created as a utility window. For strange reasons (which seem 425 to stem from the fact that the font panel is based on a NIB 426 file), the approach we use for the color panel doesn't work for 427 the font panel (and, inversely, the approach we use here doesn't 428 quite work for color panel, and crashed last time I tried). So 429 instead, we take the following steps: 430 431 1. Constructs a plain NSPanel that looks the way we want it 432 to look. Specifically, if the NoButtons option is off, we 433 construct a panel without the NSUtilityWindowMask flag 434 and with buttons (OK and Cancel). 435 436 2. Steal the content view from the shared NSFontPanel and 437 put it inside our new NSPanel's content view, together 438 with the OK and Cancel buttons. 439 440 3. Lay out the original content view and the buttons when 441 the font panel is shown and whenever it is resized. 442 443 4. Clean up after ourselves. 444 445 PS. Some customization is also done in QCocoaApplication 446 validModesForFontPanel:. 447 */ 448 449 Qt::WindowModality modality = Qt::ApplicationModal; 450 if (priv) 451 modality = priv->fontDialog()->windowModality(); 452 453 bool needButtons = !(options & QFontDialog::NoButtons); 454 // don't need our own panel if the title bar isn't visible anyway (in a sheet) 455 bool needOwnPanel = (needButtons && modality != Qt::WindowModal); 456 457 bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists]; 458 NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel]; 459 [sharedFontPanel setHidesOnDeactivate:false]; 460 461 // hack to ensure that QCocoaApplication's validModesForFontPanel: 462 // implementation is honored 463 if (!sharedFontPanelExisted && needOwnPanel) { 464 [sharedFontPanel makeKeyAndOrderFront:sharedFontPanel]; 465 [sharedFontPanel close]; 466 } 467 468 NSPanel *ourPanel = 0; 469 NSView *stolenContentView = 0; 470 NSButton *okButton = 0; 471 NSButton *cancelButton = 0; 472 473 CGFloat dialogExtraWidth = 0.0; 474 CGFloat dialogExtraHeight = 0.0; 475 476 if (!needOwnPanel) { 477 // we can reuse the NSFontPanel unchanged 478 ourPanel = sharedFontPanel; 479 } else { 480 // compute dialogExtra{Width,Height} 481 dialogExtraWidth = 2.0 * DialogSideMargin; 482 dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight 483 + ButtonBottomMargin; 484 485 // compute initial contents rectangle 486 NSRect contentRect = [sharedFontPanel contentRectForFrameRect:[sharedFontPanel frame]]; 487 contentRect.size.width += dialogExtraWidth; 488 contentRect.size.height += dialogExtraHeight; 489 490 // create the new panel 491 ourPanel = [[NSPanel alloc] initWithContentRect:contentRect 492 styleMask:StyleMask 493 backing:NSBackingStoreBuffered 494 defer:YES]; 495 [ourPanel setReleasedWhenClosed:YES]; 496 } 497 498 stolenContentView = [sharedFontPanel contentView]; 499 500 if (needButtons) { 501 // steal the font panel's contents view 502 [stolenContentView retain]; 503 [sharedFontPanel setContentView:0]; 504 505 // create a new content view and add the stolen one as a subview 506 NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; 507 NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; 508 [ourContentView addSubview:stolenContentView]; 509 510 // create OK and Cancel buttons and add these as subviews 511 okButton = macCreateButton("&OK", ourContentView); 512 cancelButton = macCreateButton("Cancel", ourContentView); 513 514 [ourPanel setContentView:ourContentView]; 515 [ourPanel setDefaultButtonCell:[okButton cell]]; 516 } 517 518 // create a delegate and set it 519 QCocoaFontPanelDelegate *delegate = 520 [[QCocoaFontPanelDelegate alloc] initWithFontPanel:sharedFontPanel 521 stolenContentView:stolenContentView 522 okButton:okButton 523 cancelButton:cancelButton 524 priv:priv 525 extraWidth:dialogExtraWidth 526 extraHeight:dialogExtraHeight]; 527 [ourPanel setDelegate:delegate]; 528 [[NSFontManager sharedFontManager] setDelegate:delegate]; 529 #ifdef QT_MAC_USE_COCOA 530 [[NSFontManager sharedFontManager] setTarget:delegate]; 531 #endif 532 setFont(delegate, initial); 533 534 // hack to get correct initial layout 535 NSRect frameRect = [ourPanel frame]; 536 frameRect.size.width += 1.0; 537 [ourPanel setFrame:frameRect display:NO]; 538 frameRect.size.width -= 1.0; 539 frameRect.size = [delegate windowWillResize:ourPanel toSize:frameRect.size]; 540 [ourPanel setFrame:frameRect display:NO]; 541 [ourPanel center]; 542 543 [ourPanel setTitle:(NSString*)(CFStringRef)QCFString(title)]; 544 545 if (priv) { 546 switch (modality) { 547 case Qt::WindowModal: 548 if (parent) { 549 #ifndef QT_MAC_USE_COCOA 550 WindowRef hiwindowRef = qt_mac_window_for(parent); 551 NSWindow *window = 552 [[NSWindow alloc] initWithWindowRef:hiwindowRef]; 553 // Cocoa docs say I should retain the Carbon ref. 554 CFRetain(hiwindowRef); 555 #else 556 NSWindow *window = qt_mac_window_for(parent); 557 #endif 558 [NSApp beginSheet:ourPanel 559 modalForWindow:window 560 modalDelegate:0 561 didEndSelector:0 562 contextInfo:0]; 563 #ifndef QT_MAC_USE_COCOA 564 [window release]; 565 #endif 566 break; 567 } 568 // fallthrough 569 case Qt::ApplicationModal: 570 [delegate setModalSession:[NSApp beginModalSessionForWindow:ourPanel]]; 571 break; 572 default: 573 [ourPanel makeKeyAndOrderFront:ourPanel]; 574 } 575 } 576 return delegate; 577 } 578 579 void QFontDialogPrivate::closeCocoaFontPanel(void *delegate) 580 { 581 QMacCocoaAutoReleasePool pool; 582 QCocoaFontPanelDelegate *theDelegate = static_cast<QCocoaFontPanelDelegate *>(delegate); 492 QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *theDelegate = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate); 583 493 NSWindow *ourPanel = [theDelegate actualPanel]; 584 494 [ourPanel close]; 495 if ([theDelegate isAppModal]) 496 [ourPanel release]; 585 497 [theDelegate cleanUpAfterMyself]; 586 [theDelegate autorelease]; 587 } 588 589 QFont QFontDialogPrivate::execCocoaFontPanel(bool *ok, const QFont &initial, 590 QWidget *parent, const QString &title, QFontDialog::FontDialogOptions options) 591 { 592 QMacCocoaAutoReleasePool pool; 593 QCocoaFontPanelDelegate *delegate = 594 static_cast<QCocoaFontPanelDelegate *>( 595 openCocoaFontPanel(initial, parent, title, options)); 596 NSWindow *ourPanel = [delegate actualPanel]; 597 [ourPanel retain]; 598 int rval = [NSApp runModalForWindow:ourPanel]; 599 QFont font([delegate qtFont]); 600 [ourPanel release]; 601 [delegate cleanUpAfterMyself]; 602 [delegate release]; 603 bool isOk = ((options & QFontDialog::NoButtons) || rval == NSOKButton); 604 if (ok) 605 *ok = isOk; 606 if (isOk) { 607 return font; 608 } else { 609 return initial; 610 } 498 [theDelegate release]; 499 this->delegate = 0; 500 sharedFontPanelAvailable = true; 611 501 } 612 502 … … 643 533 644 534 [mgr setSelectedFont:nsFont isMultiple:NO]; 645 [static_cast<QCocoaFontPanelDelegate *>(delegate) setQtFont:font]; 646 } 647 648 void *QFontDialogPrivate::_q_constructNativePanel() 649 { 535 [static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate) setQtFont:font]; 536 } 537 538 void QFontDialogPrivate::createNSFontPanelDelegate() 539 { 540 if (delegate) 541 return; 542 543 sharedFontPanelAvailable = false; 650 544 QMacCocoaAutoReleasePool pool; 651 652 545 bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists]; 653 546 NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel]; … … 671 564 // compute dialogExtra{Width,Height} 672 565 dialogExtraWidth = 2.0 * DialogSideMargin; 673 dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight 674 + ButtonBottomMargin; 566 dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight + ButtonBottomMargin; 675 567 676 568 // compute initial contents rectangle … … 685 577 defer:YES]; 686 578 [ourPanel setReleasedWhenClosed:YES]; 687 688 579 stolenContentView = [sharedFontPanel contentView]; 689 580 … … 705 596 [ourPanel setDefaultButtonCell:[okButton cell]]; 706 597 } 707 // create a delegate and set it 708 QCocoaFontPanelDelegate *delegate =709 [[QCocoaFontPanelDelegatealloc] initWithFontPanel:sharedFontPanel598 599 // create the delegate and set it 600 QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = [[QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) alloc] initWithFontPanel:sharedFontPanel 710 601 stolenContentView:stolenContentView 711 602 okButton:okButton … … 714 605 extraWidth:dialogExtraWidth 715 606 extraHeight:dialogExtraHeight]; 716 [ourPanel setDelegate:delegate]; 717 [[NSFontManager sharedFontManager] setDelegate:delegate]; 607 delegate = del; 608 [ourPanel setDelegate:del]; 609 610 [[NSFontManager sharedFontManager] setDelegate:del]; 718 611 #ifdef QT_MAC_USE_COCOA 719 [[NSFontManager sharedFontManager] setTarget:del egate];720 #endif 721 setFont(del egate, QApplication::font());612 [[NSFontManager sharedFontManager] setTarget:del]; 613 #endif 614 setFont(del, q_func()->currentFont()); 722 615 723 616 { … … 727 620 [ourPanel setFrame:frameRect display:NO]; 728 621 frameRect.size.width -= 1.0; 729 frameRect.size = [del egatewindowWillResize:ourPanel toSize:frameRect.size];622 frameRect.size = [del windowWillResize:ourPanel toSize:frameRect.size]; 730 623 [ourPanel setFrame:frameRect display:NO]; 731 624 [ourPanel center]; 732 625 } 626 [del setSubwindowStacking]; 733 627 NSString *title = @"Select font"; 734 628 [ourPanel setTitle:title]; 735 736 [delegate setModalSession:[NSApp beginModalSessionForWindow:ourPanel]];737 return delegate;738 629 } 739 630 … … 760 651 void QFontDialogPrivate::_q_macRunNativeAppModalPanel() 761 652 { 762 QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active); 653 createNSFontPanelDelegate(); 654 QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast<QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *>(delegate); 655 [del runApplicationModalPanel]; 656 } 657 658 bool QFontDialogPrivate::showCocoaFontPanel() 659 { 660 if (!sharedFontPanelAvailable) 661 return false; 662 763 663 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; 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()]; 775 669 else 776 rescode = QDialog::Rejected; 777 } 778 670 [del showModelessPanel]; 671 return true; 672 } 673 674 bool 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 } 779 687 bool QFontDialogPrivate::setVisible_sys(bool visible) 780 688 { … … 782 690 if (!visible == q->isHidden()) 783 691 return false; 784 return visible; 692 693 return visible ? showCocoaFontPanel() : hideCocoaFontPanel(); 785 694 } 786 695
Note:
See TracChangeset
for help on using the changeset viewer.