summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r--src/widgets/widgets/qcocoamenu_mac.mm268
-rw-r--r--src/widgets/widgets/qcocoamenu_mac_p.h80
-rw-r--r--src/widgets/widgets/qmenu.cpp32
-rw-r--r--src/widgets/widgets/qmenu.h18
-rw-r--r--src/widgets/widgets/qmenu_mac.mm1284
-rw-r--r--src/widgets/widgets/qmenu_p.h75
-rw-r--r--src/widgets/widgets/qmenubar.cpp67
-rw-r--r--src/widgets/widgets/qmenubar.h7
-rw-r--r--src/widgets/widgets/qmenubar_p.h38
-rw-r--r--src/widgets/widgets/widgets.pri6
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