File indexing completed on 2024-05-12 17:07:45

0001 /*
0002  *   SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
0003  *   SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
0004  *
0005  *   SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "quicksettingsmodel.h"
0009 
0010 #include <KPackage/PackageLoader>
0011 
0012 #include <QFileInfo>
0013 #include <QQmlComponent>
0014 #include <QQmlEngine>
0015 
0016 QuickSettingsModel::QuickSettingsModel(QObject *parent)
0017     : QAbstractListModel{parent}
0018     , m_savedQuickSettings{new SavedQuickSettings{this}}
0019 {
0020     connect(m_savedQuickSettings->enabledQuickSettingsModel(), &SavedQuickSettingsModel::dataUpdated, this, [this]() {
0021         loadQuickSettings();
0022     });
0023 }
0024 
0025 void QuickSettingsModel::classBegin()
0026 {
0027     m_loaded = true;
0028     loadQuickSettings();
0029 }
0030 
0031 void QuickSettingsModel::componentComplete()
0032 {
0033 }
0034 
0035 QHash<int, QByteArray> QuickSettingsModel::roleNames() const
0036 {
0037     return {{Qt::UserRole, "modelData"}};
0038 }
0039 
0040 int QuickSettingsModel::rowCount(const QModelIndex &parent) const
0041 {
0042     Q_UNUSED(parent);
0043     return m_quickSettings.size();
0044 }
0045 
0046 QVariant QuickSettingsModel::data(const QModelIndex &index, int role) const
0047 {
0048     if (!index.isValid() || index.row() >= rowCount({}) || role != Qt::UserRole) {
0049         return {};
0050     }
0051 
0052     QObject *obj = m_quickSettings[index.row()];
0053     return QVariant::fromValue<QObject *>(obj);
0054 }
0055 
0056 void QuickSettingsModel::loadQuickSettings()
0057 {
0058     if (!m_loaded) {
0059         return;
0060     }
0061 
0062     beginResetModel();
0063 
0064     for (auto *quickSetting : m_quickSettings) {
0065         quickSetting->deleteLater();
0066     }
0067     m_quickSettings.clear();
0068 
0069     QQmlEngine *engine = qmlEngine(this);
0070     QQmlComponent *c = new QQmlComponent(engine, this);
0071 
0072     // loop through enabled quick settings metadata
0073     for (const auto &metaData : m_savedQuickSettings->enabledQuickSettingsModel()->list()) {
0074         // load kpackage
0075         KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML", QFileInfo(metaData->fileName()).path());
0076         if (!package.isValid()) {
0077             continue;
0078         }
0079 
0080         // load QML from kpackage
0081         c->loadUrl(package.fileUrl("mainscript"), QQmlComponent::PreferSynchronous);
0082 
0083         auto created = c->create(engine->rootContext());
0084         auto createdSetting = qobject_cast<QuickSetting *>(created);
0085 
0086         // print errors if there were issues loading
0087         if (!createdSetting) {
0088             qWarning() << "Unable to load quick setting element:" << created;
0089             for (auto error : c->errors()) {
0090                 qWarning() << error;
0091             }
0092             delete created;
0093         } else {
0094             if (createdSetting->isAvailable()) {
0095                 m_quickSettings.push_back(createdSetting);
0096             }
0097             connect(createdSetting, &QuickSetting::availableChanged, this, &QuickSettingsModel::availabilityChanged);
0098         }
0099     }
0100 
0101     delete c;
0102 
0103     endResetModel();
0104     Q_EMIT countChanged();
0105 }
0106 
0107 void QuickSettingsModel::availabilityChanged()
0108 {
0109     auto setting = qobject_cast<QuickSetting *>(sender());
0110 
0111     if (setting->isAvailable()) {
0112         if (!m_quickSettings.contains(setting)) {
0113             auto idx = m_quickSettings.count();
0114             beginInsertRows({}, idx, idx);
0115             m_quickSettings.append(setting);
0116             endInsertRows();
0117         }
0118     } else {
0119         auto idx = m_quickSettings.indexOf(setting);
0120         if (idx >= 0) {
0121             beginRemoveRows({}, idx, idx);
0122             m_quickSettings.removeAt(idx);
0123             endRemoveRows();
0124         }
0125     }
0126 
0127     Q_EMIT countChanged();
0128 }