File indexing completed on 2024-05-12 05:12:46

0001 /*
0002  * SPDX-FileCopyrightText: 2013 Daniel Vrátil <dvratil@redhat.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  *
0006  */
0007 
0008 #include "monitorsmodel.h"
0009 #include "akonadiconsole_debug.h"
0010 #include <Akonadi/Monitor>
0011 #include <Akonadi/Session>
0012 #include <KLocalizedString>
0013 
0014 #include <QTimer>
0015 
0016 #ifndef COMPILE_WITH_UNITY_CMAKE_SUPPORT
0017 Q_DECLARE_METATYPE(Akonadi::NotificationSubscriber)
0018 #endif
0019 
0020 MonitorsModel::MonitorsModel(QObject *parent)
0021     : QAbstractItemModel(parent)
0022 {
0023     QTimer::singleShot(0, this, &MonitorsModel::init);
0024 }
0025 
0026 MonitorsModel::~MonitorsModel() = default;
0027 
0028 void MonitorsModel::init()
0029 {
0030     mMonitor = new Akonadi::Monitor(this);
0031     mMonitor->setTypeMonitored(Akonadi::Monitor::Subscribers, true);
0032     connect(mMonitor, &Akonadi::Monitor::notificationSubscriberAdded, this, &MonitorsModel::slotSubscriberAdded);
0033     connect(mMonitor, &Akonadi::Monitor::notificationSubscriberChanged, this, &MonitorsModel::slotSubscriberChanged);
0034     connect(mMonitor, &Akonadi::Monitor::notificationSubscriberRemoved, this, &MonitorsModel::slotSubscriberRemoved);
0035 }
0036 
0037 QModelIndex MonitorsModel::indexForSession(const QByteArray &session)
0038 {
0039     int pos = mSessions.indexOf(session);
0040     if (pos == -1) {
0041         pos = mSessions.count();
0042         beginInsertRows({}, pos, pos);
0043         mSessions.push_back(session);
0044         mData.insert(session, {});
0045         endInsertRows();
0046     }
0047 
0048     return index(pos, 0);
0049 }
0050 
0051 void MonitorsModel::slotSubscriberAdded(const Akonadi::NotificationSubscriber &subscriber)
0052 {
0053     auto sessionIdx = indexForSession(subscriber.sessionId());
0054     auto &sessions = mData[subscriber.sessionId()];
0055     beginInsertRows(sessionIdx, sessions.count(), sessions.count());
0056     sessions.push_back(subscriber);
0057     endInsertRows();
0058 }
0059 
0060 void MonitorsModel::slotSubscriberRemoved(const Akonadi::NotificationSubscriber &subscriber)
0061 {
0062     int idx = -1;
0063     auto sessionIdx = indexForSession(subscriber.sessionId());
0064     auto &sessions = mData[subscriber.sessionId()];
0065     for (auto it = sessions.begin(), end = sessions.end(); it != end; ++it) {
0066         ++idx;
0067         if (it->subscriber() == subscriber.subscriber()) {
0068             beginRemoveRows(sessionIdx, idx, idx);
0069             sessions.erase(it);
0070             endRemoveRows();
0071             return;
0072         }
0073     }
0074 }
0075 
0076 void MonitorsModel::slotSubscriberChanged(const Akonadi::NotificationSubscriber &subscriber)
0077 {
0078     int row = -1;
0079     auto sessionIdx = indexForSession(subscriber.sessionId());
0080     auto sessions = mData[subscriber.sessionId()];
0081     for (auto it = sessions.begin(), end = sessions.end(); it != end; ++it) {
0082         ++row;
0083         if (it->subscriber() == subscriber.subscriber()) {
0084             *it = subscriber;
0085             const auto idx = index(row, 0, sessionIdx);
0086             Q_EMIT dataChanged(idx, idx);
0087             return;
0088         }
0089     }
0090 }
0091 
0092 QVariant MonitorsModel::headerData(int section, Qt::Orientation orientation, int role) const
0093 {
0094     if (role == Qt::DisplayRole) {
0095         if (orientation == Qt::Horizontal) {
0096             if (section == 0) {
0097                 return i18n("Session/Subscriber");
0098             }
0099         }
0100     }
0101 
0102     return {};
0103 }
0104 
0105 QVariant MonitorsModel::data(const QModelIndex &index, int role) const
0106 {
0107     if (!index.isValid() || index.column() != 0) {
0108         return {};
0109     }
0110     if ((int)index.internalId() == -1) {
0111         if (index.row() >= mSessions.count()) {
0112             return {};
0113         }
0114 
0115         if (role == Qt::DisplayRole) {
0116             return mSessions.at(index.row());
0117         }
0118     } else {
0119         const auto session = mSessions.at(index.parent().row());
0120         const auto subscribers = mData.value(session);
0121         if (index.row() >= subscribers.count()) {
0122             return {};
0123         }
0124         const auto subscriber = subscribers.at(index.row());
0125         if (role == Qt::DisplayRole || role == Qt::ToolTipRole) {
0126             return subscriber.subscriber();
0127         } else if (role == SubscriberRole) {
0128             return QVariant::fromValue(subscriber);
0129         }
0130     }
0131 
0132     return {};
0133 }
0134 
0135 int MonitorsModel::columnCount(const QModelIndex &parent) const
0136 {
0137     Q_UNUSED(parent)
0138     return 1;
0139 }
0140 
0141 int MonitorsModel::rowCount(const QModelIndex &parent) const
0142 {
0143     if (!parent.isValid()) {
0144         return mSessions.count();
0145     }
0146 
0147     if ((int)parent.internalId() == -1) {
0148         const auto session = mSessions.at(parent.row());
0149         return mData.value(session).count();
0150     }
0151 
0152     return 0;
0153 }
0154 
0155 QModelIndex MonitorsModel::parent(const QModelIndex &child) const
0156 {
0157     if ((int)child.internalId() == -1) {
0158         return {};
0159     } else {
0160         return index(child.internalId(), 0, {});
0161     }
0162 
0163     return {};
0164 }
0165 
0166 QModelIndex MonitorsModel::index(int row, int column, const QModelIndex &parent) const
0167 {
0168     if (!parent.isValid()) {
0169         return createIndex(row, column, -1);
0170     }
0171 
0172     return createIndex(row, column, parent.row());
0173 }
0174 
0175 #include "moc_monitorsmodel.cpp"