Skip to content

Commit

Permalink
Merge pull request #9309 from elpaso/bugfix-21409-qgssettings-dont-st…
Browse files Browse the repository at this point in the history
…ore-unchanged

Do not store default values in user's QgsSettings
  • Loading branch information
elpaso committed Mar 8, 2019
2 parents 768b3d4 + 8d3946d commit 6714819
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
19 changes: 18 additions & 1 deletion src/core/qgssettings.cpp
Expand Up @@ -281,7 +281,24 @@ void QgsSettings::setArrayIndex( int i )
void QgsSettings::setValue( const QString &key, const QVariant &value, const QgsSettings::Section section )
{
// TODO: add valueChanged signal
mUserSettings->setValue( prefixedKey( key, section ), value );
// Do not store if it hasn't changed from default value
// First check if the values are different and if at least one of them is valid.
// The valid check is required because different invalid QVariant types
// like QVariant(QVariant::String) and QVariant(QVariant::Int))
// may be considered different and we don't want to store the value in that case.
QVariant currentValue { QgsSettings::value( prefixedKey( key, section ) ) };
if ( ( currentValue.isValid() || value.isValid() ) && ( currentValue != value ) )
{
mUserSettings->setValue( prefixedKey( key, section ), value );
}
// Deliberately an "else if" because we want to remove a value from the user settings
// only if the value is different than the one stored in the global settings (because
// it would be the default anyway). The first check is necessary because the global settings
// might be a nullptr (for example in case of standalone scripts or apps).
else if ( mGlobalSettings && mGlobalSettings->value( prefixedKey( key, section ) ) == currentValue )
{
mUserSettings->remove( prefixedKey( key, section ) );
}
}

// To lower case and clean the path
Expand Down
47 changes: 46 additions & 1 deletion tests/src/python/test_qgssettings.py
Expand Up @@ -14,7 +14,8 @@
import tempfile
from qgis.core import QgsSettings, QgsTolerance, QgsMapLayerProxyModel
from qgis.testing import start_app, unittest
from qgis.PyQt.QtCore import QSettings
from qgis.PyQt.QtCore import QSettings, QVariant
from pathlib import Path

__author__ = 'Alessandro Pasotti'
__date__ = '02/02/2017'
Expand All @@ -33,9 +34,12 @@ class TestQgsSettings(unittest.TestCase):
def setUp(self):
self.cnt += 1
h, path = tempfile.mkstemp('.ini')
Path(path).touch()
assert QgsSettings.setGlobalSettingsPath(path)
self.settings = QgsSettings('testqgissettings', 'testqgissettings%s' % self.cnt)
self.globalsettings = QSettings(self.settings.globalSettingsPath(), QSettings.IniFormat)
self.globalsettings.sync()
assert os.path.exists(self.globalsettings.fileName())

def tearDown(self):
settings_file = self.settings.fileName()
Expand Down Expand Up @@ -329,6 +333,7 @@ def test_section_getters_setters(self):
self.settings.setValue('key1', 'provider1', section=QgsSettings.Providers)
self.settings.setValue('key2', 'provider2', section=QgsSettings.Providers)

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

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

def test_overwriteDefaultValues(self):
"""Test that unchanged values are not stored"""
self.globalsettings.setValue('a_value_with_default', 'a value')
self.globalsettings.setValue('an_invalid_value', QVariant())

self.assertEqual(self.settings.value('a_value_with_default'), 'a value')
self.assertEqual(self.settings.value('an_invalid_value'), QVariant())

# Now, set them with the same current value
self.settings.setValue('a_value_with_default', 'a value')
self.settings.setValue('an_invalid_value', QVariant())

# Check
pure_settings = QSettings(self.settings.fileName(), QSettings.IniFormat)
self.assertFalse('a_value_with_default' in pure_settings.allKeys())
self.assertFalse('an_invalid_value' in pure_settings.allKeys())

# Set a changed value
self.settings.setValue('a_value_with_default', 'a new value')
self.settings.setValue('an_invalid_value', 'valid value')

# Check
self.assertTrue('a_value_with_default' in pure_settings.allKeys())
self.assertTrue('an_invalid_value' in pure_settings.allKeys())

self.assertEqual(self.settings.value('a_value_with_default'), 'a new value')
self.assertEqual(self.settings.value('an_invalid_value'), 'valid value')

# Re-set to original values
self.settings.setValue('a_value_with_default', 'a value')
self.settings.setValue('an_invalid_value', QVariant())

self.assertEqual(self.settings.value('a_value_with_default'), 'a value')
self.assertEqual(self.settings.value('an_invalid_value'), QVariant())

# Check if they are gone
pure_settings = QSettings(self.settings.fileName(), QSettings.IniFormat)
self.assertFalse('a_value_with_default' not in pure_settings.allKeys())
self.assertFalse('an_invalid_value' not in pure_settings.allKeys())


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

0 comments on commit 6714819

Please sign in to comment.