25 QgsProcessingModelChildAlgorithm::QgsProcessingModelChildAlgorithm( 
const QString &algorithmId )
 
   27   setAlgorithmId( algorithmId );
 
   30 QgsProcessingModelChildAlgorithm::QgsProcessingModelChildAlgorithm( 
const QgsProcessingModelChildAlgorithm &other )
 
   31   : QgsProcessingModelComponent( other )
 
   33   , mConfiguration( other.mConfiguration )
 
   34   , mParams( other.mParams )
 
   35   , mModelOutputs( other.mModelOutputs )
 
   36   , mActive( other.mActive )
 
   37   , mDependencies( other.mDependencies )
 
   38   , mComment( other.mComment )
 
   40   setAlgorithmId( other.algorithmId() );
 
   43 QgsProcessingModelChildAlgorithm &QgsProcessingModelChildAlgorithm::operator=( 
const QgsProcessingModelChildAlgorithm &other )
 
   45   QgsProcessingModelComponent::operator =( other );
 
   47   mConfiguration = other.mConfiguration;
 
   48   setAlgorithmId( other.algorithmId() );
 
   49   mParams = other.mParams;
 
   50   mModelOutputs = other.mModelOutputs;
 
   51   mActive = other.mActive;
 
   52   mDependencies = other.mDependencies;
 
   53   mComment = other.mComment;
 
   57 QgsProcessingModelChildAlgorithm *QgsProcessingModelChildAlgorithm::clone()
 const 
   59   return new QgsProcessingModelChildAlgorithm( *
this );
 
   62 void QgsProcessingModelChildAlgorithm::copyNonDefinitionPropertiesFromModel( QgsProcessingModelAlgorithm *model )
 
   64   const QgsProcessingModelChildAlgorithm existingChild = model->childAlgorithm( mId );
 
   65   copyNonDefinitionProperties( existingChild );
 
   68   for ( 
auto it = mModelOutputs.begin(); it != mModelOutputs.end(); ++it )
 
   70     const QMap<QString, QgsProcessingModelOutput> existingChildModelOutputs = existingChild.modelOutputs();
 
   71     auto existingOutputIt = existingChildModelOutputs.find( it.key() );
 
   72     if ( existingOutputIt == existingChildModelOutputs.end() )
 
   75     if ( !existingOutputIt->position().isNull() )
 
   77       it.value().setPosition( existingOutputIt->position() );
 
   78       it.value().setSize( existingOutputIt->size() );
 
   81       it.value().setPosition( position() + QPointF( size().width(), ( i + 1.5 ) * size().height() ) );
 
   83     if ( QgsProcessingModelComment *comment = it.value().comment() )
 
   85       if ( 
const QgsProcessingModelComment *existingComment = existingOutputIt->comment() )
 
   87         comment->setDescription( existingComment->description() );
 
   88         comment->setSize( existingComment->size() );
 
   89         comment->setPosition( existingComment->position() );
 
   90         comment->setColor( existingComment->color() );
 
   99   return mAlgorithm.get();
 
  102 void QgsProcessingModelChildAlgorithm::setModelOutputs( 
const QMap<QString, QgsProcessingModelOutput> &modelOutputs )
 
  104   mModelOutputs = modelOutputs;
 
  106   QMap<QString, QgsProcessingModelOutput>::iterator outputIt = mModelOutputs.begin();
 
  107   for ( ; outputIt != mModelOutputs.end(); ++outputIt )
 
  110     outputIt->setName( outputIt.key() );
 
  111     outputIt->setChildId( mId );
 
  115 bool QgsProcessingModelChildAlgorithm::removeModelOutput( 
const QString &name )
 
  117   mModelOutputs.remove( name );
 
  121 QVariant QgsProcessingModelChildAlgorithm::toVariant()
 const 
  124   map.insert( QStringLiteral( 
"id" ), mId );
 
  125   map.insert( QStringLiteral( 
"alg_id" ), mAlgorithmId );
 
  126   map.insert( QStringLiteral( 
"alg_config" ), mConfiguration );
 
  127   map.insert( QStringLiteral( 
"active" ), mActive );
 
  129   QVariantList dependencies;
 
  130   for ( 
const QgsProcessingModelChildDependency &dependency : mDependencies )
 
  132     dependencies << dependency.toVariant();
 
  134   map.insert( QStringLiteral( 
"dependencies" ), dependencies );
 
  136   saveCommonProperties( map );
 
  138   QVariantMap paramMap;
 
  139   QMap< QString, QgsProcessingModelChildParameterSources >::const_iterator paramIt = mParams.constBegin();
 
  140   for ( ; paramIt != mParams.constEnd(); ++paramIt )
 
  142     QVariantList sources;
 
  143     const auto constValue = paramIt.value();
 
  144     for ( 
const QgsProcessingModelChildParameterSource &source : constValue )
 
  146       sources << source.toVariant();
 
  148     paramMap.insert( paramIt.key(), sources );
 
  150   map.insert( QStringLiteral( 
"params" ), paramMap );
 
  152   QVariantMap outputMap;
 
  153   QMap< QString, QgsProcessingModelOutput >::const_iterator outputIt = mModelOutputs.constBegin();
 
  154   for ( ; outputIt != mModelOutputs.constEnd(); ++outputIt )
 
  156     outputMap.insert( outputIt.key(), outputIt.value().toVariant() );
 
  158   map.insert( QStringLiteral( 
"outputs" ), outputMap );
 
  163 bool QgsProcessingModelChildAlgorithm::loadVariant( 
const QVariant &child )
 
  165   QVariantMap map = child.toMap();
 
  167   mId = map.value( QStringLiteral( 
"id" ) ).toString();
 
  171   mConfiguration = map.value( QStringLiteral( 
"alg_config" ) ).toMap();
 
  172   setAlgorithmId( map.value( QStringLiteral( 
"alg_id" ) ).toString() );
 
  173   if ( algorithmId().isEmpty() )
 
  175   mActive = map.value( QStringLiteral( 
"active" ) ).toBool();
 
  177   mDependencies.clear();
 
  178   if ( map.value( QStringLiteral( 
"dependencies" ) ).type() == QVariant::StringList )
 
  180     const QStringList dependencies = map.value( QStringLiteral( 
"dependencies" ) ).toStringList();
 
  181     for ( 
const QString &dependency : dependencies )
 
  183       QgsProcessingModelChildDependency dep;
 
  184       dep.childId = dependency;
 
  185       mDependencies << dep;
 
  190     const QVariantList dependencies = map.value( QStringLiteral( 
"dependencies" ) ).toList();
 
  191     for ( 
const QVariant &dependency : dependencies )
 
  193       QgsProcessingModelChildDependency dep;
 
  194       dep.loadVariant( dependency.toMap() );
 
  195       mDependencies << dep;
 
  199   restoreCommonProperties( map );
 
  202   QVariantMap paramMap = map.value( QStringLiteral( 
"params" ) ).toMap();
 
  203   QVariantMap::const_iterator paramIt = paramMap.constBegin();
 
  204   for ( ; paramIt != paramMap.constEnd(); ++paramIt )
 
  206     QgsProcessingModelChildParameterSources sources;
 
  207     const auto constToList = paramIt->toList();
 
  208     for ( 
const QVariant &sourceVar : constToList )
 
  210       QgsProcessingModelChildParameterSource param;
 
  211       if ( !param.loadVariant( sourceVar.toMap() ) )
 
  215     mParams.insert( paramIt.key(), sources );
 
  218   mModelOutputs.clear();
 
  219   QVariantMap outputMap = map.value( QStringLiteral( 
"outputs" ) ).toMap();
 
  220   QVariantMap::const_iterator outputIt = outputMap.constBegin();
 
  221   for ( ; outputIt != outputMap.constEnd(); ++outputIt )
 
  223     QgsProcessingModelOutput output;
 
  224     if ( !output.loadVariant( outputIt.value().toMap() ) )
 
  227     mModelOutputs.insert( outputIt.key(), output );
 
  234     int currentIndent, 
int indentSize, 
const QMap<QString, QString> &friendlyChildNames, 
const QMap<QString, QString> &friendlyOutputNames )
 const 
  237   const QString baseIndent = QString( 
' ' ).repeated( currentIndent );
 
  238   const QString lineIndent = QString( 
' ' ).repeated( indentSize );
 
  241     return QStringList();
 
  243   if ( !description().isEmpty() )
 
  244     lines << baseIndent + QStringLiteral( 
"# %1" ).arg( description() );
 
  245   if ( !mComment.description().isEmpty() )
 
  246     lines << baseIndent + QStringLiteral( 
"# %1" ).arg( mComment.description() );
 
  248   QStringList paramParts;
 
  249   QStringList paramComments;
 
  250   for ( 
auto paramIt = mParams.constBegin(); paramIt != mParams.constEnd(); ++paramIt )
 
  252     QStringList sourceParts;
 
  253     QStringList sourceComments;
 
  255     const auto parts = paramIt.value();
 
  256     sourceParts.reserve( parts.size() );
 
  257     sourceComments.reserve( parts.size() );
 
  258     for ( 
const QgsProcessingModelChildParameterSource &source : parts )
 
  260       QString part = source.asPythonCode( outputType, def, friendlyChildNames );
 
  261       if ( !part.isEmpty() )
 
  264         sourceComments << source.asPythonComment( def );
 
  267     if ( sourceParts.count() == 1 )
 
  269       paramParts << QStringLiteral( 
"'%1': %2" ).arg( paramIt.key(), sourceParts.at( 0 ) );
 
  270       paramComments << sourceComments.at( 0 );
 
  274       paramParts << QStringLiteral( 
"'%1': [%2]" ).arg( paramIt.key(), sourceParts.join( 
',' ) );
 
  275       paramComments << QString();
 
  279   lines << baseIndent + QStringLiteral( 
"alg_params = {" );
 
  280   lines.reserve( lines.size() + paramParts.size() );
 
  282   for ( 
const QString &p : std::as_const( paramParts ) )
 
  284     QString line = baseIndent + lineIndent + p + 
',';
 
  285     if ( !paramComments.value( i ).isEmpty() )
 
  287       line += QStringLiteral( 
"  # %1" ).arg( paramComments.value( i ) );
 
  292   for ( 
auto it = extraParameters.constBegin(); it != extraParameters.constEnd(); ++it )
 
  296   if ( lines.constLast().endsWith( 
',' ) )
 
  298     lines[ lines.count() - 1 ].truncate( lines.constLast().length() - 1 );
 
  300   lines << baseIndent + QStringLiteral( 
"}" );
 
  302   lines << baseIndent + QStringLiteral( 
"outputs['%1'] = processing.run('%2', alg_params, context=context, feedback=feedback, is_child_algorithm=True)" ).arg( friendlyChildNames.value( mId, mId ), mAlgorithmId );
 
  304   for ( 
auto outputIt = mModelOutputs.constBegin(); outputIt != mModelOutputs.constEnd(); ++outputIt )
 
  306     QString outputName = QStringLiteral( 
"%1:%2" ).arg( mId, outputIt.key() );
 
  307     outputName = friendlyOutputNames.value( outputName, outputName );
 
  308     lines << baseIndent + QStringLiteral( 
"results['%1'] = outputs['%2']['%3']" ).arg( outputName, friendlyChildNames.value( mId, mId ), outputIt.value().childOutputName() );
 
  314 QVariantMap QgsProcessingModelChildAlgorithm::configuration()
 const 
  316   return mConfiguration;
 
  319 void QgsProcessingModelChildAlgorithm::setConfiguration( 
const QVariantMap &configuration )
 
  321   mConfiguration = configuration;
 
  325 void QgsProcessingModelChildAlgorithm::generateChildId( 
const QgsProcessingModelAlgorithm &model )
 
  331     id = QStringLiteral( 
"%1_%2" ).arg( mAlgorithmId ).arg( i );
 
  332     if ( !model.childAlgorithms().contains( 
id ) )
 
  339 bool QgsProcessingModelChildAlgorithm::setAlgorithmId( 
const QString &algorithmId )
 
  341   mAlgorithmId = algorithmId;
 
  343   return static_cast< bool >( mAlgorithm.get() );
 
  346 bool QgsProcessingModelChildAlgorithm::reattach()
 const 
  348   return const_cast< QgsProcessingModelChildAlgorithm * 
>( this )->setAlgorithmId( mAlgorithmId );