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