diff options
author | Morten Johan Sorvig <morten.sorvig@nokia.com> | 2012-05-10 15:35:50 +0200 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@nokia.com> | 2012-05-15 14:39:35 +0200 |
commit | 8a619f580b313c9373b816f059d91c208eb89400 (patch) | |
tree | 0a391abcc192a775d8192872cb1e773f6a691a1a | |
parent | f92f1b727626c4f7b0b99f0e1e28a34d35e58530 (diff) | |
download | qtquickcontrols-8a619f580b313c9373b816f059d91c208eb89400.tar.gz |
Port menus to Qt 5.
Copy over qtmenu and qtmenuitem from the Qt 4 branch.
Register types in qstyleplugin.cpp.
Delete Menu.qml MenuItem.qml - no longer in use
and replaced by C++ code.
Some porting was necessary, in particular changing
QtMenuBase's base class from QObject to QtQuickItem.
Bugs: On OS X the menu bar is displayed only ~50%
if the time. Other platforms are not tested.
Context menus do not work.
Change-Id: I4e9cc6952ec1c70dc28cfda2352ba9962b539b17
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
-rw-r--r-- | components/Menu.qml | 49 | ||||
-rw-r--r-- | components/MenuItem.qml | 8 | ||||
-rw-r--r-- | components/components.pro | 1 | ||||
-rw-r--r-- | components/qmldir | 1 | ||||
-rw-r--r-- | src/qstyleplugin.cpp | 11 | ||||
-rw-r--r-- | src/qtmenu.cpp | 240 | ||||
-rw-r--r-- | src/qtmenu.h | 122 | ||||
-rw-r--r-- | src/qtmenubar.cpp | 113 | ||||
-rw-r--r-- | src/qtmenubar.h | 103 | ||||
-rw-r--r-- | src/qtmenuitem.cpp | 161 | ||||
-rw-r--r-- | src/qtmenuitem.h | 141 | ||||
-rw-r--r-- | src/src.pro | 10 |
12 files changed, 898 insertions, 62 deletions
diff --git a/components/Menu.qml b/components/Menu.qml deleted file mode 100644 index b72e4c52..00000000 --- a/components/Menu.qml +++ /dev/null @@ -1,49 +0,0 @@ -import QtQuick 2.0 -import "../components/plugin" - -MenuBase { - property ListModel model - - property string selectedText: itemTextAt(selectedIndex) - property string hoveredText: itemTextAt(hoveredIndex) - - // 'centerSelectedText' means that the menu will be positioned - // so that the selected text' top left corner will be at x, y. - property bool centerSelectedText: true - - // Show, or hide, the popup by setting the 'visible' property: - visible: false - onMenuClosed: visible = false - onModelChanged: if (Component.status === Component.Ready) rebuildMenu() - Component.onCompleted: rebuildMenu() - - onHoveredIndexChanged: { - if (hoveredIndex < menuItems.length) - menuItems[hoveredIndex].emitHovered() - } - - onSelectedIndexChanged: { - if (hoveredIndex < menuItems.length) - menuItems[hoveredIndex].emitSelected() - } - - onVisibleChanged: { - if (visible) { - var globalPos = parent.mapToItem(null, x, y) - showPopup(globalPos.x, globalPos.y, centerSelectedText ? selectedIndex : 0) - } else { - closePopup() - } - } - - function rebuildMenu() - { - clearMenuItems(); - for (var i=0; i<menuItems.length; ++i) - addMenuItem(menuItems[i].text) - if (model != undefined) { - for (var j=0; j<model.count; ++j) - addMenuItem(model.get(j).text) - } - } -} diff --git a/components/MenuItem.qml b/components/MenuItem.qml deleted file mode 100644 index acd00bd4..00000000 --- a/components/MenuItem.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -Item { - property string text - property string iconName - signal hovered - signal selected -} diff --git a/components/components.pro b/components/components.pro index 519579b7..0e81b764 100644 --- a/components/components.pro +++ b/components/components.pro @@ -16,7 +16,6 @@ QML_FILES = \ ButtonRow.qml \ ButtonColumn.qml \ Frame.qml \ - MenuItem.qml \ Slider.qml \ TabBar.qml \ Tab.qml \ diff --git a/components/qmldir b/components/qmldir index 000c0218..79f6f5ad 100644 --- a/components/qmldir +++ b/components/qmldir @@ -26,7 +26,6 @@ RadioButton 0.1 RadioButton.qml plugin styleplugin plugin TableColumn 0.1 TableColumn.qml ContextMenu 0.1 ContextMenu.qml -MenuItem 0.1 MenuItem.qml Dialog 0.1 Dialog.qml StatusBar 0.1 StatusBar.qml ApplicationWindow 0.1 ApplicationWindow.qml diff --git a/src/qstyleplugin.cpp b/src/qstyleplugin.cpp index 3263e51a..e39b7369 100644 --- a/src/qstyleplugin.cpp +++ b/src/qstyleplugin.cpp @@ -41,6 +41,9 @@ #include "qstyleplugin.h" #include "qstyleitem.h" #include "qrangemodel.h" +#include "qtmenu.h" +#include "qtmenubar.h" +#include "qwindowitem.h" #include "qwindowitem.h" #include "qdesktopitem.h" #include "qwheelarea.h" @@ -83,10 +86,16 @@ void StylePlugin::registerTypes(const char *uri) qmlRegisterType<QRangeModel>(uri, 0, 2, "RangeModel"); qmlRegisterType<QWheelArea>(uri, 0, 2, "WheelArea"); + qmlRegisterType<QtMenu>(uri, 0, 2, "Menu"); + qmlRegisterType<QtMenuBar>(uri, 0, 2, "MenuBar"); + qmlRegisterType<QtMenuItem>(uri, 0, 2, "MenuItem"); + qmlRegisterType<QtMenuSeparator>(uri, 0, 2, "Separator"); + qmlRegisterType<QFileSystemModel>(uri, 0, 2, "FileSystemModel"); qmlRegisterType<QtSplitterBase>(uri, 0, 2, "Splitter"); - qmlRegisterType<QWindowItem>("QtQuick", 2, 0, "Window"); + qmlRegisterType<QWindowItem>("QtQuick", 2, 0, "Window"); // override built-in Window + qmlRegisterUncreatableType<QtMenuBase>("uri", 0, 1, "NativeMenuBase", QLatin1String("Do not create objects of type NativeMenuBase")); qmlRegisterUncreatableType<QDesktopItem>(uri, 0,2,"Desktop", QLatin1String("Do not create objects of type Desktop")); } diff --git a/src/qtmenu.cpp b/src/qtmenu.cpp new file mode 100644 index 00000000..0026aea5 --- /dev/null +++ b/src/qtmenu.cpp @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project on Qt Labs. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#include "qtmenu.h" +#include "qdebug.h" +#include <qapplication.h> +#include <qmenubar.h> +#include <qabstractitemmodel.h> +#include "qtoplevelwindow.h" + +QtMenu::QtMenu(QQuickItem *parent) + : QtMenuBase(parent), + dummy(0), + m_selectedIndex(0), + m_highlightedIndex(0), + m_hasNativeModel(false) +{ + m_qmenu = new QMenu(0); + connect(m_qmenu, SIGNAL(aboutToHide()), this, SIGNAL(menuClosed())); +} + +QtMenu::~QtMenu() +{ + delete m_qmenu; +} + +void QtMenu::setText(const QString &text) +{ + m_qmenu->setTitle(text); +} + +QString QtMenu::text() const +{ + return m_qmenu->title(); +} + +void QtMenu::setSelectedIndex(int index) +{ + m_selectedIndex = index; + QList<QAction *> actionList = m_qmenu->actions(); + if (m_selectedIndex >= 0 && m_selectedIndex < actionList.size()) + m_qmenu->setActiveAction(actionList[m_selectedIndex]); + emit selectedIndexChanged(); +} + +void QtMenu::setHoveredIndex(int index) +{ + m_highlightedIndex = index; + QList<QAction *> actionList = m_qmenu->actions(); + if (m_highlightedIndex >= 0 && m_highlightedIndex < actionList.size()) + m_qmenu->setActiveAction(actionList[m_highlightedIndex]); + emit hoveredIndexChanged(); +} + + +#if QT_VERSION < 0x050000 +QDeclarativeListProperty<QtMenuBase> QtMenu::menuItems() +{ + return QDeclarativeListProperty<QtMenuBase>(this, 0, &QtMenu::append_qmenuItem); +} +#else +QQmlListProperty<QtMenuBase> QtMenu::menuItems() +{ + return QQmlListProperty<QtMenuBase>(this, 0, &QtMenu::append_qmenuItem); +} +#endif + +void QtMenu::showPopup(qreal x, qreal y, int atActionIndex) +{ + if (m_qmenu->isVisible()) + return; + + // If atActionIndex is valid, x and y is specified from the + // the position of the corresponding QAction: + QAction *atAction = 0; + if (atActionIndex >= 0 && atActionIndex < m_qmenu->actions().size()) + atAction = m_qmenu->actions()[atActionIndex]; + + // x,y are in view coordinates, QMenu expects screen coordinates + // ### activeWindow hack + int menuBarHeight = 0; + QWidget *window = QApplication::activeWindow(); + QTopLevelWindow *tw = qobject_cast<QTopLevelWindow*>(window); + if (tw) { + QMenuBar *menuBar = tw->menuBar(); + menuBarHeight = menuBar->height(); + } + + QPoint screenPosition = window->mapToGlobal(QPoint(x, y+menuBarHeight)); + + setHoveredIndex(m_selectedIndex); + m_qmenu->popup(screenPosition, atAction); +} + +void QtMenu::hidePopup() +{ + m_qmenu->close(); +} + +QAction* QtMenu::action() +{ + return m_qmenu->menuAction(); +} + +Q_INVOKABLE void QtMenu::clearMenuItems() +{ + m_qmenu->clear(); + foreach (QtMenuBase *item, m_qmenuItems) { + delete item; + } + m_qmenuItems.clear(); +} + +void QtMenu::addMenuItem(const QString &text) +{ + QtMenuItem *menuItem = new QtMenuItem(this); + menuItem->setText(text); + m_qmenuItems.append(menuItem); + m_qmenu->addAction(menuItem->action()); + + connect(menuItem->action(), SIGNAL(triggered()), this, SLOT(emitSelected())); + connect(menuItem->action(), SIGNAL(hovered()), this, SLOT(emitHovered())); + + if (m_qmenu->actions().size() == 1) + // Inform QML that the selected action (0) now has changed contents: + emit selectedIndexChanged(); +} + +void QtMenu::emitSelected() +{ + QAction *act = qobject_cast<QAction *>(sender()); + if (!act) + return; + m_selectedIndex = m_qmenu->actions().indexOf(act); + emit selectedIndexChanged(); +} + +void QtMenu::emitHovered() +{ + QAction *act = qobject_cast<QAction *>(sender()); + if (!act) + return; + m_highlightedIndex = m_qmenu->actions().indexOf(act); + emit hoveredIndexChanged(); +} + +QString QtMenu::itemTextAt(int index) const +{ + QList<QAction *> actionList = m_qmenu->actions(); + if (index >= 0 && index < actionList.size()) + return actionList[index]->text(); + else + return ""; +} + +QString QtMenu::modelTextAt(int index) const +{ + if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(m_model.value<QObject*>())) { + return model->data(model->index(index, 0)).toString(); + } else if (m_model.canConvert(QVariant::StringList)) { + return m_model.toStringList().at(index); + } + return ""; +} + +int QtMenu::modelCount() const +{ + if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(m_model.value<QObject*>())) { + return model->rowCount(); + } else if (m_model.canConvert(QVariant::StringList)) { + return m_model.toStringList().count(); + } + return -1; +} + +#if QT_VERSION < 0x050000 +void QtMenu::append_qmenuItem(QDeclarativeListProperty<QtMenuBase> *list, QtMenuBase *menuItem) +{ + QtMenu *menu = qobject_cast<QtMenu *>(list->object); + if (menu) { + menuItem->setParent(menu); + menu->m_qmenuItems.append(menuItem); + menu->qmenu()->addAction(menuItem->action()); + } +} +#else +void QtMenu::append_qmenuItem(QQmlListProperty<QtMenuBase> *list, QtMenuBase *menuItem) +{ + QtMenu *menu = qobject_cast<QtMenu *>(list->object); + if (menu) { + menuItem->setParent(menu); + menu->m_qmenuItems.append(menuItem); + menu->qmenu()->addAction(menuItem->action()); + } +} +#endif + +void QtMenu::setModel(const QVariant &newModel) { + if (m_model != newModel) { + + // Clean up any existing connections + if (QAbstractItemModel *oldModel = qobject_cast<QAbstractItemModel*>(m_model.value<QObject*>())) { + disconnect(oldModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SIGNAL(rebuildMenu())); + } + + m_hasNativeModel = false; + m_model = newModel; + + if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(newModel.value<QObject*>())) { + m_hasNativeModel = true; + connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SIGNAL(rebuildMenu())); + } else if (newModel.canConvert(QVariant::StringList)) { + m_hasNativeModel = true; + } + emit modelChanged(m_model); + } +} diff --git a/src/qtmenu.h b/src/qtmenu.h new file mode 100644 index 00000000..a7e5541f --- /dev/null +++ b/src/qtmenu.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project on Qt Labs. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QTMLMENU_H +#define QTMLMENU_H +#include <QtCore/qglobal.h> +#include <QtWidgets/qmenu.h> +#if QT_VERSION < 0x050000 +#include <QtDeclarative/qdeclarative.h> +#include <QtDeclarative/QDeclarativeListProperty> +#else +#include <QtQuick/QtQuick> +#include <QtQml/QtQml> +#endif +#include <QtCore/qabstractitemmodel.h> +#include <QtCore/QVariant> +#include "qtmenuitem.h" + +class QtMenu : public QtMenuBase +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) + Q_PROPERTY(int selectedIndex READ selectedIndex WRITE setSelectedIndex NOTIFY selectedIndexChanged) + Q_PROPERTY(int hoveredIndex READ hoveredIndex WRITE setHoveredIndex NOTIFY hoveredIndexChanged) +#if QT_VERSION < 0x050000 + Q_PROPERTY(QDeclarativeListProperty<QtMenuBase> menuItems READ menuItems) +#else + Q_PROPERTY(QQmlListProperty<QtMenuBase> menuItems READ menuItems) +#endif + Q_CLASSINFO("DefaultProperty", "menuItems") +public: + QtMenu(QQuickItem *parent = 0); + virtual ~QtMenu(); + + void setText(const QString &text); + QString text() const; + + int selectedIndex() const { return m_selectedIndex; } + void setSelectedIndex(int index); + int hoveredIndex() const { return m_highlightedIndex; } + void setHoveredIndex(int index); + +#if QT_VERSION < 0x050000 + QDeclarativeListProperty<QtMenuBase> menuItems(); +#else + QQmlListProperty<QtMenuBase> menuItems(); +#endif + QMenu* qmenu() { return m_qmenu; } + + QAction* action(); + + Q_INVOKABLE int minimumWidth() const { return m_qmenu->minimumWidth(); } + Q_INVOKABLE void setMinimumWidth(int w) { m_qmenu->setMinimumWidth(w); } + Q_INVOKABLE void showPopup(qreal x, qreal y, int atActionIndex = -1); + Q_INVOKABLE void hidePopup(); + Q_INVOKABLE void clearMenuItems(); + Q_INVOKABLE void addMenuItem(const QString &text); + Q_INVOKABLE QString itemTextAt(int index) const; + Q_INVOKABLE QString modelTextAt(int index) const; + Q_INVOKABLE int modelCount() const; + + QVariant model() const { return m_model; } + Q_INVOKABLE bool hasNativeModel() const { return m_hasNativeModel; } + +public slots: + void setModel(const QVariant &newModel); + +public: +Q_SIGNALS: + void menuClosed(); + void selectedIndexChanged(); + void hoveredIndexChanged(); + void modelChanged(const QVariant &newModel); + void rebuldMenu(); + +private Q_SLOTS: + void emitSelected(); + void emitHovered(); + +private: +#if QT_VERSION < 0x050000 + static void append_qmenuItem(QDeclarativeListProperty<QtMenuBase> *list, QtMenuBase *menuItem); +#else + static void append_qmenuItem(QQmlListProperty<QtMenuBase> *list, QtMenuBase *menuItem); +#endif +private: + QWidget *dummy; + QMenu *m_qmenu; + QList<QtMenuBase *> m_qmenuItems; + int m_selectedIndex; + int m_highlightedIndex; + bool m_hasNativeModel; + QVariant m_model; +}; + +QML_DECLARE_TYPE(QtMenu) + +#endif // QTMLMENU_H diff --git a/src/qtmenubar.cpp b/src/qtmenubar.cpp new file mode 100644 index 00000000..308b4b9a --- /dev/null +++ b/src/qtmenubar.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTgall +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtmenubar.h" +#include "qwindowitem.h" + +#if QT_VERSION < 0x050000 +#include <QtGui/QMenu> +#include <QtGui/QMenuBar> +#else +#include <QtWidgets/QMenu> +#include <QtWidgets/QMenuBar> +#endif + +#if QT_VERSION < 0x050000 +QtMenuBar::QtMenuBar(QDeclarativeItem *parent) + : QDeclarativeItem(parent), _menuBar(0) /*, _menuBar(new QMenuBar)*/ +{ + connect(this, SIGNAL(parentChanged()), this, SLOT(updateParent())); + setFlag(QGraphicsItem::ItemHasNoContents, true); +} +#else +QtMenuBar::QtMenuBar(QQuickItem *parent) + : QQuickItem(parent), _menuBar(0) /*, _menuBar(new QMenuBar)*/ +{ + connect(this, SIGNAL(parentChanged(QQuickItem *)), this, SLOT(updateParent(QQuickItem *))); + setFlag(QQuickItem::ItemHasContents, false); +} +#endif + +QtMenuBar::~QtMenuBar() +{ +} + +#if QT_VERSION < 0x050000 +QDeclarativeListProperty<QtMenu> QtMenuBar::menus() +{ + return QDeclarativeListProperty<QtMenu>(this, 0, &QtMenuBar::append_menu); +} +#else +QQmlListProperty<QtMenu> QtMenuBar::menus() +{ + return QQmlListProperty<QtMenu>(this, 0, &QtMenuBar::append_menu); +} +#endif + +void QtMenuBar::updateParent(QQuickItem *newParent) +{ + if (QWindowItem* window = qobject_cast<QWindowItem*>(parent())) + _menuBar = window->window()->menuBar(); + + //THIS IS WRONG... WE NEED TO DO THAT DIFFERENT! + _menuBar->clear(); + + foreach (QtMenu *menu, m_menus) { + _menuBar->addMenu(menu->qmenu()); + } + //THIS IS WRONG... WE NEED TO DO THAT DIFFERENT! + +} + +#if QT_VERSION < 0x050000 +void QtMenuBar::append_menu(QDeclarativeListProperty<QtMenu> *list, QtMenu *menu) +#else +void QtMenuBar::append_menu(QQmlListProperty<QtMenu> *list, QtMenu *menu) +#endif +{ + QtMenuBar *menuBar = qobject_cast<QtMenuBar *>(list->object); + if (menuBar) { + menu->setParent(menuBar); + menuBar->m_menus.append(menu); + if (menuBar->_menuBar) + menuBar->_menuBar->addMenu(menu->qmenu()); + } +} + +# diff --git a/src/qtmenubar.h b/src/qtmenubar.h new file mode 100644 index 00000000..d7894219 --- /dev/null +++ b/src/qtmenubar.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTMENUBAR_H +#define QTMENUBAR_H + +#include <QtCore/qglobal.h> + +#if QT_VERSION < 0x050000 +#include <QDeclarativeItem> +#include <QtGui> +#else +#include <QtQuick/QQuickItem> +#include <QtWidgets> +#endif + +#include "qtmenu.h" + +#if QT_VERSION < 0x050000 +class QtMenuBar: public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QDeclarativeListProperty<QtMenu> menus READ menus) + Q_CLASSINFO("DefaultProperty", "menus") +public: + QtMenuBar(QDeclarativeItem *parent = 0); + ~QtMenuBar(); + + QDeclarativeListProperty<QtMenu> menus(); + +protected Q_SLOTS: + void updateParent(); + +private: + static void append_menu(QDeclarativeListProperty<QtMenu> *list, QtMenu *menu); + +private: + QList<QtMenu *> m_menus; + QMenuBar *_menuBar; +}; +#else +class QtMenuBar: public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(QQmlListProperty<QtMenu> menus READ menus) + Q_CLASSINFO("DefaultProperty", "menus") +public: + QtMenuBar(QQuickItem *parent = 0); + ~QtMenuBar(); + + QQmlListProperty<QtMenu> menus(); + +protected Q_SLOTS: + void updateParent(QQuickItem *newParent); + +private: + static void append_menu(QQmlListProperty<QtMenu> *list, QtMenu *menu); + +private: + QList<QtMenu *> m_menus; + QMenuBar *_menuBar; +}; +#endif + +#endif //QTMENUBAR_H diff --git a/src/qtmenuitem.cpp b/src/qtmenuitem.cpp new file mode 100644 index 00000000..1bddbb66 --- /dev/null +++ b/src/qtmenuitem.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTgall +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtmenuitem.h" + +void QtMenuBase::setIconSource(const QUrl &icon) +{ + _iconSource = icon; + if (_iconName.isEmpty()) + action()->setIcon(QIcon(icon.toLocalFile())); + else + action()->setIcon(QIcon::fromTheme(_iconName, QIcon(_iconSource.toLocalFile()))); + + emit iconSourceChanged(); +} + +QUrl QtMenuBase::iconSource() const +{ + return _iconSource; +} + +void QtMenuBase::setIconName(const QString &icon) +{ + _iconName = icon; + action()->setIcon(QIcon::fromTheme(_iconName, QIcon(_iconSource.toLocalFile()))); + + emit iconNameChanged(); +} + +QString QtMenuBase::iconName() const +{ + return _iconName; +} +#if QT_VERSION < 0x050000 +QtMenuSeparator::QtMenuSeparator(QObject *parent) +#else +QtMenuSeparator::QtMenuSeparator(QQuickItem *parent) +#endif + + : QtMenuBase(parent), _action(new QAction(this)) +{ + _action->setSeparator(true); +} + +QtMenuSeparator::~QtMenuSeparator() +{ +} + +QAction * QtMenuSeparator::action() +{ + return _action; +} + +#if QT_VERSION < 0x050000 +QtMenuItem::QtMenuItem(QObject *parent) +#else +QtMenuItem::QtMenuItem(QQuickItem *parent) +#endif + : QtMenuBase(parent), _action(new QAction(this)) +{ + connect(_action, SIGNAL(triggered()), this, SIGNAL(triggered())); + connect(_action, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool))); + connect(_action, SIGNAL(changed()), this, SIGNAL(enabledChanged())); +} + +QtMenuItem::~QtMenuItem() +{ +} + +void QtMenuItem::setText(const QString &text) +{ + _action->setText(text); + emit textChanged(); +} + +void QtMenuItem::setShortcut(const QString &shortcut) +{ + _action->setShortcut(QKeySequence(shortcut)); + emit shortcutChanged(); +} + +void QtMenuItem::setCheckable(bool checkable) +{ + _action->setCheckable(checkable); +} + +void QtMenuItem::setChecked(bool checked) +{ + _action->setChecked(checked); +} + +void QtMenuItem::setEnabled(bool enabled) +{ + _action->setEnabled(enabled); +} + +QString QtMenuItem::text() const +{ + return _action->text(); +} + +QString QtMenuItem::shortcut() const +{ + return _action->shortcut().toString(); +} + +bool QtMenuItem::checkable() const +{ + return _action->isCheckable(); +} + +bool QtMenuItem::checked() const +{ + return _action->isChecked(); +} + +bool QtMenuItem::enabled() const +{ + return _action->isEnabled(); +} + +QAction * QtMenuItem::action() +{ + return _action; +} diff --git a/src/qtmenuitem.h b/src/qtmenuitem.h new file mode 100644 index 00000000..4d2970c9 --- /dev/null +++ b/src/qtmenuitem.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTMENUITEM_H +#define QTMENUITEM_H + +#include <QtCore/QObject> +#include <QtWidgets/QAction> +#include <QtCore/QUrl> + +#if QT_VERSION >= 0x050000 +#include <QtQuick/QQuickItem> +#endif + +#if QT_VERSION < 0x050000 +class QtMenuBase: public QObject { +#else +class QtMenuBase: public QQuickItem { +#endif +Q_OBJECT + Q_PROPERTY(QUrl iconSource READ iconSource WRITE setIconSource NOTIFY iconSourceChanged) + Q_PROPERTY(QString iconName READ iconName WRITE setIconName NOTIFY iconNameChanged) + +public: +#if QT_VERSION < 0x050000 + QtMenuBase(QObject *parent = 0) : QObject(parent) {} +#else + QtMenuBase(QQuickItem *parent = 0) : QQuickItem(parent) {} +#endif + virtual QAction* action() = 0; + + void setIconSource(const QUrl &icon); + QUrl iconSource() const; + + void setIconName(const QString &icon); + QString iconName() const; + +Q_SIGNALS: + void iconSourceChanged(); + void iconNameChanged(); + +private: + QUrl _iconSource; + QString _iconName; +}; + +class QtMenuSeparator : public QtMenuBase +{ + Q_OBJECT +public: +#if QT_VERSION < 0x050000 + QtMenuSeparator(QObject *parent = 0); +#else + QtMenuSeparator(QQuickItem *parent = 0); +#endif + ~QtMenuSeparator(); + QAction* action(); + +private: + QAction *_action; +}; + +class QtMenuItem: public QtMenuBase +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged); + Q_PROPERTY(QString shortcut READ shortcut WRITE setShortcut NOTIFY shortcutChanged) + Q_PROPERTY(bool checkable READ checkable WRITE setCheckable) + Q_PROPERTY(bool checked READ checked WRITE setChecked NOTIFY toggled) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + +public: +#if QT_VERSION < 0x050000 + QtMenuItem(QObject *parent = 0); +#else + QtMenuItem(QQuickItem *parent = 0); +#endif + ~QtMenuItem(); + + void setText(const QString &text); + void setShortcut(const QString &shortcut); + void setCheckable(bool checkable); + void setChecked(bool checked); + void setEnabled(bool enabled); + + QString text() const; + QString shortcut() const; + bool checkable() const; + bool checked() const; + bool enabled() const; + + QAction* action(); + +Q_SIGNALS: + void triggered(); + void textChanged(); + void shortcutChanged(); + void toggled(bool); + void enabledChanged(); + +private: + QAction *_action; +}; + +#endif //QTMENUITEM_H diff --git a/src/src.pro b/src/src.pro index b3336a2d..e2d6b226 100644 --- a/src/src.pro +++ b/src/src.pro @@ -10,12 +10,15 @@ DESTDIR = ../components/plugin OBJECTS_DIR = obj MOC_DIR = moc -HEADERS += qrangemodel_p.h \ +HEADERS += qtmenu.h \ + qtmenubar.h \ + qrangemodel_p.h \ qrangemodel.h \ qstyleplugin.h \ qdeclarativefolderlistmodel.h \ qstyleitem.h \ qwheelarea.h \ + qtmenuitem.h \ qwindowitem.h \ qdesktopitem.h \ qtoplevelwindow.h \ @@ -23,11 +26,14 @@ HEADERS += qrangemodel_p.h \ qtooltiparea.h \ qtsplitterbase.h -SOURCES += qrangemodel.cpp \ +SOURCES += qtmenu.cpp \ + qtmenubar.cpp \ + qrangemodel.cpp \ qstyleplugin.cpp \ qdeclarativefolderlistmodel.cpp \ qstyleitem.cpp \ qwheelarea.cpp \ + qtmenuitem.cpp \ qwindowitem.cpp \ qdesktopitem.cpp \ qtoplevelwindow.cpp \ |