Skip to content

Commit a668362

Browse files
committedMay 14, 2018
add assert on metaEnum and convert existing settings to strings
1 parent d26f1e1 commit a668362

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed
 

‎src/core/qgssettings.h

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,10 @@ class CORE_EXPORT QgsSettings : public QObject
232232
*/
233233
template <class T>
234234
T enumValue( const QString &key, const T &defaultValue,
235-
const Section section = NoSection ) const
235+
const Section section = NoSection )
236236
{
237237
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
238+
Q_ASSERT( metaEnum.isValid() );
238239
if ( !metaEnum.isValid() )
239240
{
240241
QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." );
@@ -245,16 +246,29 @@ class CORE_EXPORT QgsSettings : public QObject
245246

246247
if ( metaEnum.isValid() )
247248
{
249+
// read as string
248250
QByteArray ba = value( key, metaEnum.valueToKey( defaultValue ) ).toString().toUtf8();
249251
const char *vs = ba.data();
250252
v = static_cast<T>( metaEnum.keyToValue( vs, &ok ) );
251253
}
252254
if ( !ok )
253255
{
256+
// if failed, try to read as int (old behavior)
257+
// this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
258+
// then the method could be marked as const
254259
v = static_cast<T>( value( key, static_cast<int>( defaultValue ), section ).toInt( &ok ) );
255-
if ( metaEnum.isValid() && ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) ) )
260+
if ( metaEnum.isValid() )
256261
{
257-
v = defaultValue;
262+
if ( !ok || !metaEnum.valueToKey( static_cast<int>( v ) ) )
263+
{
264+
v = defaultValue;
265+
}
266+
else
267+
{
268+
// found setting as an integer
269+
// convert the setting to the new form (string)
270+
setEnumValue( key, v, section );
271+
}
258272
}
259273
}
260274

@@ -273,6 +287,7 @@ class CORE_EXPORT QgsSettings : public QObject
273287
const Section section = NoSection )
274288
{
275289
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
290+
Q_ASSERT( metaEnum.isValid() );
276291
if ( metaEnum.isValid() )
277292
{
278293
setValue( key, metaEnum.valueToKey( value ), section );
@@ -294,9 +309,10 @@ class CORE_EXPORT QgsSettings : public QObject
294309
*/
295310
template <class T>
296311
T flagValue( const QString &key, const T &defaultValue,
297-
const Section section = NoSection ) const
312+
const Section section = NoSection )
298313
{
299314
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
315+
Q_ASSERT( metaEnum.isValid() );
300316
if ( !metaEnum.isValid() )
301317
{
302318
QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." );
@@ -305,19 +321,31 @@ class CORE_EXPORT QgsSettings : public QObject
305321
T v;
306322
bool ok = false;
307323

308-
309324
if ( metaEnum.isValid() )
310325
{
326+
// read as string
311327
QByteArray ba = value( key, metaEnum.valueToKeys( defaultValue ) ).toString().toUtf8();
312328
const char *vs = ba.data();
313329
v = static_cast<T>( metaEnum.keysToValue( vs, &ok ) );
314330
}
315331
if ( !ok )
316332
{
333+
// if failed, try to read as int (old behavior)
334+
// this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
335+
// then the method could be marked as const
317336
v = T( value( key, static_cast<int>( defaultValue ), section ).toInt( &ok ) );
318-
if ( metaEnum.isValid() && ( !ok || !metaEnum.valueToKeys( static_cast<int>( v ) ).size() ) )
337+
if ( metaEnum.isValid() )
319338
{
320-
v = defaultValue;
339+
if ( !ok || !metaEnum.valueToKeys( static_cast<int>( v ) ).size() )
340+
{
341+
v = defaultValue;
342+
}
343+
else
344+
{
345+
// found setting as an integer
346+
// convert the setting to the new form (string)
347+
setFlagValue( key, v, section );
348+
}
321349
}
322350
}
323351

@@ -336,6 +364,7 @@ class CORE_EXPORT QgsSettings : public QObject
336364
const Section section = NoSection )
337365
{
338366
QMetaEnum metaEnum = QMetaEnum::fromType<T>();
367+
Q_ASSERT( metaEnum.isValid() );
339368
if ( metaEnum.isValid() )
340369
{
341370
setValue( key, metaEnum.valueToKeys( value ), section );

‎tests/src/core/testqgssettings.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class TestQgsSettings : public QObject
3131

3232
private slots:
3333
void enumValue();
34+
void flagValue();
3435
};
3536

3637

@@ -59,12 +60,17 @@ void TestQgsSettings::enumValue()
5960
QgsUnitTypes::LayoutUnit v3 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters );
6061
QCOMPARE( v3, QgsUnitTypes::LayoutCentimeters );
6162
settings.setEnumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutCentimeters );
63+
// auto conversion of old settings (int to str)
64+
QCOMPARE( settings.value( "qgis/testing/my_value_for_units" ), QStringLiteral( "LayoutCentimeters" ) );
6265
QgsUnitTypes::LayoutUnit v3s = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters );
6366
QCOMPARE( v3s, QgsUnitTypes::LayoutCentimeters );
6467
QString v3ss = settings.value( QStringLiteral( "qgis/testing/my_value_for_units" ), QStringLiteral( "myDummyValue" ) ).toString();
6568
QCOMPARE( v3ss, QStringLiteral( "LayoutCentimeters" ) );
69+
}
6670

67-
// test for flags
71+
void TestQgsSettings::flagValue()
72+
{
73+
QgsSettings settings;
6874
QgsMapLayerProxyModel::Filters pointAndLine = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::LineLayer );
6975
QgsMapLayerProxyModel::Filters pointAndPolygon = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::PolygonLayer );
7076
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), 1e8 ); // invalid
@@ -74,6 +80,8 @@ void TestQgsSettings::enumValue()
7480
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), static_cast<int>( pointAndPolygon ) );
7581
QgsMapLayerProxyModel::Filters v5 = settings.flagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), pointAndLine, QgsSettings::NoSection );
7682
QCOMPARE( v5, pointAndPolygon );
83+
// auto conversion of old settings (int to str)
84+
QCOMPARE( settings.value( "qgis/testing/my_value_for_a_flag" ), QStringLiteral( "PointLayer|PolygonLayer" ) );
7785

7886
settings.setFlagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndPolygon, QgsSettings::NoSection );
7987
QgsMapLayerProxyModel::Filters v5s = settings.flagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndLine, QgsSettings::NoSection );

0 commit comments

Comments
 (0)
Please sign in to comment.