1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Labs Templates module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qquickplatformmenuitemgroup_p.h"
38#include "qquickplatformmenuitem_p.h"
39
40QT_BEGIN_NAMESPACE
41
42/*!
43 \qmltype MenuItemGroup
44 \inherits QtObject
45//! \instantiates QQuickPlatformMenuItemGroup
46 \inqmlmodule Qt.labs.platform
47 \since 5.8
48 \brief A group for managing native menu items.
49
50 The MenuItemGroup groups native menu items together.
51
52 MenuItemGroup is exclusive by default. In an exclusive menu item
53 group, only one item can be checked at any time; checking another
54 item automatically unchecks the previously checked one. MenuItemGroup
55 can be configured as non-exclusive, which is particularly useful for
56 showing, hiding, enabling and disabling items together as a group.
57
58 The most straight-forward way to use MenuItemGroup is to assign
59 a list of items.
60
61 \code
62 Menu {
63 id: verticalMenu
64 title: qsTr("Vertical")
65
66 MenuItemGroup {
67 id: verticalGroup
68 items: verticalMenu.items
69 }
70
71 MenuItem { text: qsTr("Top"); checkable: true }
72 MenuItem { text: qsTr("Center"); checked: true }
73 MenuItem { text: qsTr("Bottom"); checkable: true }
74 }
75 \endcode
76
77 The same menu may sometimes contain items that should not be included
78 in the same exclusive group. Such cases are best handled using the
79 \l {MenuItem::group}{group} property.
80
81 \code
82 Menu {
83 id: horizontalMenu
84 title: qsTr("Horizontal")
85
86 MenuItemGroup {
87 id: horizontalGroup
88 }
89
90 MenuItem {
91 checked: true
92 text: qsTr("Left")
93 group: horizontalGroup
94 }
95 MenuItem {
96 checkable: true
97 text: qsTr("Center")
98 group: horizontalGroup
99 }
100 MenuItem {
101 text: qsTr("Right")
102 checkable: true
103 group: horizontalGroup
104 }
105
106 MenuItem { separator: true }
107 MenuItem { text: qsTr("Justify"); checkable: true }
108 MenuItem { text: qsTr("Absolute"); checkable: true }
109 }
110 \endcode
111
112 More advanced use cases can be handled using the addItem() and
113 removeItem() methods.
114
115 \labs
116
117 \sa MenuItem
118*/
119
120/*!
121 \qmlsignal Qt.labs.platform::MenuItemGroup::triggered(MenuItem item)
122
123 This signal is emitted when an \a item in the group is triggered by the user.
124
125 \sa MenuItem::triggered()
126*/
127
128/*!
129 \qmlsignal Qt.labs.platform::MenuItemGroup::hovered(MenuItem item)
130
131 This signal is emitted when an \a item in the group is hovered by the user.
132
133 \sa MenuItem::hovered()
134*/
135
136QQuickPlatformMenuItemGroup::QQuickPlatformMenuItemGroup(QObject *parent)
137 : QObject(parent), m_enabled(true), m_visible(true), m_exclusive(true), m_checkedItem(nullptr)
138{
139}
140
141QQuickPlatformMenuItemGroup::~QQuickPlatformMenuItemGroup()
142{
143 clear();
144}
145
146/*!
147 \qmlproperty bool Qt.labs.platform::MenuItemGroup::enabled
148
149 This property holds whether the group is enabled. The default value is \c true.
150
151 The enabled state of the group affects the enabled state of each item in the group,
152 except that explicitly disabled items are not enabled even if the group is enabled.
153*/
154bool QQuickPlatformMenuItemGroup::isEnabled() const
155{
156 return m_enabled;
157}
158
159void QQuickPlatformMenuItemGroup::setEnabled(bool enabled)
160{
161 if (m_enabled == enabled)
162 return;
163
164 m_enabled = enabled;
165 emit enabledChanged();
166
167 for (QQuickPlatformMenuItem *item : qAsConst(t&: m_items)) {
168 if (item->m_enabled) {
169 item->sync();
170 emit item->enabledChanged();
171 }
172 }
173}
174
175/*!
176 \qmlproperty bool Qt.labs.platform::MenuItemGroup::visible
177
178 This property holds whether the group is visible. The default value is \c true.
179
180 The visibility of the group affects the visibility of each item in the group,
181 except that explicitly hidden items are not visible even if the group is visible.
182*/
183bool QQuickPlatformMenuItemGroup::isVisible() const
184{
185 return m_visible;
186}
187
188void QQuickPlatformMenuItemGroup::setVisible(bool visible)
189{
190 if (m_visible == visible)
191 return;
192
193 m_visible = visible;
194 emit visibleChanged();
195
196 for (QQuickPlatformMenuItem *item : qAsConst(t&: m_items)) {
197 if (item->m_visible) {
198 item->sync();
199 emit item->visibleChanged();
200 }
201 }
202}
203
204/*!
205 \qmlproperty bool Qt.labs.platform::MenuItemGroup::exclusive
206
207 This property holds whether the group is exclusive. The default value is \c true.
208
209 In an exclusive menu item group, only one item can be checked at any time;
210 checking another item automatically unchecks the previously checked one.
211*/
212bool QQuickPlatformMenuItemGroup::isExclusive() const
213{
214 return m_exclusive;
215}
216
217void QQuickPlatformMenuItemGroup::setExclusive(bool exclusive)
218{
219 if (m_exclusive == exclusive)
220 return;
221
222 m_exclusive = exclusive;
223 emit exclusiveChanged();
224
225 for (QQuickPlatformMenuItem *item : qAsConst(t&: m_items))
226 item->sync();
227}
228
229/*!
230 \qmlproperty MenuItem Qt.labs.platform::MenuItemGroup::checkedItem
231
232 This property holds the currently checked item in the group, or \c null if no item is checked.
233*/
234QQuickPlatformMenuItem *QQuickPlatformMenuItemGroup::checkedItem() const
235{
236 return m_checkedItem;
237}
238
239void QQuickPlatformMenuItemGroup::setCheckedItem(QQuickPlatformMenuItem *item)
240{
241 if (m_checkedItem == item)
242 return;
243
244 if (m_checkedItem)
245 m_checkedItem->setChecked(false);
246
247 m_checkedItem = item;
248 emit checkedItemChanged();
249
250 if (item)
251 item->setChecked(true);
252}
253
254/*!
255 \qmlproperty list<MenuItem> Qt.labs.platform::MenuItemGroup::items
256
257 This property holds the list of items in the group.
258*/
259QQmlListProperty<QQuickPlatformMenuItem> QQuickPlatformMenuItemGroup::items()
260{
261 return QQmlListProperty<QQuickPlatformMenuItem>(this, nullptr, items_append, items_count, items_at, items_clear);
262}
263
264/*!
265 \qmlmethod void Qt.labs.platform::MenuItemGroup::addItem(MenuItem item)
266
267 Adds an \a item to the group.
268*/
269void QQuickPlatformMenuItemGroup::addItem(QQuickPlatformMenuItem *item)
270{
271 if (!item || m_items.contains(t: item))
272 return;
273
274 m_items.append(t: item);
275 item->setGroup(this);
276
277 connect(sender: item, signal: &QQuickPlatformMenuItem::checkedChanged, receiver: this, slot: &QQuickPlatformMenuItemGroup::updateCurrent);
278 connect(sender: item, signal: &QQuickPlatformMenuItem::triggered, receiver: this, slot: &QQuickPlatformMenuItemGroup::activateItem);
279 connect(sender: item, signal: &QQuickPlatformMenuItem::hovered, receiver: this, slot: &QQuickPlatformMenuItemGroup::hoverItem);
280
281 if (m_exclusive && item->isChecked())
282 setCheckedItem(item);
283
284 emit itemsChanged();
285}
286
287/*!
288 \qmlmethod void Qt.labs.platform::MenuItemGroup::removeItem(MenuItem item)
289
290 Removes an \a item from the group.
291*/
292void QQuickPlatformMenuItemGroup::removeItem(QQuickPlatformMenuItem *item)
293{
294 if (!item || !m_items.contains(t: item))
295 return;
296
297 m_items.removeOne(t: item);
298 item->setGroup(nullptr);
299
300 disconnect(sender: item, signal: &QQuickPlatformMenuItem::checkedChanged, receiver: this, slot: &QQuickPlatformMenuItemGroup::updateCurrent);
301 disconnect(sender: item, signal: &QQuickPlatformMenuItem::triggered, receiver: this, slot: &QQuickPlatformMenuItemGroup::activateItem);
302 disconnect(sender: item, signal: &QQuickPlatformMenuItem::hovered, receiver: this, slot: &QQuickPlatformMenuItemGroup::hoverItem);
303
304 if (m_checkedItem == item)
305 setCheckedItem(nullptr);
306
307 emit itemsChanged();
308}
309
310/*!
311 \qmlmethod void Qt.labs.platform::MenuItemGroup::clear()
312
313 Removes all items from the group.
314*/
315void QQuickPlatformMenuItemGroup::clear()
316{
317 if (m_items.isEmpty())
318 return;
319
320 for (QQuickPlatformMenuItem *item : qAsConst(t&: m_items)) {
321 item->setGroup(nullptr);
322 disconnect(sender: item, signal: &QQuickPlatformMenuItem::checkedChanged, receiver: this, slot: &QQuickPlatformMenuItemGroup::updateCurrent);
323 disconnect(sender: item, signal: &QQuickPlatformMenuItem::triggered, receiver: this, slot: &QQuickPlatformMenuItemGroup::activateItem);
324 disconnect(sender: item, signal: &QQuickPlatformMenuItem::hovered, receiver: this, slot: &QQuickPlatformMenuItemGroup::hoverItem);
325 }
326
327 setCheckedItem(nullptr);
328
329 m_items.clear();
330 emit itemsChanged();
331}
332
333QQuickPlatformMenuItem *QQuickPlatformMenuItemGroup::findCurrent() const
334{
335 for (QQuickPlatformMenuItem *item : m_items) {
336 if (item->isChecked())
337 return item;
338 }
339 return nullptr;
340}
341
342void QQuickPlatformMenuItemGroup::updateCurrent()
343{
344 if (!m_exclusive)
345 return;
346
347 QQuickPlatformMenuItem *item = qobject_cast<QQuickPlatformMenuItem*>(object: sender());
348 if (item && item->isChecked())
349 setCheckedItem(item);
350}
351
352void QQuickPlatformMenuItemGroup::activateItem()
353{
354 QQuickPlatformMenuItem *item = qobject_cast<QQuickPlatformMenuItem*>(object: sender());
355 if (item)
356 emit triggered(item);
357}
358
359void QQuickPlatformMenuItemGroup::hoverItem()
360{
361 QQuickPlatformMenuItem *item = qobject_cast<QQuickPlatformMenuItem*>(object: sender());
362 if (item)
363 emit hovered(item);
364}
365
366void QQuickPlatformMenuItemGroup::items_append(QQmlListProperty<QQuickPlatformMenuItem> *prop, QQuickPlatformMenuItem *item)
367{
368 QQuickPlatformMenuItemGroup *group = static_cast<QQuickPlatformMenuItemGroup *>(prop->object);
369 group->addItem(item);
370}
371
372int QQuickPlatformMenuItemGroup::items_count(QQmlListProperty<QQuickPlatformMenuItem> *prop)
373{
374 QQuickPlatformMenuItemGroup *group = static_cast<QQuickPlatformMenuItemGroup *>(prop->object);
375 return group->m_items.count();
376}
377
378QQuickPlatformMenuItem *QQuickPlatformMenuItemGroup::items_at(QQmlListProperty<QQuickPlatformMenuItem> *prop, int index)
379{
380 QQuickPlatformMenuItemGroup *group = static_cast<QQuickPlatformMenuItemGroup *>(prop->object);
381 return group->m_items.value(i: index);
382}
383
384void QQuickPlatformMenuItemGroup::items_clear(QQmlListProperty<QQuickPlatformMenuItem> *prop)
385{
386 QQuickPlatformMenuItemGroup *group = static_cast<QQuickPlatformMenuItemGroup *>(prop->object);
387 group->clear();
388}
389
390QT_END_NAMESPACE
391

source code of qtquickcontrols2/src/imports/platform/qquickplatformmenuitemgroup.cpp