Skip to content

Commit 6714819

Browse files
authored
Merge pull request #9309 from elpaso/bugfix-21409-qgssettings-dont-store-unchanged
Do not store default values in user's QgsSettings
2 parents 768b3d4 + 8d3946d commit 6714819

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

src/core/qgssettings.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,24 @@ 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+
// First check if the values are different and if at least one of them is valid.
286+
// The valid check is required because different invalid QVariant types
287+
// like QVariant(QVariant::String) and QVariant(QVariant::Int))
288+
// may be considered different and we don't want to store the value in that case.
289+
QVariant currentValue { QgsSettings::value( prefixedKey( key, section ) ) };
290+
if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
291+
{
292+
mUserSettings->setValue( prefixedKey( key, section ), value );
293+
}
294+
// Deliberately an "else if" because we want to remove a value from the user settings
295+
// only if the value is different than the one stored in the global settings (because
296+
// it would be the default anyway). The first check is necessary because the global settings
297+
// might be a nullptr (for example in case of standalone scripts or apps).
298+
else if ( mGlobalSettings && mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
299+
{
300+
mUserSettings->remove( prefixedKey( key, section ) );
301+
}
285302
}
286303

287304
// To lower case and clean the path

tests/src/python/test_qgssettings.py

+46-1
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)