1 /*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2006, 2007 Thomas Braxton <kde.braxton@gmail.com>
4 SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org>
5 SPDX-FileCopyrightText: 1997 Matthias Kalle Dalheimer <kalle@kde.org>
6 SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9 */
10
11 #ifndef KCONFIGGROUP_H
12 #define KCONFIGGROUP_H
13
14 #include "kconfigbase.h"
15
16 #include <kconfigcore_export.h>
17
18 #include <QExplicitlySharedDataPointer>
19 #include <QStringList>
20 #include <QVariant>
21
22 class KConfig;
23 class KConfigGroupPrivate;
24 class KSharedConfig;
25
26 /**
27 * \class KConfigGroup kconfiggroup.h <KConfigGroup>
28 *
29 * A class for one specific group in a KConfig object.
30 *
31 * If you want to access the top-level entries of a KConfig
32 * object, which are not associated with any group, use an
33 * empty group name.
34 *
35 * A KConfigGroup will be read-only if it is constructed from a
36 * const config object or from another read-only group.
37 */
38 class KCONFIGCORE_EXPORT KConfigGroup : public KConfigBase
39 {
40 public:
41 /**
42 * Constructs an invalid group.
43 *
44 * \see isValid
45 */
46 KConfigGroup();
47
48 /**
49 * Construct a config group corresponding to @p group in @p master.
50 *
51 * This allows the creation of subgroups by passing another
52 * group as @p master.
53 *
54 * @param group name of group
55 */
56 KConfigGroup(KConfigBase *master, const QString &group);
57 /**
58 * Overload for KConfigGroup(KConfigBase*,const QString&)
59 *
60 * @param group name of group, encoded in UTF-8
61 */
62 KConfigGroup(KConfigBase *master, const char *group);
63
64 /**
65 * Construct a read-only config group.
66 *
67 * A read-only group will silently ignore any attempts to write to it.
68 *
69 * This allows the creation of subgroups by passing an existing group
70 * as @p master.
71 */
72 KConfigGroup(const KConfigBase *master, const QString &group);
73 /**
74 * Overload for KConfigGroup(const KConfigBase*,const QString&)
75 *
76 * @param group name of group, encoded in UTF-8
77 */
78 KConfigGroup(const KConfigBase *master, const char *group);
79
80 /** Overload for KConfigGroup(const KConfigBase*,const QString&) */
81 KConfigGroup(const QExplicitlySharedDataPointer<KSharedConfig> &master, const QString &group);
82 /**
83 * Overload for KConfigGroup(const KConfigBase*,const QString&)
84 *
85 * @param group name of group, encoded in UTF-8
86 */
87 KConfigGroup(const QExplicitlySharedDataPointer<KSharedConfig> &master, const char *group);
88
89 /**
90 * Creates a copy of a group.
91 */
92 KConfigGroup(const KConfigGroup &);
93 KConfigGroup &operator=(const KConfigGroup &);
94
95 ~KConfigGroup() override;
96
97 /**
98 * Whether the group is valid.
99 *
100 * A group is invalid if it was constructed without arguments.
101 *
102 * You should not call any functions on an invalid group.
103 *
104 * @return @c true if the group is valid, @c false if it is invalid.
105 */
106 bool isValid() const;
107
108 /**
109 * The name of this group.
110 *
111 * The root group is named "<default>".
112 */
113 QString name() const;
114
115 /**
116 * Check whether the containing KConfig object actually contains a
117 * group with this name.
118 */
119 bool exists() const;
120
121 /**
122 * @reimp
123 *
124 * Syncs the parent config.
125 */
126 bool sync() override;
127
128 /// @reimp
129 void markAsClean() override;
130
131 /// @reimp
132 AccessMode accessMode() const override;
133
134 /**
135 * Return the config object that this group belongs to
136 */
137 KConfig *config();
138 /**
139 * Return the config object that this group belongs to
140 */
141 const KConfig *config() const;
142
143 #if KCONFIGCORE_ENABLE_DEPRECATED_SINCE(5, 0)
144 /**
145 * Changes the group of the object
146 *
147 * @deprecated Since 5.0
148 * Create another KConfigGroup from the parent of this group instead.
149 */
150 KCONFIGCORE_DEPRECATED_VERSION(5, 0, "Create another KConfigGroup from the parent of this group")
151 void changeGroup(const QString &group);
152 #endif
153
154 #if KCONFIGCORE_ENABLE_DEPRECATED_SINCE(5, 0)
155 /**
156 * Overload for changeGroup(const QString&)
157 *
158 * @param group name of group, encoded in UTF-8
159 *
160 * @deprecated Since 5.0.
161 * Create another KConfigGroup from the parent of this group instead.
162 */
163 KCONFIGCORE_DEPRECATED_VERSION(5, 0, "Create another KConfigGroup from the parent of this group")
164 void changeGroup(const char *group);
165 #endif
166
167 /**
168 * Copies the entries in this group to another configuration object
169 *
170 * @note @p other can be either another group or a different file.
171 *
172 * @param other the configuration object to copy this group's entries to
173 * @param pFlags the flags to use when writing the entries to the
174 * other configuration object
175 *
176 * @since 4.1
177 */
178 void copyTo(KConfigBase *other, WriteConfigFlags pFlags = Normal) const;
179
180 /**
181 * Changes the configuration object that this group belongs to
182 *
183 * @note @p other can be another group, the top-level KConfig object or
184 * a different KConfig object entirely.
185 *
186 * If @p parent is already the parent of this group, this method will have
187 * no effect.
188 *
189 * @param parent the config object to place this group under
190 * @param pFlags the flags to use in determining which storage source to
191 * write the data to
192 *
193 * @since 4.1
194 */
195 void reparent(KConfigBase *parent, WriteConfigFlags pFlags = Normal);
196
197 /**
198 * Moves the key-value pairs from one config group to the other.
199 * In case the entries do not exist the key is ignored.
200 *
201 * @since 5.88
202 */
203 void moveValuesTo(const QList<const char *> &keys, KConfigGroup &other, WriteConfigFlags pFlags = Normal);
204
205 /**
206 * Returns the group that this group belongs to
207 *
208 * @return the parent group, or an invalid group if this is a top-level
209 * group
210 *
211 * @since 4.1
212 */
213 KConfigGroup parent() const;
214
215 /**
216 * @reimp
217 */
218 QStringList groupList() const override;
219
220 /**
221 * Returns a list of keys this group contains
222 */
223 QStringList keyList() const;
224
225 /**
226 * Delete all entries in the entire group
227 *
228 * @param pFlags flags passed to KConfig::deleteGroup
229 *
230 * @see deleteEntry()
231 */
232 void deleteGroup(WriteConfigFlags pFlags = Normal);
233 using KConfigBase::deleteGroup;
234
235 /**
236 * Reads the value of an entry specified by @p pKey in the current group
237 *
238 * This template method makes it possible to write
239 * QString foo = readEntry("...", QString("default"));
240 * and the same with all other types supported by QVariant.
241 *
242 * The return type of the method is simply the same as the type of the default value.
243 *
244 * @note readEntry("...", Qt::white) will not compile because Qt::white is an enum.
245 * You must turn it into readEntry("...", QColor(Qt::white)).
246 *
247 * @note Only the following QVariant types are allowed : String,
248 * StringList, List, Font, Point, Rect, Size, Color, Int, UInt, Bool,
249 * Double, LongLong, ULongLong, DateTime and Date.
250 *
251 * @param key The key to search for
252 * @param aDefault A default value returned if the key was not found
253 * @return The value for this key, or @p aDefault.
254 *
255 * @see writeEntry(), deleteEntry(), hasKey()
256 */
257 template<typename T>
readEntry(const QString & key,const T & aDefault)258 T readEntry(const QString &key, const T &aDefault) const
259 {
260 return readEntry(key.toUtf8().constData(), aDefault);
261 }
262 /**
263 * Overload for readEntry<T>(const QString&, const T&) const
264 * @param key name of key, encoded in UTF-8
265 */
266 template<typename T>
267 T readEntry(const char *key, const T &aDefault) const;
268
269 /**
270 * Reads the value of an entry specified by @p key in the current group
271 *
272 * @param key the key to search for
273 * @param aDefault a default value returned if the key was not found
274 * @return the value for this key, or @p aDefault if the key was not found
275 *
276 * @see writeEntry(), deleteEntry(), hasKey()
277 */
278 QVariant readEntry(const QString &key, const QVariant &aDefault) const;
279 /**
280 * Overload for readEntry(const QString&, const QVariant&) const
281 * @param key name of key, encoded in UTF-8
282 */
283 QVariant readEntry(const char *key, const QVariant &aDefault) const;
284
285 /**
286 * Reads the string value of an entry specified by @p key in the current group
287 *
288 * If you want to read a path, please use readPathEntry().
289 *
290 * @param key the key to search for
291 * @param aDefault a default value returned if the key was not found
292 * @return the value for this key, or @p aDefault if the key was not found
293 *
294 * @see readPathEntry(), writeEntry(), deleteEntry(), hasKey()
295 */
296 QString readEntry(const QString &key, const QString &aDefault) const;
297 /**
298 * Overload for readEntry(const QString&, const QString&) const
299 * @param key name of key, encoded in UTF-8
300 */
301 QString readEntry(const char *key, const QString &aDefault) const;
302
303 /** Overload for readEntry(const QString&, const QString&) const */
304 QString readEntry(const QString &key, const char *aDefault = nullptr) const;
305 /**
306 * Overload for readEntry(const QString&, const QString&) const
307 * @param key name of key, encoded in UTF-8
308 */
309 QString readEntry(const char *key, const char *aDefault = nullptr) const;
310
311 /**
312 * @copydoc readEntry(const char*, const QStringList&) const
313 *
314 * @warning This function doesn't convert the items returned
315 * to any type. It's actually a list of QVariant::String's. If you
316 * want the items converted to a specific type use
317 * readEntry(const char*, const QList<T>&) const
318 */
319 QVariantList readEntry(const QString &key, const QVariantList &aDefault) const;
320 /**
321 * Overload for readEntry(const QString&, const QVariantList&) const
322 * @param key name of key, encoded in UTF-8
323 */
324 QVariantList readEntry(const char *key, const QVariantList &aDefault) const;
325
326 /**
327 * Reads a list of strings from the config object
328 *
329 * @param key The key to search for
330 * @param aDefault The default value to use if the key does not exist
331 * @return The list, or @p aDefault if @p key does not exist
332 *
333 * @see readXdgListEntry(), writeEntry(), deleteEntry(), hasKey()
334 */
335 QStringList readEntry(const QString &key, const QStringList &aDefault) const;
336 /**
337 * Overload for readEntry(const QString&, const QStringList&) const
338 * @param key name of key, encoded in UTF-8
339 */
340 QStringList readEntry(const char *key, const QStringList &aDefault) const;
341
342 /**
343 * Reads a list of values from the config object
344 *
345 * @param key the key to search for
346 * @param aDefault the default value to use if the key does not exist
347 * @return the list, or @p aDefault if @p key does not exist
348 *
349 * @see readXdgListEntry(), writeEntry(), deleteEntry(), hasKey()
350 */
351 template<typename T>
readEntry(const QString & key,const QList<T> & aDefault)352 QList<T> readEntry(const QString &key, const QList<T> &aDefault) const
353 {
354 return readEntry(key.toUtf8().constData(), aDefault);
355 }
356 /**
357 * Overload for readEntry<T>(const QString&, const QList<T>&) const
358 * @param key name of key, encoded in UTF-8
359 */
360 template<typename T>
361 QList<T> readEntry(const char *key, const QList<T> &aDefault) const;
362
363 /**
364 * Reads a list of strings from the config object, following XDG
365 * desktop entry spec separator semantics
366 *
367 * @param pKey the key to search for
368 * @param aDefault the default value to use if the key does not exist
369 * @return the list, or @p aDefault if @p pKey does not exist
370 *
371 * @see readEntry(const QString&, const QStringList&) const
372 */
373 QStringList readXdgListEntry(const QString &pKey, const QStringList &aDefault = QStringList()) const;
374 /**
375 * Overload for readXdgListEntry(const QString&, const QStringList&) const
376 * @param key name of key, encoded in UTF-8
377 */
378 QStringList readXdgListEntry(const char *key, const QStringList &aDefault = QStringList()) const;
379
380 /**
381 * Reads a path
382 *
383 * Read the value of an entry specified by @p pKey in the current group
384 * and interpret it as a path. This means, dollar expansion is activated
385 * for this value, so that e.g. $HOME gets expanded.
386 *
387 * @param pKey The key to search for.
388 * @param aDefault A default value returned if the key was not found.
389 * @return The value for this key. Can be QString() if @p aDefault is null.
390 */
391 QString readPathEntry(const QString &pKey, const QString &aDefault) const;
392 /**
393 * Overload for readPathEntry(const QString&, const QString&) const
394 * @param key name of key, encoded in UTF-8
395 */
396 QString readPathEntry(const char *key, const QString &aDefault) const;
397
398 /**
399 * Reads a list of paths
400 *
401 * Read the value of an entry specified by @p pKey in the current group
402 * and interpret it as a list of paths. This means, dollar expansion is activated
403 * for this value, so that e.g. $HOME gets expanded.
404 *
405 * @param pKey the key to search for
406 * @param aDefault a default value returned if the key was not found
407 * @return the list, or @p aDefault if the key does not exist
408 */
409 QStringList readPathEntry(const QString &pKey, const QStringList &aDefault) const;
410 /**
411 * Overload for readPathEntry(const QString&, const QStringList&) const
412 * @param key name of key, encoded in UTF-8
413 */
414 QStringList readPathEntry(const char *key, const QStringList &aDefault) const;
415
416 /**
417 * Reads an untranslated string entry
418 *
419 * You should not normally need to use this.
420 *
421 * @param pKey the key to search for
422 * @param aDefault a default value returned if the key was not found
423 * @return the value for this key, or @p aDefault if the key does not exist
424 */
425 QString readEntryUntranslated(const QString &pKey, const QString &aDefault = QString()) const;
426 /**
427 * Overload for readEntryUntranslated(const QString&, const QString&) const
428 * @param key name of key, encoded in UTF-8
429 */
430 QString readEntryUntranslated(const char *key, const QString &aDefault = QString()) const;
431
432 /**
433 * Writes a value to the configuration object.
434 *
435 * @param key the key to write to
436 * @param value the value to write
437 * @param pFlags the flags to use when writing this entry
438 *
439 * @see readEntry(), writeXdgListEntry(), deleteEntry()
440 */
441 void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags = Normal);
442 /**
443 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
444 * @param key name of key, encoded in UTF-8
445 */
446 void writeEntry(const char *key, const QVariant &value, WriteConfigFlags pFlags = Normal);
447
448 /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
449 void writeEntry(const QString &key, const QString &value, WriteConfigFlags pFlags = Normal);
450 /**
451 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
452 * @param key name of key, encoded in UTF-8
453 */
454 void writeEntry(const char *key, const QString &value, WriteConfigFlags pFlags = Normal);
455
456 /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
457 void writeEntry(const QString &key, const QByteArray &value, WriteConfigFlags pFlags = Normal);
458 /**
459 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
460 * @param key name of key, encoded in UTF-8
461 */
462 void writeEntry(const char *key, const QByteArray &value, WriteConfigFlags pFlags = Normal);
463
464 /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
465 void writeEntry(const QString &key, const char *value, WriteConfigFlags pFlags = Normal);
466 /**
467 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
468 * @param key name of key, encoded in UTF-8
469 */
470 void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags = Normal);
471
472 /**
473 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
474 * @param key name of key, encoded in UTF-8
475 */
476 template<typename T>
477 void writeEntry(const char *key, const T &value, WriteConfigFlags pFlags = Normal);
478 /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
479 template<typename T>
480 void writeEntry(const QString &key, const T &value, WriteConfigFlags pFlags = Normal)
481 {
482 writeEntry(key.toUtf8().constData(), value, pFlags);
483 }
484
485 /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
486 void writeEntry(const QString &key, const QStringList &value, WriteConfigFlags pFlags = Normal);
487 /**
488 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
489 * @param key name of key, encoded in UTF-8
490 */
491 void writeEntry(const char *key, const QStringList &value, WriteConfigFlags pFlags = Normal);
492
493 /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
494 void writeEntry(const QString &key, const QVariantList &value, WriteConfigFlags pFlags = Normal);
495 /**
496 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
497 * @param key name of key, encoded in UTF-8
498 */
499 void writeEntry(const char *key, const QVariantList &value, WriteConfigFlags pFlags = Normal);
500
501 /** Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags) */
502 template<typename T>
503 void writeEntry(const QString &key, const QList<T> &value, WriteConfigFlags pFlags = Normal)
504 {
505 writeEntry(key.toUtf8().constData(), value, pFlags);
506 }
507 /**
508 * Overload for writeEntry(const QString&, const QVariant&, WriteConfigFlags)
509 * @param key name of key, encoded in UTF-8
510 */
511 template<typename T>
512 void writeEntry(const char *key, const QList<T> &value, WriteConfigFlags pFlags = Normal);
513
514 /**
515 * Writes a list of strings to the config object, following XDG
516 * desktop entry spec separator semantics
517 *
518 * @param pKey the key to write to
519 * @param value the list to write
520 * @param pFlags the flags to use when writing this entry
521 *
522 * @see writeEntry(), readXdgListEntry()
523 */
524 void writeXdgListEntry(const QString &pKey, const QStringList &value, WriteConfigFlags pFlags = Normal);
525 /**
526 * Overload for writeXdgListEntry(const QString&, const QStringList&, WriteConfigFlags)
527 * @param key name of key, encoded in UTF-8
528 */
529 void writeXdgListEntry(const char *key, const QStringList &value, WriteConfigFlags pFlags = Normal);
530
531 /**
532 * Writes a file path to the configuration
533 *
534 * If the path is located under $HOME, the user's home directory
535 * is replaced with $HOME in the persistent storage.
536 * The path should therefore be read back with readPathEntry()
537 *
538 * @param pKey the key to write to
539 * @param path the path to write
540 * @param pFlags the flags to use when writing this entry
541 *
542 * @see writeEntry(), readPathEntry()
543 */
544 void writePathEntry(const QString &pKey, const QString &path, WriteConfigFlags pFlags = Normal);
545 /**
546 * Overload for writePathEntry(const QString&, const QString&, WriteConfigFlags)
547 * @param key name of key, encoded in UTF-8
548 */
549 void writePathEntry(const char *Key, const QString &path, WriteConfigFlags pFlags = Normal);
550
551 /**
552 * Writes a list of paths to the configuration
553 *
554 * If any of the paths are located under $HOME, the user's home directory
555 * is replaced with $HOME in the persistent storage.
556 * The paths should therefore be read back with readPathEntry()
557 *
558 * @param pKey the key to write to
559 * @param value the list to write
560 * @param pFlags the flags to use when writing this entry
561 *
562 * @see writeEntry(), readPathEntry()
563 */
564 void writePathEntry(const QString &pKey, const QStringList &value, WriteConfigFlags pFlags = Normal);
565 /**
566 * Overload for writePathEntry(const QString&, const QStringList&, WriteConfigFlags)
567 * @param key name of key, encoded in UTF-8
568 */
569 void writePathEntry(const char *key, const QStringList &value, WriteConfigFlags pFlags = Normal);
570
571 /**
572 * Deletes the entry specified by @p pKey in the current group
573 *
574 * This also hides system wide defaults.
575 *
576 * @param pKey the key to delete
577 * @param pFlags the flags to use when deleting this entry
578 *
579 * @see deleteGroup(), readEntry(), writeEntry()
580 */
581 void deleteEntry(const QString &pKey, WriteConfigFlags pFlags = Normal);
582 /**
583 * Overload for deleteEntry(const QString&, WriteConfigFlags)
584 * @param key name of key, encoded in UTF-8
585 */
586 void deleteEntry(const char *key, WriteConfigFlags pFlags = Normal);
587
588 /**
589 * Checks whether the key has an entry in this group
590 *
591 * Use this to determine if a key is not specified for the current
592 * group (hasKey() returns false).
593 *
594 * If this returns @c false for a key, readEntry() (and its variants)
595 * will return the default value passed to them.
596 *
597 * @param key the key to search for
598 * @return @c true if the key is defined in this group by any of the
599 * configuration sources, @c false otherwise
600 *
601 * @see readEntry()
602 */
603 bool hasKey(const QString &key) const;
604 /**
605 * Overload for hasKey(const QString&) const
606 * @param key name of key, encoded in UTF-8
607 */
608 bool hasKey(const char *key) const;
609
610 /**
611 * Whether this group may be changed
612 *
613 * @return @c false if the group may be changed, @c true otherwise
614 */
615 bool isImmutable() const override;
616
617 /**
618 * Checks if it is possible to change the given entry
619 *
620 * If isImmutable() returns @c true, then this method will return
621 * @c true for all inputs.
622 *
623 * @param key the key to check
624 * @return @c false if the key may be changed using this configuration
625 * group object, @c true otherwise
626 */
627 bool isEntryImmutable(const QString &key) const;
628 /**
629 * Overload for isEntryImmutable(const QString&) const
630 * @param key name of key, encoded in UTF-8
631 */
632 bool isEntryImmutable(const char *key) const;
633
634 /**
635 * Reverts an entry to the default settings.
636 *
637 * Reverts the entry with key @p key in the current group in the
638 * application specific config file to either the system wide (default)
639 * value or the value specified in the global KDE config file.
640 *
641 * To revert entries in the global KDE config file, the global KDE config
642 * file should be opened explicitly in a separate config object.
643 *
644 * @note This is @em not the same as deleting the key, as instead the
645 * global setting will be copied to the configuration file that this
646 * object manipulates.
647 *
648 * @param key The key of the entry to revert.
649 */
650 // TODO KF6 merge with the other one
651 void revertToDefault(const QString &key);
652 void revertToDefault(const QString &key, WriteConfigFlags pFlag);
653
654 // TODO KF6 merge with the other one
655 /**
656 * Overload for revertToDefault(const QString&)
657 * @param key name of key, encoded in UTF-8
658 */
659 void revertToDefault(const char *key);
660 /**
661 * Overload for revertToDefault(const QString&, WriteConfigFlags)
662 * @param key name of key, encoded in UTF-8
663 */
664 void revertToDefault(const char *key, WriteConfigFlags pFlag);
665
666 /**
667 * Whether a default is specified for an entry in either the
668 * system wide configuration file or the global KDE config file
669 *
670 * If an application computes a default value at runtime for
671 * a certain entry, e.g. like:
672 * \code
673 * QColor computedDefault = qApp->palette().color(QPalette::Active, QPalette::Text);
674 * QColor color = group.readEntry(key, computedDefault);
675 * \endcode
676 * then it may wish to make the following check before
677 * writing back changes:
678 * \code
679 * if ( (value == computedDefault) && !group.hasDefault(key) )
680 * group.revertToDefault(key);
681 * else
682 * group.writeEntry(key, value);
683 * \endcode
684 *
685 * This ensures that as long as the entry is not modified to differ from
686 * the computed default, the application will keep using the computed default
687 * and will follow changes the computed default makes over time.
688 *
689 * @param key the key of the entry to check
690 * @return @c true if the global or system settings files specify a default
691 * for @p key in this group, @c false otherwise
692 */
693 bool hasDefault(const QString &key) const;
694 /**
695 * Overload for hasDefault(const QString&) const
696 * @param key name of key, encoded in UTF-8
697 */
698 bool hasDefault(const char *key) const;
699
700 /**
701 * Returns a map (tree) of entries for all entries in this group
702 *
703 * Only the actual entry string is returned, none of the
704 * other internal data should be included.
705 *
706 * @return a map of entries in this group, indexed by key
707 */
708 QMap<QString, QString> entryMap() const;
709
710 protected:
711 bool hasGroupImpl(const QByteArray &group) const override;
712 KConfigGroup groupImpl(const QByteArray &b) override;
713 const KConfigGroup groupImpl(const QByteArray &b) const override;
714 void deleteGroupImpl(const QByteArray &group, WriteConfigFlags flags) override;
715 bool isGroupImmutableImpl(const QByteArray &aGroup) const override;
716
717 private:
718 QExplicitlySharedDataPointer<KConfigGroupPrivate> d;
719
720 friend class KConfigGroupPrivate;
721
722 /**
723 * Return the data in @p value converted to a QVariant
724 *
725 * @param pKey the name of the entry being converted, this is only used for error
726 * reporting
727 * @param value the UTF-8 data to be converted
728 * @param aDefault the default value if @p pKey is not found
729 * @return @p value converted to QVariant, or @p aDefault if @p value is invalid or cannot be converted.
730 */
731 static QVariant convertToQVariant(const char *pKey, const QByteArray &value, const QVariant &aDefault);
732 friend class KServicePrivate; // XXX yeah, ugly^5
733 };
734
735 #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."
736
737 /**
738 * To add support for your own enums in KConfig, you can declare them with Q_ENUM()
739 * in a QObject subclass (which will make moc generate the code to turn the
740 * enum into a string and vice-versa), and then (in the cpp code)
741 * use the macro
742 * <code>KCONFIGGROUP_DECLARE_ENUM_QOBJECT(MyClass, MyEnum)</code>
743 *
744 */
745 #define KCONFIGGROUP_DECLARE_ENUM_QOBJECT(Class, Enum) \
746 template<> \
747 Class::Enum KConfigGroup::readEntry(const char *key, const Class::Enum &def) const \
748 { \
749 const QMetaObject *M_obj = &Class::staticMetaObject; \
750 const int M_index = M_obj->indexOfEnumerator(#Enum); \
751 if (M_index == -1) \
752 qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Enum)); \
753 const QMetaEnum M_enum = M_obj->enumerator(M_index); \
754 const QByteArray M_data = readEntry(key, QByteArray(M_enum.valueToKey(def))); \
755 return static_cast<Class::Enum>(M_enum.keyToValue(M_data.constData())); \
756 } \
757 inline Class::Enum Q_DECL_DEPRECATED readEntry(const KConfigGroup &group, const char *key, const Class::Enum &def) \
758 { \
759 return group.readEntry(key, def); \
760 } \
761 template<> \
762 void KConfigGroup::writeEntry(const char *key, const Class::Enum &value, KConfigBase::WriteConfigFlags flags) \
763 { \
764 const QMetaObject *M_obj = &Class::staticMetaObject; \
765 const int M_index = M_obj->indexOfEnumerator(#Enum); \
766 if (M_index == -1) \
767 qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Enum)); \
768 const QMetaEnum M_enum = M_obj->enumerator(M_index); \
769 writeEntry(key, QByteArray(M_enum.valueToKey(value)), flags); \
770 } \
771 inline void Q_DECL_DEPRECATED writeEntry(KConfigGroup &group, \
772 const char *key, \
773 const Class::Enum &value, \
774 KConfigBase::WriteConfigFlags flags = KConfigBase::Normal) \
775 { \
776 group.writeEntry(key, value, flags); \
777 }
778
779 /**
780 * Similar to KCONFIGGROUP_DECLARE_ENUM_QOBJECT but for flags declared with Q_FLAG()
781 * (where multiple values can be set at the same time)
782 */
783 #define KCONFIGGROUP_DECLARE_FLAGS_QOBJECT(Class, Flags) \
784 template<> \
785 Class::Flags KConfigGroup::readEntry(const char *key, const Class::Flags &def) const \
786 { \
787 const QMetaObject *M_obj = &Class::staticMetaObject; \
788 const int M_index = M_obj->indexOfEnumerator(#Flags); \
789 if (M_index == -1) \
790 qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Flags)); \
791 const QMetaEnum M_enum = M_obj->enumerator(M_index); \
792 const QByteArray M_data = readEntry(key, QByteArray(M_enum.valueToKeys(def))); \
793 return static_cast<Class::Flags>(M_enum.keysToValue(M_data.constData())); \
794 } \
795 inline Class::Flags Q_DECL_DEPRECATED readEntry(const KConfigGroup &group, const char *key, const Class::Flags &def) \
796 { \
797 return group.readEntry(key, def); \
798 } \
799 template<> \
800 void KConfigGroup::writeEntry(const char *key, const Class::Flags &value, KConfigBase::WriteConfigFlags flags) \
801 { \
802 const QMetaObject *M_obj = &Class::staticMetaObject; \
803 const int M_index = M_obj->indexOfEnumerator(#Flags); \
804 if (M_index == -1) \
805 qFatal(KCONFIGGROUP_ENUMERATOR_ERROR(#Flags)); \
806 const QMetaEnum M_enum = M_obj->enumerator(M_index); \
807 writeEntry(key, QByteArray(M_enum.valueToKeys(value)), flags); \
808 } \
809 inline void Q_DECL_DEPRECATED writeEntry(KConfigGroup &group, \
810 const char *key, \
811 const Class::Flags &value, \
812 KConfigBase::WriteConfigFlags flags = KConfigBase::Normal) \
813 { \
814 group.writeEntry(key, value, flags); \
815 }
816
817 #include "conversioncheck.h"
818
819 template<typename T>
readEntry(const char * key,const T & defaultValue)820 T KConfigGroup::readEntry(const char *key, const T &defaultValue) const
821 {
822 ConversionCheck::to_QVariant<T>();
823 return qvariant_cast<T>(readEntry(key, QVariant::fromValue(defaultValue)));
824 }
825
826 template<typename T>
readEntry(const char * key,const QList<T> & defaultValue)827 QList<T> KConfigGroup::readEntry(const char *key, const QList<T> &defaultValue) const
828 {
829 ConversionCheck::to_QVariant<T>();
830 ConversionCheck::to_QString<T>();
831
832 QVariantList data;
833
834 for (const T &value : defaultValue) {
835 data.append(QVariant::fromValue(value));
836 }
837
838 QList<T> list;
839 const auto variantList = readEntry<QVariantList>(key, data);
840 for (const QVariant &value : variantList) {
841 Q_ASSERT(value.canConvert<T>());
842 list.append(qvariant_cast<T>(value));
843 }
844
845 return list;
846 }
847
848 template<typename T>
writeEntry(const char * key,const T & value,WriteConfigFlags pFlags)849 void KConfigGroup::writeEntry(const char *key, const T &value, WriteConfigFlags pFlags)
850 {
851 ConversionCheck::to_QVariant<T>();
852 writeEntry(key, QVariant::fromValue(value), pFlags);
853 }
854
855 template<typename T>
writeEntry(const char * key,const QList<T> & list,WriteConfigFlags pFlags)856 void KConfigGroup::writeEntry(const char *key, const QList<T> &list, WriteConfigFlags pFlags)
857 {
858 ConversionCheck::to_QVariant<T>();
859 ConversionCheck::to_QString<T>();
860 QVariantList data;
861 for (const T &value : list) {
862 data.append(QVariant::fromValue(value));
863 }
864
865 writeEntry(key, data, pFlags);
866 }
867
868 #endif // KCONFIGGROUP_H
869