File indexing completed on 2024-04-21 03:53:13

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