Skip to content

Commit fe0f249

Browse files
committed
Fix generation of destination parameters for models
1 parent c36169a commit fe0f249

File tree

4 files changed

+116
-0
lines changed

4 files changed

+116
-0
lines changed

python/core/processing/qgsprocessingmodelalgorithm.sip

+15
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,10 @@ Copies are protected to avoid slicing
502502
%Docstring
503503
Returns the final model output with matching ``name``. If no output
504504
exists with the name, a new one will be created and returned.
505+
506+
If child model outputs are altered by this method, QgsProcessingModelAlgorithm.updateDestinationParameters()
507+
must be called on the parent model.
508+
505509
.. seealso:: modelOutputs()
506510
.. seealso:: setModelOutputs()
507511
:rtype: QgsProcessingModelAlgorithm.ModelOutput
@@ -512,6 +516,10 @@ Copies are protected to avoid slicing
512516
Sets the map of final model ``outputs`` which are generated by this child algorithm.
513517
The keys are the output names from this child algorithm. Only outputs which are
514518
part of the final outputs from the model should be included in this map.
519+
520+
If child model outputs are altered by this method, QgsProcessingModelAlgorithm.updateDestinationParameters()
521+
must be called on the parent model.
522+
515523
.. seealso:: modelOutputs()
516524
%End
517525

@@ -728,6 +736,13 @@ Copies are protected to avoid slicing
728736
:rtype: QgsProcessingModelAlgorithm.ModelParameter
729737
%End
730738

739+
void updateDestinationParameters();
740+
%Docstring
741+
Updates the model's parameter definitions to include all relevant destination
742+
parameters as required by child algorithm ModelOutputs.
743+
Must be called whenever child algorithm ModelOutputs are altered.
744+
%End
745+
731746
bool toFile( const QString &path ) const;
732747
%Docstring
733748
Writes the model to a file, at the specified ``path``.

src/core/processing/qgsprocessingmodelalgorithm.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,43 @@ QgsProcessingModelAlgorithm::ModelParameter &QgsProcessingModelAlgorithm::parame
327327
return mParameterComponents[ name ];
328328
}
329329

330+
void QgsProcessingModelAlgorithm::updateDestinationParameters()
331+
{
332+
//delete existing destination parameters
333+
QMutableListIterator<const QgsProcessingParameterDefinition *> it( mParameters );
334+
while ( it.hasNext() )
335+
{
336+
const QgsProcessingParameterDefinition *def = it.next();
337+
if ( def->isDestination() )
338+
{
339+
delete def;
340+
it.remove();
341+
}
342+
}
343+
344+
QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
345+
for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
346+
{
347+
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs = childIt->modelOutputs();
348+
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::const_iterator outputIt = outputs.constBegin();
349+
for ( ; outputIt != outputs.constEnd(); ++outputIt )
350+
{
351+
if ( !childIt->isActive() || !childIt->algorithm() )
352+
continue;
353+
354+
// child algorithm has a destination parameter set, copy it to the model
355+
const QgsProcessingParameterDefinition *source = childIt->algorithm()->parameterDefinition( outputIt->outputName() );
356+
if ( !source )
357+
continue;
358+
359+
QgsProcessingParameterDefinition *param = QgsProcessingParameters::parameterFromVariantMap( source->toVariantMap() );
360+
param->setName( outputIt->childId() + ':' + outputIt->outputName() );
361+
param->setDescription( outputIt->description() );
362+
addParameter( param );
363+
}
364+
}
365+
}
366+
330367
QVariant QgsProcessingModelAlgorithm::toVariant() const
331368
{
332369
QVariantMap map;
@@ -403,6 +440,8 @@ bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model )
403440
addParameter( param );
404441
}
405442

443+
updateDestinationParameters();
444+
406445
return true;
407446
}
408447

@@ -443,11 +482,13 @@ bool QgsProcessingModelAlgorithm::fromFile( const QString &path )
443482
void QgsProcessingModelAlgorithm::setChildAlgorithms( const QMap<QString, ChildAlgorithm> &childAlgorithms )
444483
{
445484
mChildAlgorithms = childAlgorithms;
485+
updateDestinationParameters();
446486
}
447487

448488
void QgsProcessingModelAlgorithm::setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm )
449489
{
450490
mChildAlgorithms.insert( algorithm.childId(), algorithm );
491+
updateDestinationParameters();
451492
}
452493

453494
QString QgsProcessingModelAlgorithm::addChildAlgorithm( ChildAlgorithm &algorithm )
@@ -456,6 +497,7 @@ QString QgsProcessingModelAlgorithm::addChildAlgorithm( ChildAlgorithm &algorith
456497
algorithm.generateChildId( *this );
457498

458499
mChildAlgorithms.insert( algorithm.childId(), algorithm );
500+
updateDestinationParameters();
459501
return algorithm.childId();
460502
}
461503

@@ -470,6 +512,7 @@ bool QgsProcessingModelAlgorithm::removeChildAlgorithm( const QString &id )
470512
return false;
471513

472514
mChildAlgorithms.remove( id );
515+
updateDestinationParameters();
473516
return true;
474517
}
475518

@@ -480,6 +523,7 @@ void QgsProcessingModelAlgorithm::deactivateChildAlgorithm( const QString &id )
480523
childAlgorithm( child ).setActive( false );
481524
}
482525
childAlgorithm( id ).setActive( false );
526+
updateDestinationParameters();
483527
}
484528

485529
bool QgsProcessingModelAlgorithm::activateChildAlgorithm( const QString &id )
@@ -490,6 +534,7 @@ bool QgsProcessingModelAlgorithm::activateChildAlgorithm( const QString &id )
490534
return false;
491535
}
492536
childAlgorithm( id ).setActive( true );
537+
updateDestinationParameters();
493538
return true;
494539
}
495540

src/core/processing/qgsprocessingmodelalgorithm.h

+15
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,10 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
491491
/**
492492
* Returns the final model output with matching \a name. If no output
493493
* exists with the name, a new one will be created and returned.
494+
*
495+
* If child model outputs are altered by this method, QgsProcessingModelAlgorithm::updateDestinationParameters()
496+
* must be called on the parent model.
497+
*
494498
* \see modelOutputs()
495499
* \see setModelOutputs()
496500
*/
@@ -500,6 +504,10 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
500504
* Sets the map of final model \a outputs which are generated by this child algorithm.
501505
* The keys are the output names from this child algorithm. Only outputs which are
502506
* part of the final outputs from the model should be included in this map.
507+
*
508+
* If child model outputs are altered by this method, QgsProcessingModelAlgorithm::updateDestinationParameters()
509+
* must be called on the parent model.
510+
*
503511
* \see modelOutputs()
504512
*/
505513
void setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &outputs );
@@ -720,6 +728,13 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
720728
*/
721729
QgsProcessingModelAlgorithm::ModelParameter &parameterComponent( const QString &name );
722730

731+
/**
732+
* Updates the model's parameter definitions to include all relevant destination
733+
* parameters as required by child algorithm ModelOutputs.
734+
* Must be called whenever child algorithm ModelOutputs are altered.
735+
*/
736+
void updateDestinationParameters();
737+
723738
/**
724739
* Writes the model to a file, at the specified \a path.
725740
* \see fromFile()

tests/src/core/testqgsprocessing.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -3752,6 +3752,47 @@ void TestQgsProcessing::modelerAlgorithm()
37523752
QCOMPARE( alg6.parameterDefinitions().count(), 1 );
37533753
QCOMPARE( alg6.parameterDefinitions().at( 0 )->type(), QStringLiteral( "boolean" ) );
37543754

3755+
// destination parameters
3756+
QgsProcessingModelAlgorithm alg7( "test", "testGroup" );
3757+
QgsProcessingModelAlgorithm::ChildAlgorithm alg7c1;
3758+
alg7c1.setChildId( "cx1" );
3759+
alg7c1.setAlgorithmId( "native:centroids" );
3760+
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c1outputs;
3761+
QgsProcessingModelAlgorithm::ModelOutput alg7c1out1;
3762+
alg7c1out1.setChildId( "cx1" );
3763+
alg7c1out1.setOutputName( "OUTPUT_LAYER" );
3764+
alg7c1out1.setDescription( QStringLiteral( "my output" ) );
3765+
alg7c1outputs.insert( QStringLiteral( "OUTPUT_LAYER" ), alg7c1out1 );
3766+
alg7c1.setModelOutputs( alg7c1outputs );
3767+
alg7.addChildAlgorithm( alg7c1 );
3768+
// verify that model has destination parameter created
3769+
QCOMPARE( alg7.destinationParameterDefinitions().count(), 1 );
3770+
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
3771+
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );
3772+
3773+
QgsProcessingModelAlgorithm::ChildAlgorithm alg7c2;
3774+
alg7c2.setChildId( "cx2" );
3775+
alg7c2.setAlgorithmId( "native:centroids" );
3776+
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c2outputs;
3777+
QgsProcessingModelAlgorithm::ModelOutput alg7c2out1;
3778+
alg7c2out1.setChildId( "cx2" );
3779+
alg7c2out1.setOutputName( "OUTPUT_LAYER" );
3780+
alg7c2out1.setDescription( QStringLiteral( "my output2" ) );
3781+
alg7c2outputs.insert( QStringLiteral( "OUTPUT_LAYER" ), alg7c2out1 );
3782+
alg7c2.setModelOutputs( alg7c2outputs );
3783+
alg7.addChildAlgorithm( alg7c2 );
3784+
3785+
QCOMPARE( alg7.destinationParameterDefinitions().count(), 2 );
3786+
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
3787+
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );
3788+
QCOMPARE( alg7.destinationParameterDefinitions().at( 1 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
3789+
QCOMPARE( alg7.destinationParameterDefinitions().at( 1 )->description(), QStringLiteral( "my output2" ) );
3790+
3791+
alg7.removeChildAlgorithm( "cx1" );
3792+
QCOMPARE( alg7.destinationParameterDefinitions().count(), 1 );
3793+
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
3794+
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output2" ) );
3795+
37553796
}
37563797

37573798
QGSTEST_MAIN( TestQgsProcessing )

0 commit comments

Comments
 (0)