File indexing completed on 2024-06-16 05:22:24

0001 /*
0002  * Copyright 2020-2021 Devin Lin <devin@kde.org>
0003  * Copyright 2021 Boris Petrov <boris.v.petrov@protonmail.com>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "timermodel.h"
0009 
0010 #include "timer.h"
0011 
0012 #include <KConfigGroup>
0013 #include <KLocalizedString>
0014 #include <KNotification>
0015 #include <KSharedConfig>
0016 
0017 #include <QDBusConnection>
0018 #include <QJsonArray>
0019 #include <QJsonDocument>
0020 #include <QJsonObject>
0021 
0022 const QString TIMERS_CFG_GROUP = QStringLiteral("Timers"), TIMERS_CFG_KEY = QStringLiteral("timersList");
0023 
0024 TimerModel *TimerModel::instance()
0025 {
0026     static TimerModel *singleton = new TimerModel();
0027     return singleton;
0028 }
0029 
0030 TimerModel::TimerModel()
0031 {
0032     load();
0033     QDBusConnection::sessionBus().registerObject(QStringLiteral("/Timers"), this, QDBusConnection::ExportScriptableContents);
0034 }
0035 
0036 void TimerModel::load()
0037 {
0038     auto config = KSharedConfig::openConfig();
0039     KConfigGroup group = config->group(TIMERS_CFG_GROUP);
0040     QJsonDocument doc = QJsonDocument::fromJson(group.readEntry(TIMERS_CFG_KEY, "{}").toUtf8());
0041     for (QJsonValueRef r : doc.array()) {
0042         QJsonObject obj = r.toObject();
0043         m_timerList.append(new Timer(obj, this));
0044     }
0045 }
0046 
0047 void TimerModel::save()
0048 {
0049     QJsonArray arr;
0050     for (auto timer : m_timerList) {
0051         arr.push_back(timer->serialize());
0052     }
0053     QJsonObject obj;
0054     obj[QStringLiteral("list")] = arr;
0055 
0056     auto config = KSharedConfig::openConfig();
0057     KConfigGroup group = config->group(TIMERS_CFG_GROUP);
0058     QByteArray data = QJsonDocument(arr).toJson(QJsonDocument::Compact);
0059     group.writeEntry(TIMERS_CFG_KEY, QString::fromStdString(data.toStdString()));
0060 
0061     group.sync();
0062 }
0063 
0064 void TimerModel::addTimer(int length, const QString &label, const QString &commandTimeout, bool running)
0065 {
0066     auto *timer = new Timer(length, label, commandTimeout, running);
0067     m_timerList.append(timer);
0068 
0069     save();
0070 
0071     Q_EMIT timerAdded(timer->uuid());
0072 }
0073 
0074 void TimerModel::removeTimer(const QString &uuid)
0075 {
0076     int ind = -1;
0077     for (int i = 0; i < m_timerList.size(); i++) {
0078         if (m_timerList[i]->uuid() == uuid) {
0079             ind = i;
0080             break;
0081         }
0082     }
0083     if (ind != -1) {
0084         this->remove(ind);
0085     }
0086 }
0087 
0088 void TimerModel::remove(int index)
0089 {
0090     if ((index < 0) || (index >= m_timerList.count()))
0091         return;
0092 
0093     auto timer = m_timerList.at(index);
0094 
0095     Q_EMIT timerRemoved(timer->uuid());
0096 
0097     m_timerList.removeAt(index);
0098     timer->deleteLater();
0099 
0100     save();
0101 }
0102 
0103 QStringList TimerModel::timers() const
0104 {
0105     QStringList ret;
0106     ret.reserve(m_timerList.size());
0107 
0108     // Filter out { } and - which are not allowed in DBus paths
0109     static QRegularExpression dbusfilter(QStringLiteral("[{}-]"));
0110 
0111     for (const Timer *timer : std::as_const(m_timerList)) {
0112         ret << timer->uuid().replace(dbusfilter, QString());
0113     }
0114     return ret;
0115 }