From: Aurélien Gâteau Date: Thu, 14 Apr 2011 08:00:24 +0000 (+0200) Subject: Introduce QAbstractMenuBarImpl X-Git-Tag: qt-v5.0.0-alpha1~4322^2~110 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1b573dd5ffe3c733b50c97bd2db0b70418fb8265;p=profile%2Fivi%2Fqtbase.git Introduce QAbstractMenuBarImpl Merge-request: 916 Reviewed-by: Thierry Bastian (cherry picked from commit 0432a6b79d35ac7db909a81793417107ebfb668f) --- diff --git a/src/gui/widgets/qabstractmenubarimpl_p.cpp b/src/gui/widgets/qabstractmenubarimpl_p.cpp new file mode 100644 index 0000000..bc16030 --- /dev/null +++ b/src/gui/widgets/qabstractmenubarimpl_p.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +QAbstractMenuBarImpl::~QAbstractMenuBarImpl() +{} diff --git a/src/gui/widgets/qabstractmenubarimpl_p.h b/src/gui/widgets/qabstractmenubarimpl_p.h new file mode 100644 index 0000000..d001008 --- /dev/null +++ b/src/gui/widgets/qabstractmenubarimpl_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2010 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QABSTRACTMENUBARIMPL_P_H +#define QABSTRACTMENUBARIMPL_P_H + +#include + +#ifndef QT_NO_MENUBAR + +QT_BEGIN_NAMESPACE + +class QAction; +class QActionEvent; +class QEvent; +class QMenuBar; +class QObject; +class QWidget; + +/** + * The platform-specific implementation of a menubar + */ +class Q_GUI_EXPORT QAbstractMenuBarImpl +{ +public: + virtual ~QAbstractMenuBarImpl(); + + // QMenuBarPrivate::init() + virtual void init(QMenuBar *) = 0; + + // QMenuBar::setVisible() + virtual bool allowSetVisible() const = 0; + + virtual void actionEvent(QActionEvent *) = 0; + + // QMenuBar::handleReparent() + virtual void handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow) = 0; + + // QMenuBarPrivate::updateGeometries() + // QMenuBar::minimumSizeHint() + // QMenuBar::sizeHint() + // QMenuBar::heightForWidth() + virtual bool allowCornerWidgets() const = 0; + + // QMenuBar::_q_internalShortcutActivated() + virtual void popupAction(QAction*) = 0; + + // QMenuBar::setNativeMenuBar() + virtual void setNativeMenuBar(bool) = 0; + + virtual bool isNativeMenuBar() const = 0; + + /** + * Return true if the native menubar is capable of listening to the + * shortcut keys. If false is returned, QMenuBar will trigger actions on + * shortcut itself. + */ + virtual bool shortcutsHandledByNativeMenuBar() const = 0; + + virtual bool menuBarEventFilter(QObject *, QEvent *event) = 0; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_MENUBAR + +#endif // QABSTRACTMENUBARIMPL_P_H diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 08c287e..0d13574 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -63,9 +63,10 @@ #include #endif +#include "qdebug.h" #include "qmenu_p.h" #include "qmenubar_p.h" -#include "qdebug.h" +#include "qmenubarimpl_p.h" #ifdef Q_WS_WINCE extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp @@ -173,7 +174,8 @@ void QMenuBarPrivate::updateGeometries() return; int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q)*2); int q_start = -1; - if(leftWidget || rightWidget) { + + if(impl->allowCornerWidgets() && (leftWidget || rightWidget)) { int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q) + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q) @@ -195,16 +197,8 @@ void QMenuBarPrivate::updateGeometries() } } -#ifdef Q_WS_MAC - if(q->isNativeMenuBar()) {//nothing to see here folks, move along.. - itemsDirty = false; - return; - } -#endif - calcActionRects(q_width, q_start); - currentAction = 0; #ifndef QT_NO_SHORTCUT - if(itemsDirty) { + if(!impl->shortcutsHandledByNativeMenuBar() && itemsDirty) { for(int j = 0; j < shortcutIndexMap.size(); ++j) q->releaseShortcut(shortcutIndexMap.value(j)); shortcutIndexMap.resize(0); // faster than clear @@ -212,6 +206,12 @@ void QMenuBarPrivate::updateGeometries() shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text()))); } #endif + if(q->isNativeMenuBar()) {//nothing to see here folks, move along.. + itemsDirty = false; + return; + } + calcActionRects(q_width, q_start); + currentAction = 0; itemsDirty = false; hiddenActions.clear(); @@ -728,21 +728,9 @@ void QMenuBarPrivate::init() Q_Q(QMenuBar); q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); q->setAttribute(Qt::WA_CustomWhatsThis); -#ifdef Q_WS_MAC - macCreateMenuBar(q->parentWidget()); - if(mac_menubar) - q->hide(); -#endif -#ifdef Q_WS_WINCE - if (qt_wince_is_mobile()) { - wceCreateMenuBar(q->parentWidget()); - if(wce_menubar) - q->hide(); - } - else { - QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true); - } -#endif + impl = new QMenuBarImpl; + impl->init(q); + q->setBackgroundRole(QPalette::Button); oldWindow = oldParent = 0; #ifdef QT3_SUPPORT @@ -751,6 +739,9 @@ void QMenuBarPrivate::init() #ifdef QT_SOFTKEYS_ENABLED menuBarAction = 0; #endif + cornerWidgetToolBar = 0; + cornerWidgetContainer = 0; + handleReparent(); q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q)); @@ -808,19 +799,8 @@ QMenuBar::QMenuBar(QWidget *parent, const char *name) : QWidget(*new QMenuBarPri */ QMenuBar::~QMenuBar() { -#ifdef Q_WS_MAC - Q_D(QMenuBar); - d->macDestroyMenuBar(); -#endif -#ifdef Q_WS_WINCE Q_D(QMenuBar); - if (qt_wince_is_mobile()) - d->wceDestroyMenuBar(); -#endif -#ifdef Q_WS_S60 - Q_D(QMenuBar); - d->symbianDestroyMenuBar(); -#endif + delete d->cornerWidgetToolBar; } /*! @@ -1072,13 +1052,10 @@ void QMenuBar::paintEvent(QPaintEvent *e) */ void QMenuBar::setVisible(bool visible) { -#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) - if (isNativeMenuBar()) { - if (!visible) - QWidget::setVisible(false); + Q_D(QMenuBar); + if (!d->impl->allowSetVisible()) { return; } -#endif QWidget::setVisible(visible); } @@ -1275,25 +1252,7 @@ void QMenuBar::actionEvent(QActionEvent *e) { Q_D(QMenuBar); d->itemsDirty = true; -#if defined (Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) - if (isNativeMenuBar()) { -#ifdef Q_WS_MAC - QMenuBarPrivate::QMacMenuBarPrivate *nativeMenuBar = d->mac_menubar; -#elif defined(Q_WS_S60) - QMenuBarPrivate::QSymbianMenuBarPrivate *nativeMenuBar = d->symbian_menubar; -#else - QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar; -#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()); - } -#endif + d->impl->actionEvent(e); if(e->type() == QEvent::ActionAdded) { connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); @@ -1369,55 +1328,10 @@ void QMenuBarPrivate::handleReparent() newWindow->installEventFilter(q); } + impl->handleReparent(oldParent, newParent, oldWindow, newWindow); + oldParent = newParent; oldWindow = newWindow; - -#ifdef Q_WS_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 - -#ifdef Q_WS_WINCE - if (qt_wince_is_mobile() && wce_menubar) - wce_menubar->rebuild(); -#endif -#ifdef Q_WS_S60 - - // Construct symbian_menubar when this code path is entered first time - // and when newParent != NULL - if (!symbian_menubar) - symbianCreateMenuBar(newParent); - - // Reparent and rebuild menubar when parent is changed - if (symbian_menubar) { - if (oldParent != newParent) - reparentMenuBar(oldParent, newParent); - q->hide(); - symbian_menubar->rebuild(); - } - -#ifdef QT_SOFTKEYS_ENABLED - // Constuct menuBarAction when this code path is entered first time - if (!menuBarAction) { - if (newParent) { - menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, newParent); - newParent->addAction(menuBarAction); - } - } else { - // If reparenting i.e. we already have menuBarAction, remove it from old parent - // and add for a new parent - if (oldParent) - oldParent->removeAction(menuBarAction); - if (newParent) - newParent->addAction(menuBarAction); - } -#endif // QT_SOFTKEYS_ENABLED -#endif // Q_WS_S60 } #ifdef QT3_SUPPORT @@ -1566,6 +1480,9 @@ bool QMenuBar::event(QEvent *e) bool QMenuBar::eventFilter(QObject *object, QEvent *event) { Q_D(QMenuBar); + if (d->impl->menuBarEventFilter(object, event)) { + return true; + } if (object == parent() && object) { #ifdef QT3_SUPPORT if (d->doAutoResize && event->type() == QEvent::Resize) { @@ -1659,11 +1576,7 @@ QRect QMenuBar::actionGeometry(QAction *act) const QSize QMenuBar::minimumSizeHint() const { Q_D(const QMenuBar); -#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif ensurePolished(); QSize ret(0, 0); @@ -1682,17 +1595,19 @@ QSize QMenuBar::minimumSizeHint() const ret += QSize(2*fw + hmargin, 2*fw + vmargin); } int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; - if(d->leftWidget) { - QSize sz = d->leftWidget->minimumSizeHint(); - ret.setWidth(ret.width() + sz.width()); - if(sz.height() + margin > ret.height()) - ret.setHeight(sz.height() + margin); - } - if(d->rightWidget) { - QSize sz = d->rightWidget->minimumSizeHint(); - ret.setWidth(ret.width() + sz.width()); - if(sz.height() + margin > ret.height()) - ret.setHeight(sz.height() + margin); + if (d->impl->allowCornerWidgets()) { + if(d->leftWidget) { + QSize sz = d->leftWidget->minimumSizeHint(); + ret.setWidth(ret.width() + sz.width()); + if(sz.height() + margin > ret.height()) + ret.setHeight(sz.height() + margin); + } + if(d->rightWidget) { + QSize sz = d->rightWidget->minimumSizeHint(); + ret.setWidth(ret.width() + sz.width()); + if(sz.height() + margin > ret.height()) + ret.setHeight(sz.height() + margin); + } } if(as_gui_menubar) { QStyleOptionMenuItem opt; @@ -1715,12 +1630,7 @@ QSize QMenuBar::minimumSizeHint() const QSize QMenuBar::sizeHint() const { Q_D(const QMenuBar); -#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif - ensurePolished(); QSize ret(0, 0); @@ -1741,17 +1651,19 @@ QSize QMenuBar::sizeHint() const ret += QSize(fw + hmargin, fw + vmargin); } int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; - if(d->leftWidget) { - QSize sz = d->leftWidget->sizeHint(); - ret.setWidth(ret.width() + sz.width()); - if(sz.height() + margin > ret.height()) - ret.setHeight(sz.height() + margin); - } - if(d->rightWidget) { - QSize sz = d->rightWidget->sizeHint(); - ret.setWidth(ret.width() + sz.width()); - if(sz.height() + margin > ret.height()) - ret.setHeight(sz.height() + margin); + if(d->impl->allowCornerWidgets()) { + if(d->leftWidget) { + QSize sz = d->leftWidget->sizeHint(); + ret.setWidth(ret.width() + sz.width()); + if(sz.height() + margin > ret.height()) + ret.setHeight(sz.height() + margin); + } + if(d->rightWidget) { + QSize sz = d->rightWidget->sizeHint(); + ret.setWidth(ret.width() + sz.width()); + if(sz.height() + margin > ret.height()) + ret.setHeight(sz.height() + margin); + } } if(as_gui_menubar) { QStyleOptionMenuItem opt; @@ -1774,11 +1686,7 @@ QSize QMenuBar::sizeHint() const int QMenuBar::heightForWidth(int) const { Q_D(const QMenuBar); -#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif const_cast(d)->updateGeometries(); int height = 0; @@ -1794,10 +1702,12 @@ int QMenuBar::heightForWidth(int) const height += 2*vmargin; } int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; - if(d->leftWidget) - height = qMax(d->leftWidget->sizeHint().height() + margin, height); - if(d->rightWidget) - height = qMax(d->rightWidget->sizeHint().height() + margin, height); + if(d->impl->allowCornerWidgets()) { + if(d->leftWidget) + height = qMax(d->leftWidget->sizeHint().height() + margin, height); + if(d->rightWidget) + height = qMax(d->rightWidget->sizeHint().height() + margin, height); + } if(as_gui_menubar) { QStyleOptionMenuItem opt; opt.init(this); @@ -1817,7 +1727,11 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id) { Q_Q(QMenuBar); QAction *act = actions.at(id); - setCurrentAction(act, true, true); + if (q->isNativeMenuBar()) { + impl->popupAction(act); + } else { + setCurrentAction(act, true, true); + } if (act && !act->menu()) { activateAction(act, QAction::Trigger); //100 is the same as the default value in QPushButton::animateClick @@ -1838,6 +1752,37 @@ void QMenuBarPrivate::_q_updateLayout() } } +void QMenuBarPrivate::updateCornerWidgetToolBar() +{ + Q_Q(QMenuBar); + if (!cornerWidgetToolBar) { + QMainWindow *window = qobject_cast(q->window()); + if (!window) { + qWarning() << "Menubar parent is not a QMainWindow, not showing corner widgets"; + return; + } + cornerWidgetToolBar = window->addToolBar(QApplication::translate("QMenuBar", "Corner Toolbar")); + cornerWidgetToolBar->setObjectName(QLatin1String("CornerToolBar")); + cornerWidgetContainer = new QWidget; + cornerWidgetToolBar->addWidget(cornerWidgetContainer); + new QHBoxLayout(cornerWidgetContainer); + } else { + QLayout *layout = cornerWidgetContainer->layout(); + while (layout->count() > 0) { + layout->takeAt(0); + } + } + if (leftWidget) { + leftWidget->setParent(cornerWidgetContainer); + cornerWidgetContainer->layout()->addWidget(leftWidget); + } + if (rightWidget) { + rightWidget->setParent(cornerWidgetContainer); + cornerWidgetContainer->layout()->addWidget(rightWidget); + } +} + + /*! \fn void QMenuBar::setCornerWidget(QWidget *widget, Qt::Corner corner) @@ -1870,9 +1815,13 @@ void QMenuBar::setCornerWidget(QWidget *w, Qt::Corner corner) return; } - if (w) { - w->setParent(this); - w->installEventFilter(this); + if(!d->impl->allowCornerWidgets()) { + d->updateCornerWidgetToolBar(); + } else { + if (w) { + w->setParent(this); + w->installEventFilter(this); + } } d->_q_updateLayout(); @@ -1923,39 +1872,13 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const void QMenuBar::setNativeMenuBar(bool nativeMenuBar) { Q_D(QMenuBar); - if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) { - d->nativeMenuBar = nativeMenuBar; -#ifdef Q_WS_MAC - if (!d->nativeMenuBar) { - extern void qt_mac_clear_menubar(); - qt_mac_clear_menubar(); - d->macDestroyMenuBar(); - const QList &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; - } - } - } else { - d->macCreateMenuBar(parentWidget()); - } - macUpdateMenuBar(); - updateGeometry(); - if (!d->nativeMenuBar && parentWidget()) - setVisible(true); -#endif - } + d->impl->setNativeMenuBar(nativeMenuBar); } bool QMenuBar::isNativeMenuBar() const { Q_D(const QMenuBar); - if (d->nativeMenuBar == -1) { - return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar); - } - return d->nativeMenuBar; + return d->impl->isNativeMenuBar(); } /*! @@ -1992,8 +1915,8 @@ void QMenuBar::setDefaultAction(QAction *act) connect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction())); connect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction())); } - if (d->wce_menubar) { - d->wce_menubar->rebuild(); + if (d->impl->nativeMenuBarAdapter()) { + d->impl->nativeMenuBarAdapter()->rebuild(); } #endif } diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index 2b8558b..b49e039 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -61,6 +61,8 @@ #include "qguifunctions_wince.h" #endif +#include "qabstractmenubarimpl_p.h" + #ifndef QT_NO_MENUBAR #ifdef Q_WS_S60 class CCoeControl; @@ -71,6 +73,7 @@ class CEikMenuBar; QT_BEGIN_NAMESPACE #ifndef QT_NO_MENUBAR +class QToolBar; class QMenuBarExtension; class QMenuBarPrivate : public QWidgetPrivate { @@ -78,33 +81,19 @@ 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) + doChildEffects(false) #ifdef QT3_SUPPORT , doAutoResize(false) #endif -#ifdef Q_WS_MAC - , mac_menubar(0) -#endif - + , impl(0) #ifdef Q_WS_WINCE - , wce_menubar(0), wceClassicMenu(false) -#endif -#ifdef Q_WS_S60 - , symbian_menubar(0) + , wceClassicMenu(false) #endif { } ~QMenuBarPrivate() { -#ifdef Q_WS_MAC - delete mac_menubar; -#endif -#ifdef Q_WS_WINCE - delete wce_menubar; -#endif -#ifdef Q_WS_S60 - delete symbian_menubar; -#endif + delete impl; } void init(); @@ -136,8 +125,6 @@ public: uint keyboardState : 1, altPressed : 1; QPointer keyboardFocusWidget; - - int nativeMenuBar : 3; // Only has values -1, 0, and 1 //firing of events void activateAction(QAction *, QAction::ActionEvent); @@ -173,106 +160,14 @@ public: #ifdef QT3_SUPPORT bool doAutoResize; #endif -#ifdef Q_WS_MAC - //mac menubar binding - struct QMacMenuBarPrivate { - QList actionItems; - OSMenuRef menu, apple_menu; - QMacMenuBarPrivate(); - ~QMacMenuBarPrivate(); - - void addAction(QAction *, QAction* =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(); - struct QWceMenuBarPrivate { - QList actionItems; - QList actionItemsLeftButton; - QList> actionItemsClassic; - HMENU menuHandle; - HMENU leftButtonMenuHandle; - HWND menubarHandle; - HWND parentWindowHandle; - bool leftButtonIsMenu; - QPointer leftButtonAction; - QMenuBarPrivate *d; - int leftButtonCommand; - - QWceMenuBarPrivate(QMenuBarPrivate *menubar); - ~QWceMenuBarPrivate(); - void addAction(QAction *, QAction* =0); - void addAction(QWceMenuAction *, QWceMenuAction* =0); - void syncAction(QWceMenuAction *); - inline void syncAction(QAction *a) { syncAction(findAction(a)); } - void removeAction(QWceMenuAction *); - void rebuild(); - inline void removeAction(QAction *a) { removeAction(findAction(a)); } - inline QWceMenuAction *findAction(QAction *a) { - for(int i = 0; i < actionItems.size(); i++) { - QWceMenuAction *act = actionItems[i]; - if(a == act->action) - return act; - } - return 0; - } - } *wce_menubar; - bool wceClassicMenu; - void wceCommands(uint command); - void wceRefresh(); - bool wceEmitSignals(QList actions, uint command); -#endif -#ifdef Q_WS_S60 - void symbianCreateMenuBar(QWidget *); - void symbianDestroyMenuBar(); - void reparentMenuBar(QWidget *oldParent, QWidget *newParent); - struct QSymbianMenuBarPrivate { - QList actionItems; - QMenuBarPrivate *d; - QSymbianMenuBarPrivate(QMenuBarPrivate *menubar); - ~QSymbianMenuBarPrivate(); - void addAction(QAction *, QAction* =0); - void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0); - void syncAction(QSymbianMenuAction *); - inline void syncAction(QAction *a) { syncAction(findAction(a)); } - void removeAction(QSymbianMenuAction *); - void rebuild(); - inline void removeAction(QAction *a) { removeAction(findAction(a)); } - inline QSymbianMenuAction *findAction(QAction *a) { - for(int i = 0; i < actionItems.size(); i++) { - QSymbianMenuAction *act = actionItems[i]; - if(a == act->action) - return act; - } - return 0; - } - void insertNativeMenuItems(const QList &actions); - - } *symbian_menubar; - static int symbianCommands(int command); -#endif + QAbstractMenuBarImpl *impl; #ifdef QT_SOFTKEYS_ENABLED QAction *menuBarAction; #endif + + void updateCornerWidgetToolBar(); + QToolBar *cornerWidgetToolBar; + QWidget *cornerWidgetContainer; }; #endif diff --git a/src/gui/widgets/qmenubarimpl.cpp b/src/gui/widgets/qmenubarimpl.cpp new file mode 100644 index 0000000..195f0ea --- /dev/null +++ b/src/gui/widgets/qmenubarimpl.cpp @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2010 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qmenubarimpl_p.h" + +#ifndef QT_NO_MENUBAR + +#include "qapplication.h" +#include "qdebug.h" +#include "qevent.h" +#include "qmenu.h" +#include "qmenubar.h" + +QT_BEGIN_NAMESPACE + +QMenuBarImpl::~QMenuBarImpl() +{ +#ifdef Q_WS_MAC + macDestroyMenuBar(); +#endif +#ifdef Q_WS_WINCE + if (qt_wince_is_mobile()) + wceDestroyMenuBar(); +#endif +#ifdef Q_WS_S60 + symbianDestroyMenuBar(); +#endif +} + +void QMenuBarImpl::init(QMenuBar *_menuBar) +{ + nativeMenuBar = -1; + menuBar = _menuBar; +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) + adapter = 0; +#endif +#ifdef Q_WS_MAC + macCreateMenuBar(menuBar->parentWidget()); + if(adapter) + menuBar->hide(); +#endif +#ifdef Q_WS_WINCE + if (qt_wince_is_mobile()) { + wceCreateMenuBar(menuBar->parentWidget()); + if(adapter) + menuBar->hide(); + } + else { + QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true); + } +#endif +} + +bool QMenuBarImpl::allowSetVisible() const +{ +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) + // FIXME: Port this to a setVisible() method + /* + if (isNativeMenuBar()) { + if (!visible) + QWidget::setVisible(false); + return; + } + */ + return !isNativeMenuBar(); +#endif + return true; +} + +void QMenuBarImpl::actionEvent(QActionEvent *e) +{ +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) + if (adapter) { + if(e->type() == QEvent::ActionAdded) + adapter->addAction(e->action(), e->before()); + else if(e->type() == QEvent::ActionRemoved) + adapter->removeAction(e->action()); + else if(e->type() == QEvent::ActionChanged) + adapter->syncAction(e->action()); + } +#else + Q_UNUSED(e); +#endif +} + +void QMenuBarImpl::handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow) +{ +#ifdef Q_WS_X11 + Q_UNUSED(oldParent) + Q_UNUSED(newParent) + Q_UNUSED(oldWindow) + Q_UNUSED(newWindow) +#endif + +#ifdef Q_WS_MAC + if (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 +#ifdef Q_WS_WINCE + if (qt_wince_is_mobile() && nativeMenuBarAdapter()) + adapter->rebuild(); +#endif +#ifdef Q_WS_S60 + + // Construct d->impl->nativeMenuBarAdapter() when this code path is entered first time + // and when newParent != NULL + if (!adapter) + symbianCreateMenuBar(newParent); + + // Reparent and rebuild menubar when parent is changed + if (adapter) { + if (oldParent != newParent) + reparentMenuBar(oldParent, newParent); + menuBar->hide(); + adapter->rebuild(); + } + +#ifdef QT_SOFTKEYS_ENABLED + // Constuct menuBarAction when this code path is entered first time + if (!menuBarAction) { + if (newParent) { + menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, newParent); + newParent->addAction(menuBarAction); + } + } else { + // If reparenting i.e. we already have menuBarAction, remove it from old parent + // and add for a new parent + if (oldParent) + oldParent->removeAction(menuBarAction); + if (newParent) + newParent->addAction(menuBarAction); + } +#endif // QT_SOFTKEYS_ENABLED +#endif // Q_WS_S60 +} + +bool QMenuBarImpl::allowCornerWidgets() const +{ + return true; +} + +void QMenuBarImpl::popupAction(QAction *) +{ +} + +void QMenuBarImpl::setNativeMenuBar(bool value) +{ + if (nativeMenuBar == -1 || (value != bool(nativeMenuBar))) { + nativeMenuBar = value; +#ifdef Q_WS_MAC + if (!nativeMenuBar) { + extern void qt_mac_clear_menubar(); + qt_mac_clear_menubar(); + macDestroyMenuBar(); + const QList &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; + } + } + } else { + macCreateMenuBar(parentWidget()); + } + macUpdateMenuBar(); + updateGeometry(); + if (!nativeMenuBar && parentWidget()) + setVisible(true); +#endif + } +} + +bool QMenuBarImpl::isNativeMenuBar() const +{ +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) + if (nativeMenuBar == -1) { + return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar); + } + return nativeMenuBar; +#else + return false; +#endif +} + +bool QMenuBarImpl::shortcutsHandledByNativeMenuBar() const +{ +#ifdef Q_WS_MAC + return true; +#else + return false; +#endif +} + +bool QMenuBarImpl::menuBarEventFilter(QObject *, QEvent *) +{ + return false; +} + +QT_END_NAMESPACE + +#endif // QT_NO_MENUBAR diff --git a/src/gui/widgets/qmenubarimpl_p.h b/src/gui/widgets/qmenubarimpl_p.h new file mode 100644 index 0000000..e770b5b --- /dev/null +++ b/src/gui/widgets/qmenubarimpl_p.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2010 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QMENUBARIMPL_P_H +#define QMENUBARIMPL_P_H + +#ifndef QT_NO_MENUBAR + +#include "qabstractmenubarimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QMenuBar; + +class QMenuBarImpl : public QAbstractMenuBarImpl +{ +public: + ~QMenuBarImpl(); + + virtual void init(QMenuBar *); + + virtual bool allowSetVisible() const; + + virtual void actionEvent(QActionEvent *e); + + virtual void handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow); + + virtual bool allowCornerWidgets() const; + + virtual void popupAction(QAction*); + + virtual void setNativeMenuBar(bool); + virtual bool isNativeMenuBar() const; + + virtual bool shortcutsHandledByNativeMenuBar() const; + virtual bool menuBarEventFilter(QObject *, QEvent *event); + +private: + QMenuBar *menuBar; + int nativeMenuBar : 3; // Only has values -1, 0, and 1 + +#ifdef Q_WS_MAC + //mac menubar binding + struct QMacMenuBarPrivate { + QList actionItems; + OSMenuRef menu, apple_menu; + QMacMenuBarPrivate(); + ~QMacMenuBarPrivate(); + + void addAction(QAction *, QAction* =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; + } + } adapter; + static bool macUpdateMenuBarImmediatly(); + bool macWidgetHasNativeMenubar(QWidget *widget); + void macCreateMenuBar(QWidget *); + void macDestroyMenuBar(); + OSMenuRef macMenu(); +#endif +#ifdef Q_WS_WINCE + void wceCreateMenuBar(QWidget *); + void wceDestroyMenuBar(); + struct QWceMenuBarPrivate { + QList actionItems; + QList actionItemsLeftButton; + QList> actionItemsClassic; + HMENU menuHandle; + HMENU leftButtonMenuHandle; + HWND menubarHandle; + HWND parentWindowHandle; + bool leftButtonIsMenu; + QPointer leftButtonAction; + QMenuBarPrivate *d; + int leftButtonCommand; + + QWceMenuBarPrivate(QMenuBarPrivate *menubar); + ~QWceMenuBarPrivate(); + void addAction(QAction *, QAction* =0); + void addAction(QWceMenuAction *, QWceMenuAction* =0); + void syncAction(QWceMenuAction *); + inline void syncAction(QAction *a) { syncAction(findAction(a)); } + void removeAction(QWceMenuAction *); + void rebuild(); + inline void removeAction(QAction *a) { removeAction(findAction(a)); } + inline QWceMenuAction *findAction(QAction *a) { + for(int i = 0; i < actionItems.size(); i++) { + QWceMenuAction *act = actionItems[i]; + if(a == act->action) + return act; + } + return 0; + } + } adapter; + bool wceClassicMenu; + void wceCommands(uint command); + void wceRefresh(); + bool wceEmitSignals(QList actions, uint command); +#endif +#ifdef Q_WS_S60 + void symbianCreateMenuBar(QWidget *); + void symbianDestroyMenuBar(); + void reparentMenuBar(QWidget *oldParent, QWidget *newParent); + struct QSymbianMenuBarPrivate { + QList actionItems; + QMenuBarPrivate *d; + QSymbianMenuBarPrivate(QMenuBarPrivate *menubar); + ~QSymbianMenuBarPrivate(); + void addAction(QAction *, QAction* =0); + void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0); + void syncAction(QSymbianMenuAction *); + inline void syncAction(QAction *a) { syncAction(findAction(a)); } + void removeAction(QSymbianMenuAction *); + void rebuild(); + inline void removeAction(QAction *a) { removeAction(findAction(a)); } + inline QSymbianMenuAction *findAction(QAction *a) { + for(int i = 0; i < actionItems.size(); i++) { + QSymbianMenuAction *act = actionItems[i]; + if(a == act->action) + return act; + } + return 0; + } + void insertNativeMenuItems(const QList &actions); + + } adapter; + static int symbianCommands(int command); +#endif +}; + +QT_END_NAMESPACE + +#endif // QT_NO_MENUBAR + +#endif /* QMENUBARIMPL_P_H */ diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri index 669b838..e5d6890 100644 --- a/src/gui/widgets/widgets.pri +++ b/src/gui/widgets/widgets.pri @@ -4,6 +4,7 @@ HEADERS += \ widgets/qbuttongroup.h \ widgets/qabstractbutton.h \ widgets/qabstractbutton_p.h \ + widgets/qabstractmenubarimpl_p.h \ widgets/qabstractslider.h \ widgets/qabstractslider_p.h \ widgets/qabstractspinbox.h \ @@ -84,6 +85,7 @@ HEADERS += \ widgets/qprintpreviewwidget.h SOURCES += \ widgets/qabstractbutton.cpp \ + widgets/qabstractmenubarimpl_p.cpp \ widgets/qabstractslider.cpp \ widgets/qabstractspinbox.cpp \ widgets/qcalendarwidget.cpp \ @@ -110,6 +112,7 @@ SOURCES += \ widgets/qmdisubwindow.cpp \ widgets/qmenu.cpp \ widgets/qmenubar.cpp \ + widgets/qmenubarimpl.cpp \ widgets/qmenudata.cpp \ widgets/qprogressbar.cpp \ widgets/qpushbutton.cpp \