File indexing completed on 2025-04-27 03:58:31

0001 /* ============================================================
0002  *
0003  * This file is a part of digikam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-20-12
0007  * Description : Interface class for objects that can store their state.
0008  *
0009  * SPDX-FileCopyrightText: 2009 by Johannes Wienke <languitar at semipol dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #ifndef DIGIKAM_STATE_SAVING_OBJECT_H
0016 #define DIGIKAM_STATE_SAVING_OBJECT_H
0017 
0018 // Qt includes
0019 
0020 #include <QObject>
0021 
0022 // Local includes
0023 
0024 #include "digikam_export.h"
0025 
0026 class KConfigGroup;
0027 
0028 namespace Digikam
0029 {
0030 
0031 /**
0032  * An interface-like class with utility methods and a general public interface
0033  * to support state saving and restoring for objects via KConfig. Use this class
0034  * as a Mixin.
0035  *
0036  * The public interface for loading and saving state is implemented designed as
0037  * template methods. To store or restore the state of a class, inherit from
0038  * this class via multiple inheritance and implement doLoadState() and
0039  * doSaveState(). In these methods always use the protected method
0040  * getConfigGroup() to access a config group. Also always use the entryName()
0041  * method for generating keys in the config (for prefixes, see below).
0042  *
0043  * Ensure that this class is inherited after a QObject-based class and pass
0044  * "this" as constructor argument.
0045  *
0046  * By default a config group based on Qt's object name of the class is used.
0047  * This behaviour can be changed by setting a dedicated config group via
0048  * setConfigGroup(). This is useful for to externally control the config group
0049  * and shouldn't be used inside the implementing class.
0050  *
0051  * Additionally to setting the config group, also a prefix for each config group
0052  * entry can be defined via setEntryPrefix(). This may be useful if multiple
0053  * instances of the same class shall be stored in the same config group or can
0054  * generally be a good idea to make the config more readable and recognizable.
0055  * By default this prefix is empty.
0056  *
0057  * This class also supports recursive saving / loading invocations based on the
0058  * QT object hierarchy. As default, calls to loadState() or saveState() only
0059  * invoke the doLoadState() or doStateSave() method of the called instance.
0060  * This behaviour can be changed with setStateSavingDepth() to automatically
0061  * call children of the instance. Various modes are supported as documented in
0062  * StateSavingDepth.
0063  *
0064  * @author jwienke
0065  */
0066 class DIGIKAM_EXPORT StateSavingObject
0067 {
0068 public:
0069 
0070     /**
0071      * This enum defines the "depth" of the StateSavingObject#loadState() and
0072      * StateSavingObject#saveState() methods.
0073      */
0074     enum StateSavingDepth
0075     {
0076         /**
0077          * Only the instance the saving / restoring was invoked on is
0078          * saved / restored.
0079          */
0080         INSTANCE,
0081 
0082         /**
0083          * The instance itself and all direct children of this instance implementing
0084          * StateSavingObject are saved / restored.
0085          */
0086         DIRECT_CHILDREN,
0087 
0088         /**
0089          * The instance and all children in the complete hierarchy are saved /
0090          * restored.
0091          */
0092         RECURSIVE
0093     };
0094 
0095     /**
0096      * Constructor. Must be called after any QObject-based constructor.
0097      *
0098      * @param host self-reference to access the object name, simply pass "this"
0099      *             as argument
0100      */
0101     explicit StateSavingObject(QObject* const host);
0102 
0103     /**
0104      * Destructor.
0105      */
0106     virtual ~StateSavingObject();
0107 
0108     /**
0109      * Returns the depth used for state saving or loading. Default is
0110      * StateSavingDepth::INSTANCE.
0111      *
0112      * @return state saving / restoring depth
0113      */
0114     StateSavingDepth getStateSavingDepth()  const;
0115 
0116     /**
0117      * Sets the depth used for state saving or loading.
0118      *
0119      * @param depth new depth to use
0120      */
0121     void setStateSavingDepth(const StateSavingDepth depth);
0122 
0123     /**
0124      * Sets a dedicated config group that will be used to store and reload
0125      * the state from. If this method is not called, a group based on the
0126      * object name is used.
0127      *
0128      * You can re-implement this method to pass the group set here to child
0129      * objects. Don't forget to call this method in your implementation.
0130      *
0131      * @param group config group to use for state saving and restoring
0132      */
0133     virtual void setConfigGroup(const KConfigGroup& group);
0134 
0135     /**
0136      * Define a prefix that will be used for every entry in the config group.
0137      * The default prefix is empty.
0138      *
0139      * You can re-implement this method to pass the prefix set here to child
0140      * objects. Don't forget to call this method in your implementation.
0141      *
0142      * @param prefix the prefix to use for the config entries
0143      */
0144     virtual void setEntryPrefix(const QString& prefix);
0145 
0146     /**
0147      * Invokes loading the class' state.
0148      */
0149     void loadState();
0150 
0151     /**
0152      * Invokes saving the class' state.
0153      */
0154     void saveState();
0155 
0156 protected:
0157 
0158     /**
0159      * Implement this hook method for state loading. Use getConfigGroup() and
0160      * entryName() for the implementation.
0161      */
0162     virtual void doLoadState() = 0;
0163 
0164     /**
0165      * Implement this hook method for state saving. Use getConfigGroup() and
0166      * entryName() for the implementation.
0167      */
0168     virtual void doSaveState() = 0;
0169 
0170     /**
0171      * Returns the config group that must be used for state saving and loading.
0172      *
0173      * @return config group for state saving and loading
0174      */
0175     KConfigGroup getConfigGroup()           const;
0176 
0177     /**
0178      * Always use this method to create config group entry names. This allows
0179      * to manipulate the entry keys externally by eg. setting a prefix.
0180      *
0181      * @param base original name planned for the config group entry
0182      * @return entry name after manipulating it with externally set parameters
0183      */
0184     QString entryName(const QString& base)  const;
0185 
0186 private:
0187 
0188     // Disable
0189     StateSavingObject(const StateSavingObject&)            = delete;
0190     StateSavingObject& operator=(const StateSavingObject&) = delete;
0191 
0192 private:
0193 
0194     class Private;
0195     Private* const d;
0196 };
0197 
0198 } // namespace Digikam
0199 
0200 #endif // DIGIKAM_STATE_SAVING_OBJECT_H