File indexing completed on 2024-05-05 16:07:09

0001 /*
0002     SPDX-FileCopyrightText: 2013 Marco Martin <notmart@gmail.com>
0003     SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "configpropertymap.h"
0009 
0010 #if KDECLARATIVE_BUILD_DEPRECATED_SINCE(5, 89)
0011 #include <KCoreConfigSkeleton>
0012 #include <QJSValue>
0013 #include <QPointer>
0014 
0015 #include <functional>
0016 
0017 namespace KDeclarative
0018 {
0019 class ConfigPropertyMapPrivate
0020 {
0021 public:
0022     ConfigPropertyMapPrivate(ConfigPropertyMap *map)
0023         : q(map)
0024     {
0025     }
0026 
0027     enum LoadConfigOption {
0028         DontEmitValueChanged,
0029         EmitValueChanged,
0030     };
0031 
0032     void loadConfig(LoadConfigOption option);
0033     void writeConfig();
0034     void writeConfigValue(const QString &key, const QVariant &value);
0035 
0036     ConfigPropertyMap *q;
0037     QPointer<KCoreConfigSkeleton> config;
0038     bool updatingConfigValue = false;
0039     bool autosave = true;
0040     bool notify = false;
0041 };
0042 
0043 ConfigPropertyMap::ConfigPropertyMap(KCoreConfigSkeleton *config, QObject *parent)
0044     : QQmlPropertyMap(this, parent)
0045     , d(new ConfigPropertyMapPrivate(this))
0046 {
0047     d->config = config;
0048 
0049     // Reload the config only if the change signal has *not* been emitted by ourselves updating the config
0050     connect(config, &KCoreConfigSkeleton::configChanged, this, [this]() {
0051         if (!d->updatingConfigValue) {
0052             d->loadConfig(ConfigPropertyMapPrivate::EmitValueChanged);
0053         }
0054     });
0055     connect(this, &ConfigPropertyMap::valueChanged, this, [this](const QString &key, const QVariant &value) {
0056         d->writeConfigValue(key, value);
0057     });
0058 
0059     d->loadConfig(ConfigPropertyMapPrivate::DontEmitValueChanged);
0060 }
0061 
0062 ConfigPropertyMap::~ConfigPropertyMap()
0063 {
0064     if (d->autosave) {
0065         d->writeConfig();
0066     }
0067     delete d;
0068 }
0069 
0070 bool KDeclarative::ConfigPropertyMap::isAutosave() const
0071 {
0072     return d->autosave;
0073 }
0074 
0075 void ConfigPropertyMap::setAutosave(bool autosave)
0076 {
0077     d->autosave = autosave;
0078 }
0079 
0080 bool ConfigPropertyMap::isNotify() const
0081 {
0082     return d->notify;
0083 }
0084 
0085 void ConfigPropertyMap::setNotify(bool notify)
0086 {
0087     d->notify = notify;
0088 }
0089 
0090 QVariant ConfigPropertyMap::updateValue(const QString &key, const QVariant &input)
0091 {
0092     Q_UNUSED(key);
0093     if (input.userType() == qMetaTypeId<QJSValue>()) {
0094         return input.value<QJSValue>().toVariant();
0095     }
0096     return input;
0097 }
0098 
0099 bool ConfigPropertyMap::isImmutable(const QString &key) const
0100 {
0101     KConfigSkeletonItem *item = d->config.data()->findItem(key);
0102     if (item) {
0103         return item->isImmutable();
0104     }
0105 
0106     return false;
0107 }
0108 
0109 void ConfigPropertyMapPrivate::loadConfig(ConfigPropertyMapPrivate::LoadConfigOption option)
0110 {
0111     if (!config) {
0112         return;
0113     }
0114 
0115     const auto &items = config.data()->items();
0116     for (KConfigSkeletonItem *item : items) {
0117         q->insert(item->key() + QStringLiteral("Default"), item->getDefault());
0118         q->insert(item->key(), item->property());
0119         if (option == EmitValueChanged) {
0120             Q_EMIT q->valueChanged(item->key(), item->property());
0121         }
0122     }
0123 }
0124 
0125 void ConfigPropertyMapPrivate::writeConfig()
0126 {
0127     if (!config) {
0128         return;
0129     }
0130 
0131     const auto lstItems = config.data()->items();
0132     for (KConfigSkeletonItem *item : lstItems) {
0133         item->setWriteFlags(notify ? KConfigBase::Notify : KConfigBase::Normal);
0134         item->setProperty(q->value(item->key()));
0135     }
0136 
0137     if (autosave) {
0138         updatingConfigValue = true;
0139         config.data()->save();
0140         updatingConfigValue = false;
0141     }
0142 }
0143 
0144 void ConfigPropertyMapPrivate::writeConfigValue(const QString &key, const QVariant &value)
0145 {
0146     KConfigSkeletonItem *item = config.data()->findItem(key);
0147     if (item) {
0148         updatingConfigValue = true;
0149         item->setWriteFlags(notify ? KConfigBase::Notify : KConfigBase::Normal);
0150         item->setProperty(value);
0151         if (autosave) {
0152             config.data()->save();
0153             // why read? read will update KConfigSkeletonItem::mLoadedValue,
0154             // allowing a write operation to be performed next time
0155             config.data()->read();
0156         }
0157         updatingConfigValue = false;
0158     }
0159 }
0160 
0161 }
0162 
0163 #include "moc_configpropertymap.cpp"
0164 #endif