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