Skip to content

Commit

Permalink
save enum settings as string for a better inspection
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed May 14, 2018
1 parent 81dabd1 commit d156e1f
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 7 deletions.
73 changes: 66 additions & 7 deletions src/core/qgssettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "qgis_core.h"
#include "qgis.h"
#include "qgslogger.h"

/**
* \ingroup core
Expand Down Expand Up @@ -224,32 +225,90 @@ class CORE_EXPORT QgsSettings : public QObject
* Return the setting value for a setting based on an enum.
* This forces the output to be a valid and existing entry of the enum.
* Hence if the setting value is incorrect, the given default value is returned.
* This tries first with setting as a string (as the enum) and then as an integer.
* If \a flag is true, the value is checked for a flag definition.
* \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS).
* \see setEnumValue
*/
template <class T>
T enumValue( const QString &key, const T &defaultValue,
const Section section = NoSection, bool flag = false ) const
{
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
if ( !metaEnum.isValid() )
{
QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." );
}

T v;
bool ok = false;
// simple enum
if ( !flag )
v = static_cast<T>( value( key, static_cast<int>( defaultValue ), section ).toInt() );
{
if ( metaEnum.isValid() )
{
QByteArray ba = value( key, metaEnum.valueToKey( defaultValue ) ).toString().toUtf8();
const char *vs = ba.data();
v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
}
if ( !ok )
{
v = static_cast<T>( value( key, static_cast<int>( defaultValue ), section ).toInt( &ok ) );
if ( metaEnum.isValid() && ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) ) )
{
v = defaultValue;
}
}
}
// flags
else
v = T( value( key, static_cast<int>( defaultValue ), section ).toInt() );
{
if ( metaEnum.isValid() )
{
QByteArray ba = value( key, metaEnum.valueToKeys( defaultValue ) ).toString().toUtf8();
const char *vs = ba.data();
v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
}
if ( !ok )
{
v = T( value( key, static_cast<int>( defaultValue ), section ).toInt( &ok ) );
if ( metaEnum.isValid() && ( !ok || !metaEnum.valueToKeys( static_cast<int>( v ) ).size() ) )
{
v = defaultValue;
}
}
}
return v;
}

/**
* Set the value of a setting based on an enum.
* The setting will be saved as string.
* If \a flag is true, the setting is saved as a flag definition.
* \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS).
* \see enumValue
*/
template <class T>
void setEnumValue( const QString &key, const T &value,
const Section section = NoSection, bool flag = false )
{
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
if ( metaEnum.isValid() )
{
if ( !flag && !metaEnum.valueToKey( static_cast<int>( v ) ) )
if ( !flag )
{
v = defaultValue;
setValue( key, metaEnum.valueToKey( value ), section );
}
else if ( flag && !metaEnum.valueToKeys( static_cast<int>( v ) ).size() )
// for a flag
else
{
v = defaultValue;
setValue( key, metaEnum.valueToKeys( value ), section );
}
}
return v;
else
{
QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." );
}
}
#endif

Expand Down
14 changes: 14 additions & 0 deletions tests/src/core/testqgssettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ void TestQgsSettings::enumValue()

// assign to inexisting value
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_units" ), -1 );
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_units_as_string" ), QStringLiteral( "myString" ) );
// just to be sure it really doesn't exist
QVERIFY( static_cast<int>( QgsUnitTypes::LayoutMeters ) != -1 );

Expand All @@ -50,11 +51,18 @@ void TestQgsSettings::enumValue()
// enum method returns default value if current setting is incorrect
QgsUnitTypes::LayoutUnit v2 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters );
QCOMPARE( v2, QgsUnitTypes::LayoutMeters );
QgsUnitTypes::LayoutUnit v2s = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units_as_string" ), QgsUnitTypes::LayoutMeters );
QCOMPARE( v2s, QgsUnitTypes::LayoutMeters );

// test a different value than default
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutCentimeters );
QgsUnitTypes::LayoutUnit v3 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters );
QCOMPARE( v3, QgsUnitTypes::LayoutCentimeters );
settings.setEnumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutCentimeters );
QgsUnitTypes::LayoutUnit v3s = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters );
QCOMPARE( v3s, QgsUnitTypes::LayoutCentimeters );
QString v3ss = settings.value( QStringLiteral( "qgis/testing/my_value_for_units" ), QStringLiteral( "myDummyValue" ) ).toString();
QCOMPARE( v3ss, QStringLiteral( "LayoutCentimeters" ) );

// test for flags
QgsMapLayerProxyModel::Filters pointAndLine = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::LineLayer );
Expand All @@ -66,6 +74,12 @@ void TestQgsSettings::enumValue()
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), static_cast<int>( pointAndPolygon ) );
QgsMapLayerProxyModel::Filters v5 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), pointAndLine, QgsSettings::NoSection, true );
QCOMPARE( v5, pointAndPolygon );

settings.setEnumValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndPolygon, QgsSettings::NoSection, true );
QgsMapLayerProxyModel::Filters v5s = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndLine, QgsSettings::NoSection, true );
QCOMPARE( v5s, pointAndPolygon );
QString v5ss = settings.value( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), QStringLiteral( "myDummyString" ), QgsSettings::NoSection ).toString();
QCOMPARE( v5ss, QStringLiteral( "PointLayer|PolygonLayer" ) );
}


Expand Down

0 comments on commit d156e1f

Please sign in to comment.