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

KDE's Doxygen guidelines are available online.