Changeset 846 for trunk/src/gui/widgets/qmenu_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/widgets/qmenu_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) … … 248 248 //now walk up firing for each "caused" widget (like in the platform independent menu) 249 249 QWidget *caused = 0; 250 if ( GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) {250 if (action_e == QAction::Hover && GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) { 251 251 MenuRef caused_menu = 0; 252 252 if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused)) … … 261 261 GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget); 262 262 if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) { 263 if (action_e == QAction::Trigger) { 264 emit qmenu->triggered(action->action); 265 } else if (action_e == QAction::Hover) { 266 action->action->showStatusText(widget); 267 emit qmenu->hovered(action->action); 268 } 263 action->action->showStatusText(widget); 264 emit qmenu->hovered(action->action); 269 265 } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) { 270 if (action_e == QAction::Trigger) { 271 emit qmenubar->triggered(action->action); 272 } else if (action_e == QAction::Hover) { 273 action->action->showStatusText(widget); 274 emit qmenubar->hovered(action->action); 275 } 266 action->action->showStatusText(widget); 267 emit qmenubar->hovered(action->action); 276 268 break; //nothing more.. 277 269 } … … 279 271 //walk up 280 272 if (GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, 281 sizeof(caused), 0, &caused) != noErr)273 sizeof(caused), 0, &caused) != noErr) 282 274 break; 283 275 if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused)) … … 650 642 initWithTitle:qt_mac_QStringToNSString(title) 651 643 action:@selector(qtDispatcherToQAction:) keyEquivalent:@""]; 652 [item setTarget: getMenuLoader()];644 [item setTarget:nil]; 653 645 return item; 654 646 } … … 674 666 } 675 667 #else 668 bool modalWindowOnScreen = qApp->activeModalWidget() != 0; 676 669 for (NSMenuItem *item in [menu itemArray]) { 677 670 OSMenuRef submenu = [item submenu]; … … 683 676 if ([item tag]) { 684 677 QAction *action = reinterpret_cast<QAction *>([item tag]); 685 syncNSMenuItemEnabled(item, action->isEnabled()); 686 } else { 687 syncNSMenuItemEnabled(item, YES); 688 } 678 syncNSMenuItemEnabled(item, action->isEnabled()); 679 } else { 680 syncNSMenuItemEnabled(item, YES); 681 } 682 // We sneak in some extra code here to handle a menu problem: 683 // If there is no window on screen, we cannot set 'nil' as 684 // menu item target, because then cocoa will disable the item 685 // (guess it assumes that there will be no first responder to 686 // catch the trigger anyway?) OTOH, If we have a modal window, 687 // then setting the menu loader as target will make cocoa not 688 // deliver the trigger because the loader is then seen as modally 689 // shaddowed). So either way there are shortcomings. Instead, we 690 // decide the target as late as possible: 691 [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()]; 689 692 } else { 690 693 syncNSMenuItemEnabled(item, NO); … … 750 753 } 751 754 752 void qt_mac_clear_menubar()753 {754 if (QApplication::testAttribute(Qt::AA_MacPluginApplication))755 return;756 757 #ifndef QT_MAC_USE_COCOA758 MenuRef clear_menu = 0;759 if (CreateNewMenu(0, 0, &clear_menu) == noErr) {760 SetRootMenu(clear_menu);761 ReleaseMenu(clear_menu);762 } else {763 qWarning("QMenu: Internal error at %s:%d", __FILE__, __LINE__);764 }765 ClearMenuBar();766 qt_mac_command_set_enabled(0, kHICommandPreferences, false);767 InvalMenuBar();768 #else769 QMacCocoaAutoReleasePool pool;770 QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();771 NSMenu *menu = [loader menu];772 [loader ensureAppMenuInMenu:menu];773 [NSApp setMainMenu:menu];774 #endif775 }776 777 778 755 QMacMenuAction::~QMacMenuAction() 779 756 { … … 944 921 { 945 922 QString ret; 923 extern QString qt_mac_applicationmenu_string(int type); 946 924 #ifdef QT_MAC_USE_COCOA 947 925 QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); … … 951 929 #ifndef QT_MAC_USE_COCOA 952 930 else if (action->command == kHICommandAbout) 953 ret = QMenuBar::tr("About %1").arg(qAppName());931 ret = qt_mac_applicationmenu_string(6).arg(qAppName()); 954 932 else if (action->command == kHICommandAboutQt) 955 933 ret = QMenuBar::tr("About Qt"); 956 934 else if (action->command == kHICommandPreferences) 957 ret = QMenuBar::tr("Preferences");935 ret = qt_mac_applicationmenu_string(4); 958 936 else if (action->command == kHICommandQuit) 959 ret = QMenuBar::tr("Quit %1").arg(qAppName()); 960 #else 961 else if (action->menuItem == [loader aboutMenuItem]) 962 ret = QMenuBar::tr("About %1").arg(qAppName()); 963 else if (action->menuItem == [loader aboutQtMenuItem]) 964 ret = QMenuBar::tr("About Qt"); 965 else if (action->menuItem == [loader preferencesMenuItem]) 966 ret = QMenuBar::tr("Preferences"); 967 else if (action->menuItem == [loader quitMenuItem]) 968 ret = QMenuBar::tr("Quit %1").arg(qAppName()); 937 ret = qt_mac_applicationmenu_string(5).arg(qAppName()); 938 #else 939 else if (action->menuItem == [loader aboutMenuItem]) { 940 ret = qt_mac_applicationmenu_string(6).arg(qAppName()); 941 } else if (action->menuItem == [loader aboutQtMenuItem]) { 942 if (action->action->text() == QString("About Qt")) 943 ret = QMenuBar::tr("About Qt"); 944 else 945 ret = action->action->text(); 946 } else if (action->menuItem == [loader preferencesMenuItem]) { 947 ret = qt_mac_applicationmenu_string(4); 948 } else if (action->menuItem == [loader quitMenuItem]) { 949 ret = qt_mac_applicationmenu_string(5).arg(qAppName()); 950 } 969 951 #endif 970 952 return ret; … … 1131 1113 [cmd retain]; 1132 1114 [cmd setAction:@selector(qtDispatcherToQAction:)]; 1133 [cmd setTarget: getMenuLoader()];1115 [cmd setTarget:nil]; 1134 1116 [action->menuItem release]; 1135 1117 action->menuItem = cmd; … … 1421 1403 [item setTitle: qt_mac_QStringToNSString(finalString)]; 1422 1404 } 1423 [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))]; 1405 1406 if (action->action->menuRole() == QAction::AboutRole || action->action->menuRole() == QAction::QuitRole) 1407 [item setTitle:qt_mac_QStringToNSString(text)]; 1408 else 1409 [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))]; 1424 1410 1425 1411 // Cocoa Enabled … … 1846 1832 mac_menubar = 0; 1847 1833 1848 if ( qt_mac_current_menubar.qmenubar == q) {1834 if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == q) { 1849 1835 #ifdef QT_MAC_USE_COCOA 1850 1836 QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); … … 1937 1923 based on the modality type of modalWidget. 1938 1924 */ 1939 static bool qt_mac_should_disable_menu(QMenuBar *menuBar, QWidget *modalWidget) 1940 { 1941 if (modalWidget == 0 || menuBar == 0) 1925 static bool qt_mac_should_disable_menu(QMenuBar *menuBar) 1926 { 1927 QWidget *modalWidget = qApp->activeModalWidget(); 1928 if (!modalWidget) 1942 1929 return false; 1943 1930 1944 // If there is an application modal window on 1945 // screen, the entries of the menubar should be disabled: 1931 if (menuBar && menuBar == menubars()->value(modalWidget)) 1932 // The menu bar is owned by the modal widget. 1933 // In that case we should enable it: 1934 return false; 1935 1936 // When there is an application modal window on screen, the entries of 1937 // the menubar should be disabled. The exception in Qt is that if the 1938 // modal window is the only window on screen, then we enable the menu bar. 1946 1939 QWidget *w = modalWidget; 1940 QWidgetList topLevelWidgets = QApplication::topLevelWidgets(); 1947 1941 while (w) { 1948 if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) 1949 return true; 1942 if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) { 1943 for (int i=0; i<topLevelWidgets.size(); ++i) { 1944 QWidget *top = topLevelWidgets.at(i); 1945 if (w != top && top->isVisible()) { 1946 // INVARIANT: we found another visible window 1947 // on screen other than our modalWidget. We therefore 1948 // disable the menu bar to follow normal modality logic: 1949 return true; 1950 } 1951 } 1952 // INVARIANT: We have only one window on screen that happends 1953 // to be application modal. We choose to enable the menu bar 1954 // in that case to e.g. enable the quit menu item. 1955 return false; 1956 } 1950 1957 w = w->parentWidget(); 1951 1958 } 1952 1959 1953 1960 // INVARIANT: modalWidget is window modal. Disable menu entries 1954 // if the menu bar belongs to an ancestor of modalWidget: 1955 return qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget); 1956 } 1957 1958 /*! 1959 \internal 1960 1961 This function will update the current menu bar and set it as the 1962 active menu bar in the Menu Manager. 1963 1964 \warning This function is not portable. 1965 1966 \sa QMenu::macMenu(), QMenuBar::macMenu() 1967 */ 1968 bool QMenuBar::macUpdateMenuBar() 1969 { 1970 cancelAllMenuTracking(); 1971 QMenuBar *mb = 0; 1972 //find a menu bar 1961 // if the menu bar belongs to an ancestor of modalWidget. If menuBar 1962 // is nil, we understand it as the default menu bar set by the nib: 1963 return menuBar ? qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget) : false; 1964 } 1965 1966 static QWidget *findWindowThatShouldDisplayMenubar() 1967 { 1973 1968 QWidget *w = qApp->activeWindow(); 1974 1975 1969 if (!w) { 1970 // We have no active window on screen. Try to 1971 // find a window from the list of top levels: 1976 1972 QWidgetList tlws = QApplication::topLevelWidgets(); 1977 1973 for(int i = 0; i < tlws.size(); ++i) { … … 1984 1980 } 1985 1981 } 1982 return w; 1983 } 1984 1985 static QMenuBar *findMenubarForWindow(QWidget *w) 1986 { 1987 QMenuBar *mb = 0; 1986 1988 if (w) { 1987 1989 mb = menubars()->value(w); … … 1997 1999 mb = menubars()->value((w = w->parentWidget())); 1998 2000 } 1999 if (!mb) 2001 2002 if (!mb) { 2003 // We could not find a menu bar for the window. Lets 2004 // check if we have a global (parentless) menu bar instead: 2000 2005 mb = fallback; 2001 //now set it 2006 } 2007 2008 return mb; 2009 } 2010 2011 void qt_mac_clear_menubar() 2012 { 2013 if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) 2014 return; 2015 2016 #ifndef QT_MAC_USE_COCOA 2017 MenuRef clear_menu = 0; 2018 if (CreateNewMenu(0, 0, &clear_menu) == noErr) { 2019 SetRootMenu(clear_menu); 2020 ReleaseMenu(clear_menu); 2021 } else { 2022 qWarning("QMenu: Internal error at %s:%d", __FILE__, __LINE__); 2023 } 2024 ClearMenuBar(); 2025 qt_mac_command_set_enabled(0, kHICommandPreferences, false); 2026 InvalMenuBar(); 2027 #else 2028 QMacCocoaAutoReleasePool pool; 2029 QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); 2030 NSMenu *menu = [loader menu]; 2031 [loader ensureAppMenuInMenu:menu]; 2032 [NSApp setMainMenu:menu]; 2033 const bool modal = qt_mac_should_disable_menu(0); 2034 if (qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal) 2035 qt_mac_set_modal_state(menu, modal); 2036 qt_mac_current_menubar.qmenubar = 0; 2037 qt_mac_current_menubar.modal = modal; 2038 #endif 2039 } 2040 2041 /*! 2042 \internal 2043 2044 This function will update the current menu bar and set it as the 2045 active menu bar in the Menu Manager. 2046 2047 \warning This function is not portable. 2048 2049 \sa QMenu::macMenu(), QMenuBar::macMenu() 2050 */ 2051 bool QMenuBar::macUpdateMenuBar() 2052 { 2053 #ifdef QT_MAC_USE_COCOA 2054 QMacCocoaAutoReleasePool pool; 2055 if (!qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar))) 2056 return QMenuBarPrivate::macUpdateMenuBarImmediatly(); 2057 return true; 2058 #else 2059 return QMenuBarPrivate::macUpdateMenuBarImmediatly(); 2060 #endif 2061 } 2062 2063 bool QMenuBarPrivate::macUpdateMenuBarImmediatly() 2064 { 2002 2065 bool ret = false; 2066 cancelAllMenuTracking(); 2067 QWidget *w = findWindowThatShouldDisplayMenubar(); 2068 QMenuBar *mb = findMenubarForWindow(w); 2069 extern bool qt_mac_app_fullscreen; //qapplication_mac.mm 2070 2071 // We need to see if we are in full screen mode, if so we need to 2072 // switch the full screen mode to be able to show or hide the menubar. 2073 if(w && mb) { 2074 // This case means we are creating a menubar, check if full screen 2075 if(w->isFullScreen()) { 2076 // Ok, switch to showing the menubar when hovering over it. 2077 SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); 2078 qt_mac_app_fullscreen = true; 2079 } 2080 } else if(w) { 2081 // Removing a menubar 2082 if(w->isFullScreen()) { 2083 // Ok, switch to not showing the menubar when hovering on it 2084 SetSystemUIMode(kUIModeAllHidden, 0); 2085 qt_mac_app_fullscreen = true; 2086 } 2087 } 2088 2003 2089 if (mb && mb->isNativeMenuBar()) { 2090 bool modal = QApplicationPrivate::modalState(); 2004 2091 #ifdef QT_MAC_USE_COCOA 2005 2092 QMacCocoaAutoReleasePool pool; … … 2031 2118 } 2032 2119 #endif 2033 QWidget *modalWidget = qApp->activeModalWidget();2034 if (mb != menubars()->value(modalWidget)) {2035 qt_mac_set_modal_state(menu, qt_mac_should_disable_menu(mb, modalWidget));2036 }2120 // Check if menu is modally shaddowed and should be disabled: 2121 modal = qt_mac_should_disable_menu(mb); 2122 if (mb != qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal) 2123 qt_mac_set_modal_state(menu, modal); 2037 2124 } 2038 2125 qt_mac_current_menubar.qmenubar = mb; 2039 qt_mac_current_menubar.modal = QApplicationPrivate::modalState();2126 qt_mac_current_menubar.modal = modal; 2040 2127 ret = true; 2041 2128 } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) { 2042 const bool modal = QApplicationPrivate::modalState(); 2129 // INVARIANT: The currently active menu bar (if any) is not native. But we do have a 2130 // native menu bar from before. So we need to decide whether or not is should be enabled: 2131 const bool modal = qt_mac_should_disable_menu(qt_mac_current_menubar.qmenubar); 2043 2132 if (modal != qt_mac_current_menubar.modal) { 2044 2133 ret = true; … … 2052 2141 syncMenuBarItemsVisiblity(qt_mac_current_menubar.qmenubar->d_func()->mac_menubar); 2053 2142 #endif 2054 QWidget *modalWidget = qApp->activeModalWidget(); 2055 if (qt_mac_current_menubar.qmenubar != menubars()->value(modalWidget)) { 2056 qt_mac_set_modal_state(menu, qt_mac_should_disable_menu(mb, modalWidget)); 2057 } 2143 qt_mac_set_modal_state(menu, modal); 2058 2144 } 2059 2145 qt_mac_current_menubar.modal = modal; 2060 2146 } 2061 2147 } 2062 if(!ret) 2148 2149 if (!ret) { 2063 2150 qt_mac_clear_menubar(); 2151 } 2064 2152 return ret; 2065 2153 } … … 2132 2220 2133 2221 QT_END_NAMESPACE 2222
Note:
See TracChangeset
for help on using the changeset viewer.