Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdbusplatformmenu.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QDateTime>
8#include <QDebug>
9#include <QWindow>
10
12
13Q_LOGGING_CATEGORY(qLcMenu, "qt.qpa.menu")
14
15static int nextDBusID = 1;
17
18QDBusPlatformMenuItem::QDBusPlatformMenuItem()
19 : m_subMenu(nullptr)
20 , m_role(NoRole)
21 , m_isEnabled(true)
22 , m_isVisible(true)
23 , m_isSeparator(false)
24 , m_isCheckable(false)
25 , m_isChecked(false)
26 , m_hasExclusiveGroup(false)
27 , m_dbusID(nextDBusID++)
28{
29 menuItemsByID.insert(m_dbusID, this);
30}
31
33{
34 menuItemsByID.remove(m_dbusID);
35 if (m_subMenu)
36 static_cast<QDBusPlatformMenu *>(m_subMenu)->setContainingMenuItem(nullptr);
37}
38
39void QDBusPlatformMenuItem::setText(const QString &text)
40{
41 qCDebug(qLcMenu) << m_dbusID << text;
42 m_text = text;
43}
44
45void QDBusPlatformMenuItem::setIcon(const QIcon &icon)
46{
47 m_icon = icon;
48}
49
50/*!
51 \internal
52 Set a submenu under this menu item.
53*/
54void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu)
55{
56 if (m_subMenu)
57 static_cast<QDBusPlatformMenu *>(m_subMenu)->setContainingMenuItem(nullptr);
58 m_subMenu = menu;
59 if (menu)
60 static_cast<QDBusPlatformMenu *>(menu)->setContainingMenuItem(this);
61}
62
64{
65 m_isEnabled = enabled;
66}
67
68void QDBusPlatformMenuItem::setVisible(bool isVisible)
69{
70 m_isVisible = isVisible;
71}
72
74{
75 m_isSeparator = isSeparator;
76}
77
78void QDBusPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role)
79{
80 m_role = role;
81}
82
84{
85 m_isCheckable = checkable;
86}
87
88void QDBusPlatformMenuItem::setChecked(bool isChecked)
89{
90 m_isChecked = isChecked;
91}
92
93void QDBusPlatformMenuItem::setHasExclusiveGroup(bool hasExclusiveGroup)
94{
95 m_hasExclusiveGroup = hasExclusiveGroup;
96}
97
98#ifndef QT_NO_SHORTCUT
99void QDBusPlatformMenuItem::setShortcut(const QKeySequence &shortcut)
100{
101 m_shortcut = shortcut;
102}
103#endif
104
106{
107 emit activated();
108}
109
111{
112 // We need to check contains because otherwise QHash would insert
113 // a default-constructed nullptr value into menuItemsByID
114 if (menuItemsByID.contains(id))
115 return menuItemsByID[id];
116 return nullptr;
117}
118
119QList<const QDBusPlatformMenuItem *> QDBusPlatformMenuItem::byIds(const QList<int> &ids)
120{
121 QList<const QDBusPlatformMenuItem *> ret;
122 for (int id : ids) {
123 if (menuItemsByID.contains(id))
124 ret << menuItemsByID[id];
125 }
126 return ret;
127}
128
129
130QDBusPlatformMenu::QDBusPlatformMenu()
131 : m_isEnabled(true)
132 , m_isVisible(true)
133 , m_revision(1)
134 , m_containingMenuItem(nullptr)
135{
136}
137
139{
140 if (m_containingMenuItem)
141 m_containingMenuItem->setMenu(nullptr);
142}
143
144void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
145{
146 QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem);
147 QDBusPlatformMenuItem *beforeItem = static_cast<QDBusPlatformMenuItem *>(before);
148 int idx = m_items.indexOf(beforeItem);
149 qCDebug(qLcMenu) << item->dbusID() << item->text();
150 if (idx < 0)
151 m_items.append(item);
152 else
153 m_items.insert(idx, item);
154 m_itemsByTag.insert(item->tag(), item);
155 if (item->menu())
156 syncSubMenu(static_cast<const QDBusPlatformMenu *>(item->menu()));
158}
159
160void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
161{
162 QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem);
163 m_items.removeAll(item);
164 m_itemsByTag.remove(menuItem->tag());
165 if (item->menu()) {
166 // disconnect from the signals we connected to in syncSubMenu()
167 const QDBusPlatformMenu *menu = static_cast<const QDBusPlatformMenu *>(item->menu());
168 disconnect(menu, &QDBusPlatformMenu::propertiesUpdated,
170 disconnect(menu, &QDBusPlatformMenu::updated,
171 this, &QDBusPlatformMenu::updated);
172 disconnect(menu, &QDBusPlatformMenu::popupRequested,
173 this, &QDBusPlatformMenu::popupRequested);
174 }
176}
177
179{
180 // The adaptor is only connected to the propertiesUpdated signal of the top-level
181 // menu, so the submenus should transfer their signals to their parents.
183 this, &QDBusPlatformMenu::propertiesUpdated, Qt::UniqueConnection);
184 connect(menu, &QDBusPlatformMenu::updated,
185 this, &QDBusPlatformMenu::updated, Qt::UniqueConnection);
186 connect(menu, &QDBusPlatformMenu::popupRequested,
187 this, &QDBusPlatformMenu::popupRequested, Qt::UniqueConnection);
188}
189
190void QDBusPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
191{
192 QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem);
193 // if a submenu was added to this item, we need to connect to its signals
194 if (item->menu())
195 syncSubMenu(static_cast<const QDBusPlatformMenu *>(item->menu()));
196 // TODO keep around copies of the QDBusMenuLayoutItems so they can be updated?
197 // or eliminate them by putting dbus streaming operators in this class instead?
198 // or somehow tell the dbusmenu client that something has changed, so it will ask for properties again
199 QDBusMenuItemList updated;
200 QDBusMenuItemKeysList removed;
201 updated << QDBusMenuItem(item);
202 qCDebug(qLcMenu) << updated;
203 emit propertiesUpdated(updated, removed);
204}
205
207{
208 if (m_containingMenuItem)
209 emit updated(++m_revision, m_containingMenuItem->dbusID());
210 else
211 emit updated(++m_revision, 0);
212}
213
214void QDBusPlatformMenu::setText(const QString &text)
215{
216 m_text = text;
217}
218
219void QDBusPlatformMenu::setIcon(const QIcon &icon)
220{
221 m_icon = icon;
222}
223
224void QDBusPlatformMenu::setEnabled(bool enabled)
225{
226 m_isEnabled = enabled;
227}
228
229void QDBusPlatformMenu::setVisible(bool isVisible)
230{
231 m_isVisible = isVisible;
232}
233
235{
236 m_containingMenuItem = item;
237}
238
239void QDBusPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
240{
241 Q_UNUSED(parentWindow);
242 Q_UNUSED(targetRect);
243 Q_UNUSED(item);
244 setVisible(true);
245 emit popupRequested(m_containingMenuItem->dbusID(), QDateTime::currentMSecsSinceEpoch());
246}
247
249{
250 return m_items.value(position);
251}
252
254{
255 return m_itemsByTag[tag];
256}
257
259{
260 return m_items;
261}
262
268
273
274QT_END_NAMESPACE
275
276#include "moc_qdbusplatformmenu_p.cpp"
QDBusMenuItem(const QDBusPlatformMenuItem *item)
void setText(const QString &text) override
void setIsSeparator(bool isSeparator) override
static QDBusPlatformMenuItem * byId(int id)
void setHasExclusiveGroup(bool hasExclusiveGroup) override
void setRole(MenuRole role) override
void setEnabled(bool enabled) override
void setChecked(bool isChecked) override
void setVisible(bool isVisible) override
void setCheckable(bool checkable) override
void setIcon(const QIcon &icon) override
void setMenu(QPlatformMenu *menu) override
void setIcon(const QIcon &icon) override
void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) override
QPlatformMenuItem * menuItemForTag(quintptr tag) const override
QPlatformMenu * createSubMenu() const override
void setEnabled(bool enabled) override
void removeMenuItem(QPlatformMenuItem *menuItem) override
void setText(const QString &text) override
const QList< QDBusPlatformMenuItem * > items() const
void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) override
void setContainingMenuItem(QDBusPlatformMenuItem *item)
QPlatformMenuItem * menuItemAt(int position) const override
void setVisible(bool visible) override
void propertiesUpdated(QDBusMenuItemList updatedProps, QDBusMenuItemKeysList removedProps)
void syncSubMenu(const QDBusPlatformMenu *menu)
void syncMenuItem(QPlatformMenuItem *menuItem) override
QPlatformMenuItem * createMenuItem() const override
Combined button and popup list for selecting options.
QList< QDBusMenuItemKeys > QDBusMenuItemKeysList
QList< QDBusMenuItem > QDBusMenuItemList
QHash< int, QDBusPlatformMenuItem * > menuItemsByID