Fix loss of output names in graphical modeler

This commit is contained in:
Nyall Dawson 2017-06-23 13:32:31 +10:00
parent 19dd0976d7
commit 24eb6fd780
6 changed files with 66 additions and 36 deletions

View File

@ -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.
@ -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()
@ -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.

View File

@ -66,7 +66,7 @@ class ModelerGraphicItem(QGraphicsItem):
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)
@ -374,7 +374,7 @@ class ModelerGraphicItem(QGraphicsItem):
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

View File

@ -293,7 +293,8 @@ class ModelerParametersDialog(QDialog):
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
@ -336,10 +337,10 @@ class ModelerParametersDialog(QDialog):
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

View File

@ -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 );
}
}
@ -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 ) )
@ -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 );
@ -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 );
@ -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 );
@ -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 );

View File

@ -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()
@ -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.
@ -327,6 +339,7 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
private:
QString mName;
QString mChildId;
QString mOutputName;
};
@ -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.

View File

@ -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;
@ -3817,19 +3817,19 @@ 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" ) );
@ -3837,33 +3837,33 @@ void TestQgsProcessing::modelerAlgorithm()
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" ) );
}
@ -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 );