File indexing completed on 2025-01-19 03:53:50

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2003-11-03
0007  * Description : Automatic retrieving, saving and resetting skeleton based settings in a dialog.
0008  *
0009  * SPDX-FileCopyrightText: 2019-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2003      by Benjamin C Meyer <ben plus kdelibs at meyerhome dot net>
0011  * SPDX-FileCopyrightText: 2003      by Waldo Bastian <bastian at kde dot org>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #ifndef DIGIKAM_DCONFIG_DLG_MNGR_H
0018 #define DIGIKAM_DCONFIG_DLG_MNGR_H
0019 
0020 // Qt includes
0021 
0022 #include <QObject>
0023 #include <QHash>
0024 #include <QWidget>
0025 #include <QByteArray>
0026 
0027 // Local includes
0028 
0029 #include "digikam_export.h"
0030 
0031 class KConfigSkeleton;
0032 class KConfigSkeletonItem;
0033 
0034 namespace Digikam
0035 {
0036 
0037 /**
0038  * The DConfigDlgMngr class provides a means of automatically
0039  * retrieving, saving and resetting basic settings.
0040  * It also can emit signals when settings have been changed
0041  * (settings were saved) or modified (the user changes a checkbox
0042  * from on to off).
0043  *
0044  * The object names of the widgets to be managed have to correspond to the names of the
0045  * configuration entries in the KConfigSkeleton object plus an additional
0046  * "kcfg_" prefix. For example a widget with the object name "kcfg_MyOption"
0047  * would be associated to the configuration entry "MyOption".
0048  *
0049  * The widget classes of Qt are supported out of the box.
0050  *
0051  * Custom widget classes are supported if they have a Q_PROPERTY defined for the
0052  * property representing the value edited by the widget. By default the property
0053  * is used for which "USER true" is set. For using another property, see below.
0054  */
0055 class DIGIKAM_EXPORT DConfigDlgMngr : public QObject
0056 {
0057     Q_OBJECT
0058 
0059 public:
0060 
0061     /**
0062      * Constructor.
0063      * @param parent Dialog widget to manage
0064      * @param conf Object that contains settings
0065      */
0066     DConfigDlgMngr(QWidget* const parent, KConfigSkeleton* const conf);
0067 
0068     /**
0069      * Destructor.
0070      */
0071     ~DConfigDlgMngr()                                                      override;
0072 
0073     /**
0074      * Add additional widgets to manage
0075      * @param widget Additional widget to manage, including all its children
0076      */
0077     void addWidget(QWidget* const widget);
0078 
0079     /**
0080      * Returns whether the current state of the known widgets are
0081      * different from the state in the config object.
0082      */
0083     bool hasChanged()                                                const;
0084 
0085     /**
0086      * Returns whether the current state of the known widgets are
0087      * the same as the default state in the config object.
0088      */
0089     bool isDefault()                                                 const;
0090 
0091 public:
0092 
0093     /**
0094      * Retrieve the map between widgets class names and the
0095      * USER properties used for the configuration values.
0096      */
0097     static QHash<QString, QByteArray>* propertyMap();
0098 
0099     /**
0100      * Retrieve the map between widgets class names and signals that are listened
0101      * to detect changes in the configuration values.
0102      */
0103     static QHash<QString, QByteArray>* changedMap();
0104 
0105 Q_SIGNALS:
0106 
0107     /**
0108      * One or more of the settings have been saved (such as when the user
0109      * clicks on the Apply button).  This is only emitted by updateSettings()
0110      * whenever one or more setting were changed and consequently saved.
0111      */
0112     void settingsChanged();
0113 
0114     /**
0115      * One or more of the settings have been changed.
0116      * @param widget - The widget group (pass in via addWidget()) that
0117      * contains the one or more modified setting.
0118      * @see settingsChanged()
0119      */
0120     void settingsChanged(QWidget* widget);
0121 
0122     /**
0123      * If retrieveSettings() was told to track changes then if
0124      * any known setting was changed this signal will be emitted.  Note
0125      * that a settings can be modified several times and might go back to the
0126      * original saved state. hasChanged() will tell you if anything has
0127      * actually changed from the saved values.
0128      */
0129     void widgetModified();
0130 
0131 public Q_SLOTS:
0132 
0133     /**
0134      * Traverse the specified widgets, saving the settings of all known
0135      * widgets in the settings object.
0136      *
0137      * Example use: User clicks Ok or Apply button in a configure dialog.
0138      */
0139     void updateSettings();
0140 
0141     /**
0142      * Traverse the specified widgets, sets the state of all known
0143      * widgets according to the state in the settings object.
0144      *
0145      * Example use: Initialisation of dialog.
0146      * Example use: User clicks Reset button in a configure dialog.
0147      */
0148     void updateWidgets();
0149 
0150     /**
0151      * Traverse the specified widgets, sets the state of all known
0152      * widgets according to the default state in the settings object.
0153      *
0154      * Example use: User clicks Defaults button in a configure dialog.
0155      */
0156     void updateWidgetsDefault();
0157 
0158 protected:
0159 
0160     /**
0161      * @param trackChanges - If any changes by the widgets should be tracked
0162      * set true.  This causes the emitting the modified() signal when
0163      * something changes.
0164      */
0165     void init(bool trackChanges);
0166 
0167     /**
0168      * Recursive function that finds all known children.
0169      * Goes through the children of widget and if any are known and not being
0170      * ignored, stores them in currentGroup.  Also checks if the widget
0171      * should be disabled because it is set immutable.
0172      * @param widget - Parent of the children to look at.
0173      * @param trackChanges - If true then tracks any changes to the children of
0174      * widget that are known.
0175      * @return bool - If a widget was set to something other than its default.
0176      */
0177     bool parseChildren(const QWidget* widget, bool trackChanges);
0178 
0179     /**
0180      * Finds the USER property name using Qt's MetaProperty system, and caches
0181      * it in the property map (the cache could be retrieved by propertyMap() ).
0182      */
0183     QByteArray getUserProperty(const QWidget* widget)                const;
0184 
0185     /**
0186      * Find the property to use for a widget by querying the "kcfg_property"
0187      * property of the widget. Like a widget can use a property other than the
0188      * USER property.
0189      */
0190     QByteArray getCustomProperty(const QWidget* widget)              const;
0191 
0192     /**
0193      * Finds the changed signal of the USER property using Qt's MetaProperty system.
0194      */
0195     QByteArray getUserPropertyChangedSignal(const QWidget* widget)   const;
0196 
0197     /**
0198      * Find the changed signal of the property to use for a widget by querying
0199      * the "kcfg_propertyNotify" property of the widget. Like a widget can use a
0200      * property change signal other than the one for USER property, if there even is one.
0201      */
0202     QByteArray getCustomPropertyChangedSignal(const QWidget* widget) const;
0203 
0204     /**
0205      * Set a property
0206      */
0207     void setProperty(QWidget* w, const QVariant& v);
0208 
0209     /**
0210      * Retrieve a property
0211      */
0212     QVariant property(QWidget* w)                                    const;
0213 
0214     /**
0215      * Setup secondary widget properties
0216      */
0217     void setupWidget(QWidget* widget, KConfigSkeletonItem* item);
0218 
0219     /**
0220      * Initializes the property maps
0221      */
0222     static void initMaps();
0223 
0224 private:
0225 
0226     class Private;
0227     Private* const d;
0228 
0229     Q_DISABLE_COPY(DConfigDlgMngr)
0230 };
0231 
0232 } // namespace Digikam
0233 
0234 #endif // DIGIKAM_DCONFIG_DLG_MNGR_H