1 /*
2 * SPDX-FileCopyrightText: 2013 Daniel Vrátil <dvratil@redhat.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 *
6 */
7
8 #include "monitorsmodel.h"
9 #include "akonadiconsole_debug.h"
10 #include <Akonadi/Monitor>
11 #include <Akonadi/Session>
12
13 #include <QTimer>
14
15 #ifndef COMPILE_WITH_UNITY_CMAKE_SUPPORT
Q_DECLARE_METATYPE(Akonadi::NotificationSubscriber)16 Q_DECLARE_METATYPE(Akonadi::NotificationSubscriber)
17 #endif
18
19 MonitorsModel::MonitorsModel(QObject *parent)
20 : QAbstractItemModel(parent)
21 {
22 QTimer::singleShot(0, this, &MonitorsModel::init);
23 }
24
~MonitorsModel()25 MonitorsModel::~MonitorsModel()
26 {
27 }
28
init()29 void MonitorsModel::init()
30 {
31 mMonitor = new Akonadi::Monitor(this);
32 mMonitor->setTypeMonitored(Akonadi::Monitor::Subscribers, true);
33 connect(mMonitor, &Akonadi::Monitor::notificationSubscriberAdded, this, &MonitorsModel::slotSubscriberAdded);
34 connect(mMonitor, &Akonadi::Monitor::notificationSubscriberChanged, this, &MonitorsModel::slotSubscriberChanged);
35 connect(mMonitor, &Akonadi::Monitor::notificationSubscriberRemoved, this, &MonitorsModel::slotSubscriberRemoved);
36 }
37
indexForSession(const QByteArray & session)38 QModelIndex MonitorsModel::indexForSession(const QByteArray &session)
39 {
40 int pos = mSessions.indexOf(session);
41 if (pos == -1) {
42 pos = mSessions.count();
43 beginInsertRows({}, pos, pos);
44 mSessions.push_back(session);
45 mData.insert(session, {});
46 endInsertRows();
47 }
48
49 return index(pos, 0);
50 }
51
slotSubscriberAdded(const Akonadi::NotificationSubscriber & subscriber)52 void MonitorsModel::slotSubscriberAdded(const Akonadi::NotificationSubscriber &subscriber)
53 {
54 auto sessionIdx = indexForSession(subscriber.sessionId());
55 auto &sessions = mData[subscriber.sessionId()];
56 beginInsertRows(sessionIdx, sessions.count(), sessions.count());
57 sessions.push_back(subscriber);
58 endInsertRows();
59 }
60
slotSubscriberRemoved(const Akonadi::NotificationSubscriber & subscriber)61 void MonitorsModel::slotSubscriberRemoved(const Akonadi::NotificationSubscriber &subscriber)
62 {
63 int idx = -1;
64 auto sessionIdx = indexForSession(subscriber.sessionId());
65 auto &sessions = mData[subscriber.sessionId()];
66 for (auto it = sessions.begin(), end = sessions.end(); it != end; ++it) {
67 ++idx;
68 if (it->subscriber() == subscriber.subscriber()) {
69 beginRemoveRows(sessionIdx, idx, idx);
70 sessions.erase(it);
71 endRemoveRows();
72 return;
73 }
74 }
75 }
76
slotSubscriberChanged(const Akonadi::NotificationSubscriber & subscriber)77 void MonitorsModel::slotSubscriberChanged(const Akonadi::NotificationSubscriber &subscriber)
78 {
79 int row = -1;
80 auto sessionIdx = indexForSession(subscriber.sessionId());
81 auto sessions = mData[subscriber.sessionId()];
82 for (auto it = sessions.begin(), end = sessions.end(); it != end; ++it) {
83 ++row;
84 if (it->subscriber() == subscriber.subscriber()) {
85 *it = subscriber;
86 const auto idx = index(row, 0, sessionIdx);
87 Q_EMIT dataChanged(idx, idx);
88 return;
89 }
90 }
91 }
92
headerData(int section,Qt::Orientation orientation,int role) const93 QVariant MonitorsModel::headerData(int section, Qt::Orientation orientation, int role) const
94 {
95 if (role == Qt::DisplayRole) {
96 if (orientation == Qt::Horizontal) {
97 if (section == 0) {
98 return QStringLiteral("Session/Subscriber");
99 }
100 }
101 }
102
103 return QVariant();
104 }
105
data(const QModelIndex & index,int role) const106 QVariant MonitorsModel::data(const QModelIndex &index, int role) const
107 {
108 if (!index.isValid() || index.column() != 0) {
109 return QVariant();
110 }
111 if ((int)index.internalId() == -1) {
112 if (index.row() >= mSessions.count()) {
113 return {};
114 }
115
116 if (role == Qt::DisplayRole) {
117 return mSessions.at(index.row());
118 }
119 } else {
120 const auto session = mSessions.at(index.parent().row());
121 const auto subscribers = mData.value(session);
122 if (index.row() >= subscribers.count()) {
123 return {};
124 }
125 const auto subscriber = subscribers.at(index.row());
126 if (role == Qt::DisplayRole || role == Qt::ToolTipRole) {
127 return subscriber.subscriber();
128 } else if (role == SubscriberRole) {
129 return QVariant::fromValue(subscriber);
130 }
131 }
132
133 return QVariant();
134 }
135
columnCount(const QModelIndex & parent) const136 int MonitorsModel::columnCount(const QModelIndex &parent) const
137 {
138 Q_UNUSED(parent)
139 return 1;
140 }
141
rowCount(const QModelIndex & parent) const142 int MonitorsModel::rowCount(const QModelIndex &parent) const
143 {
144 if (!parent.isValid()) {
145 return mSessions.count();
146 }
147
148 if ((int)parent.internalId() == -1) {
149 const auto session = mSessions.at(parent.row());
150 return mData.value(session).count();
151 }
152
153 return 0;
154 }
155
parent(const QModelIndex & child) const156 QModelIndex MonitorsModel::parent(const QModelIndex &child) const
157 {
158 if ((int)child.internalId() == -1) {
159 return {};
160 } else {
161 return index(child.internalId(), 0, {});
162 }
163
164 return QModelIndex();
165 }
166
index(int row,int column,const QModelIndex & parent) const167 QModelIndex MonitorsModel::index(int row, int column, const QModelIndex &parent) const
168 {
169 if (!parent.isValid()) {
170 return createIndex(row, column, -1);
171 }
172
173 return createIndex(row, column, parent.row());
174 }
175