Plasma5Support

activityengine.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Chani Armitage <chani@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "activityengine.h"
8#include "activityservice.h"
9
10#include <plasmaactivities/controller.h>
11#include <plasmaactivities/info.h>
12
13#include <QApplication>
14#include <QDBusServiceWatcher>
15
16#define ACTIVITYMANAGER_SERVICE "org.kde.kactivitymanagerd"
17#define ACTIVITYRANKING_OBJECT "/ActivityRanking"
18
19ActivityEngine::ActivityEngine(QObject *parent)
20 : Plasma5Support::DataEngine(parent)
21{
22 init();
23}
24
25void ActivityEngine::init()
26{
27 if (qApp->applicationName() == QLatin1String("plasma-netbook")) {
28 // hack for the netbook
29 // FIXME can I read a setting or something instead?
30 } else {
31 m_activityController = new KActivities::Controller(this);
32 m_currentActivity = m_activityController->currentActivity();
33 const QStringList activities = m_activityController->activities();
34 // setData("allActivities", activities);
35 for (const QString &id : activities) {
36 insertActivity(id);
37 }
38
39 connect(m_activityController, &KActivities::Controller::activityAdded, this, &ActivityEngine::activityAdded);
40 connect(m_activityController, &KActivities::Controller::activityRemoved, this, &ActivityEngine::activityRemoved);
41 connect(m_activityController, &KActivities::Controller::currentActivityChanged, this, &ActivityEngine::currentActivityChanged);
42
43 // some convenience sources for times when checking every activity source would suck
44 // it starts with _ so that it can easily be filtered out of sources()
45 // maybe I should just make it not included in sources() instead?
46 m_runningActivities = m_activityController->activities(KActivities::Info::Running);
47 setData(QStringLiteral("Status"), QStringLiteral("Current"), m_currentActivity);
48 setData(QStringLiteral("Status"), QStringLiteral("Running"), m_runningActivities);
49
50 m_watcher = new QDBusServiceWatcher(ACTIVITYMANAGER_SERVICE,
53 this);
54
55 connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, &ActivityEngine::enableRanking);
56 connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &ActivityEngine::disableRanking);
57
58 if (QDBusConnection::sessionBus().interface()->isServiceRegistered(ACTIVITYMANAGER_SERVICE)) {
59 enableRanking();
60 }
61 }
62}
63
64void ActivityEngine::insertActivity(const QString &id)
65{
66 // id -> name, icon, state
67 KActivities::Info *activity = new KActivities::Info(id, this);
68 m_activities[id] = activity;
69 setData(id, QStringLiteral("Name"), activity->name());
70 setData(id, QStringLiteral("Icon"), activity->icon());
71 setData(id, QStringLiteral("Current"), m_currentActivity == id);
72
73 QString state;
74 switch (activity->state()) {
75 case KActivities::Info::Running:
76 state = QLatin1String("Running");
77 break;
78 case KActivities::Info::Starting:
79 state = QLatin1String("Starting");
80 break;
81 case KActivities::Info::Stopping:
82 state = QLatin1String("Stopping");
83 break;
84 case KActivities::Info::Stopped:
85 state = QLatin1String("Stopped");
86 break;
87 case KActivities::Info::Invalid:
88 default:
89 state = QLatin1String("Invalid");
90 }
91 setData(id, QStringLiteral("State"), state);
92 setData(id, QStringLiteral("Score"), m_activityScores.value(id));
93
94 connect(activity, &KActivities::Info::infoChanged, this, &ActivityEngine::activityDataChanged);
95 connect(activity, &KActivities::Info::stateChanged, this, &ActivityEngine::activityStateChanged);
96
97 m_runningActivities << id;
98}
99
100void ActivityEngine::disableRanking()
101{
102 delete m_activityRankingClient;
103}
104
105void ActivityEngine::enableRanking()
106{
107 m_activityRankingClient = new org::kde::ActivityManager::ActivityRanking(ACTIVITYMANAGER_SERVICE, ACTIVITYRANKING_OBJECT, QDBusConnection::sessionBus());
108 connect(m_activityRankingClient, &org::kde::ActivityManager::ActivityRanking::rankingChanged, this, &ActivityEngine::rankingChanged);
109
110 QDBusMessage msg = QDBusMessage::createMethodCall(ACTIVITYMANAGER_SERVICE,
111 ACTIVITYRANKING_OBJECT,
112 QStringLiteral("org.kde.ActivityManager.ActivityRanking"),
113 QStringLiteral("activities"));
115 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
116 QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &ActivityEngine::activityScoresReply);
117}
118
119void ActivityEngine::activityScoresReply(QDBusPendingCallWatcher *watcher)
120{
122 if (reply.isError()) {
123 qDebug() << "Error getting activity scores: " << reply.error().message();
124 } else {
125 setActivityScores(reply.value());
126 }
127
128 watcher->deleteLater();
129}
130
131void ActivityEngine::rankingChanged(const QStringList &topActivities, const ActivityDataList &activities)
132{
133 Q_UNUSED(topActivities)
134
135 setActivityScores(activities);
136}
137
138void ActivityEngine::setActivityScores(const ActivityDataList &activities)
139{
140 QSet<QString> presentActivities;
141 m_activityScores.clear();
142
143 for (const ActivityData &activity : activities) {
144 if (m_activities.contains(activity.id)) {
145 setData(activity.id, QStringLiteral("Score"), activity.score);
146 }
147 presentActivities.insert(activity.id);
148 m_activityScores[activity.id] = activity.score;
149 }
150
151 const auto controllerActivities = m_activityController->activities();
152 for (const QString &activityId : controllerActivities) {
153 if (!presentActivities.contains(activityId) && m_activities.contains(activityId)) {
154 setData(activityId, QStringLiteral("Score"), 0);
155 }
156 }
157}
158
159void ActivityEngine::activityAdded(const QString &id)
160{
161 insertActivity(id);
162 setData(QStringLiteral("Status"), QStringLiteral("Running"), m_runningActivities);
163}
164
165void ActivityEngine::activityRemoved(const QString &id)
166{
167 removeSource(id);
168 KActivities::Info *activity = m_activities.take(id);
169 if (activity) {
170 delete activity;
171 }
172 m_runningActivities.removeAll(id);
173 setData(QStringLiteral("Status"), QStringLiteral("Running"), m_runningActivities);
174}
175
176void ActivityEngine::currentActivityChanged(const QString &id)
177{
178 setData(m_currentActivity, QStringLiteral("Current"), false);
179 m_currentActivity = id;
180 setData(id, QStringLiteral("Current"), true);
181 setData(QStringLiteral("Status"), QStringLiteral("Current"), id);
182}
183
184void ActivityEngine::activityDataChanged()
185{
186 KActivities::Info *activity = qobject_cast<KActivities::Info *>(sender());
187 if (!activity) {
188 return;
189 }
190 setData(activity->id(), QStringLiteral("Name"), activity->name());
191 setData(activity->id(), QStringLiteral("Icon"), activity->icon());
192 setData(activity->id(), QStringLiteral("Current"), m_currentActivity == activity->id());
193 setData(activity->id(), QStringLiteral("Score"), m_activityScores.value(activity->id()));
194}
195
196void ActivityEngine::activityStateChanged()
197{
198 KActivities::Info *activity = qobject_cast<KActivities::Info *>(sender());
199 const QString id = activity->id();
200 if (!activity) {
201 return;
202 }
203 QString state;
204 switch (activity->state()) {
205 case KActivities::Info::Running:
206 state = QLatin1String("Running");
207 break;
208 case KActivities::Info::Starting:
209 state = QLatin1String("Starting");
210 break;
211 case KActivities::Info::Stopping:
212 state = QLatin1String("Stopping");
213 break;
214 case KActivities::Info::Stopped:
215 state = QLatin1String("Stopped");
216 break;
217 case KActivities::Info::Invalid:
218 default:
219 state = QLatin1String("Invalid");
220 }
221 setData(id, QStringLiteral("State"), state);
222
223 if (activity->state() == KActivities::Info::Running) {
224 if (!m_runningActivities.contains(id)) {
225 m_runningActivities << id;
226 }
227 } else {
228 m_runningActivities.removeAll(id);
229 }
230
231 setData(QStringLiteral("Status"), QStringLiteral("Running"), m_runningActivities);
232}
233
234Plasma5Support::Service *ActivityEngine::serviceForSource(const QString &source)
235{
236 // FIXME validate the name
237 ActivityService *service = new ActivityService(m_activityController, source);
238 service->setParent(this);
239 return service;
240}
241
242K_PLUGIN_CLASS_WITH_JSON(ActivityEngine, "plasma-dataengine-activities.json")
243
244#include "activityengine.moc"
#define K_PLUGIN_CLASS_WITH_JSON(classname, jsonFile)
Data provider for plasmoids (Plasma plugins)
Definition dataengine.h:45
void removeSource(const QString &source)
Removes a data source.
void setData(const QString &source, const QVariant &value)
Sets a value for a data source.
This class provides a generic API for write access to settings or services.
Definition service.h:78
Namespace for everything in libplasma.
Definition datamodel.cpp:15
QCA_EXPORT void init()
QDBusPendingCall asyncCall(const QDBusMessage &message, int timeout) const const
QDBusConnection sessionBus()
QString message() const const
QDBusMessage createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
void finished(QDBusPendingCallWatcher *self)
QDBusError error() const const
bool isError() const const
typename Select< 0 >::Type value() const const
void serviceRegistered(const QString &serviceName)
void serviceUnregistered(const QString &serviceName)
void clear()
bool contains(const Key &key) const const
T take(const Key &key)
T value(const Key &key) const const
qsizetype removeAll(const AT &t)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
T qobject_cast(QObject *object)
QObject * sender() const const
void setParent(QObject *parent)
bool contains(const QSet< T > &other) const const
iterator insert(const T &value)
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:08:57 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.