Skip to content

Commit c54667c

Browse files
committed
Handle mixed lists of values and lists when evaluating multilayer
parameters This can happen when running models with mixed input types for multilayer parameters
1 parent e1b0f78 commit c54667c

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

src/core/processing/qgsprocessingparameters.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qgsprocessingoutputs.h"
2323
#include "qgssettings.h"
2424
#include "qgsvectorfilewriter.h"
25+
#include <functional>
2526

2627
bool QgsProcessingParameters::isDynamic( const QVariantMap &parameters, const QString &name )
2728
{
@@ -596,31 +597,36 @@ QList<QgsMapLayer *> QgsProcessingParameters::parameterAsLayerList( const QgsPro
596597

597598
QStringList resultStringList;
598599

599-
if ( val.canConvert<QgsProperty>() )
600-
resultStringList << val.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
601-
else if ( val.type() == QVariant::List )
600+
std::function< void( const QVariant &var ) > processVariant;
601+
processVariant = [ &resultStringList, &layers, &context, &definition, &processVariant ]( const QVariant & var )
602602
{
603-
Q_FOREACH ( const QVariant &var, val.toList() )
603+
if ( var.type() == QVariant::List )
604604
{
605-
if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
605+
Q_FOREACH ( const QVariant &listVar, var.toList() )
606606
{
607-
layers << layer;
607+
processVariant( listVar );
608608
}
609-
else
609+
}
610+
else if ( var.type() == QVariant::StringList )
611+
{
612+
Q_FOREACH ( const QString &s, var.toStringList() )
610613
{
611-
resultStringList << var.toString();
614+
resultStringList << s;
612615
}
613616
}
614-
}
615-
else if ( val.type() == QVariant::StringList )
616-
{
617-
Q_FOREACH ( const QString &s, val.toStringList() )
617+
else if ( var.canConvert<QgsProperty>() )
618+
resultStringList << var.value< QgsProperty >().valueAsString( context.expressionContext(), definition->defaultValue().toString() );
619+
else if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( var ) ) )
618620
{
619-
resultStringList << s;
621+
layers << layer;
620622
}
621-
}
622-
else
623-
resultStringList << val.toString();
623+
else
624+
{
625+
resultStringList << var.toString();
626+
}
627+
};
628+
629+
processVariant( val );
624630

625631
if ( layers.isEmpty() && ( resultStringList.isEmpty() || resultStringList.at( 0 ).isEmpty() ) )
626632
{

tests/src/core/testqgsprocessing.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,8 @@ void TestQgsProcessing::parameterLayerList()
21832183
QFileInfo fi1( raster1 );
21842184
QgsRasterLayer *r1 = new QgsRasterLayer( fi1.filePath(), "R1" );
21852185
QgsVectorLayer *v1 = new QgsVectorLayer( "Polygon?crs=EPSG:3111", "V4", "memory" );
2186-
p.addMapLayers( QList<QgsMapLayer *>() << v1 << r1 );
2186+
QgsVectorLayer *v2 = new QgsVectorLayer( "Polygon?crs=EPSG:3111", "V5", "memory" );
2187+
p.addMapLayers( QList<QgsMapLayer *>() << v1 << v2 << r1 );
21872188
QgsProcessingContext context;
21882189
context.setProject( &p );
21892190

@@ -2225,6 +2226,14 @@ void TestQgsProcessing::parameterLayerList()
22252226
params.insert( "non_optional", QVariantList() << QVariant::fromValue( v1 ) << QVariant::fromValue( r1 ) );
22262227
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << v1 << r1 );
22272228

2229+
// mix of list and single layers (happens from models)
2230+
params.insert( "non_optional", QVariantList() << QVariant( QVariantList() << QVariant::fromValue( v1 ) << QVariant::fromValue( v2 ) ) << QVariant::fromValue( r1 ) );
2231+
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << v1 << v2 << r1 );
2232+
2233+
// mix of two lists (happens from models)
2234+
params.insert( "non_optional", QVariantList() << QVariant( QVariantList() << QVariant::fromValue( v1 ) << QVariant::fromValue( v2 ) ) << QVariant( QVariantList() << QVariant::fromValue( r1 ) ) );
2235+
QCOMPARE( QgsProcessingParameters::parameterAsLayerList( def.get(), params, context ), QList< QgsMapLayer *>() << v1 << v2 << r1 );
2236+
22282237
// mix of existing layers and non project layer string
22292238
params.insert( "non_optional", QVariantList() << v1->id() << raster2 );
22302239
QList< QgsMapLayer *> layers = QgsProcessingParameters::parameterAsLayerList( def.get(), params, context );

0 commit comments

Comments
 (0)