8#include "activitiesmodel.h"
9#include "activitiesmodel_p.h"
13#include <QDBusPendingCall>
14#include <QDBusPendingCallWatcher>
16#include <QFutureWatcher>
21#include "utils/remove_if.h"
27template<
typename _Container>
28struct ActivityPosition {
36 ActivityPosition(
unsigned int index,
typename _Container::const_iterator iterator)
49 const unsigned int index;
50 const typename _Container::const_iterator iterator;
52 typedef typename _Container::value_type ContainerElement;
60inline bool matchingState(ActivitiesModelPrivate::InfoPtr activity,
const T &states)
62 return states.empty() || states.contains(activity->state());
69template<
typename _Container>
70inline ActivityPosition<_Container> activityPosition(
const _Container &container,
const QString &activityId)
72 auto position = std::find_if(container.begin(), container.end(), [&](
const typename ActivityPosition<_Container>::ContainerElement &activity) {
73 return activity->id() == activityId;
76 return (position != container.end()) ? ActivityPosition<_Container>(position - container.begin(), position) : ActivityPosition<_Container>();
82template<
typename _Model,
typename _Container>
83inline void emitActivityUpdated(_Model *model,
const _Container &container,
const QString &activity,
int role)
85 auto position = Private::activityPosition(container, activity);
88 Q_EMIT model->q->dataChanged(model->q->index(position.index),
89 model->q->index(position.index),
90 role ==
Qt::DecorationRole ? QList<int>{role, ActivitiesModel::ActivityIconSource} : QList<int>{role});
97template<
typename _Model,
typename _Container>
98inline void emitActivityUpdated(_Model *model,
const _Container &container, QObject *activityInfo,
int role)
100 const auto activity =
static_cast<Info *
>(activityInfo);
101 emitActivityUpdated(model, container, activity->id(), role);
111ActivitiesModel::ActivitiesModel(
QObject *parent)
113 , d(new ActivitiesModelPrivate(this))
116 connect(&d->activities, &Consumer::serviceStatusChanged,
this, [
this](Consumer::ServiceStatus
status) {
117 d->setServiceStatus(status);
120 connect(&d->activities, &Consumer::activityAdded,
this, [
this](
const QString &activity) {
121 d->onActivityAdded(activity);
123 connect(&d->activities, &Consumer::activityRemoved,
this, [
this](
const QString &activity) {
124 d->onActivityRemoved(activity);
126 connect(&d->activities, &Consumer::currentActivityChanged,
this, [
this](
const QString &activity) {
127 d->onCurrentActivityChanged(activity);
130 d->setServiceStatus(d->activities.serviceStatus());
135 , d(new ActivitiesModelPrivate(this))
137 d->shownStates = shownStates;
141 d->setServiceStatus(status);
145 d->onActivityAdded(activity);
148 d->onActivityRemoved(activity);
151 d->onCurrentActivityChanged(activity);
154 d->setServiceStatus(d->activities.serviceStatus());
157ActivitiesModel::~ActivitiesModel() =
default;
172 replaceActivities(activities.activities());
175void ActivitiesModelPrivate::replaceActivities(
const QStringList &activities)
177 q->beginResetModel();
179 knownActivities.clear();
180 shownActivities.clear();
182 for (
const QString &activity : activities) {
183 onActivityAdded(activity,
false);
189void ActivitiesModelPrivate::onActivityAdded(
const QString &
id,
bool notifyClients)
191 auto info = registerActivity(
id);
193 showActivity(info, notifyClients);
196void ActivitiesModelPrivate::onActivityRemoved(
const QString &
id)
199 unregisterActivity(
id);
202void ActivitiesModelPrivate::onCurrentActivityChanged(
const QString &
id)
206 for (
const auto &activity : shownActivities) {
211ActivitiesModelPrivate::InfoPtr ActivitiesModelPrivate::registerActivity(
const QString &
id)
213 auto position = Private::activityPosition(knownActivities,
id);
216 return *(position.iterator);
219 auto activityInfo = std::make_shared<Info>(
id);
221 auto ptr = activityInfo.get();
228 knownActivities.insert(InfoPtr(activityInfo));
234void ActivitiesModelPrivate::unregisterActivity(
const QString &
id)
236 auto position = Private::activityPosition(knownActivities,
id);
239 if (
auto shown = Private::activityPosition(shownActivities,
id)) {
240 q->beginRemoveRows(QModelIndex(), shown.index, shown.index);
241 shownActivities.removeAt(shown.index);
245 knownActivities.removeAt(position.index);
249void ActivitiesModelPrivate::showActivity(InfoPtr activityInfo,
bool notifyClients)
252 if (!Private::matchingState(activityInfo, shownStates)) {
257 if (std::binary_search(shownActivities.cbegin(), shownActivities.cend(), activityInfo, InfoPtrComparator())) {
261 auto registeredPosition = Private::activityPosition(knownActivities, activityInfo->id());
263 if (!registeredPosition) {
264 qDebug() <<
"Got a request to show an unknown activity, ignoring";
268 const auto activityInfoPtr = *(registeredPosition.iterator);
272 const auto _result = shownActivities.insert(activityInfoPtr);
274 const auto index = std::get<1>(_result);
277 q->beginInsertRows(QModelIndex(), index, index);
282void ActivitiesModelPrivate::hideActivity(
const QString &
id)
284 auto position = Private::activityPosition(shownActivities,
id);
287 q->beginRemoveRows(QModelIndex(), position.index, position.index);
288 shownActivities.removeAt(position.index);
294#define CREATE_SIGNAL_EMITTER(What,Role) \
295 void ActivitiesModelPrivate::onActivity##What##Changed(const QString &) \
297 Private::emitActivityUpdated(this, shownActivities, sender(), Role); \
305#undef CREATE_SIGNAL_EMITTER
307void ActivitiesModelPrivate::onActivityStateChanged(
Info::State state)
309 if (shownStates.empty()) {
313 auto info = findActivity(sender());
319 if (shownStates.contains(state)) {
320 showActivity(info,
true);
322 hideActivity(info->id());
329 d->shownStates = states;
331 d->replaceActivities(d->activities.activities());
333 Q_EMIT shownStatesChanged(states);
338 return d->shownStates;
341int ActivitiesModel::rowCount(
const QModelIndex &parent)
const
347 return d->shownActivities.size();
350QVariant ActivitiesModel::data(
const QModelIndex &index,
int role)
const
352 const int row =
index.row();
353 const auto &item = d->shownActivities.at(row);
364 return item->state();
368 const QString &icon = item->icon();
371 return icon.
isEmpty() ? QStringLiteral(
"activities") : icon;
375 return item->description();
378 return d->activities.currentActivity() == item->id();
385QVariant ActivitiesModel::headerData(
int section,
Qt::Orientation orientation,
int role)
const
388 Q_UNUSED(orientation);
394ActivitiesModelPrivate::InfoPtr ActivitiesModelPrivate::findActivity(QObject *ptr)
const
396 auto info = std::find_if(knownActivities.cbegin(), knownActivities.cend(), [ptr](
const InfoPtr &info) {
397 return ptr == info.get();
400 if (info == knownActivities.end()) {
409#include "moc_activitiesmodel.cpp"
410#include "moc_activitiesmodel_p.cpp"
Data model that shows existing activities.
void setShownStates(const QList< Info::State > &shownStates)
The model can filter the list of activities based on their state.
@ ActivityState
The current state of the activity.
@ ActivityDescription
Activity description.
@ ActivityIsCurrent
Is this activity the current one current.
@ ActivityId
UUID of the activity.
@ ActivityIconSource
Activity icon source name.
@ ActivityName
Activity name.
@ ActivityBackground
Activity wallpaper (currently unsupported)
ServiceStatus
Different states of the activities service.
void activityAdded(const QString &id)
This signal is emitted when a new activity is added.
void currentActivityChanged(const QString &id)
This signal is emitted when the current activity is changed.
void activityRemoved(const QString &id)
This signal is emitted when an activity has been removed.
void serviceStatusChanged(Consumer::ServiceStatus status)
This signal is emitted when the activity service goes online or offline, or when the class manages to...
State
State of the activity.
void descriptionChanged(const QString &description)
Emitted when the description is changed.
void nameChanged(const QString &name)
Emitted when the name is changed.
void stateChanged(KActivities::Info::State state)
Emitted when the activity changes state.
void iconChanged(const QString &icon)
Emitted when the icon was changed.
Q_SCRIPTABLE CaptureState status()
Namespace for everything in libkactivities.
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual QModelIndex parent(const QModelIndex &index) const const=0
QAbstractListModel(QObject *parent)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)