1/*
2 SPDX-FileCopyrightText: 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
3 SPDX-FileCopyrightText: 2023 Alexander Lohnau <alexander.lohnau@gmx.de>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KCMODULE_H
9#define KCMODULE_H
10
11#include "kcmutils_export.h"
12#include <KAbstractConfigModule>
13#include <KPluginMetaData>
14
15#include <QVariant>
16#include <QWidget>
17#include <memory>
18
19class KConfigDialogManager;
20class KCoreConfigSkeleton;
21class KConfigSkeleton;
22class KCModulePrivate;
23
24/*!
25 * \class KCModule
26 * \inmodule KCMUtils
27 *
28 * \brief The base class for QWidgets configuration modules.
29 *
30 * Configuration modules are loaded as plugins.
31 *
32 * The module in principle is a simple widget displaying the
33 * item to be changed. The module has a very small interface.
34 *
35 * To write a config module, you have to create a library
36 * that contains a factory class like the following:
37 *
38 * \code
39 * #include <KPluginFactory>
40 *
41 * K_PLUGIN_CLASS_WITH_JSON(MyKCModule, "mykcmodule.json")
42 * \endcode
43 *
44 * The constructor of the KCModule then looks like this:
45 * \code
46 * YourKCModule::YourKCModule(QWidget *parent, const KPluginMetaData &data)
47 * : KCModule(parent, data)
48 * {
49 * // KCModule does not directly extend QWidget due to ambiguity with KAbstractConfigModule
50 * // Because of this, you need to call widget() to get the parent widget
51 * auto label = new QLabel(widget());
52 * label->setText(QStringLiteral("Demo Text"));
53 * }
54 * \endcode
55 *
56 * This KCM can be loaded in a KCMultiDialog of kcmshell6.
57 *
58 * \since 6.0
59 */
60class KCMUTILS_EXPORT KCModule : public KAbstractConfigModule
61{
62 Q_OBJECT
63
64public:
65 /*!
66 * \brief Base class for all QWidgets configuration modules.
67 *
68 * \a parent The KCModule parent.
69 *
70 * \a data The JSON metadata of the KCModule.
71 *
72 * \note Do not emit changed signals here, since they are not yet connected
73 * to any slot.
74 */
75 explicit KCModule(QWidget *parent, const KPluginMetaData &data);
76
77 /*!
78 * \brief Destroys the module.
79 */
80 ~KCModule() override;
81
82 /*!
83 * \brief Returns a list of \l KConfigDialogManager's in use, if any.
84 */
85 QList<KConfigDialogManager *> configs() const;
86
87 void load() override;
88 void save() override;
89 void defaults() override;
90
91 /*!
92 * \brief Utility function that marks the KCM as changed.
93 */
94 void markAsChanged()
95 {
96 setNeedsSave(true);
97 }
98
99 /*!
100 * \brief Get the associated widget that can be embedded.
101 *
102 * The returned widget should be used as a parent for widgets you create
103 *
104 * \note Overwriting this function should not be necessary for consumers!
105 */
106 virtual QWidget *widget();
107
108protected:
109 /*!
110 * \brief Adds a KCoreConfigskeleton \a config to watch the widget \a widget.
111 *
112 * This function is useful if you need to handle multiple configuration files.
113 *
114 * Returns a pointer to the KCoreConfigDialogManager in use.
115 *
116 * \a config The KCoreConfigSkeleton to use.
117 *
118 * \a widget The widget to watch.
119 */
120 KConfigDialogManager *addConfig(KCoreConfigSkeleton *config, QWidget *widget);
121
122protected Q_SLOTS:
123 /*!
124 * \brief A managed widget was changed, the widget settings and the current
125 * settings are compared, and a corresponding needsSaveChanged() signal is emitted.
126 */
127 void widgetChanged();
128
129protected:
130 /*!
131 * \brief Returns the changed state of automatically managed widgets in this dialog.
132 */
133 bool managedWidgetChangeState() const;
134
135 /*!
136 * \brief Returns the defaulted state of automatically managed widgets in this dialog.
137 */
138 bool managedWidgetDefaultState() const;
139
140 /*!
141 * \brief Call this method when your manually managed widgets
142 * change state between "changed" and "not changed".
143 */
144 void unmanagedWidgetChangeState(bool);
145
146 /*!
147 * \brief Call this method when your manually managed widgets
148 * change state between "defaulted" and "not defaulted".
149 */
150 void unmanagedWidgetDefaultState(bool);
151
152 /*!
153 * \brief Utility overload to avoid having to take both parent and parentWidget
154 * KCModuleLoader::loadModule enforces the parent to be a QWidget anyway.
155 *
156 * \a parent The KCModule parent.
157 *
158 * \a data The JSON metadata of the KCModule.
159 */
160 explicit KCModule(QObject *parent, const KPluginMetaData &data)
161 : KCModule(qobject_cast<QWidget *>(o: parent), data)
162 {
163 }
164
165 /*!
166 * \brief Utility constructor for creating a KCModule that is embedded,
167 * for example in a KPluginWidget.
168 *
169 * This constructor should not be used for KCMs that are part launched in systemsettings!
170 *
171 * \note Do not emit changed signals here, since they are not yet connected
172 * to any slot.
173 *
174 * \a parent The KCModule parent.
175 */
176 explicit KCModule(QObject *parent)
177 : KCModule(qobject_cast<QWidget *>(o: parent), KPluginMetaData{})
178 {
179 }
180
181private:
182 std::unique_ptr<KCModulePrivate> const d;
183};
184
185#endif // KCMODULE_H
186

source code of kcmutils/src/kcmodule.h