From 4f05ed1dd7a9b3eb831efcccd5fe9ebe53cb37d7 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 15 Mar 2018 15:11:52 +0100 Subject: [PATCH] [bugfix] value relation widget with Allow multiple selection doesn't resolve Now it will accept arrays as well as string representations of arrays Added a test Fixes #16967 value relation widget with Allow multiple selection doesn't resolve the values anymore --- .../qgsvaluerelationfieldformatter.sip.in | 11 ++++++++++ .../qgsvaluerelationfieldformatter.cpp | 22 ++++++++++++++++++- .../qgsvaluerelationfieldformatter.h | 9 ++++++++ .../qgsvaluerelationwidgetwrapper.cpp | 6 +---- tests/src/python/test_qgsfieldformatters.py | 10 +++++++++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/python/core/fieldformatter/qgsvaluerelationfieldformatter.sip.in b/python/core/fieldformatter/qgsvaluerelationfieldformatter.sip.in index 2c761f352b3..e9a1d00d09a 100644 --- a/python/core/fieldformatter/qgsvaluerelationfieldformatter.sip.in +++ b/python/core/fieldformatter/qgsvaluerelationfieldformatter.sip.in @@ -63,6 +63,17 @@ This can be used to keep the value map in the local memory if doing multiple lookups in a loop. .. versionadded:: 3.0 +%End + + static QStringList valueToStringList( const QVariant &value ); +%Docstring +Utility to convert an array or a string representation of and array ``value`` to a string list + +:param value: The value to be converted + +:return: A string list + +.. versionadded:: 3.2 %End }; diff --git a/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp b/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp index c411fcff7ff..4df6a75c08b 100644 --- a/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp +++ b/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp @@ -54,7 +54,7 @@ QString QgsValueRelationFieldFormatter::representValue( QgsVectorLayer *layer, i if ( config.value( QStringLiteral( "AllowMulti" ) ).toBool() ) { - QStringList keyList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' ); + QStringList keyList = valueToStringList( value ); QStringList valueList; for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( vrCache ) ) @@ -142,3 +142,23 @@ QgsValueRelationFieldFormatter::ValueRelationCache QgsValueRelationFieldFormatte return cache; } + +QStringList QgsValueRelationFieldFormatter::valueToStringList( const QVariant &value ) +{ + QStringList checkList; + if ( value.type() == QVariant::StringList ) + checkList = value.toStringList(); + else if ( value.type() == QVariant::String ) + checkList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' ); + else if ( value.type() == QVariant::List ) + { + QVariantList valuesList( value.toList( ) ); + for ( const QVariant &listItem : qgis::as_const( valuesList ) ) + { + QString v( listItem.toString( ) ); + if ( ! v.isEmpty() ) + checkList.append( v ); + } + } + return checkList; +} diff --git a/src/core/fieldformatter/qgsvaluerelationfieldformatter.h b/src/core/fieldformatter/qgsvaluerelationfieldformatter.h index 7c67f8338cb..9840b09d76d 100644 --- a/src/core/fieldformatter/qgsvaluerelationfieldformatter.h +++ b/src/core/fieldformatter/qgsvaluerelationfieldformatter.h @@ -70,6 +70,15 @@ class CORE_EXPORT QgsValueRelationFieldFormatter : public QgsFieldFormatter * \since QGIS 3.0 */ static QgsValueRelationFieldFormatter::ValueRelationCache createCache( const QVariantMap &config ); + + /** + * Utility to convert an array or a string representation of and array \a value to a string list + * + * \param value The value to be converted + * \return A string list + * \since QGIS 3.2 + */ + static QStringList valueToStringList( const QVariant &value ); }; Q_DECLARE_METATYPE( QgsValueRelationFieldFormatter::ValueRelationCache ) diff --git a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp index 53dec6ebffa..b6f49a50215 100644 --- a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp @@ -151,11 +151,7 @@ void QgsValueRelationWidgetWrapper::setValue( const QVariant &value ) { if ( mListWidget ) { - QStringList checkList; - if ( value.type() == QVariant::StringList ) - checkList = value.toStringList(); - else if ( value.type() == QVariant::String ) - checkList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' ); + QStringList checkList( QgsValueRelationFieldFormatter::valueToStringList( value ) ); for ( int i = 0; i < mListWidget->count(); ++i ) { diff --git a/tests/src/python/test_qgsfieldformatters.py b/tests/src/python/test_qgsfieldformatters.py index b72af0d7fdd..def96b185e1 100644 --- a/tests/src/python/test_qgsfieldformatters.py +++ b/tests/src/python/test_qgsfieldformatters.py @@ -107,6 +107,16 @@ class TestQgsValueRelationFieldFormatter(unittest.TestCase): QgsProject.instance().removeMapLayer(second_layer.id()) + def test_valueToStringList(self): + + def _test(a, b): + self.assertEqual(QgsValueRelationFieldFormatter.valueToStringList(a), b) + + _test([1, 2, 3], ["1", "2", "3"]) + _test("{1,2,3}", ["1", "2", "3"]) + _test(['1', '2', '3'], ["1", "2", "3"]) + _test('not an array', ['not an array']) + class TestQgsRelationReferenceFieldFormatter(unittest.TestCase):