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 | 
