Revision control
Copy as Markdown
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qquicklabsplatformmenuitemgroup_p.h"
#include "qquicklabsplatformmenuitem_p.h"
QT_BEGIN_NAMESPACE
/*!
\qmltype MenuItemGroup
\inherits QtObject
//! \nativetype QQuickLabsPlatformMenuItemGroup
\inqmlmodule Qt.labs.platform
\since 5.8
\brief A group for managing native menu items.
The MenuItemGroup groups native menu items together.
MenuItemGroup is exclusive by default. In an exclusive menu item
group, only one item can be checked at any time; checking another
item automatically unchecks the previously checked one. MenuItemGroup
can be configured as non-exclusive, which is particularly useful for
showing, hiding, enabling and disabling items together as a group.
The most straight-forward way to use MenuItemGroup is to assign
a list of items.
\code
Menu {
id: verticalMenu
title: qsTr("Vertical")
MenuItemGroup {
id: verticalGroup
items: verticalMenu.items
}
MenuItem { text: qsTr("Top"); checkable: true }
MenuItem { text: qsTr("Center"); checked: true }
MenuItem { text: qsTr("Bottom"); checkable: true }
}
\endcode
The same menu may sometimes contain items that should not be included
in the same exclusive group. Such cases are best handled using the
\l {MenuItem::group}{group} property.
\code
Menu {
id: horizontalMenu
title: qsTr("Horizontal")
MenuItemGroup {
id: horizontalGroup
}
MenuItem {
checked: true
text: qsTr("Left")
group: horizontalGroup
}
MenuItem {
checkable: true
text: qsTr("Center")
group: horizontalGroup
}
MenuItem {
text: qsTr("Right")
checkable: true
group: horizontalGroup
}
MenuItem { separator: true }
MenuItem { text: qsTr("Justify"); checkable: true }
MenuItem { text: qsTr("Absolute"); checkable: true }
}
\endcode
More advanced use cases can be handled using the addItem() and
removeItem() methods.
\labs
\sa MenuItem
*/
/*!
\qmlsignal Qt.labs.platform::MenuItemGroup::triggered(MenuItem item)
This signal is emitted when an \a item in the group is triggered by the user.
\sa MenuItem::triggered()
*/
/*!
\qmlsignal Qt.labs.platform::MenuItemGroup::hovered(MenuItem item)
This signal is emitted when an \a item in the group is hovered by the user.
\sa MenuItem::hovered()
*/
QQuickLabsPlatformMenuItemGroup::QQuickLabsPlatformMenuItemGroup(QObject *parent)
: QObject(parent), m_enabled(true), m_visible(true), m_exclusive(true), m_checkedItem(nullptr)
{
}
QQuickLabsPlatformMenuItemGroup::~QQuickLabsPlatformMenuItemGroup()
{
clear();
}
/*!
\qmlproperty bool Qt.labs.platform::MenuItemGroup::enabled
This property holds whether the group is enabled. The default value is \c true.
The enabled state of the group affects the enabled state of each item in the group,
except that explicitly disabled items are not enabled even if the group is enabled.
*/
bool QQuickLabsPlatformMenuItemGroup::isEnabled() const
{
return m_enabled;
}
void QQuickLabsPlatformMenuItemGroup::setEnabled(bool enabled)
{
if (m_enabled == enabled)
return;
m_enabled = enabled;
emit enabledChanged();
for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
if (item->m_enabled) {
item->sync();
emit item->enabledChanged();
}
}
}
/*!
\qmlproperty bool Qt.labs.platform::MenuItemGroup::visible
This property holds whether the group is visible. The default value is \c true.
The visibility of the group affects the visibility of each item in the group,
except that explicitly hidden items are not visible even if the group is visible.
*/
bool QQuickLabsPlatformMenuItemGroup::isVisible() const
{
return m_visible;
}
void QQuickLabsPlatformMenuItemGroup::setVisible(bool visible)
{
if (m_visible == visible)
return;
m_visible = visible;
emit visibleChanged();
for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
if (item->m_visible) {
item->sync();
emit item->visibleChanged();
}
}
}
/*!
\qmlproperty bool Qt.labs.platform::MenuItemGroup::exclusive
This property holds whether the group is exclusive. The default value is \c true.
In an exclusive menu item group, only one item can be checked at any time;
checking another item automatically unchecks the previously checked one.
*/
bool QQuickLabsPlatformMenuItemGroup::isExclusive() const
{
return m_exclusive;
}
void QQuickLabsPlatformMenuItemGroup::setExclusive(bool exclusive)
{
if (m_exclusive == exclusive)
return;
m_exclusive = exclusive;
emit exclusiveChanged();
for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items))
item->sync();
}
/*!
\qmlproperty MenuItem Qt.labs.platform::MenuItemGroup::checkedItem
This property holds the currently checked item in the group, or \c null if no item is checked.
*/
QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenuItemGroup::checkedItem() const
{
return m_checkedItem;
}
void QQuickLabsPlatformMenuItemGroup::setCheckedItem(QQuickLabsPlatformMenuItem *item)
{
if (m_checkedItem == item)
return;
if (m_checkedItem)
m_checkedItem->setChecked(false);
m_checkedItem = item;
emit checkedItemChanged();
if (item)
item->setChecked(true);
}
/*!
\qmlproperty list<MenuItem> Qt.labs.platform::MenuItemGroup::items
This property holds the list of items in the group.
*/
QQmlListProperty<QQuickLabsPlatformMenuItem> QQuickLabsPlatformMenuItemGroup::items()
{
return QQmlListProperty<QQuickLabsPlatformMenuItem>(this, nullptr, items_append, items_count, items_at, items_clear);
}
/*!
\qmlmethod void Qt.labs.platform::MenuItemGroup::addItem(MenuItem item)
Adds an \a item to the group.
*/
void QQuickLabsPlatformMenuItemGroup::addItem(QQuickLabsPlatformMenuItem *item)
{
if (!item || m_items.contains(item))
return;
m_items.append(item);
item->setGroup(this);
connect(item, &QQuickLabsPlatformMenuItem::checkedChanged, this, &QQuickLabsPlatformMenuItemGroup::updateCurrent);
connect(item, &QQuickLabsPlatformMenuItem::triggered, this, &QQuickLabsPlatformMenuItemGroup::activateItem);
connect(item, &QQuickLabsPlatformMenuItem::hovered, this, &QQuickLabsPlatformMenuItemGroup::hoverItem);
if (m_exclusive && item->isChecked())
setCheckedItem(item);
emit itemsChanged();
}
/*!
\qmlmethod void Qt.labs.platform::MenuItemGroup::removeItem(MenuItem item)
Removes an \a item from the group.
*/
void QQuickLabsPlatformMenuItemGroup::removeItem(QQuickLabsPlatformMenuItem *item)
{
if (!item || !m_items.contains(item))
return;
m_items.removeOne(item);
item->setGroup(nullptr);
disconnect(item, &QQuickLabsPlatformMenuItem::checkedChanged, this, &QQuickLabsPlatformMenuItemGroup::updateCurrent);
disconnect(item, &QQuickLabsPlatformMenuItem::triggered, this, &QQuickLabsPlatformMenuItemGroup::activateItem);
disconnect(item, &QQuickLabsPlatformMenuItem::hovered, this, &QQuickLabsPlatformMenuItemGroup::hoverItem);
if (m_checkedItem == item)
setCheckedItem(nullptr);
emit itemsChanged();
}
/*!
\qmlmethod void Qt.labs.platform::MenuItemGroup::clear()
Removes all items from the group.
*/
void QQuickLabsPlatformMenuItemGroup::clear()
{
if (m_items.isEmpty())
return;
for (QQuickLabsPlatformMenuItem *item : std::as_const(m_items)) {
item->setGroup(nullptr);
disconnect(item, &QQuickLabsPlatformMenuItem::checkedChanged, this, &QQuickLabsPlatformMenuItemGroup::updateCurrent);
disconnect(item, &QQuickLabsPlatformMenuItem::triggered, this, &QQuickLabsPlatformMenuItemGroup::activateItem);
disconnect(item, &QQuickLabsPlatformMenuItem::hovered, this, &QQuickLabsPlatformMenuItemGroup::hoverItem);
}
setCheckedItem(nullptr);
m_items.clear();
emit itemsChanged();
}
QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenuItemGroup::findCurrent() const
{
for (QQuickLabsPlatformMenuItem *item : m_items) {
if (item->isChecked())
return item;
}
return nullptr;
}
void QQuickLabsPlatformMenuItemGroup::updateCurrent()
{
if (!m_exclusive)
return;
QQuickLabsPlatformMenuItem *item = qobject_cast<QQuickLabsPlatformMenuItem*>(sender());
if (item && item->isChecked())
setCheckedItem(item);
}
void QQuickLabsPlatformMenuItemGroup::activateItem()
{
QQuickLabsPlatformMenuItem *item = qobject_cast<QQuickLabsPlatformMenuItem*>(sender());
if (item)
emit triggered(item);
}
void QQuickLabsPlatformMenuItemGroup::hoverItem()
{
QQuickLabsPlatformMenuItem *item = qobject_cast<QQuickLabsPlatformMenuItem*>(sender());
if (item)
emit hovered(item);
}
void QQuickLabsPlatformMenuItemGroup::items_append(QQmlListProperty<QQuickLabsPlatformMenuItem> *prop, QQuickLabsPlatformMenuItem *item)
{
QQuickLabsPlatformMenuItemGroup *group = static_cast<QQuickLabsPlatformMenuItemGroup *>(prop->object);
group->addItem(item);
}
qsizetype QQuickLabsPlatformMenuItemGroup::items_count(QQmlListProperty<QQuickLabsPlatformMenuItem> *prop)
{
QQuickLabsPlatformMenuItemGroup *group = static_cast<QQuickLabsPlatformMenuItemGroup *>(prop->object);
return group->m_items.size();
}
QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenuItemGroup::items_at(QQmlListProperty<QQuickLabsPlatformMenuItem> *prop, qsizetype index)
{
QQuickLabsPlatformMenuItemGroup *group = static_cast<QQuickLabsPlatformMenuItemGroup *>(prop->object);
return group->m_items.value(index);
}
void QQuickLabsPlatformMenuItemGroup::items_clear(QQmlListProperty<QQuickLabsPlatformMenuItem> *prop)
{
QQuickLabsPlatformMenuItemGroup *group = static_cast<QQuickLabsPlatformMenuItemGroup *>(prop->object);
group->clear();
}
QT_END_NAMESPACE
#include "moc_qquicklabsplatformmenuitemgroup_p.cpp"