File indexing completed on 2023-09-24 04:02:48

0001 /*
0002     SPDX-FileCopyrightText: 2010-2016 Ivan Cukic <ivan.cukic(at)kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "info.h"
0008 #include "info_p.h"
0009 #include "manager_p.h"
0010 
0011 #include "utils/dbusfuture_p.h"
0012 
0013 #include <QFileSystemWatcher>
0014 
0015 namespace KActivities
0016 {
0017 // InfoPrivate
0018 
0019 InfoPrivate::InfoPrivate(Info *info, const QString &activity)
0020     : q(info)
0021     , cache(ActivitiesCache::self())
0022     , id(activity)
0023 {
0024 }
0025 
0026 // clang-format off
0027 // Filters out signals for only this activity
0028 #define IMPLEMENT_SIGNAL_HANDLER(INTERNAL)                                     \
0029     void InfoPrivate::INTERNAL(const QString &_id) const                       \
0030     {   if (id == _id) Q_EMIT q->INTERNAL(); }
0031 
0032 IMPLEMENT_SIGNAL_HANDLER(added)
0033 IMPLEMENT_SIGNAL_HANDLER(removed)
0034 IMPLEMENT_SIGNAL_HANDLER(started)
0035 IMPLEMENT_SIGNAL_HANDLER(stopped)
0036 IMPLEMENT_SIGNAL_HANDLER(infoChanged)
0037 
0038 #undef IMPLEMENT_SIGNAL_HANDLER
0039 
0040 #define IMPLEMENT_SIGNAL_HANDLER(INTERNAL)                                     \
0041     void InfoPrivate::INTERNAL##Changed(const QString &_id,                    \
0042                                         const QString &val) const              \
0043     {                                                                          \
0044         if (id == _id) {                                                       \
0045             Q_EMIT q->INTERNAL##Changed(val);                                    \
0046         }                                                                      \
0047     }
0048 
0049 IMPLEMENT_SIGNAL_HANDLER(name)
0050 IMPLEMENT_SIGNAL_HANDLER(description)
0051 IMPLEMENT_SIGNAL_HANDLER(icon)
0052 
0053 #undef IMPLEMENT_SIGNAL_HANDLER
0054 
0055 void InfoPrivate::activityStateChanged(const QString &idChanged,
0056                                        int newState) const
0057 {
0058     if (idChanged == id) {
0059         auto state = static_cast<Info::State>(newState);
0060         Q_EMIT q->stateChanged(state);
0061 
0062         if (state == KActivities::Info::Stopped) {
0063             Q_EMIT q->stopped();
0064         } else if (state == KActivities::Info::Running) {
0065             Q_EMIT q->started();
0066         }
0067     }
0068 }
0069 
0070 void InfoPrivate::setCurrentActivity(const QString &currentActivity)
0071 {
0072     if (isCurrent) {
0073         if (currentActivity != id) {
0074             // We are no longer the current activity
0075             isCurrent = false;
0076             Q_EMIT q->isCurrentChanged(false);
0077         }
0078     } else {
0079         if (currentActivity == id) {
0080             // We are the current activity
0081             isCurrent = true;
0082             Q_EMIT q->isCurrentChanged(true);
0083         }
0084     }
0085 }
0086 
0087 // Info
0088 Info::Info(const QString &activity, QObject *parent)
0089     : QObject(parent)
0090     , d(new InfoPrivate(this, activity))
0091 {
0092     // qDebug() << "Created an instance of Info: " << (void*)this;
0093 #define PASS_SIGNAL_HANDLER(SIGNAL_NAME,SLOT_NAME)                            \
0094     connect(d->cache.get(),  SIGNAL(SIGNAL_NAME(QString)),                     \
0095             this,            SLOT(SLOT_NAME(QString)));
0096 
0097     PASS_SIGNAL_HANDLER(activityAdded,added)
0098     PASS_SIGNAL_HANDLER(activityRemoved,removed)
0099     // PASS_SIGNAL_HANDLER(started)
0100     // PASS_SIGNAL_HANDLER(stopped)
0101     PASS_SIGNAL_HANDLER(activityChanged,infoChanged)
0102 #undef PASS_SIGNAL_HANDLER
0103 
0104 #define PASS_SIGNAL_HANDLER(SIGNAL_NAME,SLOT_NAME,TYPE)                      \
0105     connect(d->cache.get(),  SIGNAL(SIGNAL_NAME(QString,TYPE)),               \
0106             this,            SLOT(SLOT_NAME(QString,TYPE)));                  \
0107 
0108     PASS_SIGNAL_HANDLER(activityStateChanged,activityStateChanged,int);
0109     PASS_SIGNAL_HANDLER(activityNameChanged,nameChanged,QString);
0110     PASS_SIGNAL_HANDLER(activityDescriptionChanged,descriptionChanged,QString);
0111     PASS_SIGNAL_HANDLER(activityIconChanged,iconChanged,QString);
0112 // clang-format on
0113 #undef PASS_SIGNAL_HANDLER
0114     connect(d->cache.get(), SIGNAL(currentActivityChanged(QString)), this, SLOT(setCurrentActivity(QString)));
0115 
0116     d->isCurrent = (d->cache.get()->m_currentActivity == activity);
0117 }
0118 
0119 Info::~Info()
0120 {
0121     // qDebug() << "Deleted an instance of Info: " << (void*)this;
0122 }
0123 
0124 bool Info::isValid() const
0125 {
0126     auto currentState = state();
0127     return (currentState != Invalid && currentState != Unknown);
0128 }
0129 
0130 QString Info::uri() const
0131 {
0132     return QStringLiteral("activities://") + d->id;
0133 }
0134 
0135 QString Info::id() const
0136 {
0137     return d->id;
0138 }
0139 
0140 bool Info::isCurrent() const
0141 {
0142     return d->isCurrent;
0143 }
0144 
0145 Info::State Info::state() const
0146 {
0147     if (d->cache->m_status == Consumer::Unknown) {
0148         return Info::Unknown;
0149     }
0150 
0151     auto info = d->cache->getInfo(d->id);
0152 
0153     if (!info) {
0154         return Info::Invalid;
0155     }
0156 
0157     return static_cast<Info::State>(info->state);
0158 }
0159 
0160 void InfoPrivate::setServiceStatus(Consumer::ServiceStatus status) const
0161 {
0162     switch (status) {
0163     case Consumer::NotRunning:
0164     case Consumer::Unknown:
0165         activityStateChanged(id, Info::Unknown);
0166         break;
0167 
0168     default:
0169         activityStateChanged(id, q->state());
0170         break;
0171     }
0172 }
0173 
0174 Info::Availability Info::availability() const
0175 {
0176     Availability result = Nothing;
0177 
0178     if (!Manager::isServiceRunning()) {
0179         return result;
0180     }
0181 
0182     if (Manager::activities()->ListActivities().value().contains(d->id)) {
0183         result = BasicInfo;
0184 
0185         if (Manager::features()->IsFeatureOperational(QStringLiteral("resources/linking"))) {
0186             result = Everything;
0187         }
0188     }
0189 
0190     return result;
0191 }
0192 
0193 // clang-format off
0194 #define CREATE_GETTER(What)                                                    \
0195     QString Info::What() const                                                 \
0196     {                                                                          \
0197         auto info = d->cache->getInfo(d->id);                                  \
0198         return info ? info->What : QString();                                  \
0199     }
0200 // clang-format on
0201 
0202 CREATE_GETTER(name)
0203 CREATE_GETTER(description)
0204 CREATE_GETTER(icon)
0205 
0206 #undef CREATE_GETTER
0207 
0208 } // namespace KActivities
0209 
0210 #include "moc_info.cpp"