diff options
-rw-r--r-- | autotests/kconfigtest.cpp | 41 | ||||
-rw-r--r-- | autotests/kconfigtest.h | 2 | ||||
-rw-r--r-- | src/core/kconfig.cpp | 9 | ||||
-rw-r--r-- | src/core/kconfig_p.h | 7 | ||||
-rw-r--r-- | src/core/kconfiggroup.cpp | 26 | ||||
-rw-r--r-- | src/core/kconfiggroup.h | 8 |
6 files changed, 91 insertions, 2 deletions
diff --git a/autotests/kconfigtest.cpp b/autotests/kconfigtest.cpp index c3a68e42..00e7bbf0 100644 --- a/autotests/kconfigtest.cpp +++ b/autotests/kconfigtest.cpp @@ -1898,6 +1898,47 @@ void KConfigTest::testNewlines() #endif } +void KConfigTest::testMoveValuesTo() +{ + QTemporaryFile file; + QVERIFY(file.open()); + // Prepare kdeglobals + { + KConfig glob(QStringLiteral("kdeglobals")); + KConfigGroup general(&glob, "TestGroup"); + general.writeEntry("GlobalKey", "PlsDeleteMe"); + QVERIFY(glob.sync()); + } + + KConfigGroup grp = KSharedConfig::openConfig(file.fileName())->group("TestGroup"); + + grp.writeEntry("test1", "first_value"); + grp.writeEntry("test_empty", ""); + grp.writeEntry("other", "other_value"); + grp.writePathEntry("my_path", QStringLiteral("~/somepath")); + // because this key is from the global file it should be explicitly deleted + grp.deleteEntry("GlobalKey"); + + QTemporaryFile targetFile; + QVERIFY(targetFile.open()); + targetFile.close(); + KConfigGroup targetGroup = KSharedConfig::openConfig(targetFile.fileName(), KConfig::SimpleConfig)->group("MoveToGroup"); + + grp.moveValuesTo({"test1", "test_empty", "does_not_exist", "my_path", "GlobalKey"}, targetGroup); + QVERIFY(grp.config()->isDirty()); + QVERIFY(targetGroup.config()->isDirty()); + + QCOMPARE(grp.keyList(), QStringList{QStringLiteral("other")}); + QStringList expectedKeyList{QStringLiteral("my_path"), QStringLiteral("test1"), QStringLiteral("test_empty")}; + QCOMPARE(targetGroup.keyList(), expectedKeyList); + QCOMPARE(targetGroup.readEntry("test1"), QStringLiteral("first_value")); + + targetGroup.sync(); + QFile targetReadFile(targetFile.fileName()); + targetReadFile.open(QFile::ReadOnly); + QVERIFY(targetReadFile.readAll().contains(QByteArray("my_path[$e]=~/somepath"))); +} + void KConfigTest::testXdgListEntry() { QTemporaryFile file; diff --git a/autotests/kconfigtest.h b/autotests/kconfigtest.h index 9d519eda..f716bd70 100644 --- a/autotests/kconfigtest.h +++ b/autotests/kconfigtest.h @@ -64,6 +64,8 @@ private Q_SLOTS: void testQStringUtf8_data(); void testQStringUtf8(); + void testMoveValuesTo(); + void testSubGroup(); void testAddConfigSources(); void testWriteOnSync(); diff --git a/src/core/kconfig.cpp b/src/core/kconfig.cpp index 506e3f90..03ab67d3 100644 --- a/src/core/kconfig.cpp +++ b/src/core/kconfig.cpp @@ -1010,14 +1010,19 @@ void KConfigPrivate::revertEntry(const QByteArray &group, const char *key, KConf QByteArray KConfigPrivate::lookupData(const QByteArray &group, const char *key, KEntryMap::SearchFlags flags) const { + return lookupInternalEntry(group, key, flags).mValue; +} + +KEntry KConfigPrivate::lookupInternalEntry(const QByteArray &group, const char *key, KEntryMap::SearchFlags flags) const +{ if (bReadDefaults) { flags |= KEntryMap::SearchDefaults; } const auto it = entryMap.constFindEntry(group, key, flags); if (it == entryMap.constEnd()) { - return QByteArray(); + return {}; } - return it->mValue; + return it.value(); } QString KConfigPrivate::lookupData(const QByteArray &group, const char *key, KEntryMap::SearchFlags flags, bool *expand) const diff --git a/src/core/kconfig_p.h b/src/core/kconfig_p.h index e5c9d869..60604477 100644 --- a/src/core/kconfig_p.h +++ b/src/core/kconfig_p.h @@ -34,8 +34,15 @@ public: bool canWriteEntry(const QByteArray &group, const char *key, bool isDefault = false) const; QString lookupData(const QByteArray &group, const char *key, KEntryMap::SearchFlags flags, bool *expand) const; QByteArray lookupData(const QByteArray &group, const char *key, KEntryMap::SearchFlags flags) const; + KEntry lookupInternalEntry(const QByteArray &group, const char *key, KEntryMap::SearchFlags flags) const; void putData(const QByteArray &group, const char *key, const QByteArray &value, KConfigBase::WriteConfigFlags flags, bool expand = false); + void setEntryData(const QByteArray &group, const char *key, const QByteArray &value, KEntryMap::EntryOptions flags) + { + if (entryMap.setEntry(group, key, value, flags)) { + bDirty = true; + } + } void revertEntry(const QByteArray &group, const char *key, KConfigBase::WriteConfigFlags flags); QStringList groupList(const QByteArray &group) const; // copies the entries from @p source to @p otherGroup changing all occurrences diff --git a/src/core/kconfiggroup.cpp b/src/core/kconfiggroup.cpp index a15c45eb..be1f2b0e 100644 --- a/src/core/kconfiggroup.cpp +++ b/src/core/kconfiggroup.cpp @@ -1257,3 +1257,29 @@ void KConfigGroup::reparent(KConfigBase *parent, WriteConfigFlags pFlags) oldGroup.copyTo(this, pFlags); oldGroup.deleteGroup(); // so that the entries with the old group name are deleted on sync } + +void KConfigGroup::moveValuesTo(const QList<const char *> &keys, KConfigGroup &other, WriteConfigFlags pFlags) +{ + Q_ASSERT(isValid()); + Q_ASSERT(other.isValid()); + + for (const auto key : keys) { + const QByteArray groupName = name().toLocal8Bit(); + const auto entry = config()->d_ptr->lookupInternalEntry(groupName, key, KEntryMap::SearchLocalized); + + // Only write the entry if it is not null, if it is a global enry there is no point in moving it + if (!entry.mValue.isNull() && !entry.bGlobal) { + deleteEntry(key, pFlags); + KEntryMap::EntryOptions options = KEntryMap::EntryOption::EntryDirty; + if (entry.bDeleted) { + options |= KEntryMap::EntryDeleted; + } + + if (entry.bExpand) { + options |= KEntryMap::EntryExpansion; + } + + other.config()->d_ptr->setEntryData(other.name().toLocal8Bit(), key, entry.mValue, options); + } + } +} diff --git a/src/core/kconfiggroup.h b/src/core/kconfiggroup.h index 2584cb85..8a6243af 100644 --- a/src/core/kconfiggroup.h +++ b/src/core/kconfiggroup.h @@ -195,6 +195,14 @@ public: void reparent(KConfigBase *parent, WriteConfigFlags pFlags = Normal); /** + * Moves the key-value pairs from one config group to the other. + * In case the entries do not exist the key is ignored. + * + * @since 5.88 + */ + void moveValuesTo(const QList<const char *> &keys, KConfigGroup &other, WriteConfigFlags pFlags = Normal); + + /** * Returns the group that this group belongs to * * @return the parent group, or an invalid group if this is a top-level |