1 | /* |
---|---|
2 | SPDX-FileCopyrightText: 2020 Kevin Ottens <kevin.ottens@enioka.com> |
3 | SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #include "settingstateproxy.h" |
9 | #include "kcmutils_debug.h" |
10 | |
11 | #include <QDebug> |
12 | #include <QMetaMethod> |
13 | |
14 | KCoreConfigSkeleton *SettingStateProxy::configObject() const |
15 | { |
16 | return m_configObject; |
17 | } |
18 | |
19 | void SettingStateProxy::setConfigObject(KCoreConfigSkeleton *configObject) |
20 | { |
21 | if (m_configObject == configObject) { |
22 | return; |
23 | } |
24 | |
25 | if (m_configObject) { |
26 | m_configObject->disconnect(receiver: this); |
27 | } |
28 | |
29 | m_configObject = configObject; |
30 | Q_EMIT configObjectChanged(); |
31 | updateState(); |
32 | connectSetting(); |
33 | } |
34 | |
35 | QString SettingStateProxy::settingName() const |
36 | { |
37 | return m_settingName; |
38 | } |
39 | |
40 | void SettingStateProxy::setSettingName(const QString &settingName) |
41 | { |
42 | if (m_settingName == settingName) { |
43 | return; |
44 | } |
45 | |
46 | if (m_configObject) { |
47 | m_configObject->disconnect(receiver: this); |
48 | } |
49 | |
50 | m_settingName = settingName; |
51 | Q_EMIT settingNameChanged(); |
52 | updateState(); |
53 | connectSetting(); |
54 | } |
55 | |
56 | bool SettingStateProxy::isImmutable() const |
57 | { |
58 | return m_immutable; |
59 | } |
60 | |
61 | bool SettingStateProxy::isDefaulted() const |
62 | { |
63 | return m_defaulted; |
64 | } |
65 | |
66 | void SettingStateProxy::updateState() |
67 | { |
68 | const auto item = m_configObject ? m_configObject->findItem(name: m_settingName) : nullptr; |
69 | const auto immutable = item ? item->isImmutable() : false; |
70 | const auto defaulted = item ? item->isDefault() : true; |
71 | |
72 | if (m_immutable != immutable) { |
73 | m_immutable = immutable; |
74 | Q_EMIT immutableChanged(); |
75 | } |
76 | |
77 | if (m_defaulted != defaulted) { |
78 | m_defaulted = defaulted; |
79 | Q_EMIT defaultedChanged(); |
80 | } |
81 | } |
82 | |
83 | void SettingStateProxy::connectSetting() |
84 | { |
85 | const auto item = m_configObject ? m_configObject->findItem(name: m_settingName) : nullptr; |
86 | if (!item) { |
87 | return; |
88 | } |
89 | |
90 | const auto updateStateSlotIndex = metaObject()->indexOfMethod(method: "updateState()"); |
91 | Q_ASSERT(updateStateSlotIndex >= 0); |
92 | const auto updateStateSlot = metaObject()->method(index: updateStateSlotIndex); |
93 | Q_ASSERT(updateStateSlot.isValid()); |
94 | |
95 | const auto itemHasSignals = dynamic_cast<KConfigCompilerSignallingItem *>(item) || dynamic_cast<KPropertySkeletonItem *>(item); |
96 | if (!itemHasSignals) { |
97 | qCWarning(KCMUTILS_LOG) << "Attempting to use SettingStateProxy with a non signalling item:"<< m_settingName; |
98 | return; |
99 | } |
100 | |
101 | const auto propertyName = [this] { |
102 | auto name = m_settingName; |
103 | if (name.at(i: 0).isUpper()) { |
104 | name[0] = name[0].toLower(); |
105 | } |
106 | return name.toUtf8(); |
107 | }(); |
108 | |
109 | const auto metaObject = m_configObject->metaObject(); |
110 | const auto propertyIndex = metaObject->indexOfProperty(name: propertyName.constData()); |
111 | Q_ASSERT(propertyIndex >= 0); |
112 | const auto property = metaObject->property(index: propertyIndex); |
113 | Q_ASSERT(property.isValid()); |
114 | if (!property.hasNotifySignal()) { |
115 | qCWarning(KCMUTILS_LOG) << "Attempting to use SettingStateProxy with a non notifying property:"<< propertyName; |
116 | return; |
117 | } |
118 | |
119 | const auto changedSignal = property.notifySignal(); |
120 | Q_ASSERT(changedSignal.isValid()); |
121 | connect(sender: m_configObject, signal: changedSignal, receiver: this, method: updateStateSlot); |
122 | connect(sender: m_configObject, signal: &KCoreConfigSkeleton::configChanged, context: this, slot: &SettingStateProxy::updateState); |
123 | } |
124 | |
125 | #include "moc_settingstateproxy.cpp" |
126 |