Introduce QAbstractMenuBarImpl
authorAurélien Gâteau <agateau@kde.org>
Thu, 14 Apr 2011 08:00:24 +0000 (10:00 +0200)
committerOlivier Goffart <olivier.goffart@nokia.com>
Tue, 10 May 2011 10:54:46 +0000 (12:54 +0200)
Merge-request: 916
Reviewed-by: Thierry Bastian <thierry.bastian@nokia.com>
(cherry picked from commit 0432a6b79d35ac7db909a81793417107ebfb668f)

src/gui/widgets/qabstractmenubarimpl_p.cpp [new file with mode: 0644]
src/gui/widgets/qabstractmenubarimpl_p.h [new file with mode: 0644]
src/gui/widgets/qmenubar.cpp
src/gui/widgets/qmenubar_p.h
src/gui/widgets/qmenubarimpl.cpp [new file with mode: 0644]
src/gui/widgets/qmenubarimpl_p.h [new file with mode: 0644]
src/gui/widgets/widgets.pri

diff --git a/src/gui/widgets/qabstractmenubarimpl_p.cpp b/src/gui/widgets/qabstractmenubarimpl_p.cpp
new file mode 100644 (file)
index 0000000..bc16030
--- /dev/null
@@ -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 <private/qabstractmenubarimpl_p.h>
+
+QAbstractMenuBarImpl::~QAbstractMenuBarImpl()
+{}
diff --git a/src/gui/widgets/qabstractmenubarimpl_p.h b/src/gui/widgets/qabstractmenubarimpl_p.h
new file mode 100644 (file)
index 0000000..d001008
--- /dev/null
@@ -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 <qglobal.h>
+
+#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
index 08c287e..0d13574 100644 (file)
 #include <qmenudata.h>
 #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<QMenuBarPrivate*>(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<QMainWindow *>(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<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;
-                }
-            }
-        } 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
 }
index 2b8558b..b49e039 100644 (file)
@@ -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<QWidget> 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<QMacMenuAction*> 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<QWceMenuAction*> actionItems;
-        QList<QWceMenuAction*> actionItemsLeftButton;
-        QList<QList<QWceMenuAction*>> actionItemsClassic;
-        HMENU menuHandle;
-        HMENU leftButtonMenuHandle;
-        HWND menubarHandle;
-        HWND parentWindowHandle;
-        bool leftButtonIsMenu;
-        QPointer<QAction> 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<QWceMenuAction*> actions, uint command);
-#endif
-#ifdef Q_WS_S60
-    void symbianCreateMenuBar(QWidget *);
-    void symbianDestroyMenuBar();
-    void reparentMenuBar(QWidget *oldParent, QWidget *newParent);
-    struct QSymbianMenuBarPrivate {
-        QList<QSymbianMenuAction*> 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<QAction*> &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 (file)
index 0000000..195f0ea
--- /dev/null
@@ -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<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;
+                }
+            }
+        } 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 (file)
index 0000000..e770b5b
--- /dev/null
@@ -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<QMacMenuAction*> 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<QWceMenuAction*> actionItems;
+        QList<QWceMenuAction*> actionItemsLeftButton;
+        QList<QList<QWceMenuAction*>> actionItemsClassic;
+        HMENU menuHandle;
+        HMENU leftButtonMenuHandle;
+        HWND menubarHandle;
+        HWND parentWindowHandle;
+        bool leftButtonIsMenu;
+        QPointer<QAction> 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<QWceMenuAction*> actions, uint command);
+#endif
+#ifdef Q_WS_S60
+    void symbianCreateMenuBar(QWidget *);
+    void symbianDestroyMenuBar();
+    void reparentMenuBar(QWidget *oldParent, QWidget *newParent);
+    struct QSymbianMenuBarPrivate {
+        QList<QSymbianMenuAction*> 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<QAction*> &actions);
+
+    } adapter;
+    static int symbianCommands(int command);
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_MENUBAR
+
+#endif /* QMENUBARIMPL_P_H */
index 669b838..e5d6890 100644 (file)
@@ -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 \