aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Lohnau <alexander.lohnau@gmx.de>2021-09-19 20:02:50 +0200
committerAlexander Lohnau <alexander.lohnau@gmx.de>2021-10-11 18:11:27 +0200
commitf7754f2bb3db666e4bfb2b82af079828e0086b84 (patch)
treedb1120cab3fb234b0c4d9f55f626a93968ac3fa1
parent13b79463dd80c84c7cf1c817c363e7747e4da034 (diff)
downloadkconfig-f7754f2bb3db666e4bfb2b82af079828e0086b84.tar.gz
kconfig-f7754f2bb3db666e4bfb2b82af079828e0086b84.tar.bz2
Create utility method for moving entries from one group to another
This will become especially useful when moving state data from the config file to a dedicated state data file. Task: https://phabricator.kde.org/T12549
-rw-r--r--autotests/kconfigtest.cpp41
-rw-r--r--autotests/kconfigtest.h2
-rw-r--r--src/core/kconfig.cpp9
-rw-r--r--src/core/kconfig_p.h7
-rw-r--r--src/core/kconfiggroup.cpp26
-rw-r--r--src/core/kconfiggroup.h8
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