diff options
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r-- | src/widgets/widgets/qcocoamenu_mac.mm | 268 | ||||
-rw-r--r-- | src/widgets/widgets/qcocoamenu_mac_p.h | 80 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu.cpp | 32 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu.h | 18 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu_mac.mm | 1284 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu_p.h | 75 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar.cpp | 67 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar.h | 7 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar_p.h | 38 | ||||
-rw-r--r-- | src/widgets/widgets/widgets.pri | 6 |
10 files changed, 57 insertions, 1818 deletions
diff --git a/src/widgets/widgets/qcocoamenu_mac.mm b/src/widgets/widgets/qcocoamenu_mac.mm deleted file mode 100644 index 36e356cd4c..0000000000 --- a/src/widgets/widgets/qcocoamenu_mac.mm +++ /dev/null @@ -1,268 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmacdefines_mac.h" -#include "qapplication.h" -#include "qvarlengtharray.h" -#import <private/qcocoamenu_mac_p.h> -#import <private/qcocoamenuloader_mac_p.h> -#import <private/qcocoaapplication_mac_p.h> -#include <private/qt_cocoa_helpers_mac_p.h> -#include <private/qapplication_p.h> -#include <private/qaction_p.h> -#include <private/qcocoaapplication_mac_p.h> - -#include <QtWidgets/QMenu> - -QT_FORWARD_DECLARE_CLASS(QAction) -QT_FORWARD_DECLARE_CLASS(QWidget) -QT_FORWARD_DECLARE_CLASS(QApplication) -QT_FORWARD_DECLARE_CLASS(QCoreApplication) -QT_FORWARD_DECLARE_CLASS(QApplicationPrivate) -QT_FORWARD_DECLARE_CLASS(QKeyEvent) -QT_FORWARD_DECLARE_CLASS(QEvent) - -QT_BEGIN_NAMESPACE -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication.cpp -extern void qt_mac_menu_collapseSeparators(NSMenu *menu, bool collapse); -void qt_mac_clear_status_text(QAction *action); -QT_END_NAMESPACE - -QT_USE_NAMESPACE - -@implementation QT_MANGLE_NAMESPACE(QCocoaMenu) - -- (id)initWithQMenu:(QMenu*)menu -{ - self = [super init]; - if (self) { - qmenu = menu; - previousAction = 0; - [self setAutoenablesItems:NO]; - [self setDelegate:self]; - } - return self; -} - -- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item -{ - Q_UNUSED(menu); - - if (!item) { - if (previousAction) { - qt_mac_clear_status_text(previousAction); - previousAction = 0; - } - return; - } - - if (QAction *action = reinterpret_cast<QAction *>([item tag])) { - QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QCocoaMenu) *>(menu)->qmenu; - previousAction = action; - action->activate(QAction::Hover); - qt_mac_menu_emit_hovered(qtmenu, action); - action->showStatusText(0); // 0 widget -> action's parent - } -} - -- (void)menuWillOpen:(NSMenu*)menu -{ - while (QWidget *popup - = QApplication::activePopupWidget()) - popup->close(); - QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QCocoaMenu) *>(menu)->qmenu; - qt_mac_emit_menuSignals(qtmenu, true); - qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible()); -} - -- (void)menuDidClose:(NSMenu*)menu -{ - qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QCocoaMenu) *)menu)->qmenu, false); - if (previousAction) { - qt_mac_clear_status_text(previousAction); - previousAction = 0; - } -} - -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier - whichItem:(NSMenuItem**)outItem -{ - for (NSMenuItem *item in [menu itemArray]) { - if (![item isEnabled] || [item isHidden] || [item isSeparatorItem]) - continue; - if ([item hasSubmenu]) { - if ([self hasShortcut:[item submenu] - forKey:key - forModifiers:modifier whichItem:outItem]) { - if (outItem) - *outItem = item; - return YES; - } - } - NSString *menuKey = [item keyEquivalent]; - if (menuKey && NSOrderedSame == [menuKey compare:key] - && (modifier == [item keyEquivalentModifierMask])) { - if (outItem) - *outItem = item; - return YES; - } - } - if (outItem) - *outItem = 0; - return NO; -} - -NSString *qt_mac_removePrivateUnicode(NSString* string) -{ - int len = [string length]; - if (len) { - QVarLengthArray <unichar, 10> characters(len); - bool changed = false; - for (int i = 0; i<len; i++) { - characters[i] = [string characterAtIndex:i]; - // check if they belong to key codes in private unicode range - // currently we need to handle only the NSDeleteFunctionKey - if (characters[i] == NSDeleteFunctionKey) { - characters[i] = NSDeleteCharacter; - changed = true; - } - } - if (changed) - return [NSString stringWithCharacters:characters.data() length:len]; - } - return string; -} - -- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action -{ - // Check if the menu actually has a keysequence defined for this key event. - // If it does, then we will first send the key sequence to the QWidget that has focus - // since (in Qt's eyes) it needs to a chance at the key event first. If the widget - // accepts the key event, we then return YES, but set the target and action to be nil, - // which means that the action should not be triggered, and instead dispatch the event ourselves. - // In every other case we return NO, which means that Cocoa can do as it pleases - // (i.e., fire the menu action). - NSMenuItem *whichItem; - // Change the private unicode keys to the ones used in setting the "Key Equivalents" - NSString *characters = qt_mac_removePrivateUnicode([event characters]); - if ([self hasShortcut:menu - forKey:characters - // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... - forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask)) - whichItem:&whichItem]) { - QWidget *widget = 0; - QAction *qaction = 0; - if (whichItem && [whichItem tag]) { - qaction = reinterpret_cast<QAction *>([whichItem tag]); - } - if (qApp->activePopupWidget()) - widget = (qApp->activePopupWidget()->focusWidget() ? - qApp->activePopupWidget()->focusWidget() : qApp->activePopupWidget()); - else if (QApplicationPrivate::focus_widget) - widget = QApplicationPrivate::focus_widget; - // If we could not find any receivers, pass it to the active window - if (!widget) - widget = qApp->activeWindow(); - if (qaction && widget) { - int key = qaction->shortcut(); - QKeyEvent accel_ev(QEvent::ShortcutOverride, (key & (~Qt::KeyboardModifierMask)), - Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask)); - accel_ev.ignore(); - qt_sendSpontaneousEvent(widget, &accel_ev); - if (accel_ev.isAccepted()) { - qWarning("Unimplemented: qt_dispatchKeyEvent"); -#if 0 - qt_dispatchKeyEvent(event, widget); -#endif - *target = nil; - *action = nil; - return YES; - } - } - } - return NO; -} - -- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector -{ - NSInteger index = [super indexOfItemWithTarget:anObject andAction:actionSelector]; - static SEL selForOFCP = NSSelectorFromString(@"orderFrontCharacterPalette:"); - if (index == -1 && selForOFCP == actionSelector) { - // Check if the 'orderFrontCharacterPalette' SEL exists for QCocoaMenuLoader object - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; - return [super indexOfItemWithTarget:loader andAction:actionSelector]; - } - return index; -} - -@end - -QT_BEGIN_NAMESPACE -extern int qt_mac_menus_open_count; // qmenu_mac.mm - -void qt_mac_emit_menuSignals(QMenu *menu, bool show) -{ - if (!menu) - return; - int delta; - if (show) { - emit menu->aboutToShow(); - delta = 1; - } else { - emit menu->aboutToHide(); - delta = -1; - } - qt_mac_menus_open_count += delta; -} - -void qt_mac_clear_status_text(QAction *action) -{ - action->d_func()->showStatusText(0, QString()); -} - -void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action) -{ - emit menu->hovered(action); -} - - -QT_END_NAMESPACE - diff --git a/src/widgets/widgets/qcocoamenu_mac_p.h b/src/widgets/widgets/qcocoamenu_mac_p.h deleted file mode 100644 index 392060c90a..0000000000 --- a/src/widgets/widgets/qcocoamenu_mac_p.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qmacdefines_mac.h" -#import <Cocoa/Cocoa.h> - -QT_FORWARD_DECLARE_CLASS(QMenu) -QT_FORWARD_DECLARE_CLASS(QAction) - -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 - -@protocol NSMenuDelegate <NSObject> -- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item; -- (void)menuWillOpen:(NSMenu*)menu; -- (void)menuDidClose:(NSMenu*)menu; -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier - whichItem:(NSMenuItem**)outItem; -@end - -#endif - -@interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu <NSMenuDelegate> -{ - QMenu *qmenu; - QAction *previousAction; -} -- (id)initWithQMenu:(QMenu*)menu; -- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action; -- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector; -@end - diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index bcf7c574f0..cfcf0dc9ed 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -164,6 +164,8 @@ void QMenuPrivate::init() scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; } + platformMenu = QGuiApplicationPrivate::platformIntegration()->createPlatformMenu(q); + #ifdef QT_SOFTKEYS_ENABLED selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, q); cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Back, q); @@ -2367,10 +2369,8 @@ void QMenu::changeEvent(QEvent *e) if (d->tornPopup) // torn-off menu d->tornPopup->setEnabled(isEnabled()); d->menuAction->setEnabled(isEnabled()); -#ifdef Q_OS_MAC - if (d->mac_menu) - d->setMacMenuEnabled(isEnabled()); -#endif + if (d->platformMenu) + d->platformMenu->setMenuEnabled(isEnabled()); } QWidget::changeEvent(e); } @@ -2923,16 +2923,14 @@ void QMenu::actionEvent(QActionEvent *e) d->widgetItems.remove(e->action()); } -#ifdef Q_OS_MAC - if (d->mac_menu) { + if (d->platformMenu) { if (e->type() == QEvent::ActionAdded) - d->mac_menu->addAction(e->action(), d->mac_menu->findAction(e->before()), d); + d->platformMenu->addAction(e->action(), e->before()); else if (e->type() == QEvent::ActionRemoved) - d->mac_menu->removeAction(e->action()); + d->platformMenu->removeAction(e->action()); else if (e->type() == QEvent::ActionChanged) - d->mac_menu->syncAction(e->action()); + d->platformMenu->syncAction(e->action()); } -#endif #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) if (!d->wce_menu) @@ -3093,6 +3091,14 @@ void QMenu::setNoReplayFor(QWidget *noReplayFor) #endif } +/*!\internal +*/ +QPlatformMenu *QMenu::platformMenu() +{ + + return d_func()->platformMenu; +} + /*! \property QMenu::separatorsCollapsible \since 4.2 @@ -3123,10 +3129,8 @@ void QMenu::setSeparatorsCollapsible(bool collapse) d->updateActionRects(); update(); } -#ifdef Q_OS_MAC - if (d->mac_menu) - d->syncSeparatorsCollapsible(collapse); -#endif + if (d->platformMenu) + d->platformMenu->syncSeparatorsCollapsible(collapse); } #ifdef QT3_SUPPORT diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 84a1f1ef14..8d7e281fd4 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -46,10 +46,7 @@ #include <QtCore/qstring.h> #include <QtWidgets/qicon.h> #include <QtWidgets/qaction.h> -#ifdef Q_OS_MAC -#include "QtWidgets/qmacdefines_mac.h" -#endif - +#include <QtWidgets/qplatformmenu_qpa.h> #ifdef QT3_SUPPORT #include <QtGui/qpixmap.h> @@ -145,9 +142,7 @@ public: void setIcon(const QIcon &icon); void setNoReplayFor(QWidget *widget); -#ifdef Q_OS_MAC - OSMenuRef macMenu(OSMenuRef merge=0); -#endif + QPlatformMenu *platformMenu(); #ifdef Q_WS_WINCE HMENU wceMenu(); @@ -418,15 +413,8 @@ private: friend class QComboBox; friend class QAction; friend class QToolButtonPrivate; - -#ifdef Q_OS_MAC - friend void qt_mac_trayicon_activate_action(QMenu *, QAction *action); - friend bool qt_mac_watchingAboutToShow(QMenu *); - friend OSStatus qt_mac_menu_event(EventHandlerCallRef, EventRef, void *); - friend bool qt_mac_activate_action(OSMenuRef, uint, QAction::ActionEvent, bool); - friend void qt_mac_emit_menuSignals(QMenu *, bool); + friend void qt_mac_emit_menuSignals(QMenu *menu, bool show); friend void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action); -#endif }; #endif // QT_NO_MENU diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm deleted file mode 100644 index 5fb364ec1b..0000000000 --- a/src/widgets/widgets/qmenu_mac.mm +++ /dev/null @@ -1,1284 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <Cocoa/Cocoa.h> - -#include "qmenu.h" -#include "qhash.h" -#include <qdebug.h> -#include "qapplication.h" -#include <private/qt_mac_p.h> -#include "qregexp.h" -#include "qmainwindow.h" -#include "qdockwidget.h" -#include "qtoolbar.h" -#include "qevent.h" -#include "qstyle.h" -#include "qwidgetaction.h" -#include "qmacnativewidget_mac.h" - -#include <private/qapplication_p.h> -#include <private/qcocoaapplication_mac_p.h> -#include <private/qmenu_p.h> -#include <private/qmenubar_p.h> -#include <private/qcocoamenuloader_mac_p.h> -#include <private/qcocoamenu_mac_p.h> -#include <private/qt_cocoa_helpers_mac_p.h> - -QT_BEGIN_NAMESPACE - -/***************************************************************************** - QMenu debug facilities - *****************************************************************************/ - -/***************************************************************************** - QMenu globals - *****************************************************************************/ -bool qt_mac_no_menubar_merge = false; -bool qt_mac_quit_menu_item_enabled = true; -int qt_mac_menus_open_count = 0; - -static OSMenuRef qt_mac_create_menu(QWidget *w); - -#ifndef QT_MAC_USE_COCOA -static uint qt_mac_menu_static_cmd_id = 'QT00'; -const UInt32 kMenuCreatorQt = 'cute'; -enum { - kMenuPropertyQAction = 'QAcT', - kMenuPropertyQWidget = 'QWId', - kMenuPropertyCausedQWidget = 'QCAU', - kMenuPropertyMergeMenu = 'QApP', - kMenuPropertyMergeList = 'QAmL', - kMenuPropertyWidgetActionWidget = 'QWid', - kMenuPropertyWidgetMenu = 'QWMe', - - kHICommandAboutQt = 'AOQT', - kHICommandCustomMerge = 'AQt0' -}; -#endif - -static struct { - QPointer<QMenuBar> qmenubar; - bool modal; -} qt_mac_current_menubar = { 0, false }; - - - - -/***************************************************************************** - Externals - *****************************************************************************/ -extern OSViewRef qt_mac_hiview_for(const QWidget *w); //qwidget_mac.cpp -extern HIViewRef qt_mac_hiview_for(OSWindowRef w); //qwidget_mac.cpp -extern IconRef qt_mac_create_iconref(const QPixmap &px); //qpixmap_mac.cpp -extern QWidget * mac_keyboard_grabber; //qwidget_mac.cpp -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication_xxx.cpp -RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp -void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp - -/***************************************************************************** - QMenu utility functions - *****************************************************************************/ -bool qt_mac_watchingAboutToShow(QMenu *menu) -{ - return menu; /* && menu->receivers(SIGNAL(aboutToShow()));*/ -} - -static int qt_mac_CountMenuItems(OSMenuRef menu) -{ - if (menu) { - return [menu numberOfItems]; - } - return 0; -} - -void qt_mac_menu_collapseSeparators(NSMenu * theMenu, bool collapse) -{ - QMacCocoaAutoReleasePool pool; - OSMenuRef menu = static_cast<OSMenuRef>(theMenu); - if (collapse) { - bool previousIsSeparator = true; // setting to true kills all the separators placed at the top. - NSMenuItem *previousItem = nil; - - NSArray *itemArray = [menu itemArray]; - for (unsigned int i = 0; i < [itemArray count]; ++i) { - NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]); - if ([item isSeparatorItem]) { - [item setHidden:previousIsSeparator]; - } - - if (![item isHidden]) { - previousItem = item; - previousIsSeparator = ([previousItem isSeparatorItem]); - } - } - - // We now need to check the final item since we don't want any separators at the end of the list. - if (previousItem && previousIsSeparator) - [previousItem setHidden:YES]; - } else { - NSArray *itemArray = [menu itemArray]; - for (unsigned int i = 0; i < [itemArray count]; ++i) { - NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]); - if (QAction *action = reinterpret_cast<QAction *>([item tag])) - [item setHidden:!action->isVisible()]; - } - } -} - -#ifndef QT_NO_TRANSLATION -static const char *application_menu_strings[] = { - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1") - }; - -QString qt_mac_applicationmenu_string(int type) -{ - QString menuString = QString::fromLatin1(application_menu_strings[type]); - QString translated = qApp->translate("QMenuBar", application_menu_strings[type]); - if (translated != menuString) - return translated; - else - return qApp->translate("MAC_APPLICATION_MENU", - application_menu_strings[type]); -} -#endif - - -static quint32 constructModifierMask(quint32 accel_key) -{ - quint32 ret = 0; - const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta); -#ifndef QT_MAC_USE_COCOA - if ((accel_key & Qt::ALT) == Qt::ALT) - ret |= kMenuOptionModifier; - if ((accel_key & Qt::SHIFT) == Qt::SHIFT) - ret |= kMenuShiftModifier; - if (dontSwap) { - if ((accel_key & Qt::META) != Qt::META) - ret |= kMenuNoCommandModifier; - if ((accel_key & Qt::CTRL) == Qt::CTRL) - ret |= kMenuControlModifier; - } else { - if ((accel_key & Qt::CTRL) != Qt::CTRL) - ret |= kMenuNoCommandModifier; - if ((accel_key & Qt::META) == Qt::META) - ret |= kMenuControlModifier; - } -#else - if ((accel_key & Qt::CTRL) == Qt::CTRL) - ret |= (dontSwap ? NSControlKeyMask : NSCommandKeyMask); - if ((accel_key & Qt::META) == Qt::META) - ret |= (dontSwap ? NSCommandKeyMask : NSControlKeyMask); - if ((accel_key & Qt::ALT) == Qt::ALT) - ret |= NSAlternateKeyMask; - if ((accel_key & Qt::SHIFT) == Qt::SHIFT) - ret |= NSShiftKeyMask; -#endif - return ret; -} - -static void cancelAllMenuTracking() -{ - QMacCocoaAutoReleasePool pool; - NSMenu *mainMenu = [NSApp mainMenu]; - [mainMenu cancelTracking]; - for (NSMenuItem *item in [mainMenu itemArray]) { - if ([item submenu]) { - [[item submenu] cancelTracking]; - } - } -} - -static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp, - const QMacMenuAction *action) -{ - bool visible = action->action->isVisible(); - if (visible && action->action->text() == QString(QChar(0x14))) - return false; - if (visible && action->action->menu() && !action->action->menu()->actions().isEmpty() && - !qt_mac_CountMenuItems(action->action->menu()->macMenu(mbp->apple_menu)) && - !qt_mac_watchingAboutToShow(action->action->menu())) { - return false; - } - return visible; -} - -static inline void syncNSMenuItemVisiblity(NSMenuItem *menuItem, bool actionVisibility) -{ - [menuItem setHidden:NO]; - [menuItem setHidden:YES]; - [menuItem setHidden:!actionVisibility]; -} - -static inline void syncNSMenuItemEnabled(NSMenuItem *menuItem, bool enabled) -{ - [menuItem setEnabled:NO]; - [menuItem setEnabled:YES]; - [menuItem setEnabled:enabled]; -} - -static inline void syncMenuBarItemsVisiblity(const QMenuBarPrivate::QMacMenuBarPrivate *mac_menubar) -{ - const QList<QMacMenuAction *> &menubarActions = mac_menubar->actionItems; - for (int i = 0; i < menubarActions.size(); ++i) { - const QMacMenuAction *action = menubarActions.at(i); - syncNSMenuItemVisiblity(action->menuItem, actualMenuItemVisibility(mac_menubar, action)); - } -} - -static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader() -{ - return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; -} - -static NSMenuItem *createNSMenuItem(const QString &title) -{ - NSMenuItem *item = [[NSMenuItem alloc] - initWithTitle:qt_mac_QStringToNSString(title) - action:@selector(qtDispatcherToQAction:) keyEquivalent:@""]; - [item setTarget:nil]; - return item; -} - -// helper that recurses into a menu structure and en/dis-ables them -void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bool on) -{ - bool modalWindowOnScreen = qApp->activeModalWidget() != 0; - for (NSMenuItem *item in [menu itemArray]) { - OSMenuRef submenu = [item submenu]; - if (submenu != merge) { - if (submenu) - qt_mac_set_modal_state_helper_recursive(submenu, merge, on); - if (!on) { - // The item should follow what the QAction has. - if ([item tag]) { - QAction *action = reinterpret_cast<QAction *>([item tag]); - syncNSMenuItemEnabled(item, action->isEnabled()); - } else { - syncNSMenuItemEnabled(item, YES); - } - // We sneak in some extra code here to handle a menu problem: - // If there is no window on screen, we cannot set 'nil' as - // menu item target, because then cocoa will disable the item - // (guess it assumes that there will be no first responder to - // catch the trigger anyway?) OTOH, If we have a modal window, - // then setting the menu loader as target will make cocoa not - // deliver the trigger because the loader is then seen as modally - // shaddowed). So either way there are shortcomings. Instead, we - // decide the target as late as possible: - [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()]; - } else { - syncNSMenuItemEnabled(item, NO); - } - } - } -} - -//toggling of modal state -static void qt_mac_set_modal_state(OSMenuRef menu, bool on) -{ - OSMenuRef merge = QMenuPrivate::mergeMenuHash.value(menu); - qt_mac_set_modal_state_helper_recursive(menu, merge, on); - // I'm ignoring the special items now, since they should get handled via a syncAction() -} - -bool qt_mac_menubar_is_open() -{ - return qt_mac_menus_open_count > 0; -} - -QMacMenuAction::~QMacMenuAction() -{ - [menu release]; - // Update the menu item if this action still owns it. For some items - // (like 'Quit') ownership will be transferred between all menu bars... - if (action && action.data() == reinterpret_cast<QAction *>([menuItem tag])) { - QAction::MenuRole role = action->menuRole(); - // Check if the item is owned by Qt, and should be hidden to keep it from causing - // problems. Do it for everything but the quit menu item since that should always - // be visible. - if (role > QAction::ApplicationSpecificRole && role < QAction::QuitRole) { - [menuItem setHidden:YES]; - } else if (role == QAction::TextHeuristicRole - && menuItem != [getMenuLoader() quitMenuItem]) { - [menuItem setHidden:YES]; - } - [menuItem setTag:nil]; - } - [menuItem release]; -} - -static NSMenuItem *qt_mac_menu_merge_action(OSMenuRef merge, QMacMenuAction *action) -{ - if (qt_mac_no_menubar_merge || action->action->menu() || action->action->isSeparator() - || action->action->menuRole() == QAction::NoRole) - return 0; - - QString t = qt_mac_removeMnemonics(action->action->text().toLower()); - int st = t.lastIndexOf(QLatin1Char('\t')); - if (st != -1) - t.remove(st, t.length()-st); - t.replace(QRegExp(QString::fromLatin1("\\.*$")), QLatin1String("")); //no ellipses - //now the fun part - NSMenuItem *ret = 0; - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - - switch (action->action->menuRole()) { - case QAction::NoRole: - ret = 0; - break; - case QAction::ApplicationSpecificRole: - ret = [loader appSpecificMenuItem]; - break; - case QAction::AboutRole: - ret = [loader aboutMenuItem]; - break; - case QAction::AboutQtRole: - ret = [loader aboutQtMenuItem]; - break; - case QAction::QuitRole: - ret = [loader quitMenuItem]; - break; - case QAction::PreferencesRole: - ret = [loader preferencesMenuItem]; - break; - case QAction::TextHeuristicRole: { - QString aboutString = QMenuBar::tr("About").toLower(); - if (t.startsWith(aboutString) || t.endsWith(aboutString)) { - if (t.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) { - ret = [loader aboutMenuItem]; - } else { - ret = [loader aboutQtMenuItem]; - } - } else if (t.startsWith(QMenuBar::tr("Config").toLower()) - || t.startsWith(QMenuBar::tr("Preference").toLower()) - || t.startsWith(QMenuBar::tr("Options").toLower()) - || t.startsWith(QMenuBar::tr("Setting").toLower()) - || t.startsWith(QMenuBar::tr("Setup").toLower())) { - ret = [loader preferencesMenuItem]; - } else if (t.startsWith(QMenuBar::tr("Quit").toLower()) - || t.startsWith(QMenuBar::tr("Exit").toLower())) { - ret = [loader quitMenuItem]; - } - } - break; - } - - if (QMenuMergeList *list = QMenuPrivate::mergeMenuItemsHash.value(merge)) { - for(int i = 0; i < list->size(); ++i) { - const QMenuMergeItem &item = list->at(i); - if (item.menuItem == ret && item.action) - return 0; - } - } - - return ret; -} - -static QString qt_mac_menu_merge_text(QMacMenuAction *action) -{ - QString ret; - extern QString qt_mac_applicationmenu_string(int type); - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - if (action->action->menuRole() == QAction::ApplicationSpecificRole) - ret = action->action->text(); - else if (action->menuItem == [loader aboutMenuItem]) { - ret = qt_mac_applicationmenu_string(6).arg(qAppName()); - } else if (action->menuItem == [loader aboutQtMenuItem]) { - if (action->action->text() == QString("About Qt")) - ret = QMenuBar::tr("About Qt"); - else - ret = action->action->text(); - } else if (action->menuItem == [loader preferencesMenuItem]) { - ret = qt_mac_applicationmenu_string(4); - } else if (action->menuItem == [loader quitMenuItem]) { - ret = qt_mac_applicationmenu_string(5).arg(qAppName()); - } - return ret; -} - -static QKeySequence qt_mac_menu_merge_accel(QMacMenuAction *action) -{ - QKeySequence ret; - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - if (action->action->menuRole() == QAction::ApplicationSpecificRole) - ret = action->action->shortcut(); - else if (action->menuItem == [loader preferencesMenuItem]) - ret = QKeySequence(QKeySequence::Preferences); - else if (action->menuItem == [loader quitMenuItem]) - ret = QKeySequence(QKeySequence::Quit); - return ret; -} - -void Q_WIDGETS_EXPORT qt_mac_set_menubar_icons(bool b) -{ QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, !b); } -void Q_WIDGETS_EXPORT qt_mac_set_native_menubar(bool b) -{ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, !b); } -void Q_WIDGETS_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = !b; } - -/***************************************************************************** - QMenu bindings - *****************************************************************************/ -QMenuPrivate::QMacMenuPrivate::QMacMenuPrivate() : menu(0) -{ -} - -QMenuPrivate::QMacMenuPrivate::~QMacMenuPrivate() -{ - QMacCocoaAutoReleasePool pool; - while (actionItems.size()) { - QMacMenuAction *action = actionItems.takeFirst(); - if (QMenuMergeList *list = mergeMenuItemsHash.value(action->menu)) { - int i = 0; - while (i < list->size()) { - const QMenuMergeItem &item = list->at(i); - if (item.action == action) - list->removeAt(i); - else - ++i; - } - } - delete action; - } - mergeMenuHash.remove(menu); - mergeMenuItemsHash.remove(menu); - [menu release]; -} - -void -QMenuPrivate::QMacMenuPrivate::addAction(QAction *a, QMacMenuAction *before, QMenuPrivate *qmenu) -{ - QMacMenuAction *action = new QMacMenuAction; - action->action = a; - action->ignore_accel = 0; - action->merged = 0; - action->menu = 0; - addAction(action, before, qmenu); -} - -void -QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction *before, QMenuPrivate *qmenu) -{ - QMacCocoaAutoReleasePool pool; - Q_UNUSED(qmenu); - if (!action) - return; - int before_index = actionItems.indexOf(before); - if (before_index < 0) { - before = 0; - before_index = actionItems.size(); - } - actionItems.insert(before_index, action); - - [menu retain]; - [action->menu release]; - action->menu = menu; - - /* When the action is considered a mergable action it - will stay that way, until removed.. */ - if (!qt_mac_no_menubar_merge) { - OSMenuRef merge = QMenuPrivate::mergeMenuHash.value(menu); - if (merge) { - if (NSMenuItem *cmd = qt_mac_menu_merge_action(merge, action)) { - action->merged = 1; - [merge retain]; - [action->menu release]; - action->menu = merge; - [cmd retain]; - [cmd setAction:@selector(qtDispatcherToQAction:)]; - [cmd setTarget:nil]; - [action->menuItem release]; - action->menuItem = cmd; - QMenuMergeList *list = QMenuPrivate::mergeMenuItemsHash.value(merge); - if (!list) { - list = new QMenuMergeList; - QMenuPrivate::mergeMenuItemsHash.insert(merge, list); - } - list->append(QMenuMergeItem(cmd, action)); - } - } - } - - NSMenuItem *newItem = action->menuItem; - if (newItem == 0) { - newItem = createNSMenuItem(action->action->text()); - action->menuItem = newItem; - if (before) { - [menu insertItem:newItem atIndex:qMax(before_index, 0)]; - } else { - [menu addItem:newItem]; - } - - QWidget *widget = qmenu ? qmenu->widgetItems.value(action->action) : 0; - if (widget) { - qWarning("QMacMenuPrivate: Widgets in menus not implemented."); -#if 0 - - QMacNativeWidget *container = new QMacNativeWidget(0); - container->resize(widget->sizeHint()); - widget->setAttribute(Qt::WA_LayoutUsesWidgetRect); - widget->setParent(container); - - NSView *containerView = qt_mac_nativeview_for(container); - [containerView setAutoresizesSubviews:YES]; - [containerView setAutoresizingMask:NSViewWidthSizable]; - [qt_mac_nativeview_for(widget) setAutoresizingMask:NSViewWidthSizable]; - - [newItem setView:containerView]; - container->show(); - widget->show(); -#endif - } - - } else { - [newItem setEnabled:!QApplicationPrivate::modalState()]; - } - [newItem setTag:long(static_cast<QAction *>(action->action))]; - syncAction(action); -} - -// return an autoreleased string given a QKeySequence (currently only looks at the first one). -NSString *keySequenceToKeyEqivalent(const QKeySequence &accel) -{ - qWarning("Unimplemented: keySequenceToKeyEqivalent"); - return @""; -#if 0 - quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL)); - extern QChar qtKey2CocoaKey(Qt::Key key); - QChar cocoa_key = qtKey2CocoaKey(Qt::Key(accel_key)); - if (cocoa_key.isNull()) - cocoa_key = QChar(accel_key).toLower().unicode(); - return [NSString stringWithCharacters:&cocoa_key.unicode() length:1]; -#endif -} - -// return the cocoa modifier mask for the QKeySequence (currently only looks at the first one). -NSUInteger keySequenceModifierMask(const QKeySequence &accel) -{ - return constructModifierMask(accel[0]); -} - -void -QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) -{ - if (!action) - return; - - NSMenuItem *item = action->menuItem; - if (!item) - return; - - QMacCocoaAutoReleasePool pool; - NSMenu *menu = [item menu]; - bool actionVisible = action->action->isVisible(); - [item setHidden:!actionVisible]; - if (!actionVisible) - return; - - int itemIndex = [menu indexOfItem:item]; - Q_ASSERT(itemIndex != -1); - if (action->action->isSeparator()) { - action->menuItem = [NSMenuItem separatorItem]; - [action->menuItem retain]; - [menu insertItem: action->menuItem atIndex:itemIndex]; - [menu removeItem:item]; - [item release]; - item = action->menuItem; - return; - } else if ([item isSeparatorItem]) { - // I'm no longer a separator... - action->menuItem = createNSMenuItem(action->action->text()); - [menu insertItem:action->menuItem atIndex:itemIndex]; - [menu removeItem:item]; - [item release]; - item = action->menuItem; - } - - //find text (and accel) - action->ignore_accel = 0; - QString text = action->action->text(); - QKeySequence accel = action->action->shortcut(); - { - int st = text.lastIndexOf(QLatin1Char('\t')); - if (st != -1) { - action->ignore_accel = 1; - accel = QKeySequence(text.right(text.length()-(st+1))); - text.remove(st, text.length()-st); - } - } - { - QString cmd_text = qt_mac_menu_merge_text(action); - if (!cmd_text.isEmpty()) { - text = cmd_text; - accel = qt_mac_menu_merge_accel(action); - } - } - // Show multiple key sequences as part of the menu text. - if (accel.count() > 1) - text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")"); - -#if 0 - QString finalString = qt_mac_removeMnemonics(text); -#else - QString finalString = qt_mac_removeMnemonics(text); -#endif - // Cocoa Font and title - if (action->action->font().resolve()) { - const QFont &actionFont = action->action->font(); - NSFont *customMenuFont = [NSFont fontWithName:qt_mac_QStringToNSString(actionFont.family()) - size:actionFont.pointSize()]; - NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil]; - NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil]; - NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; - NSAttributedString *str = [[[NSAttributedString alloc] initWithString:qt_mac_QStringToNSString(finalString) - attributes:attributes] autorelease]; - [item setAttributedTitle: str]; - } else { - [item setTitle: qt_mac_QStringToNSString(finalString)]; - } - - if (action->action->menuRole() == QAction::AboutRole || action->action->menuRole() == QAction::QuitRole) - [item setTitle:qt_mac_QStringToNSString(text)]; - else - [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))]; - - // Cocoa Enabled - [item setEnabled: action->action->isEnabled()]; - - // Cocoa icon - NSImage *nsimage = 0; - if (!action->action->icon().isNull() && action->action->isIconVisibleInMenu()) { - nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(action->action->icon().pixmap(16, QIcon::Normal))); - } - [item setImage:nsimage]; - [nsimage release]; - - if (action->action->menu()) { //submenu - NSMenu *subMenu = static_cast<NSMenu *>(action->action->menu()->macMenu()); - if ([subMenu supermenu] && [subMenu supermenu] != [item menu]) { - // The menu is already a sub-menu of another one. Cocoa will throw an exception, - // in such cases. For the time being, a new QMenu with same set of actions is the - // only workaround. - action->action->setEnabled(false); - } else { - [item setSubmenu:subMenu]; - } - } else { //respect some other items - [item setSubmenu:0]; - // No key equivalent set for multiple key QKeySequence. - if (accel.count() == 1) { - [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)]; - [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)]; - } else { - [item setKeyEquivalent:@""]; - [item setKeyEquivalentModifierMask:NSCommandKeyMask]; - } - } - //mark glyph - [item setState:action->action->isChecked() ? NSOnState : NSOffState]; -} - -void -QMenuPrivate::QMacMenuPrivate::removeAction(QMacMenuAction *action) -{ - if (!action) - return; - QMacCocoaAutoReleasePool pool; - if (action->merged) { - if (reinterpret_cast<QAction *>([action->menuItem tag]) == action->action) { - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - [action->menuItem setEnabled:false]; - if (action->menuItem != [loader quitMenuItem] - && action->menuItem != [loader preferencesMenuItem]) { - [[action->menuItem menu] removeItem:action->menuItem]; - } - } - } else { - [[action->menuItem menu] removeItem:action->menuItem]; - } - actionItems.removeAll(action); -} - -OSMenuRef -QMenuPrivate::macMenu(OSMenuRef merge) -{ - Q_UNUSED(merge); - Q_Q(QMenu); - if (mac_menu && mac_menu->menu) - return mac_menu->menu; - if (!mac_menu) - mac_menu = new QMacMenuPrivate; - mac_menu->menu = qt_mac_create_menu(q); - if (merge) { - mergeMenuHash.insert(mac_menu->menu, merge); - } - QList<QAction*> items = q->actions(); - for(int i = 0; i < items.count(); i++) - mac_menu->addAction(items[i], 0, this); - syncSeparatorsCollapsible(collapsibleSeparators); - return mac_menu->menu; -} - -/*! - \internal -*/ -void -QMenuPrivate::syncSeparatorsCollapsible(bool collapse) -{ - qt_mac_menu_collapseSeparators(mac_menu->menu, collapse); -} - - - -/*! - \internal -*/ -void QMenuPrivate::setMacMenuEnabled(bool enable) -{ - if (!macMenu(0)) - return; - - QMacCocoaAutoReleasePool pool; - if (enable) { - for (int i = 0; i < mac_menu->actionItems.count(); ++i) { - QMacMenuAction *menuItem = mac_menu->actionItems.at(i); - if (menuItem && menuItem->action && menuItem->action->isEnabled()) { - [menuItem->menuItem setEnabled:true]; - } - } - } else { - NSMenu *menu = mac_menu->menu; - for (NSMenuItem *item in [menu itemArray]) { - [item setEnabled:false]; - } - } -} - -/*! - \internal - - This function will return the OSMenuRef used to create the native menu bar - bindings. - - If Qt is built against Carbon, the OSMenuRef is a MenuRef that can be used - with Carbon's Menu Manager API. - - If Qt is built against Cocoa, the OSMenuRef is a NSMenu pointer. - - \warning This function is not portable. - - \sa QMenuBar::macMenu() -*/ -OSMenuRef QMenu::macMenu(OSMenuRef merge) { return d_func()->macMenu(merge); } - -/***************************************************************************** - QMenuBar bindings - *****************************************************************************/ -typedef QHash<QWidget *, QMenuBar *> MenuBarHash; -Q_GLOBAL_STATIC(MenuBarHash, menubars) -static QMenuBar *fallback = 0; -QMenuBarPrivate::QMacMenuBarPrivate::QMacMenuBarPrivate() : menu(0), apple_menu(0) -{ -} - -QMenuBarPrivate::QMacMenuBarPrivate::~QMacMenuBarPrivate() -{ - for(QList<QMacMenuAction*>::Iterator it = actionItems.begin(); it != actionItems.end(); ++it) - delete (*it); - [apple_menu release]; - [menu release]; -} - -void -QMenuBarPrivate::QMacMenuBarPrivate::addAction(QAction *a, QMacMenuAction *before) -{ - if (a->isSeparator() || !menu) - return; - QMacMenuAction *action = new QMacMenuAction; - action->action = a; - action->ignore_accel = 1; - addAction(action, before); -} - -void -QMenuBarPrivate::QMacMenuBarPrivate::addAction(QMacMenuAction *action, QMacMenuAction *before) -{ - if (!action || !menu) - return; - - int before_index = actionItems.indexOf(before); - if (before_index < 0) { - before = 0; - before_index = actionItems.size(); - } - actionItems.insert(before_index, action); - - MenuItemIndex index = actionItems.size()-1; - - action->menu = menu; - QMacCocoaAutoReleasePool pool; - [action->menu retain]; - NSMenuItem *newItem = createNSMenuItem(action->action->text()); - action->menuItem = newItem; - - if (before) { - [menu insertItem:newItem atIndex:qMax(1, before_index + 1)]; - index = before_index; - } else { - [menu addItem:newItem]; - } - [newItem setTag:long(static_cast<QAction *>(action->action))]; - syncAction(action); -} - -void -QMenuBarPrivate::QMacMenuBarPrivate::syncAction(QMacMenuAction *action) -{ - if (!action || !menu) - return; - - QMacCocoaAutoReleasePool pool; - NSMenuItem *item = action->menuItem; - - OSMenuRef submenu = 0; - bool release_submenu = false; - if (action->action->menu()) { - if ((submenu = action->action->menu()->macMenu(apple_menu))) { - if ([submenu supermenu] && [submenu supermenu] != [item menu]) - return; - else - [item setSubmenu:submenu]; - } - } - - if (submenu) { - bool visible = actualMenuItemVisibility(this, action); - [item setSubmenu: submenu]; - [submenu setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(action->action->text()))]; - syncNSMenuItemVisiblity(item, visible); - if (release_submenu) { //no pointers to it - [submenu release]; - } - } else { - qWarning("QMenu: No OSMenuRef created for popup menu"); - } -} - -void -QMenuBarPrivate::QMacMenuBarPrivate::removeAction(QMacMenuAction *action) -{ - if (!action || !menu) - return; - QMacCocoaAutoReleasePool pool; - [action->menu removeItem:action->menuItem]; - actionItems.removeAll(action); -} - -bool QMenuBarPrivate::macWidgetHasNativeMenubar(QWidget *widget) -{ - // This function is different from q->isNativeMenuBar(), as - // it returns true only if a native menu bar is actually - // _created_. - if (!widget) - return false; - return menubars()->contains(widget->window()); -} - -void -QMenuBarPrivate::macCreateMenuBar(QWidget *parent) -{ - Q_Q(QMenuBar); - static int dontUseNativeMenuBar = -1; - // We call the isNativeMenuBar function here - // because that will make sure that local overrides - // are dealt with correctly. q->isNativeMenuBar() will, if not - // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar: - bool qt_mac_no_native_menubar = !q->isNativeMenuBar(); - if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) { - // The menubar is set to be native. Let's check (one time only - // for all menubars) if this is OK with the rest of the environment. - // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application - // might still choose to not respect, or change, this flag. - bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication); - bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty(); - dontUseNativeMenuBar = isPlugin || environmentSaysNo; - QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar); - qt_mac_no_native_menubar = !q->isNativeMenuBar(); - } - if (qt_mac_no_native_menubar == false) { - // INVARIANT: Use native menubar. - QMenuBar::macUpdateMenuBar(); - if (!parent && !fallback) { - fallback = q; - mac_menubar = new QMacMenuBarPrivate; - } else if (parent && parent->isWindow()) { - menubars()->insert(q->window(), q); - mac_menubar = new QMacMenuBarPrivate; - } - } -} - -void QMenuBarPrivate::macDestroyMenuBar() -{ - Q_Q(QMenuBar); - QMacCocoaAutoReleasePool pool; - if (fallback == q) - fallback = 0; - delete mac_menubar; - QWidget *tlw = q->window(); - menubars()->remove(tlw); - mac_menubar = 0; - - if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == q) { - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - [loader removeActionsFromAppMenu]; - QMenuBar::macUpdateMenuBar(); - } -} - -OSMenuRef QMenuBarPrivate::macMenu() -{ - Q_Q(QMenuBar); - if (!q->isNativeMenuBar() || !mac_menubar) { - return 0; - } else if (!mac_menubar->menu) { - mac_menubar->menu = qt_mac_create_menu(q); - ProcessSerialNumber mine, front; - if (GetCurrentProcess(&mine) == noErr && GetFrontProcess(&front) == noErr) { - if (!qt_mac_no_menubar_merge && !mac_menubar->apple_menu) { - mac_menubar->apple_menu = qt_mac_create_menu(q); - [mac_menubar->apple_menu setTitle:qt_mac_QStringToNSString(QString(QChar(0x14)))]; - NSMenuItem *apple_menuItem = [[NSMenuItem alloc] init]; - [apple_menuItem setSubmenu:mac_menubar->menu]; - [mac_menubar->apple_menu addItem:apple_menuItem]; - [apple_menuItem release]; - } - if (mac_menubar->apple_menu) { - QMenuPrivate::mergeMenuHash.insert(mac_menubar->menu, mac_menubar->apple_menu); - } - QList<QAction*> items = q->actions(); - for(int i = 0; i < items.count(); i++) - mac_menubar->addAction(items[i]); - } - } - return mac_menubar->menu; -} - -/*! - \internal - - This function will return the OSMenuRef used to create the native menu bar - bindings. This OSMenuRef is then set as the root menu for the Menu - Manager. - - \warning This function is not portable. - - \sa QMenu::macMenu() -*/ -OSMenuRef QMenuBar::macMenu() { return d_func()->macMenu(); } - -/* ! - \internal - Ancestor function that crosses windows (QWidget::isAncestorOf - only considers widgets within the same window). -*/ -static bool qt_mac_is_ancestor(QWidget* possibleAncestor, QWidget *child) -{ - if (!possibleAncestor) - return false; - - QWidget * current = child->parentWidget(); - while (current != 0) { - if (current == possibleAncestor) - return true; - current = current->parentWidget(); - } - return false; -} - -/* ! - \internal - Returns true if the entries of menuBar should be disabled, - based on the modality type of modalWidget. -*/ -static bool qt_mac_should_disable_menu(QMenuBar *menuBar) -{ - QWidget *modalWidget = qApp->activeModalWidget(); - if (!modalWidget) - return false; - - if (menuBar && menuBar == menubars()->value(modalWidget)) - // The menu bar is owned by the modal widget. - // In that case we should enable it: - return false; - - // When there is an application modal window on screen, the entries of - // the menubar should be disabled. The exception in Qt is that if the - // modal window is the only window on screen, then we enable the menu bar. - QWidget *w = modalWidget; - QWidgetList topLevelWidgets = QApplication::topLevelWidgets(); - while (w) { - if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) { - for (int i=0; i<topLevelWidgets.size(); ++i) { - QWidget *top = topLevelWidgets.at(i); - if (w != top && top->isVisible()) { - // INVARIANT: we found another visible window - // on screen other than our modalWidget. We therefore - // disable the menu bar to follow normal modality logic: - return true; - } - } - // INVARIANT: We have only one window on screen that happends - // to be application modal. We choose to enable the menu bar - // in that case to e.g. enable the quit menu item. - return false; - } - w = w->parentWidget(); - } - - // INVARIANT: modalWidget is window modal. Disable menu entries - // if the menu bar belongs to an ancestor of modalWidget. If menuBar - // is nil, we understand it as the default menu bar set by the nib: - return menuBar ? qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget) : false; -} - -static QWidget *findWindowThatShouldDisplayMenubar() -{ - QWidget *w = qApp->activeWindow(); - if (!w) { - // We have no active window on screen. Try to - // find a window from the list of top levels: - QWidgetList tlws = QApplication::topLevelWidgets(); - for(int i = 0; i < tlws.size(); ++i) { - QWidget *tlw = tlws.at(i); - if ((tlw->isVisible() && tlw->windowType() != Qt::Tool && - tlw->windowType() != Qt::Popup)) { - w = tlw; - break; - } - } - } - return w; -} - -static QMenuBar *findMenubarForWindow(QWidget *w) -{ - QMenuBar *mb = 0; - if (w) { - mb = menubars()->value(w); -#ifndef QT_NO_MAINWINDOW - QDockWidget *dw = qobject_cast<QDockWidget *>(w); - if (!mb && dw) { - QMainWindow *mw = qobject_cast<QMainWindow *>(dw->parentWidget()); - if (mw && (mb = menubars()->value(mw))) - w = mw; - } -#endif - while(w && !mb) - mb = menubars()->value((w = w->parentWidget())); - } - - if (!mb) { - // We could not find a menu bar for the window. Lets - // check if we have a global (parentless) menu bar instead: - mb = fallback; - } - - return mb; -} - -void qt_mac_clear_menubar() -{ - if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) - return; - - QMacCocoaAutoReleasePool pool; - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - NSMenu *menu = [loader menu]; - [loader ensureAppMenuInMenu:menu]; - [NSApp setMainMenu:menu]; - const bool modal = qt_mac_should_disable_menu(0); - if (qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal) - qt_mac_set_modal_state(menu, modal); - qt_mac_current_menubar.qmenubar = 0; - qt_mac_current_menubar.modal = modal; -} - -/*! - \internal - - This function will update the current menu bar and set it as the - active menu bar in the Menu Manager. - - \warning This function is not portable. - - \sa QMenu::macMenu(), QMenuBar::macMenu() -*/ -bool QMenuBar::macUpdateMenuBar() -{ - QMacCocoaAutoReleasePool pool; - qWarning("Unimplemented: QMenuBar::macUpdateMenuBar"); - //qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar)); - - return true; -} - -bool QMenuBarPrivate::macUpdateMenuBarImmediatly() -{ - bool ret = false; - cancelAllMenuTracking(); - QWidget *w = findWindowThatShouldDisplayMenubar(); - QMenuBar *mb = findMenubarForWindow(w); - extern bool qt_mac_app_fullscreen; //qapplication_mac.mm - - // We need to see if we are in full screen mode, if so we need to - // switch the full screen mode to be able to show or hide the menubar. - if(w && mb) { - // This case means we are creating a menubar, check if full screen - if(w->isFullScreen()) { - // Ok, switch to showing the menubar when hovering over it. - SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); - qt_mac_app_fullscreen = true; - } - } else if(w) { - // Removing a menubar - if(w->isFullScreen()) { - // Ok, switch to not showing the menubar when hovering on it - SetSystemUIMode(kUIModeAllHidden, 0); - qt_mac_app_fullscreen = true; - } - } - - if (mb && mb->isNativeMenuBar()) { - bool modal = QApplicationPrivate::modalState(); - QMacCocoaAutoReleasePool pool; - if (OSMenuRef menu = mb->macMenu()) { - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - [loader ensureAppMenuInMenu:menu]; - [NSApp setMainMenu:menu]; - syncMenuBarItemsVisiblity(mb->d_func()->mac_menubar); - - if (OSMenuRef tmpMerge = QMenuPrivate::mergeMenuHash.value(menu)) { - if (QMenuMergeList *mergeList - = QMenuPrivate::mergeMenuItemsHash.value(tmpMerge)) { - const int mergeListSize = mergeList->size(); - - for (int i = 0; i < mergeListSize; ++i) { - const QMenuMergeItem &mergeItem = mergeList->at(i); - // Ideally we would call QMenuPrivate::syncAction, but that requires finding - // the original QMen and likely doing more work than we need. - // For example, enabled is handled below. - [mergeItem.menuItem setTag:reinterpret_cast<long>( - static_cast<QAction *>(mergeItem.action->action))]; - [mergeItem.menuItem setHidden:!(mergeItem.action->action->isVisible())]; - } - } - } - // Check if menu is modally shaddowed and should be disabled: - modal = qt_mac_should_disable_menu(mb); - if (mb != qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal) - qt_mac_set_modal_state(menu, modal); - } - qt_mac_current_menubar.qmenubar = mb; - qt_mac_current_menubar.modal = modal; - ret = true; - } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) { - // INVARIANT: The currently active menu bar (if any) is not native. But we do have a - // native menu bar from before. So we need to decide whether or not is should be enabled: - const bool modal = qt_mac_should_disable_menu(qt_mac_current_menubar.qmenubar); - if (modal != qt_mac_current_menubar.modal) { - ret = true; - if (OSMenuRef menu = qt_mac_current_menubar.qmenubar->macMenu()) { - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); - [loader ensureAppMenuInMenu:menu]; - [NSApp setMainMenu:menu]; - syncMenuBarItemsVisiblity(qt_mac_current_menubar.qmenubar->d_func()->mac_menubar); - qt_mac_set_modal_state(menu, modal); - } - qt_mac_current_menubar.modal = modal; - } - } - - if (!ret) { - qt_mac_clear_menubar(); - } - return ret; -} - -QHash<OSMenuRef, OSMenuRef> QMenuPrivate::mergeMenuHash; -QHash<OSMenuRef, QMenuMergeList*> QMenuPrivate::mergeMenuItemsHash; - -bool QMenuPrivate::QMacMenuPrivate::merged(const QAction *action) const -{ - if (OSMenuRef merge = mergeMenuHash.value(menu)) { - if (QMenuMergeList *list = mergeMenuItemsHash.value(merge)) { - for(int i = 0; i < list->size(); ++i) { - const QMenuMergeItem &item = list->at(i); - if (item.action->action == action) - return true; - } - } - } - return false; -} - -//creation of the OSMenuRef -static OSMenuRef qt_mac_create_menu(QWidget *w) -{ - OSMenuRef ret; - if (QMenu *qmenu = qobject_cast<QMenu *>(w)){ - ret = [[QT_MANGLE_NAMESPACE(QCocoaMenu) alloc] initWithQMenu:qmenu]; - } else { - ret = [[NSMenu alloc] init]; - } - return ret; -} - - - -QT_END_NAMESPACE - diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index cfe1ecf2b9..bd360f5e25 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -83,37 +83,6 @@ void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id); class QTornOffMenu; class QEventLoop; -#ifdef Q_OS_MAC -# ifdef __OBJC__ -QT_END_NAMESPACE -@class NSMenuItem; -QT_BEGIN_NAMESPACE -# else -typedef void NSMenuItem; -# endif //__OBJC__ -struct QMacMenuAction { - QMacMenuAction() - : menuItem(0) - , ignore_accel(0), merged(0), menu(0) - { - } - ~QMacMenuAction(); - NSMenuItem *menuItem; - uchar ignore_accel : 1; - uchar merged : 1; - QPointer<QAction> action; - OSMenuRef menu; -}; - -struct QMenuMergeItem -{ - inline QMenuMergeItem(NSMenuItem *c, QMacMenuAction *a) : menuItem(c), action(a) { } - NSMenuItem *menuItem; - QMacMenuAction *action; -}; -typedef QList<QMenuMergeItem> QMenuMergeList; -#endif // Q_OS_MAC - #ifdef Q_WS_WINCE struct QWceMenuAction { uint command; @@ -144,13 +113,8 @@ public: cancelAction(0), #endif scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0), - hasCheckableItems(0), sloppyAction(0), doChildEffects(false) -#ifdef QT3_SUPPORT - ,emitHighlighted(false) -#endif -#ifdef Q_OS_MAC - ,mac_menu(0) -#endif + hasCheckableItems(0), sloppyAction(0), doChildEffects(false), platformMenu(0) + #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) ,wce_menu(0) #endif @@ -161,9 +125,7 @@ public: ~QMenuPrivate() { delete scroll; -#ifdef Q_OS_MAC - delete mac_menu; -#endif + delete platformMenu; #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) delete wce_menu; #endif @@ -293,36 +255,7 @@ public: //menu fading/scrolling effects bool doChildEffects; -#ifdef Q_OS_MAC - //mac menu binding - struct QMacMenuPrivate { - QList<QMacMenuAction*> actionItems; - OSMenuRef menu; - QMacMenuPrivate(); - ~QMacMenuPrivate(); - - bool merged(const QAction *action) const; - void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0); - void addAction(QMacMenuAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0); - void syncAction(QMacMenuAction *); - inline void syncAction(QAction *a) { syncAction(findAction(a)); } - void removeAction(QMacMenuAction *); - inline void removeAction(QAction *a) { removeAction(findAction(a)); } - inline QMacMenuAction *findAction(QAction *a) { - for(int i = 0; i < actionItems.size(); i++) { - QMacMenuAction *act = actionItems[i]; - if(a == act->action) - return act; - } - return 0; - } - } *mac_menu; - OSMenuRef macMenu(OSMenuRef merge); - void setMacMenuEnabled(bool enable = true); - void syncSeparatorsCollapsible(bool collapsible); - static QHash<OSMenuRef, OSMenuRef> mergeMenuHash; - static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash; -#endif + QPlatformMenu *platformMenu; QPointer<QAction> actionAboutToTrigger; #ifdef QT3_SUPPORT diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 1b8f1f8176..1caa112f1b 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -55,6 +55,7 @@ #include <qtoolbar.h> #include <qtoolbutton.h> #include <qwhatsthis.h> +#include "private/qguiapplication_p.h" #ifndef QT_NO_MENUBAR @@ -728,11 +729,11 @@ void QMenuBarPrivate::init() Q_Q(QMenuBar); q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); q->setAttribute(Qt::WA_CustomWhatsThis); -#ifdef Q_OS_MAC - macCreateMenuBar(q->parentWidget()); - if(mac_menubar) + + platformMenuBar = QGuiApplicationPrivate::platformIntegration()->createPlatformMenuBar(q); + + if (platformMenuBar) q->hide(); -#endif #ifdef Q_WS_WINCE if (qt_wince_is_mobile()) { wceCreateMenuBar(q->parentWidget()); @@ -808,10 +809,10 @@ QMenuBar::QMenuBar(QWidget *parent, const char *name) : QWidget(*new QMenuBarPri */ QMenuBar::~QMenuBar() { -#ifdef Q_OS_MAC Q_D(QMenuBar); - d->macDestroyMenuBar(); -#endif + delete d->platformMenuBar; + d->platformMenuBar = 0; + #ifdef Q_WS_WINCE Q_D(QMenuBar); if (qt_wince_is_mobile()) @@ -1275,25 +1276,23 @@ void QMenuBar::actionEvent(QActionEvent *e) { Q_D(QMenuBar); d->itemsDirty = true; -#if defined (Q_OS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) - if (isNativeMenuBar()) { -#ifdef Q_OS_MAC - QMenuBarPrivate::QMacMenuBarPrivate *nativeMenuBar = d->mac_menubar; -#elif defined(Q_WS_S60) + + if (d->platformMenuBar) { + QPlatformMenuBar *nativeMenuBar = d->platformMenuBar; +#if defined(Q_WS_S60) QMenuBarPrivate::QSymbianMenuBarPrivate *nativeMenuBar = d->symbian_menubar; -#else +#elif defined(Q_WS_WINCE) QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar; #endif if (!nativeMenuBar) return; if(e->type() == QEvent::ActionAdded) - nativeMenuBar->addAction(e->action(), nativeMenuBar->findAction(e->before())); + nativeMenuBar->addAction(e->action(), e->before()); else if(e->type() == QEvent::ActionRemoved) nativeMenuBar->removeAction(e->action()); else if(e->type() == QEvent::ActionChanged) nativeMenuBar->syncAction(e->action()); } -#endif if(e->type() == QEvent::ActionAdded) { connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); @@ -1372,15 +1371,8 @@ void QMenuBarPrivate::handleReparent() oldParent = newParent; oldWindow = newWindow; -#ifdef Q_OS_MAC - if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) { - // If the new parent got a native menubar from before, keep that - // menubar rather than replace it with this one (because a parents - // menubar has precedence over children menubars). - macDestroyMenuBar(); - macCreateMenuBar(newParent); - } -#endif + if (platformMenuBar) + platformMenuBar->handleReparent(newParent); #ifdef Q_WS_WINCE if (qt_wince_is_mobile() && wce_menubar) @@ -1925,27 +1917,18 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) Q_D(QMenuBar); if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) { d->nativeMenuBar = nativeMenuBar; -#ifdef Q_OS_MAC + if (!d->nativeMenuBar) { - extern void qt_mac_clear_menubar(); - qt_mac_clear_menubar(); - d->macDestroyMenuBar(); - const QList<QAction *> &menubarActions = actions(); - for (int i = 0; i < menubarActions.size(); ++i) { - const QAction *action = menubarActions.at(i); - if (QMenu *menu = action->menu()) { - delete menu->d_func()->mac_menu; - menu->d_func()->mac_menu = 0; - } - } + delete d->platformMenuBar; + d->platformMenuBar = 0; } else { - d->macCreateMenuBar(parentWidget()); + if (!d->platformMenuBar) + d->platformMenuBar = QGuiApplicationPrivate::platformIntegration()->createPlatformMenuBar(this); } - macUpdateMenuBar(); + updateGeometry(); if (!d->nativeMenuBar && parentWidget()) setVisible(true); -#endif } } @@ -1958,6 +1941,12 @@ bool QMenuBar::isNativeMenuBar() const return d->nativeMenuBar; } +QPlatformMenuBar *QMenuBar::platformMenuBar() +{ + Q_D(const QMenuBar); + return d->platformMenuBar; +} + /*! \since 4.4 diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h index 990027f16a..e7e8f78958 100644 --- a/src/widgets/widgets/qmenubar.h +++ b/src/widgets/widgets/qmenubar.h @@ -110,11 +110,6 @@ public: void setCornerWidget(QWidget *w, Qt::Corner corner = Qt::TopRightCorner); QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const; -#ifdef Q_OS_MAC - OSMenuRef macMenu(); - static bool macUpdateMenuBar(); -#endif - #ifdef Q_WS_WINCE void setDefaultAction(QAction *); QAction *defaultAction() const; @@ -125,7 +120,7 @@ public: bool isNativeMenuBar() const; void setNativeMenuBar(bool nativeMenuBar); - + QPlatformMenuBar *platformMenuBar(); public Q_SLOTS: virtual void setVisible(bool visible); diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index e42162a48e..5f482c228e 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -78,13 +78,10 @@ class QMenuBarPrivate : public QWidgetPrivate public: QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0), closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), - nativeMenuBar(-1), doChildEffects(false) + nativeMenuBar(-1), doChildEffects(false), platformMenuBar(0) #ifdef QT3_SUPPORT , doAutoResize(false) #endif -#ifdef Q_OS_MAC - , mac_menubar(0) -#endif #ifdef Q_WS_WINCE , wce_menubar(0), wceClassicMenu(false) @@ -96,9 +93,7 @@ public: { } ~QMenuBarPrivate() { -#ifdef Q_OS_MAC - delete mac_menubar; -#endif + delete platformMenuBar; #ifdef Q_WS_WINCE delete wce_menubar; #endif @@ -173,35 +168,8 @@ public: #ifdef QT3_SUPPORT bool doAutoResize; #endif -#ifdef Q_OS_MAC - //mac menubar binding - struct QMacMenuBarPrivate { - QList<QMacMenuAction*> actionItems; - OSMenuRef menu, apple_menu; - QMacMenuBarPrivate(); - ~QMacMenuBarPrivate(); + QPlatformMenuBar *platformMenuBar; - void addAction(QAction *, QMacMenuAction* =0); - void addAction(QMacMenuAction *, QMacMenuAction* =0); - void syncAction(QMacMenuAction *); - inline void syncAction(QAction *a) { syncAction(findAction(a)); } - void removeAction(QMacMenuAction *); - inline void removeAction(QAction *a) { removeAction(findAction(a)); } - inline QMacMenuAction *findAction(QAction *a) { - for(int i = 0; i < actionItems.size(); i++) { - QMacMenuAction *act = actionItems[i]; - if(a == act->action) - return act; - } - return 0; - } - } *mac_menubar; - static bool macUpdateMenuBarImmediatly(); - bool macWidgetHasNativeMenubar(QWidget *widget); - void macCreateMenuBar(QWidget *); - void macDestroyMenuBar(); - OSMenuRef macMenu(); -#endif #ifdef Q_WS_WINCE void wceCreateMenuBar(QWidget *); void wceDestroyMenuBar(); diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri index a272540aa8..cc4a61f493 100644 --- a/src/widgets/widgets/widgets.pri +++ b/src/widgets/widgets/widgets.pri @@ -155,12 +155,6 @@ SOURCES += \ widgets/qmacnativewidget_mac.mm \ } -mac { - OBJECTIVE_SOURCES += widgets/qmenu_mac.mm \ - widgets/qcocoamenu_mac.mm \ - platforms/mac/qt_widget_helpers_mac.mm -} - wince*: { SOURCES += widgets/qmenu_wince.cpp HEADERS += widgets/qmenu_wince_resource_p.h |