Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make handling of processing child algorithm dependencies more flexible
Instead of just using child ID strings, use a new dedicated class to
store dependency information
  • Loading branch information
nyalldawson committed Apr 16, 2020
1 parent 359df3c commit b216759
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 31 deletions.
Expand Up @@ -193,20 +193,18 @@ Sets whether the child algorithm is active.
.. seealso:: :py:func:`isActive`
%End

QStringList dependencies() const;
QList< QgsProcessingModelChildDependency > dependencies() const;
%Docstring
Returns the list of child algorithms from the parent model on which this
algorithm is dependent. The returned list contains the id() of the
dependent algorithms.
algorithm is dependent.

.. seealso:: :py:func:`setDependencies`
%End

void setDependencies( const QStringList &dependencies );
void setDependencies( const QList< QgsProcessingModelChildDependency > &dependencies );
%Docstring
Sets the list of child algorithms from the parent model on which this
algorithm is dependent. The list should contain the id() of the
dependent algorithms.
algorithm is dependent.

.. seealso:: :py:func:`dependencies`
%End
Expand Down
@@ -0,0 +1,65 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/processing/models/qgsprocessingmodelchilddependency.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/






class QgsProcessingModelChildDependency
{
%Docstring
Contains details of a child algorithm dependency.

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsprocessingmodelchilddependency.h"
%End
public:

QgsProcessingModelChildDependency( const QString &childId = QString(), const QString &conditionalBranch = QString() );
%Docstring
Constructor for QgsProcessingModelChildDependency, with the specified ``childId``.
%End

QString childId;

QString conditionalBranch;

QVariant toVariant() const;
%Docstring
Saves this dependency to a QVariant.

.. seealso:: :py:func:`loadVariant`
%End

bool loadVariant( const QVariantMap &map );
%Docstring
Loads this dependency from a QVariantMap.

.. seealso:: :py:func:`toVariant`
%End

bool operator==( const QgsProcessingModelChildDependency &other ) const;

bool operator!=( const QgsProcessingModelChildDependency &other ) const;

bool operator<( const QgsProcessingModelChildDependency &other ) const;
};



/************************************************************************
* This file has been generated automatically from *
* *
* src/core/processing/models/qgsprocessingmodelchilddependency.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -434,6 +434,7 @@
%Include auto_generated/numericformats/qgsscientificnumericformat.sip
%Include auto_generated/processing/models/qgsprocessingmodelalgorithm.sip
%Include auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip
%Include auto_generated/processing/models/qgsprocessingmodelchilddependency.sip
%Include auto_generated/processing/models/qgsprocessingmodelchildparametersource.sip
%Include auto_generated/processing/models/qgsprocessingmodelcomment.sip
%Include auto_generated/processing/models/qgsprocessingmodelcomponent.sip
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -1228,6 +1228,7 @@ SET(QGIS_CORE_HDRS

processing/models/qgsprocessingmodelalgorithm.h
processing/models/qgsprocessingmodelchildalgorithm.h
processing/models/qgsprocessingmodelchilddependency.h
processing/models/qgsprocessingmodelchildparametersource.h
processing/models/qgsprocessingmodelcomment.h
processing/models/qgsprocessingmodelcomponent.h
Expand Down
23 changes: 17 additions & 6 deletions src/core/processing/models/qgsprocessingmodelalgorithm.cpp
Expand Up @@ -1615,7 +1615,18 @@ void QgsProcessingModelAlgorithm::dependentChildAlgorithmsRecursive( const QStri
continue;

// does alg have a direct dependency on this child?
if ( childIt->dependencies().contains( childId ) )
const QList< QgsProcessingModelChildDependency > constDependencies = childIt->dependencies();
bool hasDependency = false;
for ( const QgsProcessingModelChildDependency &dep : constDependencies )
{
if ( dep.childId == childId )
{
hasDependency = true;
break;
}
}

if ( hasDependency )
{
depends.insert( childIt->childId() );
dependentChildAlgorithmsRecursive( childIt->childId(), depends );
Expand Down Expand Up @@ -1664,13 +1675,13 @@ void QgsProcessingModelAlgorithm::dependsOnChildAlgorithmsRecursive( const QStri
const QgsProcessingModelChildAlgorithm &alg = mChildAlgorithms.value( childId );

// add direct dependencies
const auto constDependencies = alg.dependencies();
for ( const QString &c : constDependencies )
const QList< QgsProcessingModelChildDependency > constDependencies = alg.dependencies();
for ( const QgsProcessingModelChildDependency &val : constDependencies )
{
if ( !depends.contains( c ) )
if ( !depends.contains( val.childId ) )
{
depends.insert( c );
dependsOnChildAlgorithmsRecursive( c, depends );
depends.insert( val.childId );
dependsOnChildAlgorithmsRecursive( val.childId, depends );
}
}

Expand Down
1 change: 1 addition & 0 deletions src/core/processing/models/qgsprocessingmodelalgorithm.h
Expand Up @@ -25,6 +25,7 @@
#include "qgsprocessingmodelparameter.h"
#include "qgsprocessingmodelchildparametersource.h"
#include "qgsprocessingmodelgroupbox.h"
#include "qgsprocessingmodelchilddependency.h"

///@cond NOT_STABLE

Expand Down
31 changes: 29 additions & 2 deletions src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp
Expand Up @@ -120,7 +120,13 @@ QVariant QgsProcessingModelChildAlgorithm::toVariant() const
map.insert( QStringLiteral( "alg_id" ), mAlgorithmId );
map.insert( QStringLiteral( "alg_config" ), mConfiguration );
map.insert( QStringLiteral( "active" ), mActive );
map.insert( QStringLiteral( "dependencies" ), mDependencies );

QVariantList dependencies;
for ( const QgsProcessingModelChildDependency &dependency : mDependencies )
{
dependencies << dependency.toVariant();
}
map.insert( QStringLiteral( "dependencies" ), dependencies );

saveCommonProperties( map );

Expand Down Expand Up @@ -157,7 +163,28 @@ bool QgsProcessingModelChildAlgorithm::loadVariant( const QVariant &child )
mConfiguration = map.value( QStringLiteral( "alg_config" ) ).toMap();
setAlgorithmId( map.value( QStringLiteral( "alg_id" ) ).toString() );
mActive = map.value( QStringLiteral( "active" ) ).toBool();
mDependencies = map.value( QStringLiteral( "dependencies" ) ).toStringList();

mDependencies.clear();
if ( map.value( QStringLiteral( "dependencies" ) ).type() == QVariant::StringList )
{
const QStringList dependencies = map.value( QStringLiteral( "dependencies" ) ).toStringList();
for ( const QString &dependency : dependencies )
{
QgsProcessingModelChildDependency dep;
dep.childId = dependency;
mDependencies << dep;
}
}
else
{
const QVariantList dependencies = map.value( QStringLiteral( "dependencies" ) ).toList();
for ( const QVariant &dependency : dependencies )
{
QgsProcessingModelChildDependency dep;
dep.loadVariant( dependency.toMap() );
mDependencies << dep;
}
}

restoreCommonProperties( map );

Expand Down
13 changes: 6 additions & 7 deletions src/core/processing/models/qgsprocessingmodelchildalgorithm.h
Expand Up @@ -24,6 +24,7 @@
#include "qgsprocessingmodelchildparametersource.h"
#include "qgsprocessingmodeloutput.h"
#include "qgsprocessingmodelcomment.h"
#include "qgsprocessingmodelchilddependency.h"
#include <memory>

class QgsProcessingModelAlgorithm;
Expand Down Expand Up @@ -190,19 +191,17 @@ class CORE_EXPORT QgsProcessingModelChildAlgorithm : public QgsProcessingModelCo

/**
* Returns the list of child algorithms from the parent model on which this
* algorithm is dependent. The returned list contains the id() of the
* dependent algorithms.
* algorithm is dependent.
* \see setDependencies()
*/
QStringList dependencies() const { return mDependencies; }
QList< QgsProcessingModelChildDependency > dependencies() const { return mDependencies; }

/**
* Sets the list of child algorithms from the parent model on which this
* algorithm is dependent. The list should contain the id() of the
* dependent algorithms.
* algorithm is dependent.
* \see dependencies()
*/
void setDependencies( const QStringList &dependencies ) { mDependencies = dependencies; }
void setDependencies( const QList< QgsProcessingModelChildDependency > &dependencies ) { mDependencies = dependencies; }

/**
* Returns the map of final model outputs which are generated by this child algorithm.
Expand Down Expand Up @@ -294,7 +293,7 @@ class CORE_EXPORT QgsProcessingModelChildAlgorithm : public QgsProcessingModelCo
bool mActive = true;

//! List of child algorithms from the parent model on which this algorithm is dependent
QStringList mDependencies;
QList< QgsProcessingModelChildDependency > mDependencies;

QgsProcessingModelComment mComment;

Expand Down
95 changes: 95 additions & 0 deletions src/core/processing/models/qgsprocessingmodelchilddependency.h
@@ -0,0 +1,95 @@
/***************************************************************************
qgsprocessingmodelchilddependency.h
-----------------------------
begin : April 2020
copyright : (C) 2020 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSPROCESSINGMODELCHILDDEPENDENCY_H
#define QGSPROCESSINGMODELCHILDDEPENDENCY_H

#include "qgis_core.h"
#include "qgis.h"


///@cond NOT_STABLE

/**
* \class QgsProcessingModelChildDependency
* \ingroup core
* Contains details of a child algorithm dependency.
* \since QGIS 3.14
*/
class CORE_EXPORT QgsProcessingModelChildDependency
{
public:

/**
* Constructor for QgsProcessingModelChildDependency, with the specified \a childId.
*/
QgsProcessingModelChildDependency( const QString &childId = QString(), const QString &conditionalBranch = QString() )
: childId( childId )
, conditionalBranch( conditionalBranch )
{
}

//! Child algorithm ID
QString childId;

//! Conditional branch output name, if applicable.
QString conditionalBranch;

/**
* Saves this dependency to a QVariant.
* \see loadVariant()
*/
QVariant toVariant() const
{
QVariantMap res;
res.insert( QStringLiteral( "child_id" ), childId );
res.insert( QStringLiteral( "conditional_branch" ), conditionalBranch );
return res;
}

/**
* Loads this dependency from a QVariantMap.
* \see toVariant()
*/
bool loadVariant( const QVariantMap &map )
{
childId = map.value( QStringLiteral( "child_id" ) ).toString();
conditionalBranch = map.value( QStringLiteral( "conditional_branch" ) ).toString();
return true;
}

bool operator==( const QgsProcessingModelChildDependency &other ) const
{
return childId == other.childId && conditionalBranch == other.conditionalBranch;
}

bool operator!=( const QgsProcessingModelChildDependency &other ) const
{
return !( *this == other );
}

bool operator<( const QgsProcessingModelChildDependency &other ) const
{
return childId == other.childId ? conditionalBranch < other.conditionalBranch : childId < other.childId;
}
};

Q_DECLARE_METATYPE( QgsProcessingModelChildDependency )

///@endcond

#endif // QGSPROCESSINGMODELCHILDDEPENDENCY_H
3 changes: 3 additions & 0 deletions src/core/qgsapplication.cpp
Expand Up @@ -66,6 +66,7 @@
#include "gps/qgsgpsconnectionregistry.h"
#include "processing/qgsprocessingregistry.h"
#include "processing/models/qgsprocessingmodelchildparametersource.h"
#include "processing/models/qgsprocessingmodelchilddependency.h"

#include "layout/qgspagesizeregistry.h"

Expand Down Expand Up @@ -232,6 +233,8 @@ void QgsApplication::init( QString profileFolder )
qRegisterMetaType<QgsProcessingModelChildParameterSource>( "QgsProcessingModelChildParameterSource" );
qRegisterMetaTypeStreamOperators<QgsProcessingModelChildParameterSource>( "QgsProcessingModelChildParameterSource" );
qRegisterMetaType<QgsRemappingSinkDefinition>( "QgsRemappingSinkDefinition" );
qRegisterMetaType<QgsProcessingModelChildDependency>( "QgsProcessingModelChildDependency" );
QMetaType::registerComparators<QgsProcessingModelChildDependency>();

( void ) resolvePkgPath();

Expand Down
7 changes: 4 additions & 3 deletions src/gui/processing/models/qgsmodelgraphicsscene.cpp
Expand Up @@ -188,10 +188,11 @@ void QgsModelGraphicsScene::createItems( QgsProcessingModelAlgorithm *model, Qgs
else
topIdx++;
}
const QStringList dependencies = it.value().dependencies();
for ( const QString &depend : dependencies )
const QList< QgsProcessingModelChildDependency > dependencies = it.value().dependencies();
for ( const QgsProcessingModelChildDependency &depend : dependencies )
{
addItem( new QgsModelArrowItem( mChildAlgorithmItems.value( depend ), mChildAlgorithmItems.value( it.value().childId() ) ) );
// TODO link to branch
addItem( new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), mChildAlgorithmItems.value( it.value().childId() ) ) );
}
}

Expand Down

0 comments on commit b216759

Please sign in to comment.