File indexing completed on 2024-05-12 03:54:10

0001 /*
0002     SPDX-FileCopyrightText: 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
0003     SPDX-FileCopyrightText: 2023 Alexander Lohnau <alexander.lohnau@gmx.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KCMODULE_H
0009 #define KCMODULE_H
0010 
0011 #include "kcmutils_export.h"
0012 #include <KAbstractConfigModule>
0013 #include <KPluginMetaData>
0014 
0015 #include <QVariant>
0016 #include <QWidget>
0017 #include <memory>
0018 
0019 class KConfigDialogManager;
0020 class KCoreConfigSkeleton;
0021 class KConfigSkeleton;
0022 class KCModulePrivate;
0023 
0024 /**
0025  * @class KCModule kcmodule.h KCModule
0026  *
0027  * The base class for QWidgets configuration modules.
0028  * Configuration modules are loaded as plugins.
0029  *
0030  * The module in principle is a simple widget displaying the
0031  * item to be changed. The module has a very small interface.
0032  *
0033  * To write a config module, you have to create a library
0034  * that contains a factory class like the following:
0035  *
0036  * \code
0037  * #include <KPluginFactory>
0038  *
0039  * K_PLUGIN_CLASS_WITH_JSON(MyKCModule, "mykcmodule.json")
0040  * \endcode
0041  *
0042  * The constructor of the KCModule then looks like this:
0043  * \code
0044  * YourKCModule::YourKCModule(QWidget *parent, const KPluginMetaData &data)
0045  *   : KCModule(parent, data)
0046  * {
0047  * // KCModule does not directly extend QWidget due to ambiguity with KAbstractConfigModule
0048  * // Because of this, you need to call widget() to get the parent widget
0049  * auto label = new QLabel(widget());
0050  * label->setText(QStringLiteral("Demo Text"));
0051  * }
0052  * \endcode
0053  *
0054  * This KCM can be loaded in a KCMultiDialog of kcmshell6
0055  *
0056  * @since 6.0
0057  */
0058 class KCMUTILS_EXPORT KCModule : public KAbstractConfigModule
0059 {
0060     Q_OBJECT
0061 
0062 public:
0063     /**
0064      * Base class for all QWidgets configuration modules.
0065      *
0066      * @note do not emit changed signals here, since they are not yet connected
0067      *       to any slot.
0068      */
0069     explicit KCModule(QWidget *parent, const KPluginMetaData &data);
0070 
0071     /**
0072      * Destroys the module.
0073      */
0074     ~KCModule() override;
0075 
0076     /**
0077      * @return a list of @ref KConfigDialogManager's in use, if any.
0078      */
0079     QList<KConfigDialogManager *> configs() const;
0080 
0081     void load() override;
0082     void save() override;
0083     void defaults() override;
0084 
0085     /**
0086      * Utility function that marks the KCM as changed
0087      */
0088     void markAsChanged()
0089     {
0090         setNeedsSave(true);
0091     }
0092 
0093     /**
0094      * Get the associated widget that can be embedded
0095      * The returned widget should be used as a parent for widgets you create
0096      *
0097      * @note Overwriting this function should not be necessary for consumers!
0098      */
0099     virtual QWidget *widget();
0100 
0101 protected:
0102     /**
0103      * Adds a KCoreConfigskeleton @p config to watch the widget @p widget
0104      *
0105      * This function is useful if you need to handle multiple configuration files.
0106      *
0107      * @return a pointer to the KCoreConfigDialogManager in use
0108      * @param config the KCoreConfigSkeleton to use
0109      * @param widget the widget to watch
0110      */
0111     KConfigDialogManager *addConfig(KCoreConfigSkeleton *config, QWidget *widget);
0112 
0113 protected Q_SLOTS:
0114     /**
0115      * A managed widget was changed, the widget settings and the current
0116      * settings are compared and a corresponding needsSaveChanged() signal is emitted
0117      */
0118     void widgetChanged();
0119 
0120 protected:
0121     /**
0122      * Returns the changed state of automatically managed widgets in this dialog
0123      */
0124     bool managedWidgetChangeState() const;
0125 
0126     /**
0127      * Returns the defaulted state of automatically managed widgets in this dialog
0128      */
0129     bool managedWidgetDefaultState() const;
0130 
0131     /**
0132      * Call this method when your manually managed widgets change state between
0133      * changed and not changed
0134      */
0135     void unmanagedWidgetChangeState(bool);
0136 
0137     /**
0138      * Call this method when your manually managed widgets change state between
0139      * defaulted and not defaulted
0140      */
0141     void unmanagedWidgetDefaultState(bool);
0142 
0143     /**
0144      * Utility overload to avoid having to take both parent and parentWidget
0145      * KCModuleLoader::loadModule enforces the parent to be a QWidget anyway
0146      */
0147     explicit KCModule(QObject *parent, const KPluginMetaData &data)
0148         : KCModule(qobject_cast<QWidget *>(parent), data)
0149     {
0150     }
0151 
0152     /**
0153      * Utility constructor for creating a KCModule that is embedded, for example in a KPluginWidget
0154      * This constructor should not be used for KCMs that are part launched in systemsettings!
0155      *
0156      * @note do not emit changed signals here, since they are not yet connected
0157      *       to any slot.
0158      */
0159     explicit KCModule(QObject *parent)
0160         : KCModule(qobject_cast<QWidget *>(parent), KPluginMetaData{})
0161     {
0162     }
0163 
0164 private:
0165     std::unique_ptr<KCModulePrivate> const d;
0166 };
0167 
0168 #endif // KCMODULE_H