KConfig

kconfiggroup.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2006, 2007 Thomas Braxton <[email protected]>
4  SPDX-FileCopyrightText: 1999 Preston Brown <[email protected]>
5  SPDX-FileCopyrightText: 1997 Matthias Kalle Dalheimer <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "kconfiggroup.h"
11 #include "kconfiggroup_p.h"
12 
13 #include "kconfig.h"
14 #include "kconfig_p.h"
15 #include "kconfig_core_log_settings.h"
16 #include "ksharedconfig.h"
17 #include "kconfigdata.h"
18 
19 #include <QDate>
20 #include <QSharedData>
21 #include <QFile>
22 #include <QPoint>
23 #include <QRect>
24 #include <QString>
25 #include <QTextStream>
26 #include <QDir>
27 #include <QUrl>
28 
29 #include <stdlib.h>
30 
31 class KConfigGroupPrivate : public QSharedData
32 {
33 public:
34  KConfigGroupPrivate(KConfig *owner, bool isImmutable, bool isConst, const QByteArray &name)
35  : mOwner(owner), mName(name), bImmutable(isImmutable), bConst(isConst)
36  {
37  }
38 
39  KConfigGroupPrivate(const KSharedConfigPtr &owner, const QByteArray &name)
40  : sOwner(owner), mOwner(sOwner.data()), mName(name),
41  bImmutable(name.isEmpty() ? owner->isImmutable() : owner->isGroupImmutable(name)), bConst(false)
42  {
43  }
44 
45  KConfigGroupPrivate(KConfigGroup *parent, bool isImmutable, bool isConst, const QByteArray &name)
46  : sOwner(parent->d->sOwner), mOwner(parent->d->mOwner), mName(name),
47  bImmutable(isImmutable), bConst(isConst)
48  {
49  if (!parent->d->mName.isEmpty()) {
50  mParent = parent->d;
51  }
52  }
53 
54  KConfigGroupPrivate(const KConfigGroupPrivate *other, bool isImmutable, const QByteArray &name)
55  : sOwner(other->sOwner), mOwner(other->mOwner), mName(name),
56  bImmutable(isImmutable), bConst(other->bConst)
57  {
58  if (!other->mName.isEmpty()) {
59  mParent = const_cast<KConfigGroupPrivate *>(other);
60  }
61  }
62 
63  KSharedConfig::Ptr sOwner;
64  KConfig *mOwner;
66  QByteArray mName;
67 
68  /* bitfield */
69  const bool bImmutable: 1; // is this group immutable?
70  const bool bConst: 1; // is this group read-only?
71 
72  QByteArray fullName() const
73  {
74  if (!mParent) {
75  return name();
76  }
77  return mParent->fullName(mName);
78  }
79 
80  QByteArray name() const
81  {
82  if (mName.isEmpty()) {
83  return QByteArrayLiteral("<default>");
84  }
85  return mName;
86  }
87 
88  QByteArray fullName(const QByteArray &aGroup) const
89  {
90  if (mName.isEmpty()) {
91  return aGroup;
92  }
93  return fullName() + '\x1d' + aGroup;
94  }
95 
97  const QByteArray &name,
98  bool isImmutable,
99  bool isConst)
100  {
102  if (dynamic_cast<KConfigGroup *>(master)) {
103  data = new KConfigGroupPrivate(static_cast<KConfigGroup *>(master), isImmutable, isConst, name);
104  } else {
105  data = new KConfigGroupPrivate(dynamic_cast<KConfig *>(master), isImmutable, isConst, name);
106  }
107  return data;
108  }
109 
110  static QByteArray serializeList(const QList<QByteArray> &list);
111  static QStringList deserializeList(const QString &data);
112 };
113 
114 QByteArray KConfigGroupPrivate::serializeList(const QList<QByteArray> &list)
115 {
116  QByteArray value;
117 
118  if (!list.isEmpty()) {
121 
122  value = QByteArray(*it).replace('\\', QByteArrayLiteral("\\\\")).replace(',', QByteArrayLiteral("\\,"));
123 
124  while (++it != end) {
125  // In the loop, so it is not done when there is only one element.
126  // Doing it repeatedly is a pretty cheap operation.
127  value.reserve(4096);
128 
129  value += ',';
130  value += QByteArray(*it).replace('\\', QByteArrayLiteral("\\\\")).replace(',', QByteArrayLiteral("\\,"));
131  }
132 
133  // To be able to distinguish an empty list from a list with one empty element.
134  if (value.isEmpty()) {
135  value = QByteArrayLiteral("\\0");
136  }
137  }
138 
139  return value;
140 }
141 
142 QStringList KConfigGroupPrivate::deserializeList(const QString &data)
143 {
144  if (data.isEmpty()) {
145  return QStringList();
146  }
147  if (data == QLatin1String("\\0")) {
148  return QStringList(QString());
149  }
150  QStringList value;
151  QString val;
152  val.reserve(data.size());
153  bool quoted = false;
154  for (int p = 0; p < data.length(); p++) {
155  if (quoted) {
156  val += data[p];
157  quoted = false;
158  } else if (data[p].unicode() == '\\') {
159  quoted = true;
160  } else if (data[p].unicode() == ',') {
161  val.squeeze(); // release any unused memory
162  value.append(val);
163  val.clear();
164  val.reserve(data.size() - p);
165  } else {
166  val += data[p];
167  }
168  }
169  value.append(val);
170  return value;
171 }
172 
173 static QVector<int> asIntList(const QByteArray &string)
174 {
175  const auto &splitString = string.split(',');
176 
177  QVector<int> list;
178  list.reserve(splitString.count());
179  for (const QByteArray &s : splitString) {
180  list << s.toInt();
181  }
182  return list;
183 }
184 
185 static QVector<qreal> asRealList(const QByteArray &string)
186 {
187  const auto &splitString = string.split(',');
188 
189  QVector<qreal> list;
190  list.reserve(splitString.count());
191  for (const QByteArray &s : splitString) {
192  list << s.toDouble();
193  }
194  return list;
195 }
196 
197 static QString errString(const char *pKey, const QByteArray &value, const QVariant &aDefault)
198 {
199  return QStringLiteral("\"%1\" - conversion of \"%3\" to %2 failed")
200  .arg( QString::fromLatin1(pKey),
202  QString::fromLatin1(value) );
203 }
204 
205 static QString formatError(int expected, int got)
206 {
207  return QStringLiteral(" (wrong format: expected %1 items, got %2)").arg(expected).arg(got);
208 }
209 
210 QVariant KConfigGroup::convertToQVariant(const char *pKey, const QByteArray &value, const QVariant &aDefault)
211 {
212  // if a type handler is added here you must add a QVConversions definition
213  // to conversioncheck.h, or ConversionCheck::to_QVariant will not allow
214  // readEntry<T> to convert to QVariant.
215  switch (static_cast<QMetaType::Type>(aDefault.type())) {
217  return QVariant();
218  case QMetaType::QString:
219  // this should return the raw string not the dollar expanded string.
220  // imho if processed string is wanted should call
221  // readEntry(key, QString) not readEntry(key, QVariant)
222  return QString::fromUtf8(value);
225  return KConfigGroupPrivate::deserializeList(QString::fromUtf8(value));
227  return value;
228  case QMetaType::Bool: {
229  const QByteArray lower(value.toLower());
230  if (lower == "false" || lower == "no" || lower == "off" || lower == "0") {
231  return false;
232  }
233  return true;
234  }
235  case QMetaType::Double:
236  case QMetaType::Float:
237  case QMetaType::Int:
238  case QMetaType::UInt:
239  case QMetaType::LongLong:
240  case QMetaType::ULongLong: {
241  QVariant tmp = value;
242  if (!tmp.convert(aDefault.type())) {
243  tmp = aDefault;
244  }
245  return tmp;
246  }
247  case QMetaType::QPoint: {
248  const auto list = asIntList(value);
249 
250  if (list.count() != 2) {
251  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
252  << formatError(2, list.count());
253  return aDefault;
254  }
255  return QPoint(list.at(0), list.at(1));
256  }
257  case QMetaType::QPointF: {
258  const auto list = asRealList(value);
259 
260  if (list.count() != 2) {
261  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
262  << formatError(2, list.count());
263  return aDefault;
264  }
265  return QPointF(list.at(0), list.at(1));
266  }
267  case QMetaType::QRect: {
268  const auto list = asIntList(value);
269 
270  if (list.count() != 4) {
271  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
272  << formatError(4, list.count());
273  return aDefault;
274  }
275  const QRect rect(list.at(0), list.at(1), list.at(2), list.at(3));
276  if (!rect.isValid()) {
277  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault);
278  return aDefault;
279  }
280  return rect;
281  }
282  case QMetaType::QRectF: {
283  const auto list = asRealList(value);
284 
285  if (list.count() != 4) {
286  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
287  << formatError(4, list.count());
288  return aDefault;
289  }
290  const QRectF rect(list.at(0), list.at(1), list.at(2), list.at(3));
291  if (!rect.isValid()) {
292  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault);
293  return aDefault;
294  }
295  return rect;
296  }
297  case QMetaType::QSize: {
298  const auto list = asIntList(value);
299 
300  if (list.count() != 2) {
301  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
302  << formatError(2, list.count());
303  return aDefault;
304  }
305  const QSize size(list.at(0), list.at(1));
306  if (!size.isValid()) {
307  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault);
308  return aDefault;
309  }
310  return size;
311  }
312  case QMetaType::QSizeF: {
313  const auto list = asRealList(value);
314 
315  if (list.count() != 2) {
316  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
317  << formatError(2, list.count());
318  return aDefault;
319  }
320  const QSizeF size(list.at(0), list.at(1));
321  if (!size.isValid()) {
322  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault);
323  return aDefault;
324  }
325  return size;
326  }
327  case QMetaType::QDateTime: {
328  const auto list = asIntList(value);
329  if (list.count() != 6) {
330  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
331  << formatError(6, list.count());
332  return aDefault;
333  }
334  const QDate date(list.at(0), list.at(1), list.at(2));
335  const QTime time(list.at(3), list.at(4), list.at(5));
336  const QDateTime dt(date, time);
337  if (!dt.isValid()) {
338  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault);
339  return aDefault;
340  }
341  return dt;
342  }
343  case QMetaType::QDate: {
344  auto list = asIntList(value);
345  if (list.count() == 6) {
346  list = list.mid(0, 3); // don't break config files that stored QDate as QDateTime
347  }
348  if (list.count() != 3) {
349  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault)
350  << formatError(3, list.count());
351  return aDefault;
352  }
353  const QDate date(list.at(0), list.at(1), list.at(2));
354  if (!date.isValid()) {
355  qCWarning(KCONFIG_CORE_LOG) << errString(pKey, value, aDefault);
356  return aDefault;
357  }
358  return date;
359  }
360  case QMetaType::QColor:
361  case QMetaType::QFont:
362  qCWarning(KCONFIG_CORE_LOG) << "KConfigGroup::readEntry was passed GUI type '"
363  << aDefault.typeName()
364  << "' but KConfigGui isn't linked! If it is linked to your program, "
365  "this is a platform bug. Please inform the KDE developers";
366  break;
367  case QMetaType::QUrl:
368  return QUrl(QString::fromUtf8(value));
369 
370  default:
371  break;
372  }
373 
374  qCWarning(KCONFIG_CORE_LOG) << "unhandled type " << aDefault.typeName();
375  return QVariant();
376 }
377 
378 #ifdef Q_OS_WIN
379 # include <QDir>
380 #endif
381 
382 static bool cleanHomeDirPath(QString &path, const QString &homeDir)
383 {
384 #ifdef Q_OS_WIN //safer
385  if (!QDir::toNativeSeparators(path).startsWith(QDir::toNativeSeparators(homeDir))) {
386  return false;
387  }
388 #else
389  if (!path.startsWith(homeDir)) {
390  return false;
391  }
392 #endif
393 
394  int len = homeDir.length();
395  // replace by "$HOME" if possible
396  if (len && (path.length() == len || path[len] == QLatin1Char('/'))) {
397  path.replace(0, len, QStringLiteral("$HOME"));
398  return true;
399  }
400 
401  return false;
402 }
403 
404 static QString translatePath(QString path) // krazy:exclude=passbyvalue
405 {
406  if (path.isEmpty()) {
407  return path;
408  }
409 
410  // only "our" $HOME should be interpreted
411  path.replace(QLatin1Char('$'), QLatin1String("$$"));
412 
413  const bool startsWithFile = path.startsWith(QLatin1String("file:"), Qt::CaseInsensitive);
414  path = startsWithFile ? QUrl(path).toLocalFile() : path;
415 
416  if (QDir::isRelativePath(path)) {
417  return path;
418  }
419 
420  // we can not use KGlobal::dirs()->relativeLocation("home", path) here,
421  // since it would not recognize paths without a trailing '/'.
422  // All of the 3 following functions to return the user's home directory
423  // can return different paths. We have to test all them.
424  const QString homeDir0 = QFile::decodeName(qgetenv("HOME"));
425  const QString homeDir1 = QDir::homePath();
426  const QString homeDir2 = QDir(homeDir1).canonicalPath();
427  if (cleanHomeDirPath(path, homeDir0) ||
428  cleanHomeDirPath(path, homeDir1) ||
429  cleanHomeDirPath(path, homeDir2)) {
430  // qDebug() << "Path was replaced\n";
431  }
432 
433  if (startsWithFile) {
434  path = QUrl::fromLocalFile(path).toString();
435  }
436 
437  return path;
438 }
439 
441 {
442 }
443 
445 {
446  return bool(d);
447 }
448 
449 KConfigGroupGui _kde_internal_KConfigGroupGui;
450 static inline bool readEntryGui(const QByteArray &data, const char *key, const QVariant &input,
451  QVariant &output)
452 {
453  if (_kde_internal_KConfigGroupGui.readEntryGui) {
454  return _kde_internal_KConfigGroupGui.readEntryGui(data, key, input, output);
455  }
456  return false;
457 }
458 
459 static inline bool writeEntryGui(KConfigGroup *cg, const char *key, const QVariant &input,
461 {
462  if (_kde_internal_KConfigGroupGui.writeEntryGui) {
463  return _kde_internal_KConfigGroupGui.writeEntryGui(cg, key, input, flags);
464  }
465  return false;
466 }
467 
469  : d(KConfigGroupPrivate::create(master, _group.toUtf8(), master->isGroupImmutable(_group), false))
470 {
471 }
472 
473 KConfigGroup::KConfigGroup(KConfigBase *master, const char *_group)
474  : d(KConfigGroupPrivate::create(master, _group, master->isGroupImmutable(_group), false))
475 {
476 }
477 
478 KConfigGroup::KConfigGroup(const KConfigBase *master, const QString &_group)
479  : d(KConfigGroupPrivate::create(const_cast<KConfigBase *>(master), _group.toUtf8(), master->isGroupImmutable(_group), true))
480 {
481 }
482 
483 KConfigGroup::KConfigGroup(const KConfigBase *master, const char *_group)
484  : d(KConfigGroupPrivate::create(const_cast<KConfigBase *>(master), _group, master->isGroupImmutable(_group), true))
485 {
486 }
487 
489  : d(new KConfigGroupPrivate(master, _group.toUtf8()))
490 {
491 }
492 
493 KConfigGroup::KConfigGroup(const KSharedConfigPtr &master, const char *_group)
494  : d(new KConfigGroupPrivate(master, _group))
495 {
496 }
497 
498 KConfigGroup &KConfigGroup::operator=(const KConfigGroup &rhs)
499 {
500  d = rhs.d;
501  return *this;
502 }
503 
505  : d(rhs.d)
506 {
507 }
508 
509 KConfigGroup::~KConfigGroup()
510 {
511  d.reset();
512 }
513 
515 {
516  Q_ASSERT_X(isValid(), "KConfigGroup::groupImpl", "accessing an invalid group");
517  Q_ASSERT_X(!aGroup.isEmpty(), "KConfigGroup::groupImpl", "can not have an unnamed child group");
518 
519  KConfigGroup newGroup;
520 
521  newGroup.d = new KConfigGroupPrivate(this, isGroupImmutableImpl(aGroup), d->bConst, aGroup);
522 
523  return newGroup;
524 }
525 
527 {
528  Q_ASSERT_X(isValid(), "KConfigGroup::groupImpl", "accessing an invalid group");
529  Q_ASSERT_X(!aGroup.isEmpty(), "KConfigGroup::groupImpl", "can not have an unnamed child group");
530 
531  KConfigGroup newGroup;
532 
533  newGroup.d = new KConfigGroupPrivate(const_cast<KConfigGroup *>(this), isGroupImmutableImpl(aGroup),
534  true, aGroup);
535 
536  return newGroup;
537 }
538 
540 {
541  Q_ASSERT_X(isValid(), "KConfigGroup::parent", "accessing an invalid group");
542 
543  KConfigGroup parentGroup;
544 
545  if (d->mParent) {
546  parentGroup.d = d->mParent;
547  } else {
548  parentGroup.d = new KConfigGroupPrivate(d->mOwner, d->mOwner->isImmutable(), d->bConst, "");
549  // make sure we keep the refcount up on the KConfig object
550  parentGroup.d->sOwner = d->sOwner;
551  }
552 
553  return parentGroup;
554 }
555 
557 {
558  Q_ASSERT_X(isValid(), "KConfigGroup::deleteGroup", "accessing an invalid group");
559  Q_ASSERT_X(!d->bConst, "KConfigGroup::deleteGroup", "deleting a read-only group");
560 
561  config()->deleteGroup(d->fullName(), flags);
562 }
563 
564 #if KCONFIGCORE_BUILD_DEPRECATED_SINCE(5, 0)
566 {
567  Q_ASSERT_X(isValid(), "KConfigGroup::changeGroup", "accessing an invalid group");
568  d.detach();
569  d->mName = group.toUtf8();
570 }
571 #endif
572 
573 #if KCONFIGCORE_BUILD_DEPRECATED_SINCE(5, 0)
575 {
576  Q_ASSERT_X(isValid(), "KConfigGroup::changeGroup", "accessing an invalid group");
577  d.detach();
578  d->mName = group;
579 }
580 #endif
581 
583 {
584  Q_ASSERT_X(isValid(), "KConfigGroup::name", "accessing an invalid group");
585 
586  return QString::fromUtf8(d->name());
587 }
588 
590 {
591  Q_ASSERT_X(isValid(), "KConfigGroup::exists", "accessing an invalid group");
592 
593  return config()->hasGroup(d->fullName());
594 }
595 
597 {
598  Q_ASSERT_X(isValid(), "KConfigGroup::sync", "accessing an invalid group");
599 
600  if (!d->bConst) {
601  return config()->sync();
602  }
603 
604  return false;
605 }
606 
608 {
609  Q_ASSERT_X(isValid(), "KConfigGroup::entryMap", "accessing an invalid group");
610 
611  return config()->entryMap(QString::fromUtf8(d->fullName()));
612 }
613 
615 {
616  Q_ASSERT_X(isValid(), "KConfigGroup::config", "accessing an invalid group");
617 
618  return d->mOwner;
619 }
620 
622 {
623  Q_ASSERT_X(isValid(), "KConfigGroup::config", "accessing an invalid group");
624 
625  return d->mOwner;
626 }
627 
628 bool KConfigGroup::isEntryImmutable(const char *key) const
629 {
630  Q_ASSERT_X(isValid(), "KConfigGroup::isEntryImmutable", "accessing an invalid group");
631 
632  return (isImmutable() ||
633  !config()->d_func()->canWriteEntry(d->fullName(), key, config()->readDefaults()));
634 }
635 
637 {
638  return isEntryImmutable(key.toUtf8().constData());
639 }
640 
641 QString KConfigGroup::readEntryUntranslated(const QString &pKey, const QString &aDefault) const
642 {
643  return readEntryUntranslated(pKey.toUtf8().constData(), aDefault);
644 }
645 
646 QString KConfigGroup::readEntryUntranslated(const char *key, const QString &aDefault) const
647 {
648  Q_ASSERT_X(isValid(), "KConfigGroup::readEntryUntranslated", "accessing an invalid group");
649 
650  QString result = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchFlags(), nullptr);
651  if (result.isNull()) {
652  return aDefault;
653  }
654  return result;
655 }
656 
657 QString KConfigGroup::readEntry(const char *key, const char *aDefault) const
658 {
659  return readEntry(key, QString::fromUtf8(aDefault));
660 }
661 
662 QString KConfigGroup::readEntry(const QString &key, const char *aDefault) const
663 {
664  return readEntry(key.toUtf8().constData(), aDefault);
665 }
666 
667 QString KConfigGroup::readEntry(const char *key, const QString &aDefault) const
668 {
669  Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group");
670 
671  bool expand = false;
672 
673  // read value from the entry map
674  QString aValue = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchLocalized,
675  &expand);
676  if (aValue.isNull()) {
677  aValue = aDefault;
678  }
679 
680  if (expand) {
681  return KConfigPrivate::expandString(aValue);
682  }
683 
684  return aValue;
685 }
686 
687 QString KConfigGroup::readEntry(const QString &key, const QString &aDefault) const
688 {
689  return readEntry(key.toUtf8().constData(), aDefault);
690 }
691 
692 QStringList KConfigGroup::readEntry(const char *key, const QStringList &aDefault) const
693 {
694  Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group");
695 
696  const QString data = readEntry(key, QString());
697  if (data.isNull()) {
698  return aDefault;
699  }
700 
701  return KConfigGroupPrivate::deserializeList(data);
702 }
703 
704 QStringList KConfigGroup::readEntry(const QString &key, const QStringList &aDefault) const
705 {
706  return readEntry(key.toUtf8().constData(), aDefault);
707 }
708 
709 QVariant KConfigGroup::readEntry(const char *key, const QVariant &aDefault) const
710 {
711  Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group");
712 
713  const QByteArray data = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchLocalized);
714  if (data.isNull()) {
715  return aDefault;
716  }
717 
718  QVariant value;
719  if (!readEntryGui(data, key, aDefault, value)) {
720  return convertToQVariant(key, data, aDefault);
721  }
722 
723  return value;
724 }
725 
726 QVariant KConfigGroup::readEntry(const QString &key, const QVariant &aDefault) const
727 {
728  return readEntry(key.toUtf8().constData(), aDefault);
729 }
730 
731 QVariantList KConfigGroup::readEntry(const char *key, const QVariantList &aDefault) const
732 {
733  Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group");
734 
735  const QString data = readEntry(key, QString());
736  if (data.isNull()) {
737  return aDefault;
738  }
739 
740  const auto &list = KConfigGroupPrivate::deserializeList(data);
741 
742  QVariantList value;
743  value.reserve(list.count());
744  for (const QString &v : list) {
745  value << v;
746  }
747 
748  return value;
749 }
750 
751 QVariantList KConfigGroup::readEntry(const QString &key, const QVariantList &aDefault) const
752 {
753  return readEntry(key.toUtf8().constData(), aDefault);
754 }
755 
757 {
758  return readXdgListEntry(key.toUtf8().constData(), aDefault);
759 }
760 
761 QStringList KConfigGroup::readXdgListEntry(const char *key, const QStringList &aDefault) const
762 {
763  Q_ASSERT_X(isValid(), "KConfigGroup::readXdgListEntry", "accessing an invalid group");
764 
765  const QString data = readEntry(key, QString());
766  if (data.isNull()) {
767  return aDefault;
768  }
769 
770  QStringList value;
771  QString val;
772  val.reserve(data.size());
773  // XXX List serialization being a separate layer from low-level parsing is
774  // probably a bug. No affected entries are defined, though.
775  bool quoted = false;
776  for (int p = 0; p < data.length(); p++) {
777  if (quoted) {
778  val += data[p];
779  quoted = false;
780  } else if (data[p] == QLatin1Char('\\')) {
781  quoted = true;
782  } else if (data[p] == QLatin1Char(';')) {
783  value.append(val);
784  val.clear();
785  val.reserve(data.size() - p);
786  } else {
787  val += data[p];
788  }
789  }
790  if (!val.isEmpty()) {
791  value.append(val);
792  }
793  return value;
794 }
795 
796 QString KConfigGroup::readPathEntry(const QString &pKey, const QString &aDefault) const
797 {
798  return readPathEntry(pKey.toUtf8().constData(), aDefault);
799 }
800 
801 QString KConfigGroup::readPathEntry(const char *key, const QString &aDefault) const
802 {
803  Q_ASSERT_X(isValid(), "KConfigGroup::readPathEntry", "accessing an invalid group");
804 
805  bool expand = false;
806 
807  QString aValue = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchLocalized,
808  &expand);
809  if (aValue.isNull()) {
810  aValue = aDefault;
811  }
812 
813  return KConfigPrivate::expandString(aValue);
814 }
815 
816 QStringList KConfigGroup::readPathEntry(const QString &pKey, const QStringList &aDefault) const
817 {
818  return readPathEntry(pKey.toUtf8().constData(), aDefault);
819 }
820 
821 QStringList KConfigGroup::readPathEntry(const char *key, const QStringList &aDefault) const
822 {
823  Q_ASSERT_X(isValid(), "KConfigGroup::readPathEntry", "accessing an invalid group");
824 
825  const QString data = readPathEntry(key, QString());
826  if (data.isNull()) {
827  return aDefault;
828  }
829 
830  return KConfigGroupPrivate::deserializeList(data);
831 }
832 
833 void KConfigGroup::writeEntry(const char *key, const QString &value, WriteConfigFlags flags)
834 {
835  Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group");
836  Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group");
837 
838  writeEntry(key, value.toUtf8(), flags);
839 }
840 
841 void KConfigGroup::writeEntry(const QString &key, const QString &value, WriteConfigFlags flags)
842 {
843  writeEntry(key.toUtf8().constData(), value, flags);
844 }
845 
846 void KConfigGroup::writeEntry(const QString &key, const char *value, WriteConfigFlags pFlags)
847 {
848  Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group");
849  Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group");
850 
851  writeEntry(key.toUtf8().constData(), QVariant(QString::fromLatin1(value)), pFlags);
852 }
853 
854 void KConfigGroup::writeEntry(const char *key, const char *value, WriteConfigFlags pFlags)
855 {
856  writeEntry(key, QVariant(QString::fromLatin1(value)), pFlags);
857 }
858 
859 void KConfigGroup::writeEntry(const char *key, const QByteArray &value,
860  WriteConfigFlags flags)
861 {
862  Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group");
863  Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group");
864 
865  config()->d_func()->putData(d->fullName(), key, value.isNull() ? QByteArray("") : value, flags);
866 }
867 
868 void KConfigGroup::writeEntry(const QString &key, const QByteArray &value,
869  WriteConfigFlags pFlags)
870 {
871  writeEntry(key.toUtf8().constData(), value, pFlags);
872 }
873 
874 void KConfigGroup::writeEntry(const char *key, const QStringList &list, WriteConfigFlags flags)
875 {
876  Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group");
877  Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group");
878 
879  QList<QByteArray> balist;
880  balist.reserve(list.count());
881 
882  for (const QString &entry : list) {
883  balist.append(entry.toUtf8());
884  }
885 
886  writeEntry(key, KConfigGroupPrivate::serializeList(balist), flags);
887 }
888 
889 void KConfigGroup::writeEntry(const QString &key, const QStringList &list, WriteConfigFlags flags)
890 {
891  writeEntry(key.toUtf8().constData(), list, flags);
892 }
893 
894 void KConfigGroup::writeEntry(const char *key, const QVariantList &list, WriteConfigFlags flags)
895 {
896  Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group");
897  Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group");
898 
899  QList<QByteArray> data;
900  data.reserve(list.count());
901 
902  for (const QVariant &v : list) {
903  if (v.type() == QVariant::ByteArray) {
904  data << v.toByteArray();
905  } else {
906  data << v.toString().toUtf8();
907  }
908  }
909 
910  writeEntry(key, KConfigGroupPrivate::serializeList(data), flags);
911 }
912 
913 void KConfigGroup::writeEntry(const char *key, const QVariant &value,
914  WriteConfigFlags flags)
915 {
916  Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group");
917  Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group");
918 
919  if (writeEntryGui(this, key, value, flags)) {
920  return; // GUI type that was handled
921  }
922 
923  QByteArray data;
924  // if a type handler is added here you must add a QVConversions definition
925  // to conversioncheck.h, or ConversionCheck::to_QVariant will not allow
926  // writeEntry<T> to convert to QVariant.
927  switch (static_cast<QMetaType::Type>(value.type())) {
929  data = "";
930  break;
932  data = value.toByteArray();
933  break;
934  case QMetaType::QString:
935  case QMetaType::Int:
936  case QMetaType::UInt:
937  case QMetaType::Double:
938  case QMetaType::Float:
939  case QMetaType::Bool:
940  case QMetaType::LongLong:
942  data = value.toString().toUtf8();
943  break;
946  qCWarning(KCONFIG_CORE_LOG) << "not all types in \"" << key << "\" can convert to QString,"
947  " information will be lost";
948  Q_FALLTHROUGH();
950  writeEntry(key, value.toList(), flags);
951  return;
952  case QMetaType::QPoint: {
953  const QPoint rPoint = value.toPoint();
954 
955  const QVariantList list{
956  rPoint.x(),
957  rPoint.y()
958  };
959 
960  writeEntry(key, list, flags);
961  return;
962  }
963  case QMetaType::QPointF: {
964  const QPointF point = value.toPointF();
965 
966  const QVariantList list{
967  point.x(),
968  point.y()
969  };
970 
971  writeEntry(key, list, flags);
972  return;
973  }
974  case QMetaType::QRect: {
975  const QRect rRect = value.toRect();
976 
977  const QVariantList list{
978  rRect.left(),
979  rRect.top(),
980  rRect.width(),
981  rRect.height()
982  };
983 
984  writeEntry(key, list, flags);
985  return;
986  }
987  case QMetaType::QRectF: {
988  const QRectF rRectF = value.toRectF();
989 
990  const QVariantList list{
991  rRectF.left(),
992  rRectF.top(),
993  rRectF.width(),
994  rRectF.height()
995  };
996 
997  writeEntry(key, list, flags);
998  return;
999  }
1000  case QMetaType::QSize: {
1001  const QSize rSize = value.toSize();
1002 
1003  const QVariantList list{
1004  rSize.width(),
1005  rSize.height()
1006  };
1007 
1008  writeEntry(key, list, flags);
1009  return;
1010  }
1011  case QMetaType::QSizeF: {
1012  const QSizeF rSizeF = value.toSizeF();
1013 
1014  const QVariantList list{
1015  rSizeF.width(),
1016  rSizeF.height()
1017  };
1018 
1019  writeEntry(key, list, flags);
1020  return;
1021  }
1022  case QMetaType::QDate: {
1023  const QDate date = value.toDate();
1024 
1025  const QVariantList list{
1026  date.year(),
1027  date.month(),
1028  date.day()
1029  };
1030 
1031  writeEntry(key, list, flags);
1032  return;
1033  }
1034  case QMetaType::QDateTime: {
1035  const QDateTime rDateTime = value.toDateTime();
1036 
1037  const QTime time = rDateTime.time();
1038  const QDate date = rDateTime.date();
1039 
1040  const QVariantList list{
1041  date.year(),
1042  date.month(),
1043  date.day(),
1044 
1045  time.hour(),
1046  time.minute(),
1047  time.second(),
1048  };
1049 
1050  writeEntry(key, list, flags);
1051  return;
1052  }
1053 
1054  case QMetaType::QColor:
1055  case QMetaType::QFont:
1056  qCWarning(KCONFIG_CORE_LOG) << "KConfigGroup::writeEntry was passed GUI type '"
1057  << value.typeName()
1058  << "' but KConfigGui isn't linked! If it is linked to your program, this is a platform bug. "
1059  "Please inform the KDE developers";
1060  break;
1061  case QMetaType::QUrl:
1062  data = QUrl(value.toUrl()).toString().toUtf8();
1063  break;
1064  default:
1065  qCWarning(KCONFIG_CORE_LOG) << "KConfigGroup::writeEntry - unhandled type" << value.typeName() << "in group" << name();
1066  }
1067 
1068  writeEntry(key, data, flags);
1069 }
1070 
1071 void KConfigGroup::writeEntry(const QString &key, const QVariant &value, WriteConfigFlags flags)
1072 {
1073  writeEntry(key.toUtf8().constData(), value, flags);
1074 }
1075 
1076 void KConfigGroup::writeEntry(const QString &key, const QVariantList &list, WriteConfigFlags flags)
1077 {
1078  writeEntry(key.toUtf8().constData(), list, flags);
1079 }
1080 
1082 {
1083  writeXdgListEntry(key.toUtf8().constData(), value, pFlags);
1084 }
1085 
1086 void KConfigGroup::writeXdgListEntry(const char *key, const QStringList &list, WriteConfigFlags flags)
1087 {
1088  Q_ASSERT_X(isValid(), "KConfigGroup::writeXdgListEntry", "accessing an invalid group");
1089  Q_ASSERT_X(!d->bConst, "KConfigGroup::writeXdgListEntry", "writing to a read-only group");
1090 
1091  QString value;
1092  value.reserve(4096);
1093 
1094  // XXX List serialization being a separate layer from low-level escaping is
1095  // probably a bug. No affected entries are defined, though.
1097  const QStringList::ConstIterator end = list.constEnd();
1098  for (; it != end; ++it) {
1099  QString val(*it);
1100  val.replace(QLatin1Char('\\'), QLatin1String("\\\\")).replace(QLatin1Char(';'), QLatin1String("\\;"));
1101  value += val;
1102  value += QLatin1Char(';');
1103  }
1104 
1105  writeEntry(key, value, flags);
1106 }
1107 
1108 void KConfigGroup::writePathEntry(const QString &pKey, const QString &path, WriteConfigFlags pFlags)
1109 {
1110  writePathEntry(pKey.toUtf8().constData(), path, pFlags);
1111 }
1112 
1113 void KConfigGroup::writePathEntry(const char *pKey, const QString &path, WriteConfigFlags pFlags)
1114 {
1115  Q_ASSERT_X(isValid(), "KConfigGroup::writePathEntry", "accessing an invalid group");
1116  Q_ASSERT_X(!d->bConst, "KConfigGroup::writePathEntry", "writing to a read-only group");
1117 
1118  config()->d_func()->putData(d->fullName(), pKey, translatePath(path).toUtf8(), pFlags, true);
1119 }
1120 
1121 void KConfigGroup::writePathEntry(const QString &pKey, const QStringList &value, WriteConfigFlags pFlags)
1122 {
1123  writePathEntry(pKey.toUtf8().constData(), value, pFlags);
1124 }
1125 
1126 void KConfigGroup::writePathEntry(const char *pKey, const QStringList &value, WriteConfigFlags pFlags)
1127 {
1128  Q_ASSERT_X(isValid(), "KConfigGroup::writePathEntry", "accessing an invalid group");
1129  Q_ASSERT_X(!d->bConst, "KConfigGroup::writePathEntry", "writing to a read-only group");
1130 
1131  QList<QByteArray> list;
1132  list.reserve(value.length());
1133  for (const QString &path : value) {
1134  list << translatePath(path).toUtf8();
1135  }
1136 
1137  config()->d_func()->putData(d->fullName(), pKey, KConfigGroupPrivate::serializeList(list), pFlags, true);
1138 }
1139 
1140 void KConfigGroup::deleteEntry(const char *key, WriteConfigFlags flags)
1141 {
1142  Q_ASSERT_X(isValid(), "KConfigGroup::deleteEntry", "accessing an invalid group");
1143  Q_ASSERT_X(!d->bConst, "KConfigGroup::deleteEntry", "deleting from a read-only group");
1144 
1145  config()->d_func()->putData(d->fullName(), key, QByteArray(), flags);
1146 }
1147 
1149 {
1150  deleteEntry(key.toUtf8().constData(), flags);
1151 }
1152 
1153 void KConfigGroup::revertToDefault(const char *key)
1154 {
1156 }
1157 
1159 {
1160  Q_ASSERT_X(isValid(), "KConfigGroup::revertToDefault", "accessing an invalid group");
1161  Q_ASSERT_X(!d->bConst, "KConfigGroup::revertToDefault", "writing to a read-only group");
1162 
1163  config()->d_func()->revertEntry(d->fullName(), key, flags);
1164 }
1165 
1167 {
1169 }
1170 
1172 {
1173  revertToDefault(key.toUtf8().constData(), flags);
1174 }
1175 
1176 bool KConfigGroup::hasDefault(const char *key) const
1177 {
1178  Q_ASSERT_X(isValid(), "KConfigGroup::hasDefault", "accessing an invalid group");
1179 
1180  KEntryMap::SearchFlags flags = KEntryMap::SearchDefaults | KEntryMap::SearchLocalized;
1181 
1182  return !config()->d_func()->lookupData(d->fullName(), key, flags).isNull();
1183 }
1184 
1185 bool KConfigGroup::hasDefault(const QString &key) const
1186 {
1187  return hasDefault(key.toUtf8().constData());
1188 }
1189 
1190 bool KConfigGroup::hasKey(const char *key) const
1191 {
1192  Q_ASSERT_X(isValid(), "KConfigGroup::hasKey", "accessing an invalid group");
1193 
1194  KEntryMap::SearchFlags flags = KEntryMap::SearchLocalized;
1195  if (config()->readDefaults()) {
1196  flags |= KEntryMap::SearchDefaults;
1197  }
1198 
1199  return !config()->d_func()->lookupData(d->fullName(), key, flags).isNull();
1200 }
1201 
1202 bool KConfigGroup::hasKey(const QString &key) const
1203 {
1204  return hasKey(key.toUtf8().constData());
1205 }
1206 
1208 {
1209  Q_ASSERT_X(isValid(), "KConfigGroup::isImmutable", "accessing an invalid group");
1210 
1211  return d->bImmutable;
1212 }
1213 
1215 {
1216  Q_ASSERT_X(isValid(), "KConfigGroup::groupList", "accessing an invalid group");
1217 
1218  return config()->d_func()->groupList(d->fullName());
1219 }
1220 
1222 {
1223  Q_ASSERT_X(isValid(), "KConfigGroup::keyList", "accessing an invalid group");
1224 
1225  return entryMap().keys();
1226 }
1227 
1229 {
1230  Q_ASSERT_X(isValid(), "KConfigGroup::markAsClean", "accessing an invalid group");
1231 
1232  config()->markAsClean();
1233 }
1234 
1236 {
1237  Q_ASSERT_X(isValid(), "KConfigGroup::accessMode", "accessing an invalid group");
1238 
1239  return config()->accessMode();
1240 }
1241 
1243 {
1244  Q_ASSERT_X(isValid(), "KConfigGroup::hasGroupImpl", "accessing an invalid group");
1245 
1246  return config()->hasGroup(d->fullName(b));
1247 }
1248 
1250 {
1251  Q_ASSERT_X(isValid(), "KConfigGroup::deleteGroupImpl", "accessing an invalid group");
1252  Q_ASSERT_X(!d->bConst, "KConfigGroup::deleteGroupImpl", "deleting from a read-only group");
1253 
1254  config()->deleteGroup(d->fullName(b), flags);
1255 }
1256 
1258 {
1259  Q_ASSERT_X(isValid(), "KConfigGroup::isGroupImmutableImpl", "accessing an invalid group");
1260 
1261  if (!hasGroupImpl(b)) { // group doesn't exist yet
1262  return d->bImmutable; // child groups are immutable if the parent is immutable.
1263  }
1264 
1265  return config()->isGroupImmutable(d->fullName(b));
1266 }
1267 
1269 {
1270  Q_ASSERT_X(isValid(), "KConfigGroup::copyTo", "accessing an invalid group");
1271  Q_ASSERT(other != nullptr);
1272 
1273  if (KConfigGroup *otherGroup = dynamic_cast<KConfigGroup *>(other)) {
1274  config()->d_func()->copyGroup(d->fullName(), otherGroup->d->fullName(), otherGroup, pFlags);
1275  } else if (KConfig *otherConfig = dynamic_cast<KConfig *>(other)) {
1276  KConfigGroup newGroup = otherConfig->group(d->fullName());
1277  otherConfig->d_func()->copyGroup(d->fullName(), d->fullName(), &newGroup, pFlags);
1278  } else {
1279  Q_ASSERT_X(false, "KConfigGroup::copyTo", "unknown type of KConfigBase");
1280  }
1281 }
1282 
1284 {
1285  Q_ASSERT_X(isValid(), "KConfigGroup::reparent", "accessing an invalid group");
1286  Q_ASSERT_X(!d->bConst, "KConfigGroup::reparent", "reparenting a read-only group");
1287  Q_ASSERT_X(!d->bImmutable, "KConfigGroup::reparent", "reparenting an immutable group");
1288  Q_ASSERT(parent != nullptr);
1289 
1290  KConfigGroup oldGroup(*this);
1291 
1292  d = KConfigGroupPrivate::create(parent, d->mName, false, false);
1293  oldGroup.copyTo(this, pFlags);
1294  oldGroup.deleteGroup(); // so that the entries with the old group name are deleted on sync
1295 }
bool canConvert(int targetTypeId) const const
QUrl toUrl() const const
bool isGroupImmutable(const QString &group) const
Can changes be made to the entries in group?
Definition: kconfigbase.cpp:81
QString readPathEntry(const QString &pKey, const QString &aDefault) const
Reads a path.
QByteArray toByteArray() const const
int minute() const const
bool sync() override
QString toNativeSeparators(const QString &pathName)
KDB_EXPORT QStringList deserializeList(const QString &data)
void markAsClean() override
Definition: kconfig.cpp:510
int width() const const
QPointF toPointF() const const
void writePathEntry(const QString &pKey, const QString &path, WriteConfigFlags pFlags=Normal)
Writes a file path to the configuration.
QByteArray toLower() const const
void reserve(int size)
int length() const const
bool hasDefault(const QString &key) const
Whether a default is specified for an entry in either the system wide configuration file or the globa...
QList< QVariant > toList() const const
void reserve(int alloc)
QAction * create(StandardAction id, const QObject *recvr, Func slot, QObject *parent)
QDateTime toDateTime() const const
bool isEntryImmutable(const QString &key) const
Checks if it is possible to change the given entry.
bool isNull() const const
int size() const const
void markAsClean() override
void reparent(KConfigBase *parent, WriteConfigFlags pFlags=Normal)
Changes the configuration object that this group belongs to.
bool isEmpty() const const
KConfigGroup parent() const
Returns the group that this group belongs to.
bool hasGroup(const QString &group) const
Returns true if the specified group is known about.
Definition: kconfigbase.cpp:16
QTime time() const const
qreal top() const const
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
Writes a value to the configuration object.
int height() const const
void changeGroup(const QString &group)
Changes the group of the object.
int day() const const
bool isValid() const
Whether the group is valid.
void deleteGroup(WriteConfigFlags pFlags=Normal)
Delete all entries in the entire group.
QString homePath()
QString toString(QUrl::FormattingOptions options) const const
qreal left() const const
int second() const const
int x() const const
int y() const const
bool isNull() const const
void deleteGroup(const QString &group, WriteConfigFlags flags=Normal)
Delete group.
Definition: kconfigbase.cpp:66
void clear()
QMap< QString, QString > entryMap(const QString &aGroup=QString()) const
Returns a map (tree) of entries in a particular group.
Definition: kconfig.cpp:373
void deleteEntry(const QString &pKey, WriteConfigFlags pFlags=Normal)
Deletes the entry specified by pKey in the current group.
QString fullName(const PartType &type)
QList< Key > keys() const const
int count(const T &value) const const
bool sync() override
Definition: kconfig.cpp:404
qreal x() const const
qreal y() const const
void append(const T &value)
QString fromUtf8(const char *str, int size)
QString readEntryUntranslated(const QString &pKey, const QString &aDefault=QString()) const
Reads an untranslated string entry.
int top() const const
bool exists() const
Check whether the containing KConfig object acutally contains a group with this name.
int left() const const
CaseInsensitive
bool isEmpty() const const
bool isEmpty() const const
const char * constData() const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QByteArray & replace(int pos, int len, const char *after)
void writeXdgListEntry(const QString &pKey, const QStringList &value, WriteConfigFlags pFlags=Normal)
Writes a list of strings to the config object, following XDG desktop entry spec separator semantics...
void deleteGroupImpl(const QByteArray &group, WriteConfigFlags flags) override
QSizeF toSizeF() const const
QStringList readXdgListEntry(const QString &pKey, const QStringList &aDefault=QStringList()) const
Reads a list of strings from the config object, following XDG desktop entry spec separator semantics...
QVector< T > mid(int pos, int length) const const
void copyTo(KConfigBase *other, WriteConfigFlags pFlags=Normal) const
Copies the entries in this group to another configuration object.
KDEGAMES_EXPORT QAction * end(const QObject *recvr, const char *slot, QObject *parent)
Interface to interact with configuration.
Definition: kconfigbase.h:30
QStringList keyList() const
Returns a list of keys this group contains.
QSize toSize() const const
QString toLocalFile() const const
int hour() const const
void reserve(int size)
bool isGroupImmutableImpl(const QByteArray &aGroup) const override
QString name() const
The name of this group.
bool isRelativePath(const QString &path)
bool hasKey(const QString &key) const
Checks whether the key has an entry in this group.
const char * typeToName(int typeId)
A class for one specific group in a KConfig object.
Definition: kconfiggroup.h:38
QDate toDate() const const
KConfigGroup group(const QString &group)
Returns an object for the named subgroup.
Definition: kconfigbase.cpp:36
QString & replace(int position, int n, QChar after)
const T & at(int i) const const
bool hasGroupImpl(const QByteArray &group) const override
The central class of the KDE configuration data system.
Definition: kconfig.h:56
KConfig * config()
Return the config object that this group belongs to.
int width() const const
qreal width() const const
QDate date() const const
KConfigGroup groupImpl(const QByteArray &b) override
AccessMode accessMode() const override
Definition: kconfig.cpp:789
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool isImmutable() const override
Whether this group may be changed.
const char * typeName() const const
typedef ConstIterator
int height() const const
int count(const T &value) const const
QStringList groupList() const override
Definition: kconfig.cpp:277
AccessMode
Possible return values for accessMode().
Definition: kconfigbase.h:175
int length() const const
void reserve(int size)
KDB_EXPORT QString serializeList(const QStringList &list)
QString fromLatin1(const char *str, int size)
QPoint toPoint() const const
AccessMode accessMode() const override
qreal height() const const
QString canonicalPath() const const
QRect toRect() const const
QList::const_iterator constEnd() const const
QList::const_iterator constBegin() const const
QVariant::Type type() const const
qreal height() const const
QRectF toRectF() const const
int year() const const
bool convert(int targetTypeId)
QString toString() const const
T readEntry(const QString &key, const T &aDefault) const
Reads the value of an entry specified by pKey in the current group.
Definition: kconfiggroup.h:250
int month() const const
void revertToDefault(const QString &key)
Reverts an entry to the default settings.
void squeeze()
QStringList groupList() const override
qreal width() const const
QMap< QString, QString > entryMap() const
Returns a map (tree) of entries for all entries in this group.
QString decodeName(const QByteArray &localFileName)
QUrl fromLocalFile(const QString &localFile)
KConfigGroup()
Constructs an invalid group.
bool readDefaults() const
Definition: kconfig.cpp:844
QFlags< WriteConfigFlag > WriteConfigFlags
Stores a combination of WriteConfigFlag values.
Definition: kconfigbase.h:67
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Thu Aug 13 2020 22:48:14 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.