Skip to content
Permalink
Browse files
QgsSettings: add writeArray and more group and array tests
  • Loading branch information
elpaso committed Apr 12, 2017
1 parent 29d228d commit 9c2f88c911b02c07735182c0bb35d2ae7b824612
Showing with 153 additions and 17 deletions.
  1. +26 −5 python/core/qgssettings.sip
  2. +6 −0 src/core/qgssettings.cpp
  3. +27 −11 src/core/qgssettings.h
  4. +94 −1 tests/src/python/test_qgssettings.py
@@ -33,8 +33,10 @@ class QgsSettings : QObject
- Gui
- Server
- Plugins
- Misc
- Auth
- App
- Providers
- Misc

.. versionadded:: 3
%End
@@ -169,17 +171,30 @@ Set the Global Settings QSettings storage file
Adds prefix to the current group and starts reading from an array. Returns the size of the array.
:rtype: int
%End

void beginWriteArray( const QString &prefix, int size = -1 );
%Docstring
Adds prefix to the current group and starts writing an array of size size.
If size is -1 (the default), it is automatically determined based on the indexes of the entries written.
.. note::

This will completely shadow any existing array with the same name in the global settings
%End
void endArray();
%Docstring
Closes the array that was started using beginReadArray() or beginWriteArray().
%End

void setArrayIndex( int i );
%Docstring
remove(), and contains() will operate on the array entry at that index.
Sets the current array index to i. Calls to functions such as setValue(), value(),
remove(), and contains() will operate on the array entry at that index.
%End

void setValue( const QString &key, const QVariant &value, const QgsSettings::Section section = QgsSettings::NoSection );
%Docstring
An optional Section argument can be used to set a value to a specific Section.
Sets the value of setting key to value. If the key already exists, the previous value is overwritten.
An optional Section argument can be used to set a value to a specific Section.
%End

SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
@@ -205,19 +220,25 @@ An optional Section argument can be used to set a value to a specific Section.

sipIsErr = !sipRes;
%End

bool contains( const QString &key, const QgsSettings::Section section = QgsSettings::NoSection ) const;
%Docstring
If a group is set using beginGroup(), key is taken to be relative to that group.
Returns true if there exists a setting called key; returns false otherwise.
If a group is set using beginGroup(), key is taken to be relative to that group.
:rtype: bool
%End
QString fileName() const;
%Docstring
Returns the path where settings written using this QSettings object are stored.
:rtype: str
%End

void sync();
%Docstring
loop at regular intervals, so you normally don't need to call it yourself.
Writes any unsaved changes to permanent storage, and reloads any settings that have been
changed in the meantime by another application.
This function is called automatically from QSettings's destructor and by the event
loop at regular intervals, so you normally don't need to call it yourself.
%End
void remove( const QString &key );
%Docstring
@@ -234,6 +234,12 @@ int QgsSettings::beginReadArray( const QString &prefix )
return size;
}

void QgsSettings::beginWriteArray( const QString &prefix, int size )
{
mUsingGlobalArray = false;
mUserSettings->beginWriteArray( prefix, size );
}

void QgsSettings::endArray()
{
mUserSettings->endArray();
@@ -44,8 +44,10 @@
* - Gui
* - Server
* - Plugins
* - Misc
* - Auth
* - App
* - Providers
* - Misc
*
* \since QGIS 3
*/
@@ -154,13 +156,23 @@ class CORE_EXPORT QgsSettings : public QObject
static bool setGlobalSettingsPath( QString path );
//! Adds prefix to the current group and starts reading from an array. Returns the size of the array.
int beginReadArray( const QString &prefix );

/** Adds prefix to the current group and starts writing an array of size size.
* If size is -1 (the default), it is automatically determined based on the indexes of the entries written.
* @note This will completely shadow any existing array with the same name in the global settings
*/
void beginWriteArray( const QString &prefix, int size = -1 );
//! Closes the array that was started using beginReadArray() or beginWriteArray().
void endArray();
//! Sets the current array index to i. Calls to functions such as setValue(), value(),
//! remove(), and contains() will operate on the array entry at that index.

/** Sets the current array index to i. Calls to functions such as setValue(), value(),
* remove(), and contains() will operate on the array entry at that index.
*/
void setArrayIndex( int i );
//! Sets the value of setting key to value. If the key already exists, the previous value is overwritten.
//! An optional Section argument can be used to set a value to a specific Section.

/** Sets the value of setting key to value. If the key already exists, the previous value is overwritten.
* An optional Section argument can be used to set a value to a specific Section.
*/
void setValue( const QString &key, const QVariant &value, const QgsSettings::Section section = QgsSettings::NoSection );

/** Returns the value for setting key. If the setting doesn't exist, it will be
@@ -190,15 +202,19 @@ class CORE_EXPORT QgsSettings : public QObject
sipIsErr = !sipRes;
% End
#endif
//! Returns true if there exists a setting called key; returns false otherwise.
//! If a group is set using beginGroup(), key is taken to be relative to that group.

/** Returns true if there exists a setting called key; returns false otherwise.
* If a group is set using beginGroup(), key is taken to be relative to that group.
*/
bool contains( const QString &key, const QgsSettings::Section section = QgsSettings::NoSection ) const;
//! Returns the path where settings written using this QSettings object are stored.
QString fileName() const;
//! Writes any unsaved changes to permanent storage, and reloads any settings that have been
//! changed in the meantime by another application.
//! This function is called automatically from QSettings's destructor and by the event
//! loop at regular intervals, so you normally don't need to call it yourself.

/** Writes any unsaved changes to permanent storage, and reloads any settings that have been
* changed in the meantime by another application.
* This function is called automatically from QSettings's destructor and by the event
* loop at regular intervals, so you normally don't need to call it yourself.
*/
void sync();
//! Removes the setting key and any sub-settings of key.
void remove( const QString &key );
@@ -68,6 +68,14 @@ def addArrayToDefaults(self, prefix, key, values):
self.globalsettings.endArray()
self.globalsettings.sync()

def addGroupToDefaults(self, prefix, kvp):
defaults = QSettings(self.settings.globalSettingsPath(), QSettings.IniFormat) # NOQA
self.globalsettings.beginGroup(prefix)
for k, v in kvp.items():
self.globalsettings.setValue(k, v)
self.globalsettings.endGroup()
self.globalsettings.sync()

def test_basic_functionality(self):
self.assertEqual(self.settings.value('testqgissettings/doesnotexists', 'notexist'), 'notexist')
self.settings.setValue('testqgissettings/name', 'qgisrocks')
@@ -95,13 +103,69 @@ def test_allkeys(self):
self.assertEqual(3, len(self.settings.allKeys()))
self.assertEqual(2, len(self.globalsettings.allKeys()))

def test_precedence(self):
def test_precedence_simple(self):
self.assertEqual(self.settings.allKeys(), [])
self.addToDefaults('testqgissettings/names/name1', 'qgisrocks1')
self.settings.setValue('testqgissettings/names/name1', 'qgisrocks-1')

self.assertEqual(self.settings.value('testqgissettings/names/name1'), 'qgisrocks-1')

def test_precedence_group(self):
"""Test if user can override a group value"""
self.assertEqual(self.settings.allKeys(), [])
self.addGroupToDefaults('connections-xyz', {
'OSM': 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png',
'OSM-b': 'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png',
})
self.settings.beginGroup('connections-xyz')
self.assertEqual(self.settings.value('OSM'), 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.assertEqual(self.settings.value('OSM-b'), 'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.settings.endGroup()

# Override edit
self.settings.beginGroup('connections-xyz')
self.settings.setValue('OSM', 'http://c.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.settings.endGroup()

# Check it again!
self.settings.beginGroup('connections-xyz')
self.assertEqual(self.settings.value('OSM'), 'http://c.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.assertEqual(self.settings.value('OSM-b'), 'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.settings.endGroup()

# Override remove: the global value will be resumed!!!
self.settings.beginGroup('connections-xyz')
self.settings.remove('OSM')
self.settings.endGroup()

# Check it again!
self.settings.beginGroup('connections-xyz')
self.assertEqual(self.settings.value('OSM'), 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.assertEqual(self.settings.value('OSM-b'), 'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.settings.endGroup()

# Override remove: store a blank!
self.settings.beginGroup('connections-xyz')
self.settings.setValue('OSM', '')
self.settings.endGroup()

# Check it again!
self.settings.beginGroup('connections-xyz')
self.assertEqual(self.settings.value('OSM'), '')
self.assertEqual(self.settings.value('OSM-b'), 'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.settings.endGroup()

# Override remove: store a None: will resume the global setting!
self.settings.beginGroup('connections-xyz')
self.settings.setValue('OSM', None)
self.settings.endGroup()

# Check it again!
self.settings.beginGroup('connections-xyz')
self.assertEqual(self.settings.value('OSM'), 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.assertEqual(self.settings.value('OSM-b'), 'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
self.settings.endGroup()

def test_uft8(self):
self.assertEqual(self.settings.allKeys(), [])
self.addToDefaults('testqgissettings/names/namèé↓1', 'qgisrocks↓1')
@@ -153,6 +217,35 @@ def test_array(self):

self.assertEqual(values, ['qgisrocks1', 'qgisrocks2', 'qgisrocks3'])

def test_array_overrides(self):
"""Test if an array completely shadows the global one"""
self.assertEqual(self.settings.allKeys(), [])
self.addArrayToDefaults('testqgissettings', 'key', ['qgisrocks1', 'qgisrocks2', 'qgisrocks3'])
self.assertEqual(self.settings.allKeys(), ['testqgissettings/1/key', 'testqgissettings/2/key', 'testqgissettings/3/key', 'testqgissettings/size'])
self.assertEqual(self.globalsettings.allKeys(), ['testqgissettings/1/key', 'testqgissettings/2/key', 'testqgissettings/3/key', 'testqgissettings/size'])

self.assertEqual(3, self.globalsettings.beginReadArray('testqgissettings'))
self.globalsettings.endArray()
self.assertEqual(3, self.settings.beginReadArray('testqgissettings'))

# Now override!
self.settings.beginWriteArray('testqgissettings')
self.settings.setArrayIndex(0)
self.settings.setValue('key', 'myqgisrocksmore1')
self.settings.setArrayIndex(1)
self.settings.setValue('key', 'myqgisrocksmore2')
self.settings.endArray()

# Check it!
self.assertEqual(2, self.settings.beginReadArray('testqgissettings'))

values = []
for i in range(2):
self.settings.setArrayIndex(i)
values.append(self.settings.value("key"))

self.assertEqual(values, ['myqgisrocksmore1', 'myqgisrocksmore2'])

def test_section_getters_setters(self):
self.assertEqual(self.settings.allKeys(), [])

0 comments on commit 9c2f88c

Please sign in to comment.