summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/kernel/kernel.pri9
-rw-r--r--src/widgets/kernel/qaction.h3
-rw-r--r--src/widgets/kernel/qplatformmenu.h94
-rw-r--r--src/widgets/kernel/qplatformmenu_qpa.cpp113
-rw-r--r--src/widgets/widgets/qmenu.cpp51
-rw-r--r--src/widgets/widgets/qmenubar.cpp78
-rw-r--r--src/widgets/widgets/qmenubar_p.h3
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();