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 Set a submenu under this menu item.
52*/
53void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu)
54{
55 if (m_subMenu)
56 static_cast<QDBusPlatformMenu *>(m_subMenu)->setContainingMenuItem(nullptr);
57 m_subMenu = menu;
58 if (menu)
59 static_cast<QDBusPlatformMenu *>(menu)->setContainingMenuItem(this);
60}
61
63{
64 m_isEnabled = enabled;
65}
66
67void QDBusPlatformMenuItem::setVisible(bool isVisible)
68{
69 m_isVisible = isVisible;
70}
71
73{
74 m_isSeparator = isSeparator;
75}
76
77void QDBusPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role)
78{
79 m_role = role;
80}
81
83{
84 m_isCheckable = checkable;
85}
86
87void QDBusPlatformMenuItem::setChecked(bool isChecked)
88{
89 m_isChecked = isChecked;
90}
91
92void QDBusPlatformMenuItem::setHasExclusiveGroup(bool hasExclusiveGroup)
93{
94 m_hasExclusiveGroup = hasExclusiveGroup;
95}
96
97#ifndef QT_NO_SHORTCUT
98void QDBusPlatformMenuItem::setShortcut(const QKeySequence &shortcut)
99{
100 m_shortcut = shortcut;
101}
102#endif
103
105{
106 emit activated();
107}
108
110{
111 // We need to check contains because otherwise QHash would insert
112 // a default-constructed nullptr value into menuItemsByID
113 if (menuItemsByID.contains(id))
114 return menuItemsByID[id];
115 return nullptr;
116}
117
118QList<const QDBusPlatformMenuItem *> QDBusPlatformMenuItem::byIds(const QList<int> &ids)
119{
120 QList<const QDBusPlatformMenuItem *> ret;
121 for (int id : ids) {
122 if (menuItemsByID.contains(id))
123 ret << menuItemsByID[id];
124 }
125 return ret;
126}
127
128
129QDBusPlatformMenu::QDBusPlatformMenu()
130 : m_isEnabled(true)
131 , m_isVisible(true)
132 , m_revision(1)
133 , m_containingMenuItem(nullptr)
134{
135}
136
138{
139 if (m_containingMenuItem)
140 m_containingMenuItem->setMenu(nullptr);
141}
142
143void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
144{
145 QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem);
146 QDBusPlatformMenuItem *beforeItem = static_cast<QDBusPlatformMenuItem *>(before);
147 int idx = m_items.indexOf(beforeItem);
148 qCDebug(qLcMenu) << item->dbusID() << item->text();
149 if (idx < 0)
150 m_items.append(item);
151 else
152 m_items.insert(idx, item);
153 m_itemsByTag.insert(item->tag(), item);
154 if (item->menu())
155 syncSubMenu(static_cast<const QDBusPlatformMenu *>(item->menu()));
157}
158
159void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
160{
161 QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem);
162 m_items.removeAll(item);
163 m_itemsByTag.remove(menuItem->tag());
164 if (item->menu()) {
165 // disconnect from the signals we connected to in syncSubMenu()
166 const QDBusPlatformMenu *menu = static_cast<const QDBusPlatformMenu *>(item->menu());
167 disconnect(menu, &QDBusPlatformMenu::propertiesUpdated,
169 disconnect(menu, &QDBusPlatformMenu::updated,
170 this, &QDBusPlatformMenu::updated);
171 disconnect(menu, &QDBusPlatformMenu::popupRequested,
172 this, &QDBusPlatformMenu::popupRequested);
173 }
175}
176
178{
179 // The adaptor is only connected to the propertiesUpdated signal of the top-level
180 // menu, so the submenus should transfer their signals to their parents.
181 connect(menu, &QDBusPlatformMenu::propertiesUpdated,
182 this, &QDBusPlatformMenu::propertiesUpdated, Qt::UniqueConnection);
183 connect(menu, &QDBusPlatformMenu::updated,
184 this, &QDBusPlatformMenu::updated, Qt::UniqueConnection);
185 connect(menu, &QDBusPlatformMenu::popupRequested,
186 this, &QDBusPlatformMenu::popupRequested, Qt::UniqueConnection);
187}
188
189void QDBusPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
190{
191 QDBusPlatformMenuItem *item = static_cast<QDBusPlatformMenuItem *>(menuItem);
192 // if a submenu was added to this item, we need to connect to its signals
193 if (item->menu())
194 syncSubMenu(static_cast<const QDBusPlatformMenu *>(item->menu()));
195 // TODO keep around copies of the QDBusMenuLayoutItems so they can be updated?
196 // or eliminate them by putting dbus streaming operators in this class instead?
197 // or somehow tell the dbusmenu client that something has changed, so it will ask for properties again
198 QDBusMenuItemList updated;
199 QDBusMenuItemKeysList removed;
200 updated << QDBusMenuItem(item);
201 qCDebug(qLcMenu) << updated;
202 emit propertiesUpdated(updated, removed);
203}
204
206{
207 if (m_containingMenuItem)
208 emit updated(++m_revision, m_containingMenuItem->dbusID());
209 else
210 emit updated(++m_revision, 0);
211}
212
213void QDBusPlatformMenu::setText(const QString &text)
214{
215 m_text = text;
216}
217
218void QDBusPlatformMenu::setIcon(const QIcon &icon)
219{
220 m_icon = icon;
221}
222
223void QDBusPlatformMenu::setEnabled(bool enabled)
224{
225 m_isEnabled = enabled;
226}
227
228void QDBusPlatformMenu::setVisible(bool isVisible)
229{
230 m_isVisible = isVisible;
231}
232
234{
235 m_containingMenuItem = item;
236}
237
238void QDBusPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
239{
240 Q_UNUSED(parentWindow);
241 Q_UNUSED(targetRect);
242 Q_UNUSED(item);
243 setVisible(true);
244 emit popupRequested(m_containingMenuItem->dbusID(), QDateTime::currentMSecsSinceEpoch());
245}
246
248{
249 return m_items.value(position);
250}
251
253{
254 return m_itemsByTag[tag];
255}
256
258{
259 return m_items;
260}
261
267
272
273QT_END_NAMESPACE
274
275#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
Set a submenu under this menu item.
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
QList< QDBusMenuItemKeys > QDBusMenuItemKeysList
QList< QDBusMenuItem > QDBusMenuItemList
QHash< int, QDBusPlatformMenuItem * > menuItemsByID