diff --git a/autotests/kconfigskeletontest.cpp b/autotests/kconfigskeletontest.cpp --- a/autotests/kconfigskeletontest.cpp +++ b/autotests/kconfigskeletontest.cpp @@ -56,6 +56,9 @@ QCOMPARE(mMyColor, DEFAULT_SETTING2); QCOMPARE(mMyFont, DEFAULT_SETTING3); QCOMPARE(mMyString, DEFAULT_SETTING4); + + QVERIFY(s->isDefaults()); + QVERIFY(!s->isSaveNeeded()); } void KConfigSkeletonTest::cleanup() @@ -70,15 +73,27 @@ mMyFont = WRITE_SETTING3; mMyString = WRITE_SETTING4; + QVERIFY(s->isSaveNeeded()); + QVERIFY(!s->isDefaults()); + s->save(); + QVERIFY(!s->isSaveNeeded()); + QVERIFY(!s->isDefaults()); + mMyBool = false; mMyColor = QColor(); mMyString.clear(); mMyFont = QFont(); + QVERIFY(s->isSaveNeeded()); + QVERIFY(!s->isDefaults()); + s->read(); + QVERIFY(!s->isSaveNeeded()); + QVERIFY(!s->isDefaults()); + QCOMPARE(mMyBool, WRITE_SETTING1); QCOMPARE(mMyColor, WRITE_SETTING2); QCOMPARE(mMyFont, WRITE_SETTING3); @@ -112,16 +127,28 @@ mMyFont = WRITE_SETTING3; mMyString = WRITE_SETTING4; + QVERIFY(s->isSaveNeeded()); + QVERIFY(!s->isDefaults()); + s->save(); + QVERIFY(!s->isSaveNeeded()); + QVERIFY(!s->isDefaults()); + s->setDefaults(); + QVERIFY(s->isSaveNeeded()); + QVERIFY(s->isDefaults()); + QCOMPARE(mMyBool, DEFAULT_SETTING1); QCOMPARE(mMyColor, DEFAULT_SETTING2); QCOMPARE(mMyFont, DEFAULT_SETTING3); QCOMPARE(mMyString, DEFAULT_SETTING4); s->save(); + + QVERIFY(!s->isSaveNeeded()); + QVERIFY(s->isDefaults()); } void KConfigSkeletonTest::testKConfigDirty() diff --git a/src/core/kcoreconfigskeleton.h b/src/core/kcoreconfigskeleton.h --- a/src/core/kcoreconfigskeleton.h +++ b/src/core/kcoreconfigskeleton.h @@ -210,6 +210,21 @@ */ bool isImmutable() const; + /** + * Indicates if the item is set to its default value. + * + * @since 5.64 + */ + bool isDefault() const; + + /** + * Indicates if the item has a different value than the + * previously loaded value. + * + * @since 5.64 + */ + bool isSaveNeeded() const; + protected: /** * sets mIsImmutable to true if mKey in config is immutable @@ -221,6 +236,11 @@ QString mKey; ///< The config key for this item QString mName; ///< The name of this item + // HACK: Necessary to avoid introducing new virtuals in KConfigSkeletonItem + // KF6: Use proper pure virtuals in KConfigSkeletonItem + void setIsDefaultImpl(const std::function &impl); + void setIsSaveNeededImpl(const std::function &impl); + private: KConfigSkeletonItemPrivate *const d; }; @@ -240,6 +260,8 @@ : KConfigSkeletonItem(_group, _key), mReference(reference), mDefault(defaultValue), mLoadedValue(defaultValue) { + setIsDefaultImpl([this] { return mReference == mDefault; }); + setIsSaveNeededImpl([this] { return mReference != mLoadedValue; }); } /** @@ -1077,6 +1099,21 @@ */ void read(); + /** + * Indicates if all the registered items are set to their default value. + * + * @since 5.64 + */ + bool isDefaults() const; + + /** + * Indicates if any registered item has a different value than the + * previously loaded value. + * + * @since 5.64 + */ + bool isSaveNeeded() const; + /** * Set the config file group for subsequent addItem() calls. It is valid * until setCurrentGroup() is called with a new argument. Call this before diff --git a/src/core/kcoreconfigskeleton.cpp b/src/core/kcoreconfigskeleton.cpp --- a/src/core/kcoreconfigskeleton.cpp +++ b/src/core/kcoreconfigskeleton.cpp @@ -135,11 +135,31 @@ return d->mIsImmutable; } +bool KConfigSkeletonItem::isDefault() const +{ + return d->mIsDefaultImpl(); +} + +bool KConfigSkeletonItem::isSaveNeeded() const +{ + return d->mIsSaveNeededImpl(); +} + void KConfigSkeletonItem::readImmutability(const KConfigGroup &group) { d->mIsImmutable = group.isEntryImmutable(mKey); } +void KConfigSkeletonItem::setIsDefaultImpl(const std::function &impl) +{ + d->mIsDefaultImpl = impl; +} + +void KConfigSkeletonItem::setIsSaveNeededImpl(const std::function &impl) +{ + d->mIsSaveNeededImpl = impl; +} + KCoreConfigSkeleton::ItemString::ItemString(const QString &_group, const QString &_key, QString &reference, const QString &defaultValue, @@ -1091,6 +1111,28 @@ usrRead(); } +bool KCoreConfigSkeleton::isDefaults() const +{ + KConfigSkeletonItem::List::ConstIterator it; + for (it = d->mItems.constBegin(); it != d->mItems.constEnd(); ++it) { + if (!(*it)->isDefault()) { + return false; + } + } + return true; +} + +bool KCoreConfigSkeleton::isSaveNeeded() const +{ + KConfigSkeletonItem::List::ConstIterator it; + for (it = d->mItems.constBegin(); it != d->mItems.constEnd(); ++it) { + if ((*it)->isSaveNeeded()) { + return true; + } + } + return false; +} + bool KCoreConfigSkeleton::save() { //qDebug(); @@ -1394,6 +1436,9 @@ Q_ASSERT(mTargetFunction); Q_ASSERT(mItem); Q_ASSERT(mObject); + + setIsDefaultImpl([this] { return mItem->isDefault(); }); + setIsSaveNeededImpl([this] { return mItem->isSaveNeeded(); }); } KConfigCompilerSignallingItem::~KConfigCompilerSignallingItem() diff --git a/src/core/kcoreconfigskeleton_p.h b/src/core/kcoreconfigskeleton_p.h --- a/src/core/kcoreconfigskeleton_p.h +++ b/src/core/kcoreconfigskeleton_p.h @@ -60,6 +60,10 @@ QString mLabel; ///< The label for this item QString mToolTip; ///< The ToolTip text for this item QString mWhatsThis; ///< The What's This text for this item + + // HACK: Necessary to avoid introducing new virtuals in KConfigSkeletonItem + std::function mIsDefaultImpl; + std::function mIsSaveNeededImpl; }; #endif