File indexing completed on 2024-05-12 05:36:10

0001 // SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
0002 // SPDX-License-Identifier: LGPL-2.0-or-later
0003 
0004 #include "savedquicksettings.h"
0005 
0006 #include <KPackage/PackageLoader>
0007 
0008 #include <QFileInfo>
0009 
0010 SavedQuickSettings::SavedQuickSettings(QObject *parent)
0011     : QObject{parent}
0012     , m_settings{new QuickSettingsConfig{this}}
0013     , m_enabledQSModel{new SavedQuickSettingsModel{this}}
0014     , m_disabledQSModel{new SavedQuickSettingsModel{this}}
0015     , m_updateTimer{new QTimer{this}}
0016     , m_saveTimer{new QTimer{this}}
0017 {
0018     // throttle model updates from config, to avoid performance issues with fast reloading
0019     m_updateTimer->setInterval(2000);
0020     m_updateTimer->setSingleShot(true);
0021     connect(m_updateTimer, &QTimer::timeout, this, [this]() {
0022         refreshModel();
0023     });
0024 
0025     // throttle saving so that we don't have conflicts while writing and then getting notified about updates
0026     m_saveTimer->setInterval(1000);
0027     m_saveTimer->setSingleShot(true);
0028     connect(m_saveTimer, &QTimer::timeout, this, [this]() {
0029         saveModel();
0030     });
0031 
0032     // load quicksettings packages
0033     auto packages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KPackage/GenericQML"), "plasma/quicksettings");
0034     for (auto &metaData : packages) {
0035         KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML", QFileInfo(metaData.fileName()).path());
0036         if (!package.isValid()) {
0037             qWarning() << "Quick setting package invalid:" << metaData.fileName();
0038             continue;
0039         }
0040         m_validPackages.push_back(metaData);
0041     }
0042 
0043     // subscribe to config changes
0044     connect(m_settings, &QuickSettingsConfig::enabledQuickSettingsChanged, this, [this]() {
0045         m_updateTimer->start();
0046     });
0047     connect(m_settings, &QuickSettingsConfig::disabledQuickSettingsChanged, this, [this]() {
0048         m_updateTimer->start();
0049     });
0050 
0051     // subscribe to model changes
0052     connect(m_enabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData> data) -> void {
0053         m_enabledPackages.clear();
0054         for (auto metaData : data) {
0055             m_enabledPackages.push_back(metaData);
0056         }
0057 
0058         m_saveTimer->start();
0059         if (m_updateTimer->isActive()) {
0060             m_updateTimer->start(); // reset update timer if it's running
0061         }
0062     });
0063     connect(m_disabledQSModel, &SavedQuickSettingsModel::dataUpdated, this, [this](QList<KPluginMetaData> data) -> void {
0064         m_disabledPackages.clear();
0065         for (auto metaData : data) {
0066             m_disabledPackages.push_back(metaData);
0067         }
0068 
0069         m_saveTimer->start();
0070         if (m_updateTimer->isActive()) {
0071             m_updateTimer->start(); // reset update timer if it's running
0072         }
0073     });
0074 
0075     // load
0076     refreshModel();
0077 }
0078 
0079 SavedQuickSettings::~SavedQuickSettings()
0080 {
0081     // save immediately if was requested
0082     if (m_saveTimer->isActive()) {
0083         saveModel();
0084     }
0085 }
0086 
0087 SavedQuickSettingsModel *SavedQuickSettings::enabledQuickSettingsModel() const
0088 {
0089     return m_enabledQSModel;
0090 }
0091 
0092 SavedQuickSettingsModel *SavedQuickSettings::disabledQuickSettingsModel() const
0093 {
0094     return m_disabledQSModel;
0095 }
0096 
0097 void SavedQuickSettings::enableQS(int index)
0098 {
0099     KPluginMetaData tmp = m_disabledQSModel->takeRow(index);
0100 
0101     if (!tmp.isValid()) {
0102         return;
0103     }
0104 
0105     m_enabledQSModel->insertRow(tmp, m_enabledQSModel->rowCount({}));
0106 }
0107 
0108 void SavedQuickSettings::disableQS(int index)
0109 {
0110     KPluginMetaData tmp = m_enabledQSModel->takeRow(index);
0111 
0112     if (!tmp.isValid()) {
0113         return;
0114     }
0115 
0116     m_disabledQSModel->insertRow(tmp, m_disabledQSModel->rowCount({}));
0117 }
0118 
0119 void SavedQuickSettings::refreshModel()
0120 {
0121     QList<QString> enabledQS = m_settings->enabledQuickSettings();
0122     QList<QString> disabledQS = m_settings->disabledQuickSettings();
0123 
0124     m_enabledPackages.clear();
0125     m_disabledPackages.clear();
0126 
0127     // add enabled quick settings in order
0128     for (const QString &pluginId : enabledQS) {
0129         for (auto &metaData : m_validPackages) {
0130             if (pluginId == metaData.pluginId()) {
0131                 m_enabledPackages.push_back(metaData);
0132                 break;
0133             }
0134         }
0135     }
0136 
0137     // add disabled quick settings in order
0138     for (const QString &pluginId : disabledQS) {
0139         for (auto &metaData : m_validPackages) {
0140             if (pluginId == metaData.pluginId()) {
0141                 m_disabledPackages.push_back(metaData);
0142                 break;
0143             }
0144         }
0145     }
0146 
0147     // add undefined quick settings to the back of enabled quick settings
0148     for (auto &metaData : m_validPackages) {
0149         if (!enabledQS.contains(metaData.pluginId()) && !disabledQS.contains(metaData.pluginId())) {
0150             m_enabledPackages.push_back(metaData);
0151         }
0152     }
0153 
0154     m_enabledQSModel->updateData(m_enabledPackages);
0155     m_disabledQSModel->updateData(m_disabledPackages);
0156 }
0157 
0158 void SavedQuickSettings::saveModel()
0159 {
0160     QList<QString> enabledQS;
0161     QList<QString> disabledQS;
0162 
0163     for (auto &metaData : m_enabledPackages) {
0164         enabledQS.push_back(metaData.pluginId());
0165     }
0166     for (auto &metaData : m_disabledPackages) {
0167         disabledQS.push_back(metaData.pluginId());
0168     }
0169 
0170     m_settings->setEnabledQuickSettings(enabledQS);
0171     m_settings->setDisabledQuickSettings(disabledQS);
0172 }