diff --git a/src/common/dbus/org.kde.ActivityManager.Activities.xml b/src/common/dbus/org.kde.ActivityManager.Activities.xml --- a/src/common/dbus/org.kde.ActivityManager.Activities.xml +++ b/src/common/dbus/org.kde.ActivityManager.Activities.xml @@ -9,6 +9,12 @@ + + + + + + diff --git a/src/service/Activities.h b/src/service/Activities.h --- a/src/service/Activities.h +++ b/src/service/Activities.h @@ -78,6 +78,16 @@ */ 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 diff --git a/src/service/Activities.cpp b/src/service/Activities.cpp --- a/src/service/Activities.cpp +++ b/src/service/Activities.cpp @@ -51,6 +51,14 @@ // Private #define ACTIVITY_MANAGER_CONFIG_FILE_NAME QStringLiteral("kactivitymanagerdrc") +static +bool infoLessThan(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 @@ -143,6 +151,23 @@ 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(), &infoLessThan); + + QWriteLocker lock(&activitiesLock); + sortedActivities = a; } void Activities::Private::loadLastActivity() @@ -204,6 +229,46 @@ return true; } +bool Activities::Private::previousActivity() +{ + QString r; + { + QReadLocker lock(&activitiesLock); + + for (int i = 0; i < sortedActivities.count(); ++i) { + if (sortedActivities[i].id == currentActivity) { + r = sortedActivities[(i + sortedActivities.size() - 1) % sortedActivities.size()].id; + } + } + } + + if (r.isEmpty()) { + return false; + } + + return setCurrentActivity(r); +} + +bool Activities::Private::nextActivity() +{ + QString r; + { + QReadLocker lock(&activitiesLock); + + for (int i = 0; i < sortedActivities.count(); ++i) { + if (sortedActivities[i].id == currentActivity) { + r = sortedActivities[(i + 1) % sortedActivities.size()].id; + } + } + } + + if (r.isEmpty()) { + return false; + } + + return setCurrentActivity(r); +} + QString Activities::Private::addActivity(const QString &name) { QString activity; @@ -234,6 +299,8 @@ q->SetActivityName(activity, name); + updateSortedActivityList(); + emit q->ActivityAdded(activity); scheduleConfigSync(); @@ -279,6 +346,7 @@ // set another activity as current currentActivityDeleted = (currentActivity == activity); } + updateSortedActivityList(); activityNameConfig().deleteEntry(activity); activityDescriptionConfig().deleteEntry(activity); @@ -370,6 +438,8 @@ + activities.keys(Activities::Stopping)); scheduleConfigSync(); } + + updateSortedActivityList(); } void Activities::Private::ensureCurrentActivityIsRunning() @@ -471,6 +541,16 @@ 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 @@ -494,13 +574,25 @@ 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 @@ -596,4 +688,3 @@ QReadLocker lock(&d->activitiesLock); return d->activities.contains(activity) ? d->activities[activity] : Invalid; } - diff --git a/src/service/Activities_p.h b/src/service/Activities_p.h --- a/src/service/Activities_p.h +++ b/src/service/Activities_p.h @@ -54,6 +54,9 @@ public Q_SLOTS: bool setCurrentActivity(const QString &activity); + bool previousActivity(); + bool nextActivity(); + void updateSortedActivityList(); public: void setActivityState(const QString &activity, Activities::State state); @@ -70,6 +73,7 @@ KSMServer *ksmserver; QHash activities; + QVector sortedActivities; QReadWriteLock activitiesLock; QString currentActivity;