Commit e3a7cb2f authored by Christian Muehlhaeuser's avatar Christian Muehlhaeuser
Browse files

Add previous-/nextActivity methods

Summary:
These two methods can be used to switch to the previous/next activity in
alphabetical order. They are exposed via the DBus interface. This
functionality can also be accessed by kactivities(-cli) and plasmashell, which
currently both implement their own separate versions of it.

@ivan mentioned being a bit wary of keeping a sorted activity list in
kactivitymanagerd, so I've opted to only retrieve and sort the list on demand
here.

Reviewers: ivan

Reviewed By: ivan

Subscribers: ivan, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D22381
parent 5b27e609
......@@ -9,6 +9,12 @@
<arg type="b" direction="out"/>
<arg name="activity" type="s" direction="in"/>
</method>
<method name="PreviousActivity">
<arg type="b" direction="out"/>
</method>
<method name="NextActivity">
<arg type="b" direction="out"/>
</method>
<method name="AddActivity">
<arg type="s" direction="out"/>
......
......@@ -51,6 +51,16 @@
// 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
......@@ -143,6 +153,23 @@ Activities::Private::Private(Activities *parent)
activities[keys] = Activities::Running;
}
}
QMetaObject::invokeMethod(
this,
"updateSortedActivityList",
Qt::QueuedConnection);
}
void Activities::Private::updateSortedActivityList() {
QVector<ActivityInfo> 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()
......@@ -204,6 +231,32 @@ bool Activities::Private::setCurrentActivity(const QString &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;
......@@ -234,6 +287,8 @@ QString Activities::Private::addActivity(const QString &name)
q->SetActivityName(activity, name);
updateSortedActivityList();
emit q->ActivityAdded(activity);
scheduleConfigSync();
......@@ -275,6 +330,13 @@ void Activities::Private::removeActivity(const QString &activity)
// 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);
......@@ -370,6 +432,8 @@ void Activities::Private::setActivityState(const QString &activity,
+ activities.keys(Activities::Stopping));
scheduleConfigSync();
}
updateSortedActivityList();
}
void Activities::Private::ensureCurrentActivityIsRunning()
......@@ -471,6 +535,16 @@ bool Activities::SetCurrentActivity(const QString &activity)
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 +568,25 @@ void Activities::RemoveActivity(const QString &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<ActivityInfo> Activities::ListActivitiesWithInformation() const
......@@ -596,4 +682,3 @@ int Activities::ActivityState(const QString &activity) const
QReadLocker lock(&d->activitiesLock);
return d->activities.contains(activity) ? d->activities[activity] : Invalid;
}
......@@ -78,6 +78,16 @@ public Q_SLOTS:
*/
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
......
......@@ -54,6 +54,9 @@ public:
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 @@ public:
KSMServer *ksmserver;
QHash<QString, Activities::State> activities;
QVector<ActivityInfo> sortedActivities;
QReadWriteLock activitiesLock;
QString currentActivity;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment