diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/kernel/kernel.pri | 9 | ||||
-rw-r--r-- | src/widgets/kernel/qaction.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qplatformmenu.h | 94 | ||||
-rw-r--r-- | src/widgets/kernel/qplatformmenu_qpa.cpp | 113 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu.cpp | 51 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar.cpp | 78 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar_p.h | 3 |
7 files changed, 120 insertions, 231 deletions
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index c4853bd369..ac363c5f7a 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -36,8 +36,7 @@ HEADERS += \ kernel/qsoftkeymanager_p.h \ kernel/qsoftkeymanager_common_p.h \ kernel/qdesktopwidget_qpa_p.h \ - kernel/qwidgetwindow_qpa_p.h \ - kernel/qplatformmenu.h + kernel/qwidgetwindow_qpa_p.h SOURCES += \ kernel/qaction.cpp \ @@ -66,8 +65,8 @@ SOURCES += \ kernel/qapplication_qpa.cpp \ kernel/qdesktopwidget_qpa.cpp \ kernel/qwidget_qpa.cpp \ - kernel/qwidgetwindow_qpa.cpp \ - kernel/qplatformmenu_qpa.cpp + kernel/qwidgetwindow_qpa.cpp + # TODO false:!x11:mac { @@ -75,7 +74,7 @@ false:!x11:mac { kernel/qclipboard_mac.cpp \ kernel/qmime_mac.cpp \ kernel/qt_mac.cpp \ - kernel/qkeymapper_mac.cpp + kernel/qkeymapper_mac.cpp OBJECTIVE_HEADERS += \ qcocoawindow_mac_p.h \ diff --git a/src/widgets/kernel/qaction.h b/src/widgets/kernel/qaction.h index bb7de852c1..ea3138fb23 100644 --- a/src/widgets/kernel/qaction.h +++ b/src/widgets/kernel/qaction.h @@ -90,7 +90,8 @@ class Q_WIDGETS_EXPORT QAction : public QObject Q_PROPERTY(Priority priority READ priority WRITE setPriority) public: - enum MenuRole { NoRole, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole, + // note this is copied into qplatformmenu.h, which must stay in sync + enum MenuRole { NoRole = 0, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole, AboutRole, PreferencesRole, QuitRole }; enum SoftKeyRole { NoSoftKey, PositiveSoftKey, NegativeSoftKey, SelectSoftKey }; diff --git a/src/widgets/kernel/qplatformmenu.h b/src/widgets/kernel/qplatformmenu.h deleted file mode 100644 index cbd7eae6ac..0000000000 --- a/src/widgets/kernel/qplatformmenu.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** 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$ -** -****************************************************************************/ - -#ifndef QPLATFORMMENU_H -#define QPLATFORMMENU_H - -#include <QtCore/qglobal.h> -#include <QtCore/qpointer.h> -#include <QtWidgets/qaction.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QMenuPrivate; -class Q_WIDGETS_EXPORT QPlatformMenuAction -{ -public: - virtual ~QPlatformMenuAction(); - QPointer<QAction> action; -}; - -class Q_WIDGETS_EXPORT QPlatformMenu { -public: - QPlatformMenu(); - virtual ~QPlatformMenu(); - - virtual bool merged(const QAction *action) const = 0; - - virtual void addAction(QAction *action, QAction *before) = 0; - virtual void removeAction(QAction *action) = 0; - virtual void syncAction(QAction *action) = 0; - - virtual void setMenuEnabled(bool enable); - virtual void syncSeparatorsCollapsible(bool enable); -}; - -class Q_WIDGETS_EXPORT QPlatformMenuBar { -public: - QPlatformMenuBar(); - virtual ~QPlatformMenuBar(); - - virtual void addAction(QAction *action, QAction *before = 0) = 0; - virtual void syncAction(QAction *action) = 0; - virtual void removeAction(QAction *action) = 0; - - virtual void handleReparent(QWidget *newParent); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif - diff --git a/src/widgets/kernel/qplatformmenu_qpa.cpp b/src/widgets/kernel/qplatformmenu_qpa.cpp deleted file mode 100644 index f28560e560..0000000000 --- a/src/widgets/kernel/qplatformmenu_qpa.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtWidgets 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 "qplatformmenu.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QPlatformMenuAction - \since 5.0 - \internal - \preliminary - \ingroup qpa - - \brief The QPlatformMenuAction class provides an abstraction for menu actions. - */ - -QPlatformMenuAction::~QPlatformMenuAction() -{ - -} - -/*! - \class QPlatformMenu - \since 5.0 - \internal - \preliminary - \ingroup qpa - - \brief The QPlatformMenu class provides an abstraction for menus. - */ -QPlatformMenu::QPlatformMenu() -{ -} - -QPlatformMenu::~QPlatformMenu() -{ - -} - -void QPlatformMenu::setMenuEnabled(bool enable) -{ - Q_UNUSED(enable); -} - -void QPlatformMenu::syncSeparatorsCollapsible(bool enable) -{ - Q_UNUSED(enable); -} - -/*! - \class QPlatformMenuBar - \since 5.0 - \internal - \preliminary - \ingroup qpa - - \brief The QPlatformMenuBar class provides an abstraction for menu bars. - */ -QPlatformMenuBar::QPlatformMenuBar() -{ - -} - -QPlatformMenuBar::~QPlatformMenuBar() -{ - -} - -void QPlatformMenuBar::handleReparent(QWidget *newParent) -{ - Q_UNUSED(newParent); -} - -QT_END_NAMESPACE diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 995edcbbbc..8d50b03edb 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -154,7 +154,11 @@ void QMenuPrivate::init() scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; } - platformMenu = QGuiApplicationPrivate::platformTheme()->createPlatformMenu(q); + platformMenu = QGuiApplicationPrivate::platformTheme()->createPlatformMenu(); + if (platformMenu) { + QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow())); + QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide())); + } #ifdef QT_SOFTKEYS_ENABLED selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, q); @@ -2300,7 +2304,7 @@ void QMenu::changeEvent(QEvent *e) d->tornPopup->setEnabled(isEnabled()); d->menuAction->setEnabled(isEnabled()); if (d->platformMenu) - d->platformMenu->setMenuEnabled(isEnabled()); + d->platformMenu->setEnabled(isEnabled()); } QWidget::changeEvent(e); } @@ -2822,6 +2826,25 @@ QMenu::timerEvent(QTimerEvent *e) } } +void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem* item) +{ + item->setText(action->text()); + item->setIsSeparator(action->isSeparator()); +// item->setIcon(action->icon()); + item->setVisible(action->isVisible()); + item->setShortcut(action->shortcut()); + item->setChecked(action->isChecked()); + item->setFont(action->font()); + item->setRole((QPlatformMenuItem::MenuRole) action->menuRole()); + item->setEnabled(action->isEnabled()); + + if (action->menu()) { + item->setMenu(action->menu()->platformMenu()); + } else { + item->setMenu(0); + } +} + /*! \reimp */ @@ -2854,12 +2877,24 @@ void QMenu::actionEvent(QActionEvent *e) } if (d->platformMenu) { - if (e->type() == QEvent::ActionAdded) - d->platformMenu->addAction(e->action(), e->before()); - else if (e->type() == QEvent::ActionRemoved) - d->platformMenu->removeAction(e->action()); - else if (e->type() == QEvent::ActionChanged) - d->platformMenu->syncAction(e->action()); + if (e->type() == QEvent::ActionAdded) { + QPlatformMenuItem *menuItem = + QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem(); + menuItem->setTag(reinterpret_cast<quintptr>(e->action())); + QObject::connect(menuItem, SIGNAL(activated()), e->action(), SLOT(trigger())); + copyActionToPlatformItem(e->action(), menuItem); + QPlatformMenuItem* beforeItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->before())); + d->platformMenu->insertMenuItem(menuItem, beforeItem); + } else if (e->type() == QEvent::ActionRemoved) { + QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->action())); + d->platformMenu->removeMenuItem(menuItem); + } else if (e->type() == QEvent::ActionChanged) { + QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->action())); + copyActionToPlatformItem(e->action(), menuItem); + d->platformMenu->syncMenuItem(menuItem); + } + + d->platformMenu->syncSeparatorsCollapsible(d->collapsibleSeparators); } #if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR) diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 7c1e6b9166..fc28cd6d1c 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -57,6 +57,7 @@ #include <qwhatsthis.h> #include <qpa/qplatformtheme.h> #include "private/qguiapplication_p.h" +#include "qplatformintegration_qpa.h" #ifndef QT_NO_MENUBAR @@ -719,7 +720,7 @@ void QMenuBarPrivate::init() q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); q->setAttribute(Qt::WA_CustomWhatsThis); - platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(q); + platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); if (platformMenuBar) q->hide(); @@ -1238,6 +1239,14 @@ void QMenuBar::leaveEvent(QEvent *) d->setCurrentAction(0); } +QPlatformMenu *getPlatformMenu(QAction *action) +{ + if (!action || !action->menu()) + return 0; + + return action->menu()->platformMenu(); +} + /*! \reimp */ @@ -1254,12 +1263,52 @@ void QMenuBar::actionEvent(QActionEvent *e) #endif if (!nativeMenuBar) return; - if(e->type() == QEvent::ActionAdded) - 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()); + + if (e->type() == QEvent::ActionAdded) { + QPlatformMenu *menu = getPlatformMenu(e->action()); + if (menu) { + QPlatformMenu* beforeMenu = NULL; + for (int beforeIndex = d->indexOf(e->action()) + 1; + !beforeMenu && (beforeIndex < actions().size()); + ++beforeIndex) + { + beforeMenu = getPlatformMenu(actions().at(beforeIndex)); + } + + menu->setTag(reinterpret_cast<quintptr>(e->action())); + menu->setText(e->action()->text()); + d->platformMenuBar->insertMenu(menu, beforeMenu); + } + } else if (e->type() == QEvent::ActionRemoved) { + QPlatformMenu *menu = getPlatformMenu(e->action()); + if (menu) + d->platformMenuBar->removeMenu(menu); + } else if (e->type() == QEvent::ActionChanged) { + QPlatformMenu* cur = d->platformMenuBar->menuForTag(reinterpret_cast<quintptr>(e->action())); + QPlatformMenu *menu = getPlatformMenu(e->action()); + + // the menu associated with the action can change, need to + // remove and/or insert the new platform menu + if (menu != cur) { + if (cur) + d->platformMenuBar->removeMenu(cur); + if (menu) { + menu->setTag(reinterpret_cast<quintptr>(e->action())); + + QPlatformMenu* beforeMenu = NULL; + for (int beforeIndex = d->indexOf(e->action()) + 1; + !beforeMenu && (beforeIndex < actions().size()); + ++beforeIndex) + { + beforeMenu = getPlatformMenu(actions().at(beforeIndex)); + } + d->platformMenuBar->insertMenu(menu, beforeMenu); + } + } else if (menu) { + menu->setText(e->action()->text()); + d->platformMenuBar->syncMenu(menu); + } + } } if(e->type() == QEvent::ActionAdded) { @@ -1339,8 +1388,17 @@ void QMenuBarPrivate::handleReparent() oldParent = newParent; oldWindow = newWindow; - if (platformMenuBar) - platformMenuBar->handleReparent(newParent); + if (platformMenuBar) { + if (newWindow) { + // force the underlying platform window to be created, since + // the platform menubar needs it (and we have no other way to + // discover when the platform window is created) + newWindow->createWinId(); + platformMenuBar->handleReparent(newWindow->windowHandle()); + } else { + platformMenuBar->handleReparent(0); + } + } #ifdef Q_OS_WINCE if (qt_wince_is_mobile() && wce_menubar) @@ -1804,7 +1862,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) d->platformMenuBar = 0; } else { if (!d->platformMenuBar) - d->platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(this); + d->platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); } updateGeometry(); diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index 139f5703de..b4e178b7d2 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -55,6 +55,7 @@ #include "QtWidgets/qstyleoption.h" #include <private/qmenu_p.h> // Mac needs what in this file! +#include <qpa/qplatformmenu.h> QT_BEGIN_NAMESPACE @@ -145,6 +146,8 @@ public: QBasicTimer autoReleaseTimer; QPlatformMenuBar *platformMenuBar; + inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); } + #ifdef Q_OS_WINCE void wceCreateMenuBar(QWidget *); void wceDestroyMenuBar(); |