Skip to content

Commit

Permalink
Merge pull request #51117 from 3nids/settings-registry-migration-core-2
Browse files Browse the repository at this point in the history
migrate babel devices settings
  • Loading branch information
3nids committed Dec 12, 2022
2 parents 098154b + 8ca06ea commit 6c48145
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 32 deletions.
Expand Up @@ -25,6 +25,7 @@ A registry for :py:class:`QgsAbstractBabelFormat` GPSBabel formats.
%End
public:


QgsBabelFormatRegistry();
%Docstring
Constructor for QgsBabelFormatRegistry.
Expand Down
20 changes: 20 additions & 0 deletions python/core/auto_generated/settings/qgssettingsentry.sip.in
Expand Up @@ -304,6 +304,24 @@ Returns the former value of the settings if it has been enabled in the options
Returns the current value (or default) if there is no former value.

.. versionadded:: 3.26
%End

bool migrateFromKey( const QString &oldKey, const QString &oldSection = QString(), const QString &dynamicKeyPart = QString() ) const;
%Docstring
Check if the settings does not exist and try to set it from a given ``oldKey`` and ``oldSection``

.. versionadded:: 3.30
%End

bool migrateFromKey( const QString &oldKey, const QString &oldSection, const QStringList &dynamicKeyPartList ) const;
%Docstring
Check if the settings does not exist and try to set it from a given ``oldKey``

.. note::

The old key must contain its section (the section from the current setting will not be prepended)

.. versionadded:: 3.30
%End

protected:
Expand Down Expand Up @@ -375,6 +393,7 @@ The ``defaultValueOverride`` argument if valid is used instead of the normal def
%Docstring
Returns the settings value with a ``defaultValueOverride`` and with an optional ``dynamicKeyPart``
%End

T valueWithDefaultOverride( const T &defaultValueOverride, const QStringList &dynamicKeyPartList ) const;
%Docstring
Returns the settings value with a ``defaultValueOverride`` for the ``dynamicKeyPartList``
Expand Down Expand Up @@ -505,6 +524,7 @@ The ``defaultValueOverride`` argument if valid is used instead of the normal def
%Docstring
Returns the settings value with a ``defaultValueOverride`` and with an optional ``dynamicKeyPart``
%End

T valueWithDefaultOverride( T defaultValueOverride, const QStringList &dynamicKeyPartList ) const;
%Docstring
Returns the settings value with a ``defaultValueOverride`` for the ``dynamicKeyPartList``
Expand Down
41 changes: 12 additions & 29 deletions src/core/gps/qgsbabelformatregistry.cpp
Expand Up @@ -18,7 +18,6 @@
#include "qgsbabelformatregistry.h"
#include "qgsbabelformat.h"
#include "qgsbabelgpsdevice.h"
#include "qgssettings.h"
#include <QString>
#include <QRegularExpression>

Expand Down Expand Up @@ -265,44 +264,28 @@ void QgsBabelFormatRegistry::reloadFromSettings()
QStringLiteral( "%babel -t -i garmin -o gpx %in %out" ),
QStringLiteral( "%babel -t -i gpx -o garmin %in %out" ) );

QgsSettings settings;

bool useOldPath = false;
QStringList deviceNames = settings.value( QStringLiteral( "babelDeviceList" ), QVariant(), QgsSettings::Gps ).toStringList();
if ( deviceNames.empty() ) // migrate old settings
{
useOldPath = true;
deviceNames = settings.value( QStringLiteral( "Plugin-GPS/devicelist" ) ).toStringList();
}
bool useOldSettingPath = QgsBabelFormatRegistry::settingsBabelDeviceList.migrateFromKey( QStringLiteral( "Plugin-GPS/devicelist" ) );
QStringList deviceNames = QgsBabelFormatRegistry::settingsBabelDeviceList.value();

for ( const QString &device : std::as_const( deviceNames ) )
{
QString baseKey;
QgsSettings::Section section = QgsSettings::Gps;
if ( !useOldPath )
baseKey = QStringLiteral( "babelDevices/%1" ).arg( device );
else
if ( useOldSettingPath )
{
baseKey = QStringLiteral( "/Plugin-GPS/devices/%1" ).arg( device );
section = QgsSettings::NoSection;
settingsBabelWptDownload.migrateFromKey( QStringLiteral( "/Plugin-GPS/devices/%1/wptdownload" ), device );
settingsBabelWptUpload.migrateFromKey( QStringLiteral( "/Plugin-GPS/devices/%1/wptupload" ), device );
settingsBabelRteDownload.migrateFromKey( QStringLiteral( "/Plugin-GPS/devices/%1/rtedownload" ), device );
settingsBabelRteUpload.migrateFromKey( QStringLiteral( "/Plugin-GPS/devices/%1/rteupload" ), device );
settingsBabelTrkDownload.migrateFromKey( QStringLiteral( "/Plugin-GPS/devices/%1/trkdownload" ), device );
settingsBabelTrkUpload.migrateFromKey( QStringLiteral( "/Plugin-GPS/devices/%1/trkupload" ), device );
}

const QString wptDownload = settings.value( QStringLiteral( "%1/wptdownload" ).arg( baseKey ), QVariant(), section ).toString();
const QString wptUpload = settings.value( QStringLiteral( "%1/wptupload" ).arg( baseKey ), QVariant(), section ).toString();
const QString rteDownload = settings.value( QStringLiteral( "%1/rtedownload" ).arg( baseKey ), QVariant(), section ).toString();
const QString rteUpload = settings.value( QStringLiteral( "%1/rteupload" ).arg( baseKey ), QVariant(), section ).toString();
const QString trkDownload = settings.value( QStringLiteral( "%1/trkdownload" ).arg( baseKey ), QVariant(), section ).toString();
const QString trkUpload = settings.value( QStringLiteral( "%1/trkupload" ).arg( baseKey ), QVariant(), section ).toString();

// don't leak memory if there's already a device with this name...
delete mDevices.value( device );

mDevices[device] = new QgsBabelGpsDeviceFormat( wptDownload,
wptUpload,
rteDownload,
rteUpload,
trkDownload,
trkUpload );
mDevices[device] = new QgsBabelGpsDeviceFormat( settingsBabelWptDownload.value( device ), settingsBabelWptUpload.value( device ),
settingsBabelRteDownload.value( device ), settingsBabelRteUpload.value( device ),
settingsBabelTrkDownload.value( device ), settingsBabelTrkUpload.value( device ) );
}
}

14 changes: 14 additions & 0 deletions src/core/gps/qgsbabelformatregistry.h
Expand Up @@ -17,6 +17,7 @@
#define QGSBABELFORMATREGISTRY_H

#include "qgis_core.h"
#include "qgssettingsentryimpl.h"
#include "qgis.h"

class QgsBabelSimpleImportFormat;
Expand All @@ -36,6 +37,19 @@ class CORE_EXPORT QgsBabelFormatRegistry
{
public:

#ifndef SIP_RUN
static const inline QgsSettingsEntryStringList settingsBabelDeviceList = QgsSettingsEntryStringList( QStringLiteral( "babelDeviceList" ), QgsSettings::Prefix::GPS, QStringList() );

static const inline QgsSettingsEntryString settingsBabelWptDownload = QgsSettingsEntryString( QStringLiteral( "babelDevices/%1/wptdownload" ), QgsSettings::Prefix::GPS );
static const inline QgsSettingsEntryString settingsBabelWptUpload = QgsSettingsEntryString( QStringLiteral( "babelDevices/%1/wptupload" ), QgsSettings::Prefix::GPS );
static const inline QgsSettingsEntryString settingsBabelRteDownload = QgsSettingsEntryString( QStringLiteral( "babelDevices/%1/rtedownload" ), QgsSettings::Prefix::GPS );
static const inline QgsSettingsEntryString settingsBabelRteUpload = QgsSettingsEntryString( QStringLiteral( "babelDevices/%1/rteupload" ), QgsSettings::Prefix::GPS );
static const inline QgsSettingsEntryString settingsBabelTrkDownload = QgsSettingsEntryString( QStringLiteral( "babelDevices/%1/trkdownload" ), QgsSettings::Prefix::GPS );
static const inline QgsSettingsEntryString settingsBabelTrkUpload = QgsSettingsEntryString( QStringLiteral( "babelDevices/%1/trkupload" ), QgsSettings::Prefix::GPS );

static const inline QgsSettingsEntryGroup settingsBabelDeviceGroup = QgsSettingsEntryGroup( {&settingsBabelWptDownload, &settingsBabelWptUpload, &settingsBabelRteDownload, &settingsBabelRteUpload, &settingsBabelTrkDownload, &settingsBabelTrkUpload } );
#endif

/**
* Constructor for QgsBabelFormatRegistry.
*
Expand Down
32 changes: 30 additions & 2 deletions src/core/settings/qgssettingsentry.cpp
Expand Up @@ -113,7 +113,12 @@ QString QgsSettingsEntryBase::key( const QString &dynamicKeyPart ) const

QString QgsSettingsEntryBase::key( const QStringList &dynamicKeyPartList ) const
{
QString completeKey = mKey;
return completeKeyPrivate( mKey, dynamicKeyPartList );
}

QString QgsSettingsEntryBase::completeKeyPrivate( const QString &key, const QStringList &dynamicKeyPartList ) const
{
QString completeKey = key;
if ( !mPluginName.isEmpty() )
{
if ( !completeKey.startsWith( '/' ) )
Expand Down Expand Up @@ -280,11 +285,34 @@ QVariant QgsSettingsEntryBase::formerValueAsVariant( const QStringList &dynamicK
{
Q_ASSERT( mOptions.testFlag( Qgis::SettingsOption::SaveFormerValue ) );
QVariant defaultValueOverride = valueAsVariant( key( dynamicKeyPartList ) );
return QgsSettings().value( formerValuekey( dynamicKeyPartList ), defaultValueOverride );
return QgsSettings().value( formerValuekey( dynamicKeyPartList ), defaultValueOverride );
}

bool QgsSettingsEntryBase::migrateFromKey( const QString &oldKey, const QString &oldSection, const QString &dynamicKeyPart ) const
{
return migrateFromKey( oldKey, oldSection, dynamicKeyPartToList( dynamicKeyPart ) );
}

bool QgsSettingsEntryBase::migrateFromKey( const QString &oldKey, const QString &oldSection, const QStringList &dynamicKeyPartList ) const
{
if ( exists( dynamicKeyPartList ) )
return false;

const QString oldCompleteKey = completeKeyPrivate( QStringLiteral( "%1/%2" ).arg( oldSection, oldKey ), dynamicKeyPartList );

if ( QgsSettings().contains( oldCompleteKey ) )
{
QVariant oldValue = QgsSettings().value( oldCompleteKey, mDefaultValue );
setVariantValuePrivate( oldValue );
return true;
}
return false;
}

QString QgsSettingsEntryBase::formerValuekey( const QStringList &dynamicKeyPartList ) const
{
return key( dynamicKeyPartList ) + QStringLiteral( "_formervalue" );
}



17 changes: 17 additions & 0 deletions src/core/settings/qgssettingsentry.h
Expand Up @@ -316,6 +316,19 @@ class CORE_EXPORT QgsSettingsEntryBase
*/
QVariant formerValueAsVariant( const QStringList &dynamicKeyPartList ) const;

/**
* Check if the settings does not exist and try to set it from a given \a oldKey and \a oldSection
* \since QGIS 3.30
*/
bool migrateFromKey( const QString &oldKey, const QString &oldSection = QString(), const QString &dynamicKeyPart = QString() ) const;

/**
* Check if the settings does not exist and try to set it from a given \a oldKey
* \note The old key must contain its section (the section from the current setting will not be prepended)
* \since QGIS 3.30
*/
bool migrateFromKey( const QString &oldKey, const QString &oldSection, const QStringList &dynamicKeyPartList ) const;

protected:

/**
Expand All @@ -328,6 +341,8 @@ class CORE_EXPORT QgsSettingsEntryBase
private:
QString formerValuekey( const QStringList &dynamicKeyPartList ) const;

QString completeKeyPrivate( const QString &key, const QStringList &dynamicKeyPartList ) const;

QString mKey;
QVariant mDefaultValue;
QString mDescription;
Expand Down Expand Up @@ -388,6 +403,7 @@ class QgsSettingsEntryByReference : public QgsSettingsEntryBase

//! Returns the settings value with a \a defaultValueOverride and with an optional \a dynamicKeyPart
T valueWithDefaultOverride( const T &defaultValueOverride, const QString &dynamicKeyPart = QString() ) const { return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPart ) );}

//! Returns the settings value with a \a defaultValueOverride for the \a dynamicKeyPartList
T valueWithDefaultOverride( const T &defaultValueOverride, const QStringList &dynamicKeyPartList ) const { return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPartList ) );}

Expand Down Expand Up @@ -529,6 +545,7 @@ class QgsSettingsEntryByValue : public QgsSettingsEntryBase

//! Returns the settings value with a \a defaultValueOverride and with an optional \a dynamicKeyPart
T valueWithDefaultOverride( T defaultValueOverride, const QString &dynamicKeyPart = QString() ) const { return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPart ) );}

//! Returns the settings value with a \a defaultValueOverride for the \a dynamicKeyPartList
T valueWithDefaultOverride( T defaultValueOverride, const QStringList &dynamicKeyPartList ) const { return this->convertFromVariant( valueAsVariantWithDefaultOverride( defaultValueOverride, dynamicKeyPartList ) );}

Expand Down
6 changes: 5 additions & 1 deletion src/core/settings/qgssettingsregistrycore.cpp
Expand Up @@ -25,12 +25,13 @@
#include "qgsnewsfeedparser.h"
#include "qgsowsconnection.h"
#include "qgsprocessing.h"
#include "qgsvectorlayer.h"
#include "qgsogrdbconnection.h"
#include "qgsfontmanager.h"
#include "qgsgpsconnection.h"
#include "qgsbabelformatregistry.h"
#include "qgsgpslogger.h"


QgsSettingsRegistryCore::QgsSettingsRegistryCore()
: QgsSettingsRegistry()
{
Expand Down Expand Up @@ -131,6 +132,9 @@ QgsSettingsRegistryCore::QgsSettingsRegistryCore()
addSettingsEntry( &QgsGpsConnection::settingsGpsTimeStampTimeZone );
addSettingsEntry( &QgsGpsConnection::settingsGpsTimeStampOffsetFromUtc );

addSettingsEntry( &QgsBabelFormatRegistry::settingsBabelDeviceList );
addSettingsEntryGroup( &QgsBabelFormatRegistry::settingsBabelDeviceGroup );

addSettingsEntry( &QgsGpsLogger::settingsGpsStoreAttributeInMValues );
addSettingsEntry( &QgsGpsLogger::settingsGpsMValueComponent );
}
Expand Down
18 changes: 18 additions & 0 deletions tests/src/python/test_qgssettingsentry.py
Expand Up @@ -412,6 +412,24 @@ def test_settings_entry_group(self):
self.assertFalse(settingsEntryString_1.exists())
self.assertFalse(settingsEntryString_2.exists())

def test_migrate_from_key(self):
settingsNewKey = "settingsEntryMigrationNewKey"
settingsEntryNew = QgsSettingsEntryString(settingsNewKey, self.pluginName)
settingsEntryNew.remove()

settingsOldKey = "settingsEntryMigrationOldKey"
settingsEntryOld = QgsSettingsEntryString(settingsOldKey, self.pluginName)
settingsEntryOld.setValue("value from old key")

self.assertFalse(settingsEntryNew.exists())
self.assertTrue(settingsEntryNew.migrateFromKey(f"plugins/{self.pluginName}/{settingsOldKey}"))
self.assertTrue(settingsEntryNew.exists())

self.assertEqual(settingsEntryNew.value(), settingsEntryOld.value())
settingsEntryNew.setValue("a new value")
self.assertFalse(settingsEntryNew.migrateFromKey(settingsOldKey))
self.assertNotEqual(settingsEntryNew.value(), settingsEntryOld.value())


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

0 comments on commit 6c48145

Please sign in to comment.