@@ -0,0 +1,141 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "applicationmenuregistry.h"
18+
19+#include <QQmlEngine>
20+#include <QDebug>
21+
22+Q_LOGGING_CATEGORY(UNITY_APPMENU, "unity.appmenu", QtDebugMsg)
23+
24+#define DEBUG_MSG qCDebug(UNITY_APPMENU).nospace().noquote() << "ApplicationMenuRegistry::" << __func__
25+#define WARNING_MSG qCWarning(UNITY_APPMENU).nospace().noquote() << "ApplicationMenuRegistry::" << __func__
26+
27+ApplicationMenuRegistry::ApplicationMenuRegistry(QObject *parent)
28+ : QObject(parent)
29+{
30+}
31+
32+ApplicationMenuRegistry::~ApplicationMenuRegistry()
33+{
34+ qDeleteAll(m_appMenus);
35+ m_appMenus.clear();
36+
37+ qDeleteAll(m_surfaceMenus);
38+ m_surfaceMenus.clear();
39+}
40+
41+void ApplicationMenuRegistry::RegisterAppMenu(pid_t processId,
42+ const QDBusObjectPath &menuObjectPath,
43+ const QDBusObjectPath &actionObjectPath,
44+ const QString &service)
45+{
46+ DEBUG_MSG << "(pid=" << processId
47+ << ", menuPath=" << menuObjectPath.path()
48+ << ", actionPath=" << actionObjectPath.path()
49+ << ", service=" << service;
50+
51+ auto i = m_appMenus.find(processId);
52+ while (i != m_appMenus.end() && i.key() == processId) {
53+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
54+ WARNING_MSG << "Already have a menu for application (pid= " << processId
55+ << ", service=" << service
56+ << ", menuPath=" << menuObjectPath.path() << ")";
57+ return;
58+ }
59+ ++i;
60+ }
61+
62+ auto menu = new MenuServicePath(service, menuObjectPath, actionObjectPath);
63+ QQmlEngine::setObjectOwnership(menu, QQmlEngine::CppOwnership);
64+
65+ m_appMenus.insert(processId, menu);
66+ Q_EMIT appMenuRegistered(processId);
67+}
68+
69+void ApplicationMenuRegistry::UnregisterAppMenu(pid_t processId, const QDBusObjectPath &menuObjectPath)
70+{
71+ DEBUG_MSG << "(pid=" << processId
72+ << ", menuPath=" << menuObjectPath.path();
73+
74+ auto i = m_appMenus.find(processId);
75+ while (i != m_appMenus.end() && i.key() == processId) {
76+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
77+ i.value()->deleteLater();
78+ m_appMenus.erase(i);
79+ Q_EMIT appMenuUnregistered(processId);
80+ break;
81+ }
82+ ++i;
83+ }
84+}
85+
86+void ApplicationMenuRegistry::RegisterSurfaceMenu(const QString &surfaceId,
87+ const QDBusObjectPath &menuObjectPath,
88+ const QDBusObjectPath &actionObjectPath,
89+ const QString &service)
90+{
91+ DEBUG_MSG << "(surfaceId=" << surfaceId
92+ << ", menuPath=" << menuObjectPath.path()
93+ << ", actionPath=" << actionObjectPath.path()
94+ << ", service=" << service;
95+
96+ auto i = m_surfaceMenus.find(surfaceId);
97+ while (i != m_surfaceMenus.end() && i.key() == surfaceId) {
98+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
99+ WARNING_MSG << "Already have a menu for surface (surfaceId= " << surfaceId
100+ << ", service=" << service
101+ << ", menuPath=" << menuObjectPath.path() << ")";
102+ return;
103+ }
104+ ++i;
105+ }
106+
107+ auto menu = new MenuServicePath(service, menuObjectPath, actionObjectPath);
108+ QQmlEngine::setObjectOwnership(menu, QQmlEngine::CppOwnership);
109+
110+ m_surfaceMenus.insert(surfaceId, menu);
111+ Q_EMIT surfaceMenuRegistered(surfaceId);
112+}
113+
114+void ApplicationMenuRegistry::UnregisterSurfaceMenu(const QString &surfaceId, const QDBusObjectPath &menuObjectPath)
115+{
116+ DEBUG_MSG << "(surfaceId=" << surfaceId
117+ << ", menuPath=" << menuObjectPath.path();
118+
119+ auto i = m_surfaceMenus.find(surfaceId);
120+ while (i != m_surfaceMenus.end() && i.key() == surfaceId) {
121+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
122+ i.value()->deleteLater();
123+ m_surfaceMenus.erase(i);
124+ Q_EMIT surfaceMenuUnregistered(surfaceId);
125+ break;
126+ }
127+ ++i;
128+ }
129+}
130+
131+QList<QObject*> ApplicationMenuRegistry::getMenusForSurface(const QString &surfaceId) const
132+{
133+ QList<QObject*> list;
134+
135+ auto i = m_surfaceMenus.find(surfaceId);
136+ while (i != m_surfaceMenus.constEnd() && i.key() == surfaceId) {
137+ list << i.value();
138+ ++i;
139+ }
140+ return list;
141+}