diff --git a/shell/activity.h b/shell/activity.h --- a/shell/activity.h +++ b/shell/activity.h @@ -1,5 +1,6 @@ /* * Copyright 2010 Chani Armitage + * Copyright 2016 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 @@ -26,24 +27,24 @@ #include #include +#include + class QSize; class QString; class QPixmap; class KConfig; namespace KActivities { - class Consumer; + class Controller; } // namespace KActivities namespace Plasma { class Corona; } // namespace Plasma -class DesktopCorona; - /** * This class represents one activity. * an activity has an ID and a name, from nepomuk. @@ -58,28 +59,19 @@ Activity(const QString &id, Plasma::Corona *parent = 0); ~Activity() override; - QString id(); - QString name(); - QPixmap pixmap(const QSize &size); //FIXME do we want diff. sizes? updates? - - enum State { - Invalid = KActivities::Info::Invalid, - Running = KActivities::Info::Running, - Starting = KActivities::Info::Starting, - Stopped = KActivities::Info::Stopped, - Stopping = KActivities::Info::Stopping, - PreCreation = 32 - }; + QString id() const; + QString name() const; + QPixmap pixmap(const QSize &size) const; //FIXME do we want diff. sizes? updates? /** * whether this is the currently active activity */ - bool isCurrent(); + bool isCurrent() const; /** * state of the activity */ - KActivities::Info::State state(); + KActivities::Info::State state() const; /** * set the plugin to use when creating new containments @@ -132,18 +124,13 @@ void open(); private Q_SLOTS: - void activityChanged(); - void checkIfCurrent(); void cleanupActivity(); private: - QString m_id; - QString m_name; - QString m_icon; + KActivities::Info m_info; QString m_plugin; - KActivities::Info *m_info; - KActivities::Consumer *m_activityConsumer; - bool m_current; + std::shared_ptr m_activityController; + }; #endif diff --git a/shell/activity.cpp b/shell/activity.cpp --- a/shell/activity.cpp +++ b/shell/activity.cpp @@ -1,5 +1,6 @@ /* * Copyright 2010 Chani Armitage + * Copyright 2016 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 @@ -35,124 +36,123 @@ #include #include -#include #include "activity.h" -Activity::Activity(const QString &id, Plasma::Corona *parent) - : QObject(parent), - m_id(id), - m_plugin(QStringLiteral("org.kde.desktopcontainment")),//FIXME ask the corona - m_info(new KActivities::Info(id, this)), - m_activityConsumer(new KActivities::Consumer(this)), - m_current(false) -{ - m_name = m_info->name(); - m_icon = m_info->icon(); +#include +// #include + +namespace { + std::shared_ptr activitiesControllerInstance() + { + static std::weak_ptr s_instance; - connect(m_info, &KActivities::Info::infoChanged, this, &Activity::activityChanged); - connect(m_info, &KActivities::Info::stateChanged, this, &Activity::stateChanged); - connect(m_info, &KActivities::Info::started, this, &Activity::opened); - connect(m_info, &KActivities::Info::stopped, this, &Activity::closed); - connect(m_info, &KActivities::Info::removed, this, &Activity::removed); - connect(m_info, &KActivities::Info::removed, this, &Activity::cleanupActivity); + // TODO: If it turns out we need these in multiple threads, + // all hell will break loose (well, not really) + // static std::mutex sharedSingleton; + // std::lock_guard sharedSingletonLock(sharedSingleton); + + auto result = s_instance.lock(); + + if (s_instance.expired()) { + result.reset(new KActivities::Controller()); + s_instance = result; + } + + return result; + } - connect(m_activityConsumer, &KActivities::Consumer::currentActivityChanged, this, &Activity::checkIfCurrent); - checkIfCurrent(); } -Activity::~Activity() +Activity::Activity(const QString &id, Plasma::Corona *parent) + : QObject(parent), + m_info(id), + m_plugin(QStringLiteral("org.kde.desktopcontainment")),//FIXME ask the corona + m_activityController(activitiesControllerInstance()) { + connect(&m_info, &KActivities::Info::stateChanged, this, &Activity::stateChanged); + connect(&m_info, &KActivities::Info::started, this, &Activity::opened); + connect(&m_info, &KActivities::Info::stopped, this, &Activity::closed); + connect(&m_info, &KActivities::Info::removed, this, &Activity::removed); + connect(&m_info, &KActivities::Info::removed, this, &Activity::cleanupActivity); } -void Activity::activityChanged() +Activity::~Activity() { - setName(m_info->name()); - setIcon(m_info->icon()); } -QString Activity::id() +QString Activity::id() const { - return m_id; + return m_info.id(); } -QString Activity::name() +QString Activity::name() const { - return m_name; + return m_info.name(); } -QPixmap Activity::pixmap(const QSize &size) +QPixmap Activity::pixmap(const QSize &size) const { - if (m_info->isValid() && !m_info->icon().isEmpty()) { - return QIcon::fromTheme(m_info->icon()).pixmap(size); + if (m_info.isValid() && !m_info.icon().isEmpty()) { + return QIcon::fromTheme(m_info.icon()).pixmap(size); } else { - return KIdenticonGenerator::self()->generatePixmap(size.width(), m_id); + return QIcon().pixmap(size); } } -bool Activity::isCurrent() +bool Activity::isCurrent() const { - return m_current; - //TODO maybe plasmaapp should cache the current activity to reduce dbus calls? -} - -void Activity::checkIfCurrent() -{ - const bool current = m_id == m_activityConsumer->currentActivity(); - if (current != m_current) { - m_current = current; - emit currentStatusChanged(); - } + return m_info.isCurrent(); } -KActivities::Info::State Activity::state() +KActivities::Info::State Activity::state() const { - return m_info->state(); + return m_info.state(); } void Activity::remove() { - KActivities::Controller().removeActivity(m_id); + m_activityController->removeActivity(m_info.id()); } void Activity::cleanupActivity() { - const QString name = "activities/" + m_id; + const QString name = "activities/" + m_info.id(); QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation)+QChar('/')+name); } void Activity::activate() { - KActivities::Controller().setCurrentActivity(m_id); + m_activityController->setCurrentActivity(m_info.id()); } void Activity::setName(const QString &name) { - m_name = name; + m_activityController->setActivityName(m_info.id(), name); } void Activity::setIcon(const QString &icon) { - m_icon = icon; + m_activityController->setActivityIcon(m_info.id(), icon); } void Activity::close() { - KActivities::Controller().stopActivity(m_id); + m_activityController->stopActivity(m_info.id()); } KConfigGroup Activity::config() const { - const QString name = "activities/" + m_id; + const QString name = "activities/" + m_info.id(); KConfig external(name, KConfig::SimpleConfig, QStandardPaths::GenericDataLocation); //passing an empty string for the group name turns a kconfig into a kconfiggroup return external.group(QString()); } void Activity::open() { - KActivities::Controller().startActivity(m_id); + m_activityController->startActivity(m_info.id()); } void Activity::setDefaultPlugin(const QString &plugin) @@ -168,7 +168,7 @@ const KActivities::Info * Activity::info() const { - return m_info; + return &m_info; }