Skip to content

Commit cd5fedf

Browse files
committed
Do not store default values in user's QgsSettings
The new behavior is to store a value in user's QSettings (that overrides the global settings) only if the the value has changed from the default reported by QgsSettings. If a value was changed and it is changed back to the default the override must be removed from the user settings. The rationale is that global settings should be the ultimate source of default values, unless the user override the default with a different value. Fixes #21049
1 parent 34a0650 commit cd5fedf

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

src/core/qgssettings.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,17 @@ void QgsSettings::setArrayIndex( int i )
281281
void QgsSettings::setValue( const QString &key, const QVariant &value, const QgsSettings::Section section )
282282
{
283283
// TODO: add valueChanged signal
284-
mUserSettings->setValue( prefixedKey( key, section ), value );
284+
// Do not store if it hasn't changed from default value
285+
QVariant v = QgsSettings::value( prefixedKey( key, section ) );
286+
QVariant currentValue { QgsSettings::value( prefixedKey( key, section ) ) };
287+
if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
288+
{
289+
mUserSettings->setValue( prefixedKey( key, section ), value );
290+
}
291+
else if ( mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
292+
{
293+
mUserSettings->remove( prefixedKey( key, section ) );
294+
}
285295
}
286296

287297
// To lower case and clean the path

tests/src/python/test_qgssettings.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
import tempfile
1515
from qgis.core import QgsSettings, QgsTolerance, QgsMapLayerProxyModel
1616
from qgis.testing import start_app, unittest
17-
from qgis.PyQt.QtCore import QSettings
17+
from qgis.PyQt.QtCore import QSettings, QVariant
18+
from pathlib import Path
1819

1920
__author__ = 'Alessandro Pasotti'
2021
__date__ = '02/02/2017'
@@ -33,9 +34,12 @@ class TestQgsSettings(unittest.TestCase):
3334
def setUp(self):
3435
self.cnt += 1
3536
h, path = tempfile.mkstemp('.ini')
37+
Path(path).touch()
3638
assert QgsSettings.setGlobalSettingsPath(path)
3739
self.settings = QgsSettings('testqgissettings', 'testqgissettings%s' % self.cnt)
3840
self.globalsettings = QSettings(self.settings.globalSettingsPath(), QSettings.IniFormat)
41+
self.globalsettings.sync()
42+
assert os.path.exists(self.globalsettings.fileName())
3943

4044
def tearDown(self):
4145
settings_file = self.settings.fileName()
@@ -329,6 +333,7 @@ def test_section_getters_setters(self):
329333
self.settings.setValue('key1', 'provider1', section=QgsSettings.Providers)
330334
self.settings.setValue('key2', 'provider2', section=QgsSettings.Providers)
331335

336+
# This is an overwrite of previous setting and it is intentional
332337
self.settings.setValue('key1', 'auth1', section=QgsSettings.Auth)
333338
self.settings.setValue('key2', 'auth2', section=QgsSettings.Auth)
334339

@@ -422,6 +427,46 @@ def test_flagValue(self):
422427
self.assertEqual(self.settings.flagValue('flag', pointAndLine), pointAndLine)
423428
self.assertEqual(type(self.settings.flagValue('enum', pointAndLine)), QgsMapLayerProxyModel.Filters)
424429

430+
def test_overwriteDefaultValues(self):
431+
"""Test that unchanged values are not stored"""
432+
self.globalsettings.setValue('a_value_with_default', 'a value')
433+
self.globalsettings.setValue('an_invalid_value', QVariant())
434+
435+
self.assertEqual(self.settings.value('a_value_with_default'), 'a value')
436+
self.assertEqual(self.settings.value('an_invalid_value'), QVariant())
437+
438+
# Now, set them with the same current value
439+
self.settings.setValue('a_value_with_default', 'a value')
440+
self.settings.setValue('an_invalid_value', QVariant())
441+
442+
# Check
443+
pure_settings = QSettings(self.settings.fileName(), QSettings.IniFormat)
444+
self.assertFalse('a_value_with_default' in pure_settings.allKeys())
445+
self.assertFalse('an_invalid_value' in pure_settings.allKeys())
446+
447+
# Set a changed value
448+
self.settings.setValue('a_value_with_default', 'a new value')
449+
self.settings.setValue('an_invalid_value', 'valid value')
450+
451+
# Check
452+
self.assertTrue('a_value_with_default' in pure_settings.allKeys())
453+
self.assertTrue('an_invalid_value' in pure_settings.allKeys())
454+
455+
self.assertEqual(self.settings.value('a_value_with_default'), 'a new value')
456+
self.assertEqual(self.settings.value('an_invalid_value'), 'valid value')
457+
458+
# Re-set to original values
459+
self.settings.setValue('a_value_with_default', 'a value')
460+
self.settings.setValue('an_invalid_value', QVariant())
461+
462+
self.assertEqual(self.settings.value('a_value_with_default'), 'a value')
463+
self.assertEqual(self.settings.value('an_invalid_value'), QVariant())
464+
465+
# Check if they are gone
466+
pure_settings = QSettings(self.settings.fileName(), QSettings.IniFormat)
467+
self.assertFalse('a_value_with_default' not in pure_settings.allKeys())
468+
self.assertFalse('an_invalid_value' not in pure_settings.allKeys())
469+
425470

426471
if __name__ == '__main__':
427472
unittest.main()

0 commit comments

Comments
 (0)