From 2b309cf52dfff7307a055b2662e7ce1a53d44bdb Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 12 Apr 2013 17:05:22 +0200 Subject: Rename QtMenuXxx to QQuickMenuXxx Change-Id: I89aa205686f0bdf2b267ad17a8ae0470c2f4751f Reviewed-by: Gabriel de Dietrich --- src/controls/qquickmenuitem.cpp | 607 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 607 insertions(+) create mode 100644 src/controls/qquickmenuitem.cpp (limited to 'src/controls/qquickmenuitem.cpp') diff --git a/src/controls/qquickmenuitem.cpp b/src/controls/qquickmenuitem.cpp new file mode 100644 index 00000000..f27c80d9 --- /dev/null +++ b/src/controls/qquickmenuitem.cpp @@ -0,0 +1,607 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmenuitem_p.h" +#include "qquickaction_p.h" +#include "qquickmenu_p.h" +#include "qquickmenuitemcontainer_p.h" + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QQuickMenuBase::QQuickMenuBase(QObject *parent) + : QObject(parent), m_visible(true), m_parentMenu(0), m_container(0), m_visualItem(0) +{ + m_platformItem = QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem(); +} + +QQuickMenuBase::~QQuickMenuBase() +{ + setParentMenu(0); + if (m_platformItem) { + delete m_platformItem; + m_platformItem = 0; + } +} + +void QQuickMenuBase::setVisible(bool v) +{ + if (v != m_visible) { + m_visible = v; + + if (m_platformItem) { + m_platformItem->setVisible(m_visible); + syncWithPlatformMenu(); + } + + emit visibleChanged(); + } +} + +QQuickMenu *QQuickMenuBase::parentMenu() const +{ + return m_parentMenu; +} + +void QQuickMenuBase::setParentMenu(QQuickMenu *parentMenu) +{ + if (m_parentMenu && m_parentMenu->platformMenu()) + m_parentMenu->platformMenu()->removeMenuItem(m_platformItem); + + m_parentMenu = parentMenu; +} + +QQuickMenuItemContainer *QQuickMenuBase::container() const +{ + return m_container; +} + +void QQuickMenuBase::setContainer(QQuickMenuItemContainer *c) +{ + m_container = c; +} + +void QQuickMenuBase::syncWithPlatformMenu() +{ + QQuickMenu *menu = parentMenu(); + if (menu && menu->platformMenu() && platformItem() + && menu->contains(this)) // If not, it'll be added later and then sync'ed + menu->platformMenu()->syncMenuItem(platformItem()); +} + +QQuickItem *QQuickMenuBase::visualItem() const +{ + return m_visualItem; +} + +void QQuickMenuBase::setVisualItem(QQuickItem *item) +{ + m_visualItem = item; +} + +/*! + \qmltype MenuSeparator + \instantiates QQuickMenuSeparator + \inqmlmodule QtQuick.Controls 1.0 + \ingroup menus + \brief MenuSeparator provides a separator for items inside a menu. + + \sa Menu, MenuItem +*/ + +/*! + \qmlproperty bool MenuSeparator::visible + + Whether the menu separator should be visible. +*/ + +/*! + \qmlproperty enumeration MenuSeparator::type + + This property is read-only and constant, and its value is \l MenuItemType.Separator. +*/ + +QQuickMenuSeparator::QQuickMenuSeparator(QObject *parent) + : QQuickMenuBase(parent) +{ + if (platformItem()) + platformItem()->setIsSeparator(true); +} + +QQuickMenuText::QQuickMenuText(QObject *parent) + : QQuickMenuBase(parent), m_action(new QQuickAction(this)) +{ + connect(m_action, SIGNAL(enabledChanged()), this, SLOT(updateEnabled())); + connect(m_action, SIGNAL(textChanged()), this, SLOT(updateText())); + connect(m_action, SIGNAL(iconNameChanged()), this, SLOT(updateIcon())); + connect(m_action, SIGNAL(iconNameChanged()), this, SIGNAL(iconNameChanged())); + connect(m_action, SIGNAL(iconSourceChanged()), this, SLOT(updateIcon())); + connect(m_action, SIGNAL(iconSourceChanged()), this, SIGNAL(iconSourceChanged())); +} + +QQuickMenuText::~QQuickMenuText() +{ + delete m_action; +} + +bool QQuickMenuText::enabled() const +{ + return action()->isEnabled(); +} + +void QQuickMenuText::setEnabled(bool e) +{ + action()->setEnabled(e); +} + +QString QQuickMenuText::text() const +{ + return m_action->text(); +} + +void QQuickMenuText::setText(const QString &t) +{ + m_action->setText(t); +} + +QUrl QQuickMenuText::iconSource() const +{ + return m_action->iconSource(); +} + +void QQuickMenuText::setIconSource(const QUrl &iconSource) +{ + m_action->setIconSource(iconSource); +} + +QString QQuickMenuText::iconName() const +{ + return m_action->iconName(); +} + +void QQuickMenuText::setIconName(const QString &iconName) +{ + m_action->setIconName(iconName); +} + +QIcon QQuickMenuText::icon() const +{ + return m_action->icon(); +} + +void QQuickMenuText::updateText() +{ + if (platformItem()) { + platformItem()->setText(text()); + syncWithPlatformMenu(); + } + emit __textChanged(); +} + +void QQuickMenuText::updateEnabled() +{ + if (platformItem()) { + platformItem()->setEnabled(enabled()); + syncWithPlatformMenu(); + } + emit enabledChanged(); +} + +void QQuickMenuText::updateIcon() +{ + if (platformItem()) { + platformItem()->setIcon(icon()); + syncWithPlatformMenu(); + } + emit __iconChanged(); +} + +/*! + \qmltype MenuItem + \instantiates QQuickMenuItem + \ingroup menus + \inqmlmodule QtQuick.Controls 1.0 + \brief MenuItem provides an item to add in a menu or a menu bar. + + \code + Menu { + text: "Edit" + + MenuItem { + text: "Cut" + shortcut: "Ctrl+X" + onTriggered: ... + } + + MenuItem { + text: "Copy" + shortcut: "Ctrl+C" + onTriggered: ... + } + + MenuItem { + text: "Paste" + shortcut: "Ctrl+V" + onTriggered: ... + } + } + \endcode + + \sa MenuBar, Menu, MenuSeparator, Action +*/ + +/*! + \qmlproperty bool MenuItem::visible + + Whether the menu item should be visible. Defaults to \c true. +*/ + +/*! + \qmlproperty enumeration MenuItem::type + + This property is read-only and constant, and its value is \l MenuItemType.Item. +*/ + +/*! + \qmlproperty string MenuItem::text + + Text for the menu item. Overrides the item's bound action \c text property. + + Mnemonics are supported by prefixing the shortcut letter with \&. + For instance, \c "\&Open" will bind the \c Alt-O shortcut to the + \c "Open" menu item. Note that not all platforms support mnemonics. + + Defaults to the empty string. + + \sa Action::text +*/ + +/*! + \qmlproperty bool MenuItem::enabled + + Whether the menu item is enabled, and responsive to user interaction. Defaults to \c true. +*/ + +/*! + \qmlproperty url MenuItem::iconSource + + Sets the icon file or resource url for the \l MenuItem icon. + Overrides the item's bound action \c iconSource property. Defaults to the empty URL. + + \sa iconName, Action::iconSource +*/ + +/*! + \qmlproperty string MenuItem::iconName + + Sets the icon name for the \l MenuItem icon. This will pick the icon + with the given name from the current theme. Overrides the item's bound + action \c iconName property. Defaults to the empty string. + + \sa iconSource, Action::iconName +*/ + +/*! \qmlsignal MenuItem::triggered() + + Emitted when either the menu item or its bound action have been activated. + + \sa trigger(), Action::triggered(), Action::toggled() +*/ + +/*! \qmlmethod MenuItem::trigger() + + Manually trigger a menu item. Will also trigger the item's bound action. + + \sa triggered(), Action::trigger() +*/ + +/*! + \qmlproperty string MenuItem::shortcut + + Shorcut bound to the menu item. Defaults to the empty string. + + \sa Action::shortcut +*/ + +/*! + \qmlproperty bool MenuItem::checkable + + Whether the menu item can be checked, or toggled. Defaults to \c false. + + \sa checked +*/ + +/*! + \qmlproperty bool MenuItem::checked + + If the menu item is checkable, this property reflects its checked state. Defaults to \c false. + + \sa checkable, Action::toggled() +*/ + +/*! \qmlproperty ExclusiveGroup MenuItem::exclusiveGroup + + If a menu item is checkable, an \l ExclusiveGroup can be attached to it. + All the menu items sharing the same exclusive group, and by extension, any \l Action sharing it, + become mutually exclusive selectable, meaning that only the last checked menu item will + actually be checked. + + Defaults to \c null, meaning no exclusive behavior is to be expected. + + \sa checked, checkable +*/ + +/*! \qmlsignal MenuItem::toggled(checked) + + Emitted whenever a menu item's \c checked property changes. + This usually happens at the same time as \l triggered(). + + \sa checked, triggered(), Action::triggered(), Action::toggled() +*/ + +/*! + \qmlproperty Action MenuItem::action + + The action bound to this menu item. It will provide values for all the properties of the menu item. + However, it is possible to override the action's \c text, \c iconSource, and \c iconName + properties by just assigning these properties, allowing some customization. + + In addition, the menu item \c triggered() and \c toggled() signals will not be emitted. + Instead, the action \c triggered() and \c toggled() signals will be. + + Defaults to \c null, meaning no action is bound to the menu item. +*/ + +QQuickMenuItem::QQuickMenuItem(QObject *parent) + : QQuickMenuText(parent), m_boundAction(0) +{ + connect(this, SIGNAL(__textChanged()), this, SIGNAL(textChanged())); + + connect(action(), SIGNAL(triggered()), this, SIGNAL(triggered())); + connect(action(), SIGNAL(toggled(bool)), this, SLOT(updateChecked())); + if (platformItem()) + connect(platformItem(), SIGNAL(activated()), this, SLOT(trigger())); +} + +QQuickMenuItem::~QQuickMenuItem() +{ + unbindFromAction(m_boundAction); + if (platformItem()) + disconnect(platformItem(), SIGNAL(activated()), this, SLOT(trigger())); +} + +void QQuickMenuItem::setParentMenu(QQuickMenu *parentMenu) +{ + QQuickMenuText::setParentMenu(parentMenu); + if (parentMenu) + connect(this, SIGNAL(triggered()), parentMenu, SLOT(updateSelectedIndex())); +} + +void QQuickMenuItem::bindToAction(QQuickAction *action) +{ + m_boundAction = action; + + connect(m_boundAction, SIGNAL(destroyed(QObject*)), this, SLOT(unbindFromAction(QObject*))); + + connect(m_boundAction, SIGNAL(triggered()), this, SIGNAL(triggered())); + connect(m_boundAction, SIGNAL(toggled(bool)), this, SLOT(updateChecked())); + connect(m_boundAction, SIGNAL(exclusiveGroupChanged()), this, SIGNAL(exclusiveGroupChanged())); + connect(m_boundAction, SIGNAL(enabledChanged()), this, SLOT(updateEnabled())); + connect(m_boundAction, SIGNAL(textChanged()), this, SLOT(updateText())); + connect(m_boundAction, SIGNAL(shortcutChanged(QString)), this, SLOT(updateShortcut())); + connect(m_boundAction, SIGNAL(checkableChanged()), this, SIGNAL(checkableChanged())); + connect(m_boundAction, SIGNAL(iconNameChanged()), this, SLOT(updateIcon())); + connect(m_boundAction, SIGNAL(iconNameChanged()), this, SIGNAL(iconNameChanged())); + connect(m_boundAction, SIGNAL(iconSourceChanged()), this, SLOT(updateIcon())); + connect(m_boundAction, SIGNAL(iconSourceChanged()), this, SIGNAL(iconSourceChanged())); + + if (m_boundAction->parent() != this) { + updateText(); + updateShortcut(); + updateEnabled(); + updateIcon(); + if (checkable()) + updateChecked(); + } +} + +void QQuickMenuItem::unbindFromAction(QObject *o) +{ + if (!o) + return; + + if (o == m_boundAction) + m_boundAction = 0; + + QQuickAction *action = qobject_cast(o); + if (!action) + return; + + disconnect(action, SIGNAL(destroyed(QObject*)), this, SLOT(unbindFromAction(QObject*))); + + disconnect(action, SIGNAL(triggered()), this, SIGNAL(triggered())); + disconnect(action, SIGNAL(toggled(bool)), this, SLOT(updateChecked())); + disconnect(action, SIGNAL(exclusiveGroupChanged()), this, SIGNAL(exclusiveGroupChanged())); + disconnect(action, SIGNAL(enabledChanged()), this, SLOT(updateEnabled())); + disconnect(action, SIGNAL(textChanged()), this, SLOT(updateText())); + disconnect(action, SIGNAL(shortcutChanged(QString)), this, SLOT(updateShortcut())); + disconnect(action, SIGNAL(checkableChanged()), this, SIGNAL(checkableChanged())); + disconnect(action, SIGNAL(iconNameChanged()), this, SLOT(updateIcon())); + disconnect(action, SIGNAL(iconNameChanged()), this, SIGNAL(iconNameChanged())); + disconnect(action, SIGNAL(iconSourceChanged()), this, SLOT(updateIcon())); + disconnect(action, SIGNAL(iconSourceChanged()), this, SIGNAL(iconSourceChanged())); +} + +QQuickAction *QQuickMenuItem::action() const +{ + if (m_boundAction) + return m_boundAction; + return QQuickMenuText::action(); +} + +void QQuickMenuItem::setBoundAction(QQuickAction *a) +{ + if (a == m_boundAction) + return; + + if (m_boundAction) { + if (m_boundAction->parent() == this) + delete m_boundAction; + else + unbindFromAction(m_boundAction); + } + + bindToAction(a); + emit actionChanged(); +} + +QString QQuickMenuItem::text() const +{ + QString ownText = QQuickMenuText::text(); + if (!ownText.isEmpty()) + return ownText; + return m_boundAction ? m_boundAction->text() : QString(); +} + +QUrl QQuickMenuItem::iconSource() const +{ + QUrl ownIconSource = QQuickMenuText::iconSource(); + if (!ownIconSource.isEmpty()) + return ownIconSource; + return m_boundAction ? m_boundAction->iconSource() : QUrl(); +} + +QString QQuickMenuItem::iconName() const +{ + QString ownIconName = QQuickMenuText::iconName(); + if (!ownIconName.isEmpty()) + return ownIconName; + return m_boundAction ? m_boundAction->iconName() : QString(); +} + +QIcon QQuickMenuItem::icon() const +{ + QIcon ownIcon = QQuickMenuText::icon(); + if (!ownIcon.isNull()) + return ownIcon; + return m_boundAction ? m_boundAction->icon() : QIcon(); +} + +QString QQuickMenuItem::shortcut() const +{ + return action()->shortcut(); +} + +void QQuickMenuItem::setShortcut(const QString &shortcut) +{ + if (!m_boundAction) + action()->setShortcut(shortcut); +} + +void QQuickMenuItem::updateShortcut() +{ + if (platformItem()) { + platformItem()->setShortcut(QKeySequence(shortcut())); + syncWithPlatformMenu(); + } + emit shortcutChanged(); +} + +bool QQuickMenuItem::checkable() const +{ + return action()->isCheckable(); +} + +void QQuickMenuItem::setCheckable(bool checkable) +{ + if (!m_boundAction) + action()->setCheckable(checkable); +} + +bool QQuickMenuItem::checked() const +{ + return action()->isChecked(); +} + +void QQuickMenuItem::setChecked(bool checked) +{ + if (!m_boundAction) + action()->setChecked(checked); +} + +void QQuickMenuItem::updateChecked() +{ + bool checked = this->checked(); + if (platformItem()) { + platformItem()->setChecked(checked); + syncWithPlatformMenu(); + } + + emit toggled(checked); +} + +QQuickExclusiveGroup *QQuickMenuItem::exclusiveGroup() const +{ + return action()->exclusiveGroup(); +} + +void QQuickMenuItem::setExclusiveGroup(QQuickExclusiveGroup *eg) +{ + if (!m_boundAction) + action()->setExclusiveGroup(eg); +} + +void QQuickMenuItem::setEnabled(bool enabled) +{ + if (!m_boundAction) + action()->setEnabled(enabled); +} + +void QQuickMenuItem::trigger() +{ + action()->trigger(); +} + +QT_END_NAMESPACE -- cgit v1.2.1