Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/widgets/qmenu_mac.mm

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    248248    //now walk up firing for each "caused" widget (like in the platform independent menu)
    249249    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) {
    251251        MenuRef caused_menu = 0;
    252252        if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
     
    261261            GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget);
    262262            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);
    269265            } 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);
    276268                break; //nothing more..
    277269            }
     
    279271            //walk up
    280272            if (GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget,
    281                                    sizeof(caused), 0, &caused) != noErr)
     273                                    sizeof(caused), 0, &caused) != noErr)
    282274                break;
    283275            if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
     
    650642                         initWithTitle:qt_mac_QStringToNSString(title)
    651643                         action:@selector(qtDispatcherToQAction:) keyEquivalent:@""];
    652     [item setTarget:getMenuLoader()];
     644    [item setTarget:nil];
    653645    return item;
    654646}
     
    674666    }
    675667#else
     668    bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
    676669    for (NSMenuItem *item in [menu itemArray]) {
    677670        OSMenuRef submenu = [item submenu];
     
    683676                if ([item tag]) {
    684677                    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()];
    689692            } else {
    690693                syncNSMenuItemEnabled(item, NO);
     
    750753}
    751754
    752 void qt_mac_clear_menubar()
    753 {
    754     if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
    755         return;
    756 
    757 #ifndef QT_MAC_USE_COCOA
    758     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 #else
    769     QMacCocoaAutoReleasePool pool;
    770     QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
    771     NSMenu *menu = [loader menu];
    772     [loader ensureAppMenuInMenu:menu];
    773     [NSApp setMainMenu:menu];
    774 #endif
    775 }
    776 
    777 
    778755QMacMenuAction::~QMacMenuAction()
    779756{
     
    944921{
    945922    QString ret;
     923    extern QString qt_mac_applicationmenu_string(int type);
    946924#ifdef QT_MAC_USE_COCOA
    947925    QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
     
    951929#ifndef QT_MAC_USE_COCOA
    952930    else if (action->command == kHICommandAbout)
    953         ret = QMenuBar::tr("About %1").arg(qAppName());
     931        ret = qt_mac_applicationmenu_string(6).arg(qAppName());
    954932    else if (action->command == kHICommandAboutQt)
    955933        ret = QMenuBar::tr("About Qt");
    956934    else if (action->command == kHICommandPreferences)
    957         ret = QMenuBar::tr("Preferences");
     935        ret = qt_mac_applicationmenu_string(4);
    958936    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    }
    969951#endif
    970952    return ret;
     
    11311113                [cmd retain];
    11321114                [cmd setAction:@selector(qtDispatcherToQAction:)];
    1133                 [cmd setTarget:getMenuLoader()];
     1115                [cmd setTarget:nil];
    11341116                [action->menuItem release];
    11351117                action->menuItem = cmd;
     
    14211403        [item setTitle: qt_mac_QStringToNSString(finalString)];
    14221404    }
    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))];
    14241410
    14251411    // Cocoa Enabled
     
    18461832    mac_menubar = 0;
    18471833
    1848     if (qt_mac_current_menubar.qmenubar == q) {
     1834    if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == q) {
    18491835#ifdef QT_MAC_USE_COCOA
    18501836        QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
     
    19371923    based on the modality type of modalWidget.
    19381924*/
    1939 static bool qt_mac_should_disable_menu(QMenuBar *menuBar, QWidget *modalWidget)
    1940 {
    1941     if (modalWidget == 0 || menuBar == 0)
     1925static bool qt_mac_should_disable_menu(QMenuBar *menuBar)
     1926{
     1927    QWidget *modalWidget = qApp->activeModalWidget();
     1928    if (!modalWidget)
    19421929        return false;
    19431930
    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.
    19461939    QWidget *w = modalWidget;
     1940    QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
    19471941    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        }
    19501957        w = w->parentWidget();
    19511958    }
    19521959
    19531960    // 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
     1966static QWidget *findWindowThatShouldDisplayMenubar()
     1967{
    19731968    QWidget *w = qApp->activeWindow();
    1974 
    19751969    if (!w) {
     1970        // We have no active window on screen. Try to
     1971        // find a window from the list of top levels:
    19761972        QWidgetList tlws = QApplication::topLevelWidgets();
    19771973        for(int i = 0; i < tlws.size(); ++i) {
     
    19841980        }
    19851981    }
     1982    return w;
     1983}
     1984
     1985static QMenuBar *findMenubarForWindow(QWidget *w)
     1986{
     1987    QMenuBar *mb = 0;
    19861988    if (w) {
    19871989        mb = menubars()->value(w);
     
    19971999            mb = menubars()->value((w = w->parentWidget()));
    19982000    }
    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:
    20002005        mb = fallback;
    2001     //now set it
     2006    }
     2007
     2008    return mb;
     2009}
     2010
     2011void 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*/
     2051bool 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
     2063bool QMenuBarPrivate::macUpdateMenuBarImmediatly()
     2064{
    20022065    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
    20032089    if (mb && mb->isNativeMenuBar()) {
     2090        bool modal = QApplicationPrivate::modalState();
    20042091#ifdef QT_MAC_USE_COCOA
    20052092        QMacCocoaAutoReleasePool pool;
     
    20312118            }
    20322119#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);
    20372124        }
    20382125        qt_mac_current_menubar.qmenubar = mb;
    2039         qt_mac_current_menubar.modal = QApplicationPrivate::modalState();
     2126        qt_mac_current_menubar.modal = modal;
    20402127        ret = true;
    20412128    } 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);
    20432132        if (modal != qt_mac_current_menubar.modal) {
    20442133            ret = true;
     
    20522141                syncMenuBarItemsVisiblity(qt_mac_current_menubar.qmenubar->d_func()->mac_menubar);
    20532142#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);
    20582144            }
    20592145            qt_mac_current_menubar.modal = modal;
    20602146        }
    20612147    }
    2062     if(!ret)
     2148
     2149    if (!ret) {
    20632150        qt_mac_clear_menubar();
     2151    }
    20642152    return ret;
    20652153}
     
    21322220
    21332221QT_END_NAMESPACE
     2222
Note: See TracChangeset for help on using the changeset viewer.