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 #include "statesavingobject.h" 0016 0017 // KDE includes 0018 0019 #include <kconfiggroup.h> 0020 #include <ksharedconfig.h> 0021 0022 // Local includes 0023 0024 #include "digikam_debug.h" 0025 0026 namespace Digikam 0027 { 0028 0029 class Q_DECL_HIDDEN StateSavingObject::Private 0030 { 0031 public: 0032 0033 explicit Private() 0034 : host (nullptr), 0035 group (), 0036 prefix (), 0037 groupSet(false), 0038 depth (StateSavingObject::INSTANCE) 0039 { 0040 } 0041 0042 inline KConfigGroup getGroupFromObjectName() 0043 { 0044 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0045 0046 if (host->objectName().isEmpty()) 0047 { 0048 qCWarning(DIGIKAM_WIDGETS_LOG) << "Object name for " << host 0049 << " is empty. Returning the default config group"; 0050 } 0051 0052 return config->group(host->objectName()); 0053 } 0054 0055 void recurse(const QObjectList& children, const bool save) 0056 { 0057 for (QObjectList::const_iterator childIt = children.constBegin() ; 0058 childIt != children.constEnd() ; ++childIt) 0059 { 0060 StateSavingObject* const statefulChild = dynamic_cast<StateSavingObject*>(*childIt); 0061 0062 if (statefulChild) 0063 { 0064 // if the child implements the interface, it can be save / 0065 // restored 0066 0067 // but before invoking these actions, avoid duplicate calls to 0068 // the methods of deeper children 0069 0070 const StateSavingObject::StateSavingDepth oldState = statefulChild->getStateSavingDepth(); 0071 statefulChild->setStateSavingDepth(StateSavingObject::INSTANCE); 0072 0073 // decide which action to invoke 0074 0075 if (save) 0076 { 0077 statefulChild->saveState(); 0078 } 0079 else 0080 { 0081 statefulChild->loadState(); 0082 } 0083 0084 statefulChild->setStateSavingDepth(oldState); 0085 } 0086 0087 // recurse children every time 0088 0089 recurse((*childIt)->children(), save); 0090 } 0091 } 0092 0093 void recurseOperation(const bool save) 0094 { 0095 QString action = QLatin1String("loading"); 0096 0097 if (save) 0098 { 0099 action = QLatin1String("saving"); 0100 } 0101 0102 if (depth == StateSavingObject::DIRECT_CHILDREN) 0103 { 0104 //qCDebug(DIGIKAM_WIDGETS_LOG) << "Also restoring " << action << " of direct children"; 0105 0106 for (QObjectList::const_iterator childIt = host->children().begin() ; 0107 childIt != host->children().end() ; ++childIt) 0108 { 0109 StateSavingObject* const statefulChild = dynamic_cast<StateSavingObject*>(*childIt); 0110 0111 if (statefulChild) 0112 { 0113 if (save) 0114 { 0115 statefulChild->saveState(); 0116 } 0117 else 0118 { 0119 statefulChild->loadState(); 0120 } 0121 } 0122 } 0123 } 0124 else if (depth == StateSavingObject::RECURSIVE) 0125 { 0126 //qCDebug(DIGIKAM_WIDGETS_LOG) << "Also " << action << " state of all children (recursive)"; 0127 recurse(host->children(), save); 0128 } 0129 } 0130 0131 public: 0132 0133 QObject* host; 0134 KConfigGroup group; 0135 QString prefix; 0136 bool groupSet; 0137 StateSavingObject::StateSavingDepth depth; 0138 }; 0139 0140 StateSavingObject::StateSavingObject(QObject* const host) 0141 : d(new Private) 0142 { 0143 d->host = host; 0144 0145 // we cannot safely create the default config group here, because the host 0146 // may not have been properly initialized or its object name is set after 0147 // the constructor call 0148 } 0149 0150 StateSavingObject::~StateSavingObject() 0151 { 0152 delete d; 0153 } 0154 0155 StateSavingObject::StateSavingDepth StateSavingObject::getStateSavingDepth() const 0156 { 0157 return d->depth; 0158 } 0159 0160 void StateSavingObject::setStateSavingDepth(const StateSavingObject::StateSavingDepth depth) 0161 { 0162 d->depth = depth; 0163 } 0164 0165 void StateSavingObject::setConfigGroup(const KConfigGroup& group) 0166 { 0167 /* 0168 qCDebug(DIGIKAM_WIDGETS_LOG) << "received new config group: " << group.name(); 0169 */ 0170 d->group = group; 0171 d->groupSet = true; 0172 } 0173 0174 void StateSavingObject::setEntryPrefix(const QString& prefix) 0175 { 0176 d->prefix = prefix; 0177 } 0178 0179 void StateSavingObject::loadState() 0180 { 0181 /* 0182 qCDebug(DIGIKAM_WIDGETS_LOG) << "Loading state"; 0183 */ 0184 doLoadState(); 0185 0186 d->recurseOperation(false); 0187 } 0188 0189 void StateSavingObject::saveState() 0190 { 0191 /* 0192 qCDebug(DIGIKAM_WIDGETS_LOG) << "Saving state"; 0193 */ 0194 doSaveState(); 0195 0196 d->recurseOperation(true); 0197 } 0198 0199 KConfigGroup StateSavingObject::getConfigGroup() const 0200 { 0201 if (!d->groupSet) 0202 { 0203 /* 0204 qCDebug(DIGIKAM_WIDGETS_LOG) << "No config group set, returning one based on object name"; 0205 */ 0206 return d->getGroupFromObjectName(); 0207 } 0208 0209 if (!d->group.isValid()) 0210 { 0211 qCWarning(DIGIKAM_WIDGETS_LOG) << "KConfigGroup set via setConfigGroup is invalid. " 0212 << "Using object name based group."; 0213 return d->getGroupFromObjectName(); 0214 } 0215 0216 return d->group; 0217 } 0218 0219 QString StateSavingObject::entryName(const QString& base) const 0220 { 0221 return (d->prefix + base); 0222 } 0223 0224 } // namespace Digikam