File indexing completed on 2024-04-28 15:19:36

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2006, 2007 Thomas Braxton <kde.braxton@gmail.com>
0004     SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org>
0005     SPDX-FileCopyrightText: 1997 Matthias Kalle Dalheimer <kalle@kde.org>
0006     SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org>
0007 
0008     SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 
0011 #ifndef KCONFIGGROUP_H
0012 #define KCONFIGGROUP_H
0013 
0014 #include "kconfigbase.h"
0015 
0016 #include <kconfigcore_export.h>
0017 
0018 #include <QExplicitlySharedDataPointer>
0019 #include <QStringList>
0020 #include <QVariant>
0021 
0022 class KConfig;
0023 class KConfigGroupPrivate;
0024 class KSharedConfig;
0025 
0026 /**
0027  * \class KConfigGroup kconfiggroup.h <KConfigGroup>
0028  *
0029  * A class for one specific group in a KConfig object.
0030  *
0031  * If you want to access the top-level entries of a KConfig
0032  * object, which are not associated with any group, use an
0033  * empty group name.
0034  *
0035  * A KConfigGroup will be read-only if it is constructed from a
0036  * const config object or from another read-only group.
0037  */
0038 class KCONFIGCORE_EXPORT KConfigGroup : public KConfigBase
0039 {
0040 public:
0041     /**
0042      * Constructs an invalid group.
0043      *
0044      * \see isValid
0045      */
0046     KConfigGroup();
0047 
0048     /**
0049      * Construct a config group corresponding to @p group in @p master.
0050      *
0051      * This allows the creation of subgroups by passing another
0052      * group as @p master.
0053      *
0054      * @param group name of group
0055      */
0056     KConfigGroup(KConfigBase *master, const QString &group);
0057     /**
0058      * Overload for KConfigGroup(KConfigBase*,const QString&)
0059      *
0060      * @param group name of group, encoded in UTF-8
0061      */
0062     KConfigGroup(KConfigBase *master, const char *group);
0063 
0064     /**
0065      * Construct a read-only config group.
0066      *
0067      * A read-only group will silently ignore any attempts to write to it.
0068      *
0069      * This allows the creation of subgroups by passing an existing group
0070      * as @p master.
0071      */
0072     KConfigGroup(const KConfigBase *master, const QString &group);
0073     /**
0074      * Overload for KConfigGroup(const KConfigBase*,const QString&)
0075      *
0076      * @param group name of group, encoded in UTF-8
0077      */
0078     KConfigGroup(const KConfigBase *master, const char *group);
0079 
0080     /** Overload for KConfigGroup(const KConfigBase*,const QString&) */
0081     KConfigGroup(const QExplicitlySharedDataPointer<KSharedConfig> &master, const QString &group);
0082     /**
0083      * Overload for KConfigGroup(const KConfigBase*,const QString&)
0084      *
0085      * @param group name of group, encoded in UTF-8
0086      */
0087     KConfigGroup(const QExplicitlySharedDataPointer<KSharedConfig> &master, const char *group);
0088 
0089     /**
0090      * Creates a copy of a group.
0091      */
0092     KConfigGroup(const KConfigGroup &);
0093     KConfigGroup &operator=(const KConfigGroup &);
0094 
0095     ~KConfigGroup() override;
0096 
0097     /**
0098      * Whether the group is valid.
0099      *
0100      * A group is invalid if it was constructed without arguments.
0101      *
0102      * You should not call any functions on an invalid group.
0103      *
0104      * @return @c true if the group is valid, @c false if it is invalid.
0105      */
0106     bool isValid() const;
0107 
0108     /**
0109      * The name of this group.
0110      *
0111      * The root group is named "<default>".
0112      */
0113     QString name() const;
0114 
0115     /**
0116      * Check whether the containing KConfig object actually contains a
0117      * group with this name.
0118      */
0119     bool exists() const;
0120 
0121     /**
0122      * @reimp
0123      *
0124      * Syncs the parent config.
0125      */
0126     bool sync() override;
0127 
0128     /// @reimp
0129     void markAsClean() override;
0130 
0131     /// @reimp
0132     AccessMode accessMode() const override;
0133 
0134     /**
0135      * Return the config object that this group belongs to
0136      */
0137     KConfig *config();
0138     /**
0139      * Return the config object that this group belongs to
0140      */
0141     const KConfig *config() const;
0142 
0143 #if KCONFIGCORE_ENABLE_DEPRECATED_SINCE(5, 0)
0144     /**
0145      * Changes the group of the object
0146      *
0147      * @deprecated Since 5.0
0148      * Create another KConfigGroup from the parent of this group instead.
0149      */
0150     KCONFIGCORE_DEPRECATED_VERSION(5, 0, "Create another KConfigGroup from the parent of this group")
0151     void changeGroup(const QString &group);
0152 #endif
0153 
0154 #if KCONFIGCORE_ENABLE_DEPRECATED_SINCE(5, 0)
0155     /**
0156      * Overload for changeGroup(const QString&)
0157      *
0158      * @param group name of group, encoded in UTF-8
0159      *
0160      * @deprecated Since 5.0.
0161      * Create another KConfigGroup from the parent of this group instead.
0162      */
0163     KCONFIGCORE_DEPRECATED_VERSION(5, 0, "Create another KConfigGroup from the parent of this group")
0164     void changeGroup(const char *group);
0165 #endif
0166 
0167     /**
0168      * Copies the entries in this group to another configuration object
0169      *
0170      * @note @p other can be either another group or a different file.
0171      *
0172      * @param other  the configuration object to copy this group's entries to
0173      * @param pFlags the flags to use when writing the entries to the
0174      *               other configuration object
0175      *
0176      * @since 4.1
0177      */
0178     void copyTo(KConfigBase *other, WriteConfigFlags pFlags = Normal) const;
0179 
0180     /**
0181      * Changes the configuration object that this group belongs to
0182      *
0183      * @note @p other can be another group, the top-level KConfig object or
0184      * a different KConfig object entirely.
0185      *
0186      * If @p parent is already the parent of this group, this method will have
0187      * no effect.
0188      *
0189      * @param parent the config object to place this group under
0190      * @param pFlags the flags to use in determining which storage source to
0191      *               write the data to
0192      *
0193      * @since 4.1
0194      */
0195     void reparent(KConfigBase *parent, WriteConfigFlags pFlags = Normal);
0196 
0197     /**
0198      * Moves the key-value pairs from one config group to the other.
0199      * In case the entries do not exist the key is ignored.
0200      *
0201      * @since 5.88
0202      */
0203     void moveValuesTo(const QList<const char *> &keys, KConfigGroup &other, WriteConfigFlags pFlags = Normal);
0204 
0205     /**
0206      * Returns the group that this group belongs to
0207      *
0208      * @return the parent group, or an invalid group if this is a top-level
0209      *          group
0210      *
0211      * @since 4.1
0212      */
0213     KConfigGroup parent() const;
0214 
0215     /**
0216      * @reimp
0217      */
0218     QStringList groupList() const override;
0219 
0220     /**
0221      * Returns a list of keys this group contains
0222      */
0223     QStringList keyList() const;
0224 
0225     /**
0226      * Delete all entries in the entire group
0227      *
0228      * @param pFlags flags passed to KConfig::deleteGroup
0229      *
0230      * @see deleteEntry()
0231      */
0232     void deleteGroup(WriteConfigFlags pFlags = Normal);
0233     using KConfigBase::deleteGroup;
0234 
0235     /**
0236      * Reads the value of an entry specified by @p pKey in the current group
0237      *
0238      * This template method makes it possible to write
0239      *    QString foo = readEntry("...", QString("default"));
0240      * and the same with all other types supported by QVariant.
0241      *
0242      * The return type of the method is simply the same as the type of the default value.
0243      *
0244      * @note readEntry("...", Qt::white) will not compile because Qt::white is an enum.
0245      * You must turn it into readEntry("...", QColor(Qt::white)).
0246      *
0247      * @note Only the following QVariant types are allowed : String,
0248      * StringList, List, Font, Point, Rect, Size, Color, Int, UInt, Bool,
0249      * Double, LongLong, ULongLong, DateTime and Date.
0250      *
0251      * @param key The key to search for
0252      * @param aDefault A default value returned if the key was not found
0253      * @return The value for this key, or @p aDefault.
0254      *
0255      * @see writeEntry(), deleteEntry(), hasKey()
0256      */
0257     template<typename T>
0258     T readEntry(const QString &key, const T &aDefault) const
0259     {
0260         return readEntry(key.toUtf8().constData(), aDefault);
0261     }
0262     /**
0263      * Overload for readEntry<T>(const QString&, const T&) const
0264      * @param key name of key, encoded in UTF-8
0265      */
0266     template<typename T>
0267     T readEntry(const char *key, const T &aDefault) const;
0268 
0269     /**
0270      * Reads the value of an entry specified by @p key in the current group
0271      *
0272      * @param key the key to search for
0273      * @param aDefault a default value returned if the key was not found
0274      * @return the value for this key, or @p aDefault if the key was not found
0275      *
0276      * @see writeEntry(), deleteEntry(), hasKey()
0277      */
0278     QVariant readEntry(const QString &key, const QVariant &aDefault) const;
0279     /**
0280      * Overload for readEntry(const QString&, const QVariant&) const
0281      * @param key name of key, encoded in UTF-8
0282      */
0283     QVariant readEntry(const char *key, const QVariant &aDefault) const;
0284 
0285     /**
0286      * Reads the string value of an entry specified by @p key in the current group
0287      *
0288      * If you want to read a path, please use readPathEntry().
0289      *
0290      * @param key the key to search for
0291      * @param aDefault a default value returned if the key was not found
0292      * @return the value for this key, or @p aDefault if the key was not found
0293      *
0294      * @see readPathEntry(), writeEntry(), deleteEntry(), hasKey()
0295      */
0296     QString readEntry(const QString &key, const QString &aDefault) const;
0297     /**
0298      * Overload for readEntry(const QString&, const QString&) const
0299      * @param key name of key, encoded in UTF-8
0300      */
0301     QString readEntry(const char *key, const QString &aDefault) const;
0302 
0303     /** Overload for readEntry(const QString&, const QString&) const */
0304     QString readEntry(const QString &key, const char *aDefault = nullptr) const;
0305     /**
0306      * Overload for readEntry(const QString&, const QString&) const
0307      * @param key name of key, encoded in UTF-8
0308      */
0309     QString readEntry(const char *key, const char *aDefault = nullptr) const;
0310 
0311     /**
0312      * @copydoc readEntry(const char*, const QStringList&) const
0313      *
0314      * @warning This function doesn't convert the items returned
0315      *          to any type. It's actually a list of QVariant::String's. If you
0316      *          want the items converted to a specific type use
0317      *          readEntry(const char*, const QList<T>&) const
0318      */
0319     QVariantList readEntry(const QString &key, const QVariantList &aDefault) const;
0320     /**
0321      * Overload for readEntry(const QString&, const QVariantList&) const
0322      * @param key name of key, encoded in UTF-8
0323      */
0324     QVariantList readEntry(const char *key, const QVariantList &aDefault) const;
0325 
0326     /**
0327      * Reads a list of strings from the config object
0328      *
0329      * @param key The key to search for
0330      * @param aDefault The default value to use if the key does not exist
0331      * @return The list, or @p aDefault if @p key does not exist
0332      *
0333      * @see readXdgListEntry(), writeEntry(), deleteEntry(), hasKey()
0334      */
0335     QStringList readEntry(const QString &key, const QStringList &aDefault) const;
0336     /**
0337      * Overload for readEntry(const QString&, const QStringList&) const
0338      * @param key name of key, encoded in UTF-8
0339      */
0340     QStringList readEntry(const char *key, const QStringList &aDefault) const;
0341 
0342     /**
0343      * Reads a list of values from the config object
0344      *
0345      * @param key the key to search for
0346      * @param aDefault the default value to use if the key does not exist
0347      * @return the list, or @p aDefault if @p key does not exist
0348      *
0349      * @see readXdgListEntry(), writeEntry(), deleteEntry(), hasKey()
0350      */
0351     template<typename T>
0352     QList<T> readEntry(const QString &key, const QList<T> &aDefault) const
0353     {
0354         return readEntry(key.toUtf8().constData(), aDefault);
0355     }
0356     /**
0357      * Overload for readEntry<T>(const QString&, const QList<T>&) const
0358      * @param key name of key, encoded in UTF-8
0359      */
0360     template<typename T>
0361     QList<T> readEntry(const char *key, const QList<T> &aDefault) const;
0362 
0363     /**
0364      * Reads a list of strings from the config object, following XDG
0365      * desktop entry spec separator semantics
0366      *
0367      * @param pKey the key to search for
0368      * @param aDefault the default value to use if the key does not exist
0369      * @return the list, or @p aDefault if @p pKey does not exist
0370      *
0371      * @see readEntry(const QString&, const QStringList&) const
0372      */
0373     QStringList readXdgListEntry(const QString &pKey, const QStringList &aDefault = QStringList()) const;
0374     /**
0375      * Overload for readXdgListEntry(const QString&, const QStringList&) const
0376      * @param key name of key, encoded in UTF-8
0377      */
0378     QStringList readXdgListEntry(const char *key, const QStringList &aDefault = QStringList()) const;
0379 
0380     /**
0381      * Reads a path
0382      *
0383      * Read the value of an entry specified by @p pKey in the current group
0384      * and interpret it as a path. This means, dollar expansion is activated
0385      * for this value, so that e.g. $HOME gets expanded.
0386      *
0387      * @param pKey The key to search for.
0388      * @param aDefault A default value returned if the key was not found.
0389      * @return The value for this key. Can be QString() if @p aDefault is null.
0390      */
0391     QString readPathEntry(const QString &pKey, const QString &aDefault) const;
0392     /**
0393      * Overload for readPathEntry(const QString&, const QString&) const
0394      * @param key name of key, encoded in UTF-8
0395      */
0396     QString readPathEntry(const char *key, const QString &aDefault) const;
0397 
0398     /**
0399      * Reads a list of paths
0400      *
0401      * Read the value of an entry specified by @p pKey in the current group
0402      * and interpret it as a list of paths. This means, dollar expansion is activated
0403      * for this value, so that e.g. $HOME gets expanded.
0404      *
0405      * @param pKey the key to search for
0406      * @param aDefault a default value returned if the key was not found
0407      * @return the list, or @p aDefault if the key does not exist
0408      */
0409     QStringList readPathEntry(const QString &pKey, const QStringList &aDefault) const;
0410     /**
0411      * Overload for readPathEntry(const QString&, const QStringList&) const
0412      * @param key name of key, encoded in UTF-8
0413      */
0414     QStringList readPathEntry(const char *key, const QStringList &aDefault) const;
0415 
0416     /**
0417      * Reads an untranslated string entry
0418      *
0419      * You should not normally need to use this.
0420      *
0421      * @param pKey the key to search for
0422      * @param aDefault a default value returned if the key was not found
0423      * @return the value for this key, or @p aDefault if the key does not exist
0424      */
0425     QString readEntryUntranslated(const QString &pKey, const QString &aDefault = QString()) const;
0426     /**
0427      * Overload for readEntryUntranslated(const QString&, const QString&) const
0428      * @param key name of key, encoded in UTF-8
0429      */
0430     QString readEntryUntranslated(const char *key, const QString &aDefault = QString()) const;
0431 
0432     /**
0433      * Writes a value to the configuration object.
0434      *
0435      * @param key the key to write to
0436      * @param value the value to write
0437      * @param pFlags the flags to use when writing this entry
0438      *
0439      * @see readEntry(), writeXdgListEntry(), deleteEntry()
0440      */
0441     void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags = Normal);
0442     /**
0443      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0444      * @param key name of key, encoded in UTF-8
0445      */
0446     void writeEntry(const char *key, const QVariant &value, WriteConfigFlags pFlags = Normal);
0447 
0448     /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
0449     void writeEntry(const QString &key, const QString &value, WriteConfigFlags pFlags = Normal);
0450     /**
0451      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0452      * @param key name of key, encoded in UTF-8
0453      */
0454     void writeEntry(const char *key, const QString &value, WriteConfigFlags pFlags = Normal);
0455 
0456     /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
0457     void writeEntry(const QString &key, const QByteArray &value, WriteConfigFlags pFlags = Normal);
0458     /**
0459      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0460      * @param key name of key, encoded in UTF-8
0461      */
0462     void writeEntry(const char *key, const QByteArray &value, WriteConfigFlags pFlags = Normal);
0463 
0464     /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
0465     void writeEntry(const QString &key, const char *value, WriteConfigFlags pFlags = Normal);
0466     /**
0467      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0468      * @param key name of key, encoded in UTF-8
0469      */
0470     void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags = Normal);
0471 
0472     /**
0473      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0474      * @param key name of key, encoded in UTF-8
0475      */
0476     template<typename T>
0477     void writeEntry(const char *key, const T &value, WriteConfigFlags pFlags = Normal);
0478     /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
0479     template<typename T>
0480     void writeEntry(const QString &key, const T &value, WriteConfigFlags pFlags = Normal)
0481     {
0482         writeEntry(key.toUtf8().constData(), value, pFlags);
0483     }
0484 
0485     /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
0486     void writeEntry(const QString &key, const QStringList &value, WriteConfigFlags pFlags = Normal);
0487     /**
0488      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0489      * @param key name of key, encoded in UTF-8
0490      */
0491     void writeEntry(const char *key, const QStringList &value, WriteConfigFlags pFlags = Normal);
0492 
0493     /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
0494     void writeEntry(const QString &key, const QVariantList &value, WriteConfigFlags pFlags = Normal);
0495     /**
0496      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0497      * @param key name of key, encoded in UTF-8
0498      */
0499     void writeEntry(const char *key, const QVariantList &value, WriteConfigFlags pFlags = Normal);
0500 
0501     /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
0502     template<typename T>
0503     void writeEntry(const QString &key, const QList<T> &value, WriteConfigFlags pFlags = Normal)
0504     {
0505         writeEntry(key.toUtf8().constData(), value, pFlags);
0506     }
0507     /**
0508      * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
0509      * @param key name of key, encoded in UTF-8
0510      */
0511     template<typename T>
0512     void writeEntry(const char *key, const QList<T> &value, WriteConfigFlags pFlags = Normal);
0513 
0514     /**
0515      * Writes a list of strings to the config object, following XDG
0516      * desktop entry spec separator semantics
0517      *
0518      * @param pKey the key to write to
0519      * @param value the list to write
0520      * @param pFlags the flags to use when writing this entry
0521      *
0522      * @see writeEntry(), readXdgListEntry()
0523      */
0524     void writeXdgListEntry(const QString &pKey, const QStringList &value, WriteConfigFlags pFlags = Normal);
0525     /**
0526      * Overload for writeXdgListEntry(const QString&, const QStringList&, WriteConfigFlags)
0527      * @param key name of key, encoded in UTF-8
0528      */
0529     void writeXdgListEntry(const char *key, const QStringList &value, WriteConfigFlags pFlags = Normal);
0530 
0531     /**
0532      * Writes a file path to the configuration
0533      *
0534      * If the path is located under $HOME, the user's home directory
0535      * is replaced with $HOME in the persistent storage.
0536      * The path should therefore be read back with readPathEntry()
0537      *
0538      * @param pKey the key to write to
0539      * @param path the path to write
0540      * @param pFlags the flags to use when writing this entry
0541      *
0542      * @see writeEntry(), readPathEntry()
0543      */
0544     void writePathEntry(const QString &pKey, const QString &path, WriteConfigFlags pFlags = Normal);
0545     /**
0546      * Overload for writePathEntry(const QString&, const QString&, WriteConfigFlags)
0547      * @param key name of key, encoded in UTF-8
0548      */
0549     void writePathEntry(const char *Key, const QString &path, WriteConfigFlags pFlags = Normal);
0550 
0551     /**
0552      * Writes a list of paths to the configuration
0553      *
0554      * If any of the paths are located under $HOME, the user's home directory
0555      * is replaced with $HOME in the persistent storage.
0556      * The paths should therefore be read back with readPathEntry()
0557      *
0558      * @param pKey the key to write to
0559      * @param value the list to write
0560      * @param pFlags the flags to use when writing this entry
0561      *
0562      * @see writeEntry(), readPathEntry()
0563      */
0564     void writePathEntry(const QString &pKey, const QStringList &value, WriteConfigFlags pFlags = Normal);
0565     /**
0566      * Overload for writePathEntry(const QString&, const QStringList&, WriteConfigFlags)
0567      * @param key name of key, encoded in UTF-8
0568      */
0569     void writePathEntry(const char *key, const QStringList &value, WriteConfigFlags pFlags = Normal);
0570 
0571     /**
0572      * Deletes the entry specified by @p pKey in the current group
0573      *
0574      * This also hides system wide defaults.
0575      *
0576      * @param pKey the key to delete
0577      * @param pFlags the flags to use when deleting this entry
0578      *
0579      * @see deleteGroup(), readEntry(), writeEntry()
0580      */
0581     void deleteEntry(const QString &pKey, WriteConfigFlags pFlags = Normal);
0582     /**
0583      * Overload for deleteEntry(const QString&, WriteConfigFlags)
0584      * @param key name of key, encoded in UTF-8
0585      */
0586     void deleteEntry(const char *key, WriteConfigFlags pFlags = Normal);
0587 
0588     /**
0589      * Checks whether the key has an entry in this group
0590      *
0591      * Use this to determine if a key is not specified for the current
0592      * group (hasKey() returns false).
0593      *
0594      * If this returns @c false for a key, readEntry() (and its variants)
0595      * will return the default value passed to them.
0596      *
0597      * @param key the key to search for
0598      * @return @c true if the key is defined in this group by any of the
0599      *         configuration sources, @c false otherwise
0600      *
0601      * @see readEntry()
0602      */
0603     bool hasKey(const QString &key) const;
0604     /**
0605      * Overload for hasKey(const QString&) const
0606      * @param key name of key, encoded in UTF-8
0607      */
0608     bool hasKey(const char *key) const;
0609 
0610     /**
0611      * Whether this group may be changed
0612      *
0613      * @return @c false if the group may be changed, @c true otherwise
0614      */
0615     bool isImmutable() const override;
0616 
0617     /**
0618      * Checks if it is possible to change the given entry
0619      *
0620      * If isImmutable() returns @c true, then this method will return
0621      * @c true for all inputs.
0622      *
0623      * @param key the key to check
0624      * @return @c false if the key may be changed using this configuration
0625      *         group object, @c true otherwise
0626      */
0627     bool isEntryImmutable(const QString &key) const;
0628     /**
0629      * Overload for isEntryImmutable(const QString&) const
0630      * @param key name of key, encoded in UTF-8
0631      */
0632     bool isEntryImmutable(const char *key) const;
0633 
0634     /**
0635      * Reverts an entry to the default settings.
0636      *
0637      * Reverts the entry with key @p key in the current group in the
0638      * application specific config file to either the system wide (default)
0639      * value or the value specified in the global KDE config file.
0640      *
0641      * To revert entries in the global KDE config file, the global KDE config
0642      * file should be opened explicitly in a separate config object.
0643      *
0644      * @note This is @em not the same as deleting the key, as instead the
0645      * global setting will be copied to the configuration file that this
0646      * object manipulates.
0647      *
0648      * @param key The key of the entry to revert.
0649      */
0650     // TODO KF6 merge with the other one
0651     void revertToDefault(const QString &key);
0652     void revertToDefault(const QString &key, WriteConfigFlags pFlag);
0653 
0654     // TODO KF6 merge with the other one
0655     /**
0656      * Overload for revertToDefault(const QString&)
0657      * @param key name of key, encoded in UTF-8
0658      */
0659     void revertToDefault(const char *key);
0660     /**
0661      * Overload for revertToDefault(const QString&, WriteConfigFlags)
0662      * @param key name of key, encoded in UTF-8
0663      */
0664     void revertToDefault(const char *key, WriteConfigFlags pFlag);
0665 
0666     /**
0667      * Whether a default is specified for an entry in either the
0668      * system wide configuration file or the global KDE config file
0669      *
0670      * If an application computes a default value at runtime for
0671      * a certain entry, e.g. like:
0672      * \code
0673      * QColor computedDefault = qApp->palette().color(QPalette::Active, QPalette::Text);
0674      * QColor color = group.readEntry(key, computedDefault);
0675      * \endcode
0676      * then it may wish to make the following check before
0677      * writing back changes:
0678      * \code
0679      * if ( (value == computedDefault) && !group.hasDefault(key) )
0680      *    group.revertToDefault(key);
0681      * else
0682      *    group.writeEntry(key, value);
0683      * \endcode
0684      *
0685      * This ensures that as long as the entry is not modified to differ from
0686      * the computed default, the application will keep using the computed default
0687      * and will follow changes the computed default makes over time.
0688      *
0689      * @param key the key of the entry to check
0690      * @return @c true if the global or system settings files specify a default
0691      *          for @p key in this group, @c false otherwise
0692      */
0693     bool hasDefault(const QString &key) const;
0694     /**
0695      * Overload for hasDefault(const QString&) const
0696      * @param key name of key, encoded in UTF-8
0697      */
0698     bool hasDefault(const char *key) const;
0699 
0700     /**
0701      * Returns a map (tree) of entries for all entries in this group
0702      *
0703      * Only the actual entry string is returned, none of the
0704      * other internal data should be included.
0705      *
0706      * @return a map of entries in this group, indexed by key
0707      */
0708     QMap<QString, QString> entryMap() const;
0709 
0710 protected:
0711     bool hasGroupImpl(const QByteArray &group) const override;
0712     KConfigGroup groupImpl(const QByteArray &b) override;
0713     const KConfigGroup groupImpl(const QByteArray &b) const override;
0714     void deleteGroupImpl(const QByteArray &group, WriteConfigFlags flags) override;
0715     bool isGroupImmutableImpl(const QByteArray &aGroup) const override;
0716 
0717 private:
0718     QExplicitlySharedDataPointer<KConfigGroupPrivate> d;
0719 
0720     friend class KConfigGroupPrivate;
0721 
0722     /**
0723      * Return the data in @p value converted to a QVariant
0724      *
0725      * @param pKey the name of the entry being converted, this is only used for error
0726      * reporting
0727      * @param value the UTF-8 data to be converted
0728      * @param aDefault the default value if @p pKey is not found
0729      * @return @p value converted to QVariant, or @p aDefault if @p value is invalid or cannot be converted.
0730      */
0731     static QVariant convertToQVariant(const char *pKey, const QByteArray &value, const QVariant &aDefault);
0732     // exported for usage by KServices' KService & KServiceAction
0733     friend class KServicePrivate; // XXX yeah, ugly^5
0734     friend class KServiceAction;
0735 };
0736 
0737 #define KCONFIGGROUP_ENUMERATOR_ERROR(ENUM) "The Qt MetaObject system does not seem to know about \"" ENUM "\" please use Q_ENUM or Q_FLAG to register it."
0738 
0739 /**
0740  * To add support for your own enums in KConfig, you can declare them with Q_ENUM()
0741  * in a QObject subclass (which will make moc generate the code to turn the
0742  * enum into a string and vice-versa), and then (in the cpp code)
0743  * use the macro
0744  * <code>KCONFIGGROUP_DECLARE_ENUM_QOBJECT(MyClass, MyEnum)</code>
0745  *
0746  */
0747 #define KCONFIGGROUP_DECLARE_ENUM_QOBJECT(Class, Enum)                                                                                                         \
0748     template<>                                                                                                                                                 \
0749     Class::Enum KConfigGroup::readEntry(const char *key, const Class::Enum &def) const                                                                         \
0750     {                                                                                                                                                          \
0751         const QMetaObject *M_obj = &Class::staticMetaObject;                                                                                                   \
0752         const int M_index = M_obj->indexOfEnumerator(#Enum);                                                                                                   \
0753         if (M_index == -1)                                                                                                                                     \
0754             qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Enum));                                                                                                      \
0755         const QMetaEnum M_enum = M_obj->enumerator(M_index);                                                                                                   \
0756         const QByteArray M_data = readEntry(key, QByteArray(M_enum.valueToKey(def)));                                                                          \
0757         return static_cast<Class::Enum>(M_enum.keyToValue(M_data.constData()));                                                                                \
0758     }                                                                                                                                                          \
0759     inline Class::Enum KCONFIGCORE_DECL_DEPRECATED readEntry(const KConfigGroup &group, const char *key, const Class::Enum &def)                               \
0760     {                                                                                                                                                          \
0761         return group.readEntry(key, def);                                                                                                                      \
0762     }                                                                                                                                                          \
0763     template<>                                                                                                                                                 \
0764     void KConfigGroup::writeEntry(const char *key, const Class::Enum &value, KConfigBase::WriteConfigFlags flags)                                              \
0765     {                                                                                                                                                          \
0766         const QMetaObject *M_obj = &Class::staticMetaObject;                                                                                                   \
0767         const int M_index = M_obj->indexOfEnumerator(#Enum);                                                                                                   \
0768         if (M_index == -1)                                                                                                                                     \
0769             qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Enum));                                                                                                      \
0770         const QMetaEnum M_enum = M_obj->enumerator(M_index);                                                                                                   \
0771         writeEntry(key, QByteArray(M_enum.valueToKey(value)), flags);                                                                                          \
0772     }                                                                                                                                                          \
0773     inline void KCONFIGCORE_DECL_DEPRECATED writeEntry(KConfigGroup &group,                                                                                    \
0774                                                        const char *key,                                                                                        \
0775                                                        const Class::Enum &value,                                                                               \
0776                                                        KConfigBase::WriteConfigFlags flags = KConfigBase::Normal)                                              \
0777     {                                                                                                                                                          \
0778         group.writeEntry(key, value, flags);                                                                                                                   \
0779     }
0780 
0781 /**
0782  * Similar to KCONFIGGROUP_DECLARE_ENUM_QOBJECT but for flags declared with Q_FLAG()
0783  * (where multiple values can be set at the same time)
0784  */
0785 #define KCONFIGGROUP_DECLARE_FLAGS_QOBJECT(Class, Flags)                                                                                                       \
0786     template<>                                                                                                                                                 \
0787     Class::Flags KConfigGroup::readEntry(const char *key, const Class::Flags &def) const                                                                       \
0788     {                                                                                                                                                          \
0789         const QMetaObject *M_obj = &Class::staticMetaObject;                                                                                                   \
0790         const int M_index = M_obj->indexOfEnumerator(#Flags);                                                                                                  \
0791         if (M_index == -1)                                                                                                                                     \
0792             qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Flags));                                                                                                     \
0793         const QMetaEnum M_enum = M_obj->enumerator(M_index);                                                                                                   \
0794         const QByteArray M_data = readEntry(key, QByteArray(M_enum.valueToKeys(def)));                                                                         \
0795         return static_cast<Class::Flags>(M_enum.keysToValue(M_data.constData()));                                                                              \
0796     }                                                                                                                                                          \
0797     inline Class::Flags KCONFIGCORE_DECL_DEPRECATED readEntry(const KConfigGroup &group, const char *key, const Class::Flags &def)                             \
0798     {                                                                                                                                                          \
0799         return group.readEntry(key, def);                                                                                                                      \
0800     }                                                                                                                                                          \
0801     template<>                                                                                                                                                 \
0802     void KConfigGroup::writeEntry(const char *key, const Class::Flags &value, KConfigBase::WriteConfigFlags flags)                                             \
0803     {                                                                                                                                                          \
0804         const QMetaObject *M_obj = &Class::staticMetaObject;                                                                                                   \
0805         const int M_index = M_obj->indexOfEnumerator(#Flags);                                                                                                  \
0806         if (M_index == -1)                                                                                                                                     \
0807             qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Flags));                                                                                                     \
0808         const QMetaEnum M_enum = M_obj->enumerator(M_index);                                                                                                   \
0809         writeEntry(key, QByteArray(M_enum.valueToKeys(value)), flags);                                                                                         \
0810     }                                                                                                                                                          \
0811     inline void KCONFIGCORE_DECL_DEPRECATED writeEntry(KConfigGroup &group,                                                                                    \
0812                                                        const char *key,                                                                                        \
0813                                                        const Class::Flags &value,                                                                              \
0814                                                        KConfigBase::WriteConfigFlags flags = KConfigBase::Normal)                                              \
0815     {                                                                                                                                                          \
0816         group.writeEntry(key, value, flags);                                                                                                                   \
0817     }
0818 
0819 #include "conversioncheck.h"
0820 
0821 template<typename T>
0822 T KConfigGroup::readEntry(const char *key, const T &defaultValue) const
0823 {
0824     ConversionCheck::to_QVariant<T>();
0825     return qvariant_cast<T>(readEntry(key, QVariant::fromValue(defaultValue)));
0826 }
0827 
0828 template<typename T>
0829 QList<T> KConfigGroup::readEntry(const char *key, const QList<T> &defaultValue) const
0830 {
0831     ConversionCheck::to_QVariant<T>();
0832     ConversionCheck::to_QString<T>();
0833 
0834     QVariantList data;
0835 
0836     for (const T &value : defaultValue) {
0837         data.append(QVariant::fromValue(value));
0838     }
0839 
0840     QList<T> list;
0841     const auto variantList = readEntry<QVariantList>(key, data);
0842     for (const QVariant &value : variantList) {
0843         Q_ASSERT(value.canConvert<T>());
0844         list.append(qvariant_cast<T>(value));
0845     }
0846 
0847     return list;
0848 }
0849 
0850 template<typename T>
0851 void KConfigGroup::writeEntry(const char *key, const T &value, WriteConfigFlags pFlags)
0852 {
0853     ConversionCheck::to_QVariant<T>();
0854     writeEntry(key, QVariant::fromValue(value), pFlags);
0855 }
0856 
0857 template<typename T>
0858 void KConfigGroup::writeEntry(const char *key, const QList<T> &list, WriteConfigFlags pFlags)
0859 {
0860     ConversionCheck::to_QVariant<T>();
0861     ConversionCheck::to_QString<T>();
0862     QVariantList data;
0863     for (const T &value : list) {
0864         data.append(QVariant::fromValue(value));
0865     }
0866 
0867     writeEntry(key, data, pFlags);
0868 }
0869 
0870 #endif // KCONFIGGROUP_H