Changeset View
Changeset View
Standalone View
Standalone View
applets/systemtray/systemtraymodel.cpp
- This file was added.
1 | /*************************************************************************** | ||||
---|---|---|---|---|---|
2 | * Copyright (C) 2019 Konrad Materka <materka@gmail.com> * | ||||
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; either version 2 of the License, or * | ||||
7 | * (at your option) any later version. * | ||||
8 | * * | ||||
9 | * This program is distributed in the hope that it will be useful, * | ||||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||||
12 | * GNU General Public License for more details. * | ||||
13 | * * | ||||
14 | * You should have received a copy of the GNU General Public License * | ||||
15 | * along with this program; if not, write to the * | ||||
16 | * Free Software Foundation, Inc., * | ||||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * | ||||
18 | ***************************************************************************/ | ||||
19 | | ||||
20 | #include "systemtraymodel.h" | ||||
21 | #include "debug.h" | ||||
22 | | ||||
23 | #include <QQuickItem> | ||||
24 | | ||||
25 | #include <Plasma/Applet> | ||||
26 | #include <Plasma/DataContainer> | ||||
27 | #include <Plasma/Service> | ||||
28 | #include <PluginLoader> | ||||
29 | | ||||
30 | #include <KLocalizedString> | ||||
31 | | ||||
32 | PlasmoidModel::PlasmoidModel(QObject *parent) : QStandardItemModel(parent) | ||||
33 | { | ||||
34 | for (const auto &info : Plasma::PluginLoader::self()->listAppletMetaData(QString())) { | ||||
35 | if (!info.isValid() || info.value(QStringLiteral("X-Plasma-NotificationArea")) != "true") { | ||||
36 | continue; | ||||
37 | } | ||||
38 | | ||||
39 | QString name = info.name(); | ||||
40 | const QString dbusactivation = | ||||
41 | info.rawData().value(QStringLiteral("X-Plasma-DBusActivationService")).toString(); | ||||
42 | | ||||
43 | if (!dbusactivation.isEmpty()) { | ||||
44 | name += i18n(" (Automatic load)"); | ||||
45 | } | ||||
46 | QStandardItem *item = new QStandardItem(QIcon::fromTheme(info.iconName()), name); | ||||
47 | item->setData(info.pluginId(), static_cast<int>(BaseRole::ItemId)); | ||||
48 | item->setData("Plasmoid", static_cast<int>(BaseRole::ItemType)); | ||||
49 | item->setData(false, static_cast<int>(BaseRole::CanRender)); | ||||
50 | item->setData(false, static_cast<int>(Role::HasApplet)); | ||||
51 | appendRow(item); | ||||
52 | } | ||||
53 | sort(0); | ||||
54 | } | ||||
55 | | ||||
56 | QHash<int, QByteArray> PlasmoidModel::roleNames() const | ||||
57 | { | ||||
58 | QHash<int, QByteArray> roles = QStandardItemModel::roleNames(); | ||||
59 | | ||||
60 | roles.insert(static_cast<int>(BaseRole::ItemType), QByteArrayLiteral("itemType")); | ||||
61 | roles.insert(static_cast<int>(BaseRole::ItemId), QByteArrayLiteral("itemId")); | ||||
62 | roles.insert(static_cast<int>(BaseRole::CanRender), QByteArrayLiteral("canRender")); | ||||
63 | | ||||
64 | roles.insert(static_cast<int>(Role::Applet), QByteArrayLiteral("applet")); | ||||
65 | roles.insert(static_cast<int>(Role::HasApplet), QByteArrayLiteral("hasApplet")); | ||||
66 | | ||||
67 | return roles; | ||||
68 | } | ||||
69 | | ||||
70 | void PlasmoidModel::addApplet(Plasma::Applet *applet) | ||||
71 | { | ||||
72 | auto info = applet->pluginMetaData(); | ||||
73 | QStandardItem *dataItem = nullptr; | ||||
74 | for (int i = 0; i < rowCount(); i++) { | ||||
75 | QStandardItem *currentItem = item(i); | ||||
76 | if (currentItem->data(static_cast<int>(BaseRole::ItemId)) == info.pluginId()) { | ||||
77 | dataItem = currentItem; | ||||
78 | break; | ||||
79 | } | ||||
80 | } | ||||
81 | | ||||
82 | if (!dataItem) { | ||||
83 | dataItem = new QStandardItem(QIcon::fromTheme(info.iconName()), info.name()); | ||||
84 | appendRow(dataItem); | ||||
85 | } | ||||
86 | | ||||
87 | dataItem->setData(info.pluginId(), static_cast<int>(BaseRole::ItemId)); | ||||
88 | dataItem->setData(applet->property("_plasma_graphicObject"), static_cast<int>(Role::Applet)); | ||||
89 | dataItem->setData(true, static_cast<int>(Role::HasApplet)); | ||||
90 | dataItem->setData(true, static_cast<int>(BaseRole::CanRender)); | ||||
91 | } | ||||
92 | | ||||
93 | void PlasmoidModel::removeApplet(Plasma::Applet *applet) | ||||
94 | { | ||||
95 | int rows = rowCount(); | ||||
96 | for (int i = 0; i < rows; i++) { | ||||
97 | QStandardItem *currentItem = item(i); | ||||
98 | QVariant plugin = currentItem->data(static_cast<int>(BaseRole::ItemId)); | ||||
99 | if (plugin.isValid() && plugin.value<QString>() == applet->pluginMetaData().pluginId()) { | ||||
100 | currentItem->setData(false, static_cast<int>(BaseRole::CanRender)); | ||||
101 | currentItem->setData(QVariant(), static_cast<int>(Role::Applet)); | ||||
102 | currentItem->setData(false, static_cast<int>(Role::HasApplet)); | ||||
103 | return; | ||||
104 | } | ||||
105 | } | ||||
106 | } | ||||
107 | | ||||
108 | StatusNotifierModel::StatusNotifierModel(QObject *parent) : QStandardItemModel(parent) | ||||
109 | { | ||||
110 | m_dataEngine = dataEngine(QStringLiteral("statusnotifieritem")); | ||||
111 | | ||||
112 | connect(m_dataEngine, &Plasma::DataEngine::sourceAdded, this, &StatusNotifierModel::addSource); | ||||
113 | connect(m_dataEngine, &Plasma::DataEngine::sourceRemoved, this, &StatusNotifierModel::removeSource); | ||||
114 | | ||||
115 | m_dataEngine->connectAllSources(this); | ||||
116 | } | ||||
117 | | ||||
118 | QHash<int, QByteArray> StatusNotifierModel::roleNames() const | ||||
119 | { | ||||
120 | QHash<int, QByteArray> roles = QStandardItemModel::roleNames(); | ||||
121 | | ||||
122 | roles.insert(static_cast<int>(BaseRole::ItemType), QByteArrayLiteral("itemType")); | ||||
123 | roles.insert(static_cast<int>(BaseRole::ItemId), QByteArrayLiteral("itemId")); | ||||
124 | roles.insert(static_cast<int>(BaseRole::CanRender), QByteArrayLiteral("canRender")); | ||||
125 | | ||||
126 | roles.insert(static_cast<int>(Role::DataEngineSource), QByteArrayLiteral("DataEngineSource")); | ||||
127 | roles.insert(static_cast<int>(Role::AttentionIcon), QByteArrayLiteral("AttentionIcon")); | ||||
128 | roles.insert(static_cast<int>(Role::AttentionIconName), QByteArrayLiteral("AttentionIconName")); | ||||
129 | roles.insert(static_cast<int>(Role::AttentionMovieName), QByteArrayLiteral("AttentionMovieName")); | ||||
130 | roles.insert(static_cast<int>(Role::Category), QByteArrayLiteral("Category")); | ||||
131 | roles.insert(static_cast<int>(Role::Icon), QByteArrayLiteral("Icon")); | ||||
132 | roles.insert(static_cast<int>(Role::IconName), QByteArrayLiteral("IconName")); | ||||
133 | roles.insert(static_cast<int>(Role::IconThemePath), QByteArrayLiteral("IconThemePath")); | ||||
134 | roles.insert(static_cast<int>(Role::IconsChanged), QByteArrayLiteral("IconsChanged")); | ||||
135 | roles.insert(static_cast<int>(Role::Id), QByteArrayLiteral("Id")); | ||||
136 | roles.insert(static_cast<int>(Role::ItemIsMenu), QByteArrayLiteral("ItemIsMenu")); | ||||
137 | roles.insert(static_cast<int>(Role::OverlayIconName), QByteArrayLiteral("OverlayIconName")); | ||||
138 | roles.insert(static_cast<int>(Role::Status), QByteArrayLiteral("Status")); | ||||
139 | roles.insert(static_cast<int>(Role::StatusChanged), QByteArrayLiteral("StatusChanged")); | ||||
140 | roles.insert(static_cast<int>(Role::Title), QByteArrayLiteral("Title")); | ||||
141 | roles.insert(static_cast<int>(Role::TitleChanged), QByteArrayLiteral("TitleChanged")); | ||||
142 | roles.insert(static_cast<int>(Role::ToolTipChanged), QByteArrayLiteral("ToolTipChanged")); | ||||
143 | roles.insert(static_cast<int>(Role::ToolTipIcon), QByteArrayLiteral("ToolTipIcon")); | ||||
144 | roles.insert(static_cast<int>(Role::ToolTipSubTitle), QByteArrayLiteral("ToolTipSubTitle")); | ||||
145 | roles.insert(static_cast<int>(Role::ToolTipTitle), QByteArrayLiteral("ToolTipTitle")); | ||||
146 | roles.insert(static_cast<int>(Role::WindowId), QByteArrayLiteral("WindowId")); | ||||
147 | | ||||
148 | return roles; | ||||
149 | } | ||||
150 | | ||||
151 | Plasma::Service *StatusNotifierModel::serviceForSource(const QString &source) | ||||
152 | { | ||||
153 | if (!m_services.contains(source)) { | ||||
154 | Plasma::Service *service = m_dataEngine->serviceForSource(source); | ||||
155 | if (!service) { | ||||
156 | return nullptr; | ||||
157 | } | ||||
158 | m_services[source] = service; | ||||
159 | } | ||||
160 | | ||||
161 | return m_services.value(source); | ||||
162 | } | ||||
163 | | ||||
164 | void StatusNotifierModel::addSource(const QString &source) | ||||
165 | { | ||||
166 | m_dataEngine->connectSource(source, this); | ||||
167 | } | ||||
168 | | ||||
169 | void StatusNotifierModel::removeSource(const QString &source) | ||||
170 | { | ||||
171 | m_dataEngine->disconnectSource(source, this); | ||||
172 | if (m_sources.contains(source)) { | ||||
173 | removeRow(m_sources.indexOf(source)); | ||||
174 | m_sources.removeAll(source); | ||||
175 | } | ||||
176 | | ||||
177 | QHash<QString, Plasma::Service *>::iterator it = m_services.find(source); | ||||
178 | if (it != m_services.end()) { | ||||
179 | delete it.value(); | ||||
180 | m_services.erase(it); | ||||
181 | } | ||||
182 | } | ||||
183 | | ||||
184 | void StatusNotifierModel::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) | ||||
185 | { | ||||
186 | QStandardItem *dataItem; | ||||
187 | if (m_sources.contains(sourceName)) { | ||||
188 | dataItem = item(m_sources.indexOf(sourceName)); | ||||
189 | } else { | ||||
190 | dataItem = new QStandardItem(); | ||||
191 | dataItem->setData("StatusNotifier", static_cast<int>(BaseRole::ItemType)); | ||||
192 | dataItem->setData(true, static_cast<int>(BaseRole::CanRender)); | ||||
193 | } | ||||
194 | | ||||
195 | dataItem->setData(data.value("Title"), Qt::DisplayRole); | ||||
196 | QVariant icon = data.value("Icon"); | ||||
197 | if (icon.isValid() && icon.canConvert<QIcon>() && !icon.value<QIcon>().isNull()) { | ||||
198 | dataItem->setData(icon, Qt::DecorationRole); | ||||
199 | } else { | ||||
200 | dataItem->setData(data.value("IconName"), Qt::DecorationRole); | ||||
201 | } | ||||
202 | | ||||
203 | dataItem->setData(data.value("Id"), static_cast<int>(BaseRole::ItemId)); | ||||
204 | | ||||
205 | dataItem->setData(sourceName, static_cast<int>(Role::DataEngineSource)); | ||||
206 | updateItemData(dataItem, data, Role::AttentionIcon); | ||||
207 | updateItemData(dataItem, data, Role::AttentionIconName); | ||||
208 | updateItemData(dataItem, data, Role::AttentionMovieName); | ||||
209 | updateItemData(dataItem, data, Role::Category); | ||||
210 | updateItemData(dataItem, data, Role::Icon); | ||||
211 | updateItemData(dataItem, data, Role::IconName); | ||||
212 | updateItemData(dataItem, data, Role::IconThemePath); | ||||
213 | updateItemData(dataItem, data, Role::IconsChanged); | ||||
214 | updateItemData(dataItem, data, Role::Id); | ||||
215 | updateItemData(dataItem, data, Role::ItemIsMenu); | ||||
216 | updateItemData(dataItem, data, Role::OverlayIconName); | ||||
217 | updateItemData(dataItem, data, Role::Status); | ||||
218 | updateItemData(dataItem, data, Role::StatusChanged); | ||||
219 | updateItemData(dataItem, data, Role::Title); | ||||
220 | updateItemData(dataItem, data, Role::TitleChanged); | ||||
221 | updateItemData(dataItem, data, Role::ToolTipChanged); | ||||
222 | updateItemData(dataItem, data, Role::ToolTipIcon); | ||||
223 | updateItemData(dataItem, data, Role::ToolTipSubTitle); | ||||
224 | updateItemData(dataItem, data, Role::ToolTipTitle); | ||||
225 | updateItemData(dataItem, data, Role::WindowId); | ||||
226 | | ||||
227 | if (!m_sources.contains(sourceName)) { | ||||
228 | m_sources.append(sourceName); | ||||
229 | appendRow(dataItem); | ||||
230 | } | ||||
231 | } | ||||
232 | | ||||
233 | void StatusNotifierModel::updateItemData(QStandardItem *dataItem, | ||||
234 | const Plasma::DataEngine::Data &data, const Role role) | ||||
235 | { | ||||
236 | int roleId = static_cast<int>(role); | ||||
237 | dataItem->setData(data.value(roleNames().value(roleId)), roleId); | ||||
238 | } | ||||
239 | | ||||
240 | SystemTrayModel::SystemTrayModel(QObject *parent) : KConcatenateRowsProxyModel(parent) | ||||
241 | { | ||||
242 | m_roleNames = KConcatenateRowsProxyModel::roleNames(); | ||||
243 | } | ||||
244 | | ||||
245 | QHash<int, QByteArray> SystemTrayModel::roleNames() const | ||||
246 | { | ||||
247 | return m_roleNames; | ||||
248 | } | ||||
249 | | ||||
250 | void SystemTrayModel::addSourceModel(QAbstractItemModel *sourceModel) | ||||
251 | { | ||||
252 | m_roleNames.unite(sourceModel->roleNames()); | ||||
253 | KConcatenateRowsProxyModel::addSourceModel(sourceModel); | ||||
254 | } |