1/*
2 SPDX-FileCopyrightText: 2019 Kevin Ottens <kevin.ottens@enioka.com>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include "kquickmanagedconfigmodule.h"
7
8#include <KCoreConfigSkeleton>
9#include <QPointer>
10#include <QTimer>
11
12class KQuickManagedConfigModulePrivate
13{
14public:
15 KQuickManagedConfigModulePrivate(KQuickManagedConfigModule *mod)
16 {
17 QTimer::singleShot(interval: 0, receiver: mod, slot: [mod]() {
18 const auto skeletons = mod->findChildren<KCoreConfigSkeleton *>();
19 for (auto *skeleton : skeletons) {
20 mod->registerSettings(skeleton);
21 }
22 });
23 }
24
25 QList<QPointer<KCoreConfigSkeleton>> _skeletons;
26};
27
28KQuickManagedConfigModule::KQuickManagedConfigModule(QObject *parent, const KPluginMetaData &metaData)
29 : KQuickConfigModule(parent, metaData)
30 , d(new KQuickManagedConfigModulePrivate(this))
31{
32}
33
34KQuickManagedConfigModule::~KQuickManagedConfigModule() = default;
35
36void KQuickManagedConfigModule::load()
37{
38 for (const auto &skeleton : std::as_const(t&: d->_skeletons)) {
39 if (skeleton) {
40 skeleton->load();
41 }
42 }
43}
44
45void KQuickManagedConfigModule::save()
46{
47 for (const auto &skeleton : std::as_const(t&: d->_skeletons)) {
48 if (skeleton) {
49 skeleton->save();
50 }
51 }
52}
53
54void KQuickManagedConfigModule::defaults()
55{
56 for (const auto &skeleton : std::as_const(t&: d->_skeletons)) {
57 if (skeleton) {
58 skeleton->setDefaults();
59 }
60 }
61}
62
63bool KQuickManagedConfigModule::isSaveNeeded() const
64{
65 return false;
66}
67
68bool KQuickManagedConfigModule::isDefaults() const
69{
70 return true;
71}
72
73void KQuickManagedConfigModule::settingsChanged()
74{
75 bool needsSave = false;
76 bool representsDefaults = true;
77 for (const auto &skeleton : std::as_const(t&: d->_skeletons)) {
78 if (skeleton) {
79 needsSave |= skeleton->isSaveNeeded();
80 representsDefaults &= skeleton->isDefaults();
81 }
82 }
83
84 if (!needsSave) {
85 needsSave = isSaveNeeded();
86 }
87
88 if (representsDefaults) {
89 representsDefaults = isDefaults();
90 }
91
92 setRepresentsDefaults(representsDefaults);
93 setNeedsSave(needsSave);
94}
95
96void KQuickManagedConfigModule::registerSettings(KCoreConfigSkeleton *skeleton)
97{
98 if (!skeleton || d->_skeletons.contains(t: skeleton)) {
99 return;
100 }
101
102 d->_skeletons.append(t: skeleton);
103
104 auto settingsChangedSlotIndex = metaObject()->indexOfMethod(method: "settingsChanged()");
105 auto settingsChangedSlot = metaObject()->method(index: settingsChangedSlotIndex);
106
107 QObject::connect(sender: skeleton, signal: &KCoreConfigSkeleton::configChanged, context: this, slot: &KQuickManagedConfigModule::settingsChanged);
108
109 const auto items = skeleton->items();
110 for (auto item : items) {
111 const auto itemHasSignals = dynamic_cast<KConfigCompilerSignallingItem *>(item) || dynamic_cast<KPropertySkeletonItem *>(item);
112 if (!itemHasSignals) {
113 continue;
114 }
115
116 auto name = item->name();
117 if (name.at(i: 0).isUpper()) {
118 name[0] = name[0].toLower();
119 }
120
121 const auto metaObject = skeleton->metaObject();
122 const auto propertyIndex = metaObject->indexOfProperty(name: name.toUtf8().constData());
123 const auto property = metaObject->property(index: propertyIndex);
124 if (!property.hasNotifySignal()) {
125 continue;
126 }
127
128 const auto changedSignal = property.notifySignal();
129 QObject::connect(sender: skeleton, signal: changedSignal, receiver: this, method: settingsChangedSlot);
130 }
131
132 auto toRemove = std::remove_if(first: d->_skeletons.begin(), last: d->_skeletons.end(), pred: [](const QPointer<KCoreConfigSkeleton> &value) {
133 return value.isNull();
134 });
135 d->_skeletons.erase(abegin: toRemove, aend: d->_skeletons.end());
136
137 QMetaObject::invokeMethod(obj: this, member: "settingsChanged", c: Qt::QueuedConnection);
138}
139
140#include "moc_kquickmanagedconfigmodule.cpp"
141

source code of kcmutils/src/qml/kquickmanagedconfigmodule.cpp