diff --git a/src/kdeclarative/configpropertymap.cpp b/src/kdeclarative/configpropertymap.cpp index 06b5db4..f231e21 100644 --- a/src/kdeclarative/configpropertymap.cpp +++ b/src/kdeclarative/configpropertymap.cpp @@ -1,137 +1,142 @@ /* * Copyright 2013 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpropertymap.h" #include #include #include #include namespace KDeclarative { class ConfigPropertyMapPrivate { public: ConfigPropertyMapPrivate(ConfigPropertyMap *map) : q(map) { } enum LoadConfigOption { DontEmitValueChanged, EmitValueChanged }; void loadConfig(LoadConfigOption option); void writeConfig(); void writeConfigValue(const QString &key, const QVariant &value); ConfigPropertyMap *q; QPointer config; + bool updatingConfigValue = false; }; ConfigPropertyMap::ConfigPropertyMap(KCoreConfigSkeleton *config, QObject *parent) : QQmlPropertyMap(this, parent), d(new ConfigPropertyMapPrivate(this)) { d->config = config; - //FIXME: find a prettier way to connect without lambdas - connect(config, &KCoreConfigSkeleton::configChanged, this, std::bind(&ConfigPropertyMapPrivate::loadConfig, d, ConfigPropertyMapPrivate::EmitValueChanged)); + // Reload the config only if the change signal has *not* been emitted by ourselves updating the config + connect(config, &KCoreConfigSkeleton::configChanged, this, [this] () { + if (!d->updatingConfigValue) { + d->loadConfig(ConfigPropertyMapPrivate::EmitValueChanged); + } + }); connect(this, &ConfigPropertyMap::valueChanged, this, [this](const QString &key, const QVariant &value){d->writeConfigValue(key, value);}); d->loadConfig(ConfigPropertyMapPrivate::DontEmitValueChanged); } ConfigPropertyMap::~ConfigPropertyMap() { d->writeConfig(); delete d; } QVariant ConfigPropertyMap::updateValue(const QString &key, const QVariant &input) { Q_UNUSED(key); if (input.userType() == qMetaTypeId()) { return input.value().toVariant(); } return input; } bool ConfigPropertyMap::isImmutable(const QString &key) const { KConfigSkeletonItem *item = d->config.data()->findItem(key); if (item) { return item->isImmutable(); } return false; } void ConfigPropertyMapPrivate::loadConfig(ConfigPropertyMapPrivate::LoadConfigOption option) { if (!config) { return; } const auto &items = config.data()->items(); for (KConfigSkeletonItem *item : items) { q->insert(item->key(), item->property()); if (option == EmitValueChanged) { emit q->valueChanged(item->key(), item->property()); } } } void ConfigPropertyMapPrivate::writeConfig() { if (!config) { return; } const auto lstItems = config.data()->items(); for (KConfigSkeletonItem *item : lstItems) { item->setProperty(q->value(item->key())); } - config.data()->blockSignals(true); + updatingConfigValue = true; config.data()->save(); - config.data()->blockSignals(false); + updatingConfigValue = false; } void ConfigPropertyMapPrivate::writeConfigValue(const QString &key, const QVariant &value) { KConfigSkeletonItem *item = config.data()->findItem(key); if (item) { + updatingConfigValue = true; item->setProperty(value); - config.data()->blockSignals(true); config.data()->save(); //why read? read will update KConfigSkeletonItem::mLoadedValue, //allowing a write operation to be performed next time config.data()->read(); - config.data()->blockSignals(false); + updatingConfigValue = false; } } } #include "moc_configpropertymap.cpp"