diff --git a/src/common/dbus/org.kde.ActivityManager.Activities.xml b/src/common/dbus/org.kde.ActivityManager.Activities.xml
index 8d3e074..83fa6de 100644
--- a/src/common/dbus/org.kde.ActivityManager.Activities.xml
+++ b/src/common/dbus/org.kde.ActivityManager.Activities.xml
@@ -1,115 +1,121 @@
+
+
+
+
+
+
diff --git a/src/service/Activities.cpp b/src/service/Activities.cpp
index 27f7d90..188f71c 100644
--- a/src/service/Activities.cpp
+++ b/src/service/Activities.cpp
@@ -1,599 +1,684 @@
/*
* Copyright (C) 2010 - 2016 by Ivan Cukic
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
// Self
#include
#include "Activities.h"
#include "Activities_p.h"
// Qt
#include
#include
#include
#include
#include
#include
// KDE
#include
#include
#include
#include
#include
// Utils
#include
#include
// Local
#include "DebugActivities.h"
#include "activitiesadaptor.h"
#include "ksmserver/KSMServer.h"
#include "common/dbus/common.h"
// Private
#define ACTIVITY_MANAGER_CONFIG_FILE_NAME QStringLiteral("kactivitymanagerdrc")
+namespace {
+ inline
+ bool nameBasedOrdering(const ActivityInfo &info, const ActivityInfo &other)
+ {
+ const auto comp =
+ QString::compare(info.name, other.name, Qt::CaseInsensitive);
+ return comp < 0 || (comp == 0 && info.id < other.id);
+ }
+}
+
Activities::Private::KDE4ConfigurationTransitionChecker::KDE4ConfigurationTransitionChecker()
{
// Checking whether we need to transfer the KActivities/KDE4
// configuration file to the new location.
const QString newConfigLocation
= QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)
+ QLatin1Char('/') + ACTIVITY_MANAGER_CONFIG_FILE_NAME;
if (QFile(newConfigLocation).exists()) {
return;
}
// Testing for kdehome
Kdelibs4Migration migration;
if (!migration.kdeHomeFound()) {
return;
}
QString oldConfigFile(migration.locateLocal("config", QStringLiteral("activitymanagerrc")));
if (!oldConfigFile.isEmpty()) {
QFile(oldConfigFile).copy(newConfigLocation);
}
}
Activities::Private::Private(Activities *parent)
: kde4ConfigurationTransitionChecker()
, config(QStringLiteral("kactivitymanagerdrc"))
, q(parent)
{
// qCDebug(KAMD_ACTIVITIES) << "Using this configuration file:"
// << config.name()
// << config.locationType()
// << QStandardPaths::standardLocations(config.locationType())
// ;
// Reading activities from the config file.
// Saving only the running activities means that if we have any
// errors in the config, we might end up with all activities
// stopped
const auto defaultState
= !mainConfig().hasKey("runningActivities") ? Activities::Running :
!mainConfig().hasKey("stoppedActivities") ? Activities::Stopped :
Activities::Running;
const auto runningActivities
= mainConfig().readEntry("runningActivities", QStringList()).toSet();
const auto stoppedActivities
= mainConfig().readEntry("stoppedActivities", QStringList()).toSet();
// Do we have a running activity?
bool atLeastOneRunning = false;
for (const auto &activity: activityNameConfig().keyList()) {
auto state =
runningActivities.contains(activity) ? Activities::Running :
stoppedActivities.contains(activity) ? Activities::Stopped :
defaultState;
activities[activity] = state;
if (state == Activities::Running) {
atLeastOneRunning = true;
}
}
// Is this our first start?
if (activities.isEmpty()) {
// We need to add this only after the service has been properly started
KConfigGroup cg(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("Activities"));
//NOTE: config key still singular for retrocompatibility
const QStringList names = cg.readEntry("defaultActivityName", QStringList{i18n("Default")});
for (const auto &name : names) {
QMetaObject::invokeMethod(
q,
"AddActivity",
Qt::QueuedConnection,
Q_ARG(QString, name));
}
} else if (!atLeastOneRunning) {
// If we have no running activities, but we have activities,
// we are in a problem. This should not happen unless the
// configuration file is in a big problem and told us there
// are no running activities, and enlists all of them as stopped.
// In that case, we will pretend all of them are running
qCWarning(KAMD_LOG_ACTIVITIES) << "The config file enlisted all activities as stopped";
for (const auto &keys: activities.keys()) {
activities[keys] = Activities::Running;
}
}
+
+ QMetaObject::invokeMethod(
+ this,
+ "updateSortedActivityList",
+ Qt::QueuedConnection);
+}
+
+void Activities::Private::updateSortedActivityList() {
+ QVector a;
+ for (const auto &activity : activities.keys()) {
+ a.append(q->ActivityInformation(activity));
+ }
+
+ std::sort(a.begin(), a.end(), &nameBasedOrdering);
+
+ QWriteLocker lock(&activitiesLock);
+ sortedActivities = a;
}
void Activities::Private::loadLastActivity()
{
// This is called from constructor, no need for locking
// If there are no public activities, try to load the last used activity
const auto lastUsedActivity
= mainConfig().readEntry("currentActivity", QString());
setCurrentActivity(
(lastUsedActivity.isEmpty() && activities.size() > 0)
? activities.keys().at(0)
: lastUsedActivity);
}
Activities::Private::~Private()
{
configSync();
}
bool Activities::Private::setCurrentActivity(const QString &activity)
{
{
// There is nothing expensive in this block, not a problem to lock
QWriteLocker lock(&activitiesLock);
// Should we change the activity at all?
if (currentActivity == activity) {
return true;
}
// If the activity is empty, this means we are entering a limbo state
if (activity.isEmpty()) {
currentActivity.clear();
emit q->CurrentActivityChanged(currentActivity);
return true;
}
// Does the requested activity exist?
if (!activities.contains(activity)) {
return false;
}
}
// Start activity
q->StartActivity(activity);
// Saving the current activity, and notifying
// clients of the change
currentActivity = activity;
mainConfig().writeEntry("currentActivity", activity);
scheduleConfigSync();
emit q->CurrentActivityChanged(activity);
return true;
}
+bool Activities::Private::previousActivity()
+{
+ const auto a = q->ListActivities(Activities::Running);
+
+ for (int i = 0; i < a.count(); ++i) {
+ if (a[i] == currentActivity) {
+ return setCurrentActivity(a[(i + a.size() - 1) % a.size()]);
+ }
+ }
+
+ return false;
+}
+
+bool Activities::Private::nextActivity()
+{
+ const auto a = q->ListActivities(Activities::Running);
+
+ for (int i = 0; i < a.count(); ++i) {
+ if (a[i] == currentActivity) {
+ return setCurrentActivity(a[(i + 1) % a.size()]);
+ }
+ }
+
+ return false;
+}
+
QString Activities::Private::addActivity(const QString &name)
{
QString activity;
if (name.isEmpty()) {
Q_ASSERT(!name.isEmpty());
return activity;
}
int activitiesCount = 0;
{
QWriteLocker lock(&activitiesLock);
// Ensuring a new Uuid. The loop should usually end after only
// one iteration
while (activity.isEmpty() || activities.contains(activity)) {
activity = QUuid::createUuid().toString().mid(1, 36);
}
// Saves the activity info to the config
activities[activity] = Invalid;
activitiesCount = activities.size();
}
setActivityState(activity, Running);
q->SetActivityName(activity, name);
+ updateSortedActivityList();
+
emit q->ActivityAdded(activity);
scheduleConfigSync();
if (activitiesCount == 1) {
q->SetCurrentActivity(activity);
}
return activity;
}
void Activities::Private::removeActivity(const QString &activity)
{
Q_ASSERT(!activity.isEmpty());
// Sanity checks
{
QWriteLocker lock(&activitiesLock);
if (!activities.contains(activity)) {
return;
}
// Is somebody trying to remove the last activity?
if (activities.size() == 1) {
return;
}
}
// If the activity is running, stash it
q->StopActivity(activity);
setActivityState(activity, Activities::Invalid);
bool currentActivityDeleted = false;
{
QWriteLocker lock(&activitiesLock);
// Removing the activity
activities.remove(activity);
+ for (int i = 0; i < sortedActivities.count(); ++i) {
+ if (sortedActivities[i].id == activity) {
+ sortedActivities.remove(i);
+ break;
+ }
+ }
+
// If the removed activity was the current one,
// set another activity as current
currentActivityDeleted = (currentActivity == activity);
}
activityNameConfig().deleteEntry(activity);
activityDescriptionConfig().deleteEntry(activity);
activityIconConfig().deleteEntry(activity);
if (currentActivityDeleted) {
ensureCurrentActivityIsRunning();
}
emit q->ActivityRemoved(activity);
QMetaObject::invokeMethod(q, "ActivityRemoved", Qt::QueuedConnection,
Q_ARG(QString, activity));
QMetaObject::invokeMethod(this, "configSync", Qt::QueuedConnection);
}
void Activities::Private::scheduleConfigSync()
{
static const auto shortInterval = 1000;
// If the timer is not running, or has a longer interval than we need,
// start it
// Note: If you want to add multiple different delays for different
// events based on the importance of how quickly something needs
// to be synced to the config, don't. Since the QTimer lives in a
// separate thread, we have to communicate with it in via
// queued connections, which means that we don't know whether
// the timer was already started when this method was invoked,
// we do not know whether the interval is properly set etc.
if (!configSyncTimer.isActive()) {
QMetaObject::invokeMethod(
&configSyncTimer, "start", Qt::QueuedConnection,
Q_ARG(int, shortInterval));
}
}
void Activities::Private::configSync()
{
// Stop the timer and reset the interval to zero
QMetaObject::invokeMethod(&configSyncTimer, "stop", Qt::QueuedConnection);
config.sync();
}
void Activities::Private::setActivityState(const QString &activity,
Activities::State state)
{
bool configNeedsUpdating = false;
{
QWriteLocker lock(&activitiesLock);
Q_ASSERT(activities.contains(activity));
if (activities.value(activity) == state) {
return;
}
// Treating 'Starting' as 'Running', and 'Stopping' as 'Stopped'
// as far as the config file is concerned
configNeedsUpdating = ((activities[activity] & 4) != (state & 4));
activities[activity] = state;
}
switch (state) {
case Activities::Running:
emit q->ActivityStarted(activity);
break;
case Activities::Stopped:
emit q->ActivityStopped(activity);
break;
default:
break;
}
emit q->ActivityStateChanged(activity, state);
if (configNeedsUpdating) {
QReadLocker lock(&activitiesLock);
mainConfig().writeEntry("runningActivities",
activities.keys(Activities::Running)
+ activities.keys(Activities::Starting));
mainConfig().writeEntry("stoppedActivities",
activities.keys(Activities::Stopped)
+ activities.keys(Activities::Stopping));
scheduleConfigSync();
}
+
+ updateSortedActivityList();
}
void Activities::Private::ensureCurrentActivityIsRunning()
{
// If the current activity is not running,
// make some other activity current
const auto runningActivities = q->ListActivities(Activities::Running);
if (!runningActivities.contains(currentActivity) &&
runningActivities.size() > 0) {
setCurrentActivity(runningActivities.first());
}
}
void Activities::Private::activitySessionStateChanged(const QString &activity,
int status)
{
QString currentActivity = this->currentActivity;
{
QReadLocker lock(&activitiesLock);
if (!activities.contains(activity)) {
return;
}
}
switch (status) {
case KSMServer::Started:
case KSMServer::FailedToStop:
setActivityState(activity, Activities::Running);
break;
case KSMServer::Stopped:
setActivityState(activity, Activities::Stopped);
if (currentActivity == activity) {
ensureCurrentActivityIsRunning();
}
break;
}
QMetaObject::invokeMethod(this, "configSync", Qt::QueuedConnection);
}
// Main
Activities::Activities(QObject *parent)
: Module(QStringLiteral("activities"), parent)
, d(this)
{
qCDebug(KAMD_LOG_ACTIVITIES) << "Starting the KDE Activity Manager daemon"
<< QDateTime::currentDateTime();
// Basic initialization ////////////////////////////////////////////////////
// Initializing D-Bus service
new ActivitiesAdaptor(this);
KDBusConnectionPool::threadConnection().registerObject(
KAMD_DBUS_OBJECT_PATH(Activities), this);
// Initializing config
qCDebug(KAMD_LOG_ACTIVITIES) << "Config timer connecting...";
d->connect(&d->configSyncTimer, SIGNAL(timeout()),
SLOT(configSync()),
Qt::QueuedConnection);
d->configSyncTimer.setSingleShot(true);
d->ksmserver = new KSMServer(this);
d->connect(d->ksmserver, SIGNAL(activitySessionStateChanged(QString, int)),
SLOT(activitySessionStateChanged(QString, int)));
// Loading the last used activity, if possible
d->loadLastActivity();
}
Activities::~Activities()
{
}
QString Activities::CurrentActivity() const
{
QReadLocker lock(&d->activitiesLock);
return d->currentActivity;
}
bool Activities::SetCurrentActivity(const QString &activity)
{
// Public method can not put us in a limbo state
if (activity.isEmpty()) {
return false;
}
return d->setCurrentActivity(activity);
}
+bool Activities::PreviousActivity()
+{
+ return d->previousActivity();
+}
+
+bool Activities::NextActivity()
+{
+ return d->nextActivity();
+}
+
QString Activities::AddActivity(const QString &name)
{
// We do not care about authorization if this is the first start
if (!d->activities.isEmpty() &&
!KAuthorized::authorize(QStringLiteral("plasma-desktop/add_activities"))) {
return QString();
}
return d->addActivity(name);
}
void Activities::RemoveActivity(const QString &activity)
{
if (!KAuthorized::authorize(QStringLiteral("plasma-desktop/add_activities"))) {
return;
}
d->removeActivity(activity);
}
QStringList Activities::ListActivities() const
{
QReadLocker lock(&d->activitiesLock);
- return d->activities.keys();
+
+ QStringList s;
+ for (const auto &a : d->sortedActivities) {
+ s << a.id;
+ }
+ return s;
}
QStringList Activities::ListActivities(int state) const
{
QReadLocker lock(&d->activitiesLock);
- return d->activities.keys((State)state);
+
+ QStringList s;
+ for (const auto &a : d->sortedActivities) {
+ if (a.state == (State)state) {
+ s << a.id;
+ }
+ }
+ return s;
}
QList Activities::ListActivitiesWithInformation() const
{
using namespace kamd::utils;
// Mapping activity ids to info
return as_collection>(
ListActivities()
| transformed(&Activities::ActivityInformation, this)
);
}
ActivityInfo Activities::ActivityInformation(const QString &activity) const
{
return ActivityInfo {
activity,
ActivityName(activity),
ActivityDescription(activity),
ActivityIcon(activity),
ActivityState(activity)
};
}
#define CREATE_GETTER_AND_SETTER(What) \
QString Activities::Activity##What(const QString &activity) const \
{ \
QReadLocker lock(&d->activitiesLock); \
return d->activities.contains(activity) ? d->activity##What(activity) \
: QString(); \
} \
\
void Activities::SetActivity##What(const QString &activity, \
const QString &value) \
{ \
{ \
QReadLocker lock(&d->activitiesLock); \
if (value == d->activity##What(activity) \
|| !d->activities.contains(activity)) { \
return; \
} \
} \
\
d->activity##What##Config().writeEntry(activity, value); \
d->scheduleConfigSync(); \
\
emit Activity##What##Changed(activity, value); \
emit ActivityChanged(activity); \
}
CREATE_GETTER_AND_SETTER(Name)
CREATE_GETTER_AND_SETTER(Description)
CREATE_GETTER_AND_SETTER(Icon)
#undef CREATE_GETTER_AND_SETTER
// Main
void Activities::StartActivity(const QString &activity)
{
{
QReadLocker lock(&d->activitiesLock);
if (!d->activities.contains(activity)
|| d->activities[activity] != Stopped) {
return;
}
}
d->setActivityState(activity, Starting);
d->ksmserver->startActivitySession(activity);
}
void Activities::StopActivity(const QString &activity)
{
{
QReadLocker lock(&d->activitiesLock);
if (!d->activities.contains(activity)
|| d->activities[activity] == Stopped
|| d->activities.size() == 1
|| d->activities.keys(Activities::Running).size() <= 1
) {
return;
}
}
d->setActivityState(activity, Stopping);
d->ksmserver->stopActivitySession(activity);
}
int Activities::ActivityState(const QString &activity) const
{
QReadLocker lock(&d->activitiesLock);
return d->activities.contains(activity) ? d->activities[activity] : Invalid;
}
-
diff --git a/src/service/Activities.h b/src/service/Activities.h
index 0b84925..0896e6e 100644
--- a/src/service/Activities.h
+++ b/src/service/Activities.h
@@ -1,242 +1,252 @@
/*
* Copyright (C) 2010 - 2016 by Ivan Cukic
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef ACTIVITIES_H
#define ACTIVITIES_H
// Qt
#include
#include
// Utils
#include
// Local
#include "Module.h"
#include
/**
* Service for tracking the user actions and managing the
* activities
*/
class Activities : public Module {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.ActivityManager.Activities")
Q_PROPERTY(QString CurrentActivity READ CurrentActivity WRITE SetCurrentActivity NOTIFY CurrentActivityChanged)
public:
/**
* Activity state
* @note: Do not change the values, needed for bit-operations
*/
enum State {
Invalid = 0,
Running = 2,
Starting = 3,
Stopped = 4,
Stopping = 5
};
/**
* Creates new Activities object
*/
explicit Activities(QObject *parent = nullptr);
/**
* Destroys this interface
*/
~Activities() override;
// workspace activities control
public Q_SLOTS:
/**
* @returns the id of the current activity, empty string if none
*/
QString CurrentActivity() const;
/**
* Sets the current activity
* @param activity id of the activity to make current
*/
bool SetCurrentActivity(const QString &activity);
+ /**
+ * Switches to the previous activity
+ */
+ bool PreviousActivity();
+
+ /**
+ * Switches to the next activity
+ */
+ bool NextActivity();
+
/**
* Adds a new activity
* @param name name of the activity
* @returns id of the newly created activity
*/
QString AddActivity(const QString &name);
/**
* Starts the specified activity
* @param activity id of the activity to stash
*/
void StartActivity(const QString &activity);
/**
* Stops the specified activity
* @param activity id of the activity to stash
*/
void StopActivity(const QString &activity);
/**
* @returns the state of the activity
* @param activity id of the activity
*/
int ActivityState(const QString &activity) const;
/**
* Removes the specified activity
* @param activity id of the activity to delete
*/
void RemoveActivity(const QString &activity);
/**
* @returns the list of all existing activities
*/
QStringList ListActivities() const;
/**
* @returns the list of activities with the specified state
* @param state state
*/
QStringList ListActivities(int state) const;
/**
* @returns the name of the specified activity
* @param activity id of the activity
*/
QString ActivityName(const QString &activity) const;
/**
* Sets the name of the specified activity
* @param activity id of the activity
* @param name name to be set
*/
void SetActivityName(const QString &activity, const QString &name);
/**
* @returns the description of the specified activity
* @param activity id of the activity
*/
QString ActivityDescription(const QString &activity) const;
/**
* Sets the description of the specified activity
* @param activity id of the activity
* @param description description to be set
*/
void SetActivityDescription(const QString &activity, const QString &description);
/**
* @returns the icon of the specified activity
* @param activity id of the activity
*/
QString ActivityIcon(const QString &activity) const;
/**
* Sets the icon of the specified activity
* @param activity id of the activity
* @param icon icon to be set
*/
void SetActivityIcon(const QString &activity, const QString &icon);
public Q_SLOTS:
/**
* @returns a list of activities with basic info about them
*/
ActivityInfoList ListActivitiesWithInformation() const;
/**
* @returns the info about an activity
*/
ActivityInfo ActivityInformation(const QString &activity) const;
Q_SIGNALS:
/**
* This signal is emitted when the global
* activity is changed
* @param activity id of the new current activity
*/
void CurrentActivityChanged(const QString &activity);
/**
* This signal is emitted when a new activity is created
* @param activity id of the activity
*/
void ActivityAdded(const QString &activity);
/**
* This signal is emitted when an activity is started
* @param activity id of the activity
*/
void ActivityStarted(const QString &activity);
/**
* This signal is emitted when an activity is stashed
* @param activity id of the activity
*/
void ActivityStopped(const QString &activity);
/**
* This signal is emitted when an activity is deleted
* @param activity id of the activity
*/
void ActivityRemoved(const QString &activity);
/**
* Emitted when an activity name is changed
* @param activity id of the changed activity
* @param name name of the changed activity
*/
void ActivityNameChanged(const QString &activity, const QString &name);
/**
* Emitted when an activity description is changed
* @param activity id of the changed activity
* @param description description of the changed activity
*/
void ActivityDescriptionChanged(const QString &activity,
const QString &description);
/**
* Emitted when an activity icon is changed
* @param activity id of the changed activity
* @param icon name of the changed activity
*/
void ActivityIconChanged(const QString &activity, const QString &icon);
/**
* Emitted when an activity is changed (name, icon, or some other property)
* @param activity id of the changed activity
*/
void ActivityChanged(const QString &activity);
/**
* Emitted when the state of activity is changed
*/
void ActivityStateChanged(const QString &activity, int state);
private:
D_PTR;
};
#endif // ACTIVITIES_H
diff --git a/src/service/Activities_p.h b/src/service/Activities_p.h
index dae44f4..4a1e969 100644
--- a/src/service/Activities_p.h
+++ b/src/service/Activities_p.h
@@ -1,128 +1,132 @@
/*
* Copyright (C) 2010 - 2016 by Ivan Cukic
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef ACTIVITIES_P_H
#define ACTIVITIES_P_H
// Self
#include "Activities.h"
// Qt
#include
#include
#include
// KDE
#include
#include
class KSMServer;
class Activities::Private : public QObject {
Q_OBJECT
public:
Private(Activities *parent);
~Private() override;
// Loads the last activity
// the user has used
void loadLastActivity();
// If the current activity is not running,
// make some other activity current
void ensureCurrentActivityIsRunning();
public Q_SLOTS:
bool setCurrentActivity(const QString &activity);
+ bool previousActivity();
+ bool nextActivity();
+ void updateSortedActivityList();
public:
void setActivityState(const QString &activity, Activities::State state);
// Configuration
class KDE4ConfigurationTransitionChecker {
public:
KDE4ConfigurationTransitionChecker();
} kde4ConfigurationTransitionChecker;
QTimer configSyncTimer;
KConfig config;
// Interface to the session management
KSMServer *ksmserver;
QHash activities;
+ QVector sortedActivities;
QReadWriteLock activitiesLock;
QString currentActivity;
public:
inline KConfigGroup activityNameConfig()
{
return KConfigGroup(&config, "activities");
}
inline KConfigGroup activityDescriptionConfig()
{
return KConfigGroup(&config, "activities-descriptions");
}
inline KConfigGroup activityIconConfig()
{
return KConfigGroup(&config, "activities-icons");
}
inline KConfigGroup mainConfig()
{
return KConfigGroup(&config, "main");
}
inline QString activityName(const QString &activity)
{
return activityNameConfig().readEntry(activity, QString());
}
inline QString activityDescription(const QString &activity)
{
return activityDescriptionConfig().readEntry(activity, QString());
}
inline QString activityIcon(const QString &activity)
{
return activityIconConfig().readEntry(activity, QString());
}
public Q_SLOTS:
// Schedules config syncing to be done after
// a predefined time interval
void scheduleConfigSync();
// Immediately syncs the configuration file
void configSync();
QString addActivity(const QString &name);
void removeActivity(const QString &activity);
void activitySessionStateChanged(const QString &activity, int state);
private:
Activities *const q;
};
#endif // ACTIVITIES_P_H