Skip to content
Permalink
Browse files

create dedicated function for flags

there is a small redundancy in code, but it makes it much nicer to read the calls:
flagValue( key, default) instead of enumValue( key, default, NoSection, false )
  • Loading branch information
3nids committed Mar 29, 2018
1 parent d156e1f commit dce235d62efa7a5ee616292f80e0467ef732942d
Showing with 83 additions and 48 deletions.
  1. +77 −42 src/core/qgssettings.h
  2. +3 −3 tests/src/app/testqgisappclipboard.cpp
  3. +3 −3 tests/src/core/testqgssettings.cpp
@@ -225,14 +225,14 @@ 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.
* This tries first with setting as a string (as the enum) and then as an integer value.
* \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS).
* \see setEnumValue
* \see flagValue
*/
template <class T>
T enumValue( const QString &key, const T &defaultValue,
const Section section = NoSection, bool flag = false ) const
const Section section = NoSection ) const
{
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
if ( !metaEnum.isValid() )
@@ -242,69 +242,104 @@ class CORE_EXPORT QgsSettings : public QObject

T v;
bool ok = false;
// simple enum
if ( !flag )

if ( metaEnum.isValid() )
{
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;
}
}
QByteArray ba = value( key, metaEnum.valueToKey( defaultValue ) ).toString().toUtf8();
const char *vs = ba.data();
v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
}
// flags
else
if ( !ok )
{
if ( metaEnum.isValid() )
v = static_cast<T>( value( key, static_cast<int>( defaultValue ), section ).toInt( &ok ) );
if ( metaEnum.isValid() && ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) ) )
{
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;
}
v = defaultValue;
}
}

return v;

This comment has been minimized.

Copy link
@elpaso

elpaso Jun 8, 2018

Contributor

@3nids I'm getting a build warning:

/build/QGIS/src/core/qgssettings.h: In member function 'T QgsSettings::enumValue(const QString&, const T&, QgsSettings::Section) [with T = QgsSnappingConfig::SnappingType]':
/build/QGIS/src/core/qgssettings.h:276:14: warning: 'v' may be used uninitialized in this function [-Wmaybe-uninitialized]
       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
* \see setFlagValue
*/
template <class T>
void setEnumValue( const QString &key, const T &value,
const Section section = NoSection, bool flag = false )
const Section section = NoSection )
{
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
if ( metaEnum.isValid() )
{
if ( !flag )
{
setValue( key, metaEnum.valueToKey( value ), section );
}
// for a flag
else
setValue( key, metaEnum.valueToKey( value ), section );
}
else
{
QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." );
}
}

/**
* Return the setting value for a setting based on a flag.
* This forces the output to be a valid and existing entry of the flag.
* Hence if the setting value is incorrect, the given default value is returned.
* This tries first with setting as a string (using a byte array) and then as an integer value.
* \note The flag needs to be declared with Q_FLAG (not Q_FLAGS).
* \see setFlagValue
* \see enumValue
*/
template <class T>
T flagValue( const QString &key, const T &defaultValue,
const Section section = NoSection ) 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;


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() ) )
{
setValue( key, metaEnum.valueToKeys( value ), section );
v = defaultValue;
}
}

return v;
}

/**
* Set the value of a setting based on a flaf.
* The setting will be saved as string.
* \note The flag needs to be declared with Q_FLAG (not Q_FLAGS).
* \see flagValue
* \see setEnumValue
*/
template <class T>
void setFlagValue( const QString &key, const T &value,
const Section section = NoSection )
{
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
if ( metaEnum.isValid() )
{
setValue( key, metaEnum.valueToKeys( value ), section );
}
else
{
QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." );
@@ -140,12 +140,12 @@ void TestQgisAppClipboard::copyToText()

// attributes only
QgsSettings settings;
settings.setValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesOnly );
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesOnly );
QString result = mQgisApp->clipboard()->generateClipboardText();
QCOMPARE( result, QString( "int_field\tstring_field\n9\tval\n19\tval2" ) );

// attributes with WKT
settings.setValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKT );
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKT );
result = mQgisApp->clipboard()->generateClipboardText();
QCOMPARE( result, QString( "wkt_geom\tint_field\tstring_field\nPoint (5 6)\t9\tval\nPoint (7 8)\t19\tval2" ) );

@@ -155,7 +155,7 @@ void TestQgisAppClipboard::copyToText()
QCOMPARE( result, QString( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/></head><body><table border=\"1\"><tr><td>wkt_geom</td><td>int_field</td><td>string_field</td></tr><tr><td>Point (5 6)</td><td>9</td><td>val</td></tr><tr><td>Point (7 8)</td><td>19</td><td>val2</td></tr></table></body></html>" ) );

// GeoJSON
settings.setValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::GeoJSON );
settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::GeoJSON );
result = mQgisApp->clipboard()->generateClipboardText();
QString expected = "{ \"type\": \"FeatureCollection\",\n \"features\":[\n"
"{\n \"type\":\"Feature\",\n"
@@ -72,11 +72,11 @@ void TestQgsSettings::enumValue()
QCOMPARE( v4, pointAndLine );

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 );
QgsMapLayerProxyModel::Filters v5 = settings.flagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), pointAndLine, QgsSettings::NoSection );
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 );
settings.setFlagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndPolygon, QgsSettings::NoSection );
QgsMapLayerProxyModel::Filters v5s = settings.flagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndLine, QgsSettings::NoSection );
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" ) );

0 comments on commit dce235d

Please sign in to comment.
You can’t perform that action at this time.