File indexing completed on 2024-05-19 15:09:22

0001 /*
0002     SPDX-FileCopyrightText: 2020 Kevin Ottens <kevin.ottens@enioka.com>
0003     SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "settingstateproxy.h"
0009 
0010 #include <QDebug>
0011 #include <QMetaMethod>
0012 
0013 KCoreConfigSkeleton *SettingStateProxy::configObject() const
0014 {
0015     return m_configObject;
0016 }
0017 
0018 void SettingStateProxy::setConfigObject(KCoreConfigSkeleton *configObject)
0019 {
0020     if (m_configObject == configObject) {
0021         return;
0022     }
0023 
0024     if (m_configObject) {
0025         m_configObject->disconnect(this);
0026     }
0027 
0028     m_configObject = configObject;
0029     Q_EMIT configObjectChanged();
0030     updateState();
0031     connectSetting();
0032 }
0033 
0034 QString SettingStateProxy::settingName() const
0035 {
0036     return m_settingName;
0037 }
0038 
0039 void SettingStateProxy::setSettingName(const QString &settingName)
0040 {
0041     if (m_settingName == settingName) {
0042         return;
0043     }
0044 
0045     if (m_configObject) {
0046         m_configObject->disconnect(this);
0047     }
0048 
0049     m_settingName = settingName;
0050     Q_EMIT settingNameChanged();
0051     updateState();
0052     connectSetting();
0053 }
0054 
0055 bool SettingStateProxy::isImmutable() const
0056 {
0057     return m_immutable;
0058 }
0059 
0060 bool SettingStateProxy::isDefaulted() const
0061 {
0062     return m_defaulted;
0063 }
0064 
0065 void SettingStateProxy::updateState()
0066 {
0067     const auto item = m_configObject ? m_configObject->findItem(m_settingName) : nullptr;
0068     const auto immutable = item ? item->isImmutable() : false;
0069     const auto defaulted = item ? item->isDefault() : true;
0070 
0071     if (m_immutable != immutable) {
0072         m_immutable = immutable;
0073         Q_EMIT immutableChanged();
0074     }
0075 
0076     if (m_defaulted != defaulted) {
0077         m_defaulted = defaulted;
0078         Q_EMIT defaultedChanged();
0079     }
0080 }
0081 
0082 void SettingStateProxy::connectSetting()
0083 {
0084     const auto item = m_configObject ? m_configObject->findItem(m_settingName) : nullptr;
0085     if (!item) {
0086         return;
0087     }
0088 
0089     const auto updateStateSlotIndex = metaObject()->indexOfMethod("updateState()");
0090     Q_ASSERT(updateStateSlotIndex >= 0);
0091     const auto updateStateSlot = metaObject()->method(updateStateSlotIndex);
0092     Q_ASSERT(updateStateSlot.isValid());
0093 
0094     const auto itemHasSignals = dynamic_cast<KConfigCompilerSignallingItem *>(item) || dynamic_cast<KPropertySkeletonItem *>(item);
0095     if (!itemHasSignals) {
0096         qWarning() << "Attempting to use SettingStateProxy with a non signalling item:" << m_settingName;
0097         return;
0098     }
0099 
0100     const auto propertyName = [this] {
0101         auto name = m_settingName;
0102         if (name.at(0).isUpper()) {
0103             name[0] = name[0].toLower();
0104         }
0105         return name.toUtf8();
0106     }();
0107 
0108     const auto metaObject = m_configObject->metaObject();
0109     const auto propertyIndex = metaObject->indexOfProperty(propertyName.constData());
0110     Q_ASSERT(propertyIndex >= 0);
0111     const auto property = metaObject->property(propertyIndex);
0112     Q_ASSERT(property.isValid());
0113     if (!property.hasNotifySignal()) {
0114         qWarning() << "Attempting to use SettingStateProxy with a non notifying property:" << propertyName;
0115         return;
0116     }
0117 
0118     const auto changedSignal = property.notifySignal();
0119     Q_ASSERT(changedSignal.isValid());
0120     connect(m_configObject, changedSignal, this, updateStateSlot);
0121     connect(m_configObject, &KCoreConfigSkeleton::configChanged, this, &SettingStateProxy::updateState);
0122 }
0123 
0124 #include "moc_settingstateproxy.cpp"