Skip to content

Commit

Permalink
Fix loss of output names in graphical modeler
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 23, 2017
1 parent 19dd097 commit 24eb6fd
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 36 deletions.
20 changes: 16 additions & 4 deletions python/core/processing/qgsprocessingmodelalgorithm.sip
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,19 @@ Copies are protected to avoid slicing
Constructor for ModelOutput with the specified ``name`` and ``description``.
%End

QString name() const;
%Docstring
Returns the model output name.
.. seealso:: setName()
:rtype: str
%End

void setName( const QString &name );
%Docstring
Sets the model output ``name``.
.. seealso:: name()
%End

QString childId() const;
%Docstring
Returns the child algorithm ID from which this output is generated.
Expand All @@ -300,14 +313,14 @@ Copies are protected to avoid slicing
.. seealso:: childId()
%End

QString outputName() const;
QString childOutputName() const;
%Docstring
Returns the child algorithm output name from which this output is generated.
.. seealso:: setOutputName()
:rtype: str
%End

void setOutputName( const QString &name );
void setChildOutputName( const QString &name );
%Docstring
Sets the child algorithm output ``name`` from which this output is generated.
.. seealso:: outputName()
Expand Down Expand Up @@ -514,8 +527,7 @@ Copies are protected to avoid slicing
void setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &outputs );
%Docstring
Sets the map of final model ``outputs`` which are generated by this child algorithm.
The keys are the output names from this child algorithm. Only outputs which are
part of the final outputs from the model should be included in this map.
Only outputs which are part of the final outputs from the model should be included in this map.

If child model outputs are altered by this method, QgsProcessingModelAlgorithm.updateDestinationParameters()
must be called on the parent model.
Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/modeler/ModelerGraphicItem.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def __init__(self, element, model, controls, scene=None):
painter = QPainter(self.picture)
svg.render(painter)
self.pixmap = None
self.text = element.description()
self.text = element.name()
else:
self.text = element.description()
self.pixmap = element.algorithm().icon().pixmap(15, 15)
Expand Down Expand Up @@ -374,7 +374,7 @@ def itemChange(self, change, value):
elif isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
self.model.parameterComponent(self.element.parameterName()).setPosition(self.pos())
elif isinstance(self.element, QgsProcessingModelAlgorithm.ModelOutput):
self.model.childAlgorithm(self.element.childId()).modelOutput(self.element.outputName()).setPosition(self.pos())
self.model.childAlgorithm(self.element.childId()).modelOutput(self.element.name()).setPosition(self.pos())

return value

Expand Down
9 changes: 5 additions & 4 deletions python/plugins/processing/modeler/ModelerParametersDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ def setPreviousValues(self):

self.wrappers[param.name()].setValue(value)
for name, out in list(alg.modelOutputs().items()):
self.valueItems[name].setText(out.description())
if out.childOutputName() in self.valueItems:
self.valueItems[out.childOutputName()].setText(out.name())

selected = []
dependencies = self.getAvailableDependencies() # spellok
Expand Down Expand Up @@ -336,10 +337,10 @@ def createAlgorithm(self):
if not dest.flags() & QgsProcessingParameterDefinition.FlagHidden:
name = str(self.valueItems[dest.name()].text())
if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME:
output = QgsProcessingModelAlgorithm.ModelOutput(name)
output = QgsProcessingModelAlgorithm.ModelOutput(name, name)
output.setChildId(alg.childId())
output.setOutputName(dest.name())
outputs[dest.name()] = output
output.setChildOutputName(dest.name())
outputs[name] = output
alg.setModelOutputs(outputs)

selectedOptions = self.dependenciesPanel.selectedoptions
Expand Down
14 changes: 9 additions & 5 deletions src/core/processing/qgsprocessingmodelalgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ void QgsProcessingModelAlgorithm::ChildAlgorithm::setModelOutputs( const QMap<QS
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::iterator outputIt = mModelOutputs.begin();
for ( ; outputIt != mModelOutputs.end(); ++outputIt )
{
// make sure values are consistent
outputIt->setName( outputIt.key() );
outputIt->setChildId( mId );
}
}
Expand Down Expand Up @@ -332,7 +334,7 @@ QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm( const Chil
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::const_iterator outputIt = outputs.constBegin();
for ( ; outputIt != outputs.constEnd(); ++outputIt )
{
if ( outputIt->outputName() == destParam->name() )
if ( outputIt->childOutputName() == destParam->name() )
{
QString paramName = child.childId() + ':' + outputIt.key();
if ( modelParameters.contains( paramName ) )
Expand Down Expand Up @@ -454,7 +456,7 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::const_iterator outputIt = outputs.constBegin();
for ( ; outputIt != outputs.constEnd(); ++outputIt )
{
finalResults.insert( childId + ':' + outputIt->outputName(), results.value( outputIt->outputName() ) );
finalResults.insert( childId + ':' + outputIt->name(), results.value( outputIt->childOutputName() ) );
}

executed.insert( childId );
Expand Down Expand Up @@ -531,12 +533,12 @@ void QgsProcessingModelAlgorithm::updateDestinationParameters()
continue;

// child algorithm has a destination parameter set, copy it to the model
const QgsProcessingParameterDefinition *source = childIt->algorithm()->parameterDefinition( outputIt->outputName() );
const QgsProcessingParameterDefinition *source = childIt->algorithm()->parameterDefinition( outputIt->childOutputName() );
if ( !source )
continue;

QgsProcessingParameterDefinition *param = QgsProcessingParameters::parameterFromVariantMap( source->toVariantMap() );
param->setName( outputIt->childId() + ':' + outputIt->outputName() );
param->setName( outputIt->childId() + ':' + outputIt->name() );
param->setDescription( outputIt->description() );
addParameter( param );

Expand Down Expand Up @@ -971,12 +973,13 @@ bool QgsProcessingModelAlgorithm::ChildParameterSource::loadVariant( const QVari

QgsProcessingModelAlgorithm::ModelOutput::ModelOutput( const QString &name, const QString &description )
: QgsProcessingModelAlgorithm::Component( description )
, mOutputName( name )
, mName( name )
{}

QVariant QgsProcessingModelAlgorithm::ModelOutput::toVariant() const
{
QVariantMap map;
map.insert( QStringLiteral( "name" ), mName );
map.insert( QStringLiteral( "child_id" ), mChildId );
map.insert( QStringLiteral( "output_name" ), mOutputName );
saveCommonProperties( map );
Expand All @@ -985,6 +988,7 @@ QVariant QgsProcessingModelAlgorithm::ModelOutput::toVariant() const

bool QgsProcessingModelAlgorithm::ModelOutput::loadVariant( const QVariantMap &map )
{
mName = map.value( QStringLiteral( "name" ) ).toString();
mChildId = map.value( QStringLiteral( "child_id" ) ).toString();
mOutputName = map.value( QStringLiteral( "output_name" ) ).toString();
restoreCommonProperties( map );
Expand Down
20 changes: 16 additions & 4 deletions src/core/processing/qgsprocessingmodelalgorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
*/
ModelOutput( const QString &name = QString(), const QString &description = QString() );

/**
* Returns the model output name.
* \see setName()
*/
QString name() const { return mName; }

/**
* Sets the model output \a name.
* \see name()
*/
void setName( const QString &name ) { mName = name; }

/**
* Returns the child algorithm ID from which this output is generated.
* \see setChildId()
Expand All @@ -305,13 +317,13 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
* Returns the child algorithm output name from which this output is generated.
* \see setOutputName()
*/
QString outputName() const { return mOutputName; }
QString childOutputName() const { return mOutputName; }

/**
* Sets the child algorithm output \a name from which this output is generated.
* \see outputName()
*/
void setOutputName( const QString &name ) { mOutputName = name; }
void setChildOutputName( const QString &name ) { mOutputName = name; }

/**
* Saves this output to a QVariant.
Expand All @@ -327,6 +339,7 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm

private:

QString mName;
QString mChildId;
QString mOutputName;
};
Expand Down Expand Up @@ -502,8 +515,7 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm

/**
* Sets the map of final model \a outputs which are generated by this child algorithm.
* The keys are the output names from this child algorithm. Only outputs which are
* part of the final outputs from the model should be included in this map.
* Only outputs which are part of the final outputs from the model should be included in this map.
*
* If child model outputs are altered by this method, QgsProcessingModelAlgorithm::updateDestinationParameters()
* must be called on the parent model.
Expand Down
35 changes: 18 additions & 17 deletions tests/src/core/testqgsprocessing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3471,8 +3471,8 @@ void TestQgsProcessing::modelerAlgorithm()
QgsProcessingModelAlgorithm::ModelOutput testModelOut;
testModelOut.setChildId( QStringLiteral( "my_id" ) );
QCOMPARE( testModelOut.childId(), QStringLiteral( "my_id" ) );
testModelOut.setOutputName( QStringLiteral( "my_output" ) );
QCOMPARE( testModelOut.outputName(), QStringLiteral( "my_output" ) );
testModelOut.setChildOutputName( QStringLiteral( "my_output" ) );
QCOMPARE( testModelOut.childOutputName(), QStringLiteral( "my_output" ) );

QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs;
QgsProcessingModelAlgorithm::ModelOutput out1;
Expand Down Expand Up @@ -3817,53 +3817,53 @@ void TestQgsProcessing::modelerAlgorithm()
alg7c1.setChildId( "cx1" );
alg7c1.setAlgorithmId( "native:centroids" );
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c1outputs;
QgsProcessingModelAlgorithm::ModelOutput alg7c1out1;
QgsProcessingModelAlgorithm::ModelOutput alg7c1out1( QStringLiteral( "my_output" ) );
alg7c1out1.setChildId( "cx1" );
alg7c1out1.setOutputName( "OUTPUT_LAYER" );
alg7c1out1.setChildOutputName( "OUTPUT_LAYER" );
alg7c1out1.setDescription( QStringLiteral( "my output" ) );
alg7c1outputs.insert( QStringLiteral( "OUTPUT_LAYER" ), alg7c1out1 );
alg7c1outputs.insert( QStringLiteral( "my_output" ), alg7c1out1 );
alg7c1.setModelOutputs( alg7c1outputs );
alg7.addChildAlgorithm( alg7c1 );
// verify that model has destination parameter created
QCOMPARE( alg7.destinationParameterDefinitions().count(), 1 );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:my_output" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );
QCOMPARE( alg7.outputDefinitions().count(), 1 );
QCOMPARE( alg7.outputDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->name(), QStringLiteral( "cx1:my_output" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->type(), QStringLiteral( "outputVector" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );

QgsProcessingModelAlgorithm::ChildAlgorithm alg7c2;
alg7c2.setChildId( "cx2" );
alg7c2.setAlgorithmId( "native:centroids" );
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg7c2outputs;
QgsProcessingModelAlgorithm::ModelOutput alg7c2out1;
QgsProcessingModelAlgorithm::ModelOutput alg7c2out1( QStringLiteral( "my_output2" ) );
alg7c2out1.setChildId( "cx2" );
alg7c2out1.setOutputName( "OUTPUT_LAYER" );
alg7c2out1.setChildOutputName( "OUTPUT_LAYER" );
alg7c2out1.setDescription( QStringLiteral( "my output2" ) );
alg7c2outputs.insert( QStringLiteral( "OUTPUT_LAYER" ), alg7c2out1 );
alg7c2outputs.insert( QStringLiteral( "my_output2" ), alg7c2out1 );
alg7c2.setModelOutputs( alg7c2outputs );
alg7.addChildAlgorithm( alg7c2 );

QCOMPARE( alg7.destinationParameterDefinitions().count(), 2 );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx1:my_output" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 1 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 1 )->name(), QStringLiteral( "cx2:my_output2" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 1 )->description(), QStringLiteral( "my output2" ) );
QCOMPARE( alg7.outputDefinitions().count(), 2 );
QCOMPARE( alg7.outputDefinitions().at( 0 )->name(), QStringLiteral( "cx1:OUTPUT_LAYER" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->name(), QStringLiteral( "cx1:my_output" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->type(), QStringLiteral( "outputVector" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->description(), QStringLiteral( "my output" ) );
QCOMPARE( alg7.outputDefinitions().at( 1 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
QCOMPARE( alg7.outputDefinitions().at( 1 )->name(), QStringLiteral( "cx2:my_output2" ) );
QCOMPARE( alg7.outputDefinitions().at( 1 )->type(), QStringLiteral( "outputVector" ) );
QCOMPARE( alg7.outputDefinitions().at( 1 )->description(), QStringLiteral( "my output2" ) );

alg7.removeChildAlgorithm( "cx1" );
QCOMPARE( alg7.destinationParameterDefinitions().count(), 1 );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->name(), QStringLiteral( "cx2:my_output2" ) );
QCOMPARE( alg7.destinationParameterDefinitions().at( 0 )->description(), QStringLiteral( "my output2" ) );
QCOMPARE( alg7.outputDefinitions().count(), 1 );
QCOMPARE( alg7.outputDefinitions().at( 0 )->name(), QStringLiteral( "cx2:OUTPUT_LAYER" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->name(), QStringLiteral( "cx2:my_output2" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->type(), QStringLiteral( "outputVector" ) );
QCOMPARE( alg7.outputDefinitions().at( 0 )->description(), QStringLiteral( "my output2" ) );
}
Expand Down Expand Up @@ -3908,7 +3908,8 @@ void TestQgsProcessing::modelExecution()
alg2c1.addParameterSource( "JOIN_STYLE", QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 2 ) );
alg2c1.addParameterSource( "DISSOLVE", QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( false ) );
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs1;
QgsProcessingModelAlgorithm::ModelOutput out1( "OUTPUT_LAYER" );
QgsProcessingModelAlgorithm::ModelOutput out1( "MODEL_OUT_LAYER" );
out1.setChildOutputName( "OUTPUT_LAYER" );
outputs1.insert( QStringLiteral( "MODEL_OUT_LAYER" ), out1 );
alg2c1.setModelOutputs( outputs1 );
model2.addChildAlgorithm( alg2c1 );
Expand Down

0 comments on commit 24eb6fd

Please sign in to comment.