File indexing completed on 2024-06-23 05:45:41

0001 /*
0002  * Copyright 2020 Han Young <hanyoung@protonmail.com>
0003  * Copyright 2020-2021 Devin Lin <devin@kde.org>
0004  * Copyright 2021 Boris Petrov <boris.v.petrov@protonmail.com>
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include "timermodel.h"
0010 
0011 #include "timer.h"
0012 
0013 #include <QDebug>
0014 #include <QJsonArray>
0015 #include <QJsonDocument>
0016 #include <QJsonObject>
0017 #include <QtGlobal>
0018 
0019 TimerModel *TimerModel::instance()
0020 {
0021     static TimerModel *singleton = new TimerModel();
0022     return singleton;
0023 }
0024 
0025 TimerModel::TimerModel(QObject *parent)
0026     : QAbstractListModel{parent}
0027     , m_interface(new OrgKdeKclockTimerModelInterface(QStringLiteral("org.kde.kclockd"), QStringLiteral("/Timers"), QDBusConnection::sessionBus(), this))
0028 {
0029     if (m_interface->isValid()) {
0030         // connect timer signals
0031         connect(m_interface, SIGNAL(timerAdded(QString)), this, SLOT(addTimer(QString)));
0032         connect(m_interface, SIGNAL(timerRemoved(QString)), this, SLOT(removeTimer(QString)));
0033     }
0034 
0035     // load timers
0036     const QStringList timers = m_interface->timers();
0037     for (const QString &timerId : timers) {
0038         addTimer(timerId);
0039     }
0040 
0041     // watch for kclockd's status
0042     setConnectedToDaemon(m_interface->isValid());
0043     m_watcher = new QDBusServiceWatcher(QStringLiteral("org.kde.kclockd"), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
0044     connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, [this]() -> void {
0045         setConnectedToDaemon(true);
0046     });
0047     connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, [this]() -> void {
0048         setConnectedToDaemon(false);
0049     });
0050 }
0051 
0052 int TimerModel::rowCount(const QModelIndex &parent) const
0053 {
0054     Q_UNUSED(parent);
0055     return m_timersList.size();
0056 }
0057 
0058 QVariant TimerModel::data(const QModelIndex &index, int role) const
0059 {
0060     Q_UNUSED(role)
0061 
0062     if ((index.row() < 0) || (index.row() >= m_timersList.count()))
0063         return {};
0064 
0065     return QVariant::fromValue(m_timersList.at(index.row()));
0066 }
0067 
0068 QHash<int, QByteArray> TimerModel::roleNames() const
0069 {
0070     return {{TimerRole, "timer"}};
0071 }
0072 
0073 void TimerModel::addNew(int length, QString label, QString commandTimeout)
0074 {
0075     m_interface->addTimer(length, label, commandTimeout, false);
0076 }
0077 
0078 void TimerModel::remove(int index)
0079 {
0080     if (index < 0 || index >= m_timersList.size())
0081         return;
0082 
0083     // request kclockd to remove timer, which will trigger a signal back to remove it from the UI
0084     m_interface->removeTimer(m_timersList.at(index)->uuid().toString());
0085 }
0086 
0087 void TimerModel::addTimer(QString uuid)
0088 {
0089     auto *timer = new Timer(uuid.remove(QRegularExpression(QStringLiteral("[{}-]"))));
0090 
0091     Q_EMIT beginInsertRows(QModelIndex(), 0, 0);
0092     m_timersList.insert(0, timer);
0093     Q_EMIT endInsertRows();
0094 }
0095 
0096 void TimerModel::removeTimer(const QString &uuid)
0097 {
0098     for (int i = 0; i < m_timersList.size(); ++i) {
0099         if (m_timersList[i]->uuid().toString() == uuid) {
0100             beginRemoveRows(QModelIndex(), i, i);
0101             m_timersList.at(i)->deleteLater();
0102             m_timersList.removeAt(i);
0103             endRemoveRows();
0104         }
0105     }
0106 }
0107 
0108 bool TimerModel::connectedToDaemon()
0109 {
0110     return m_connectedToDaemon;
0111 }
0112 
0113 void TimerModel::setConnectedToDaemon(bool connectedToDaemon)
0114 {
0115     if (m_connectedToDaemon != connectedToDaemon) {
0116         m_connectedToDaemon = connectedToDaemon;
0117         Q_EMIT connectedToDaemonChanged();
0118     }
0119 }