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 | |
19 | class KConfigDialogManager; |
20 | class KCoreConfigSkeleton; |
21 | class KConfigSkeleton; |
22 | class 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 | */ |
60 | class KCMUTILS_EXPORT KCModule : public KAbstractConfigModule |
61 | { |
62 | Q_OBJECT |
63 | |
64 | public: |
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 | |
108 | protected: |
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 | |
122 | protected 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 | |
129 | protected: |
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 | |
181 | private: |
182 | std::unique_ptr<KCModulePrivate> const d; |
183 | }; |
184 | |
185 | #endif // KCMODULE_H |
186 | |