mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
Begin port of modeler algorithm to c++
This commit is contained in:
parent
efe8bba006
commit
f6358b2118
@ -288,6 +288,7 @@
|
||||
%Include processing/qgsprocessingalgrunnertask.sip
|
||||
%Include processing/qgsprocessingcontext.sip
|
||||
%Include processing/qgsprocessingfeedback.sip
|
||||
%Include processing/qgsprocessingmodelalgorithm.sip
|
||||
%Include processing/qgsprocessingoutputs.sip
|
||||
%Include processing/qgsprocessingparameters.sip
|
||||
%Include processing/qgsprocessingprovider.sip
|
||||
|
@ -276,6 +276,12 @@ class QgsProcessingAlgorithm
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void removeParameter( const QString &name );
|
||||
%Docstring
|
||||
Removes the parameter with matching ``name`` from the algorithm, and deletes any existing
|
||||
definition.
|
||||
%End
|
||||
|
||||
bool addOutput( QgsProcessingOutputDefinition *outputDefinition /Transfer/ );
|
||||
%Docstring
|
||||
Adds an output ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
|
||||
|
617
python/core/processing/qgsprocessingmodelalgorithm.sip
Normal file
617
python/core/processing/qgsprocessingmodelalgorithm.sip
Normal file
@ -0,0 +1,617 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/processing/qgsprocessingmodelalgorithm.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm
|
||||
{
|
||||
%Docstring
|
||||
Model based algorithm with processing.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
class ChildParameterSource
|
||||
{
|
||||
%Docstring
|
||||
Source for the value of a parameter for a child algorithm within a model.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
enum Source
|
||||
{
|
||||
ModelParameter,
|
||||
ChildOutput,
|
||||
StaticValue,
|
||||
};
|
||||
|
||||
ChildParameterSource();
|
||||
%Docstring
|
||||
Constructor for ChildParameterSource. It is recommended that the static methods
|
||||
fromStaticValue(), fromModelParameter() and fromChildOutput() are used instead.
|
||||
%End
|
||||
|
||||
bool operator==( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const;
|
||||
bool operator!=( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const;
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static QgsProcessingModelAlgorithm::ChildParameterSource fromStaticValue( const QVariant &value );
|
||||
%Docstring
|
||||
Returns a new ChildParameterSource which takes its value from a static ``value``.
|
||||
.. seealso:: fromModelParameter()
|
||||
.. seealso:: fromChildOutput()
|
||||
:rtype: QgsProcessingModelAlgorithm.ChildParameterSource
|
||||
%End
|
||||
|
||||
static QgsProcessingModelAlgorithm::ChildParameterSource fromModelParameter( const QString ¶meterName );
|
||||
%Docstring
|
||||
Returns a new ChildParameterSource which takes its value from a parent model parameter.
|
||||
.. seealso:: fromStaticValue()
|
||||
.. seealso:: fromChildOutput()
|
||||
:rtype: QgsProcessingModelAlgorithm.ChildParameterSource
|
||||
%End
|
||||
|
||||
static QgsProcessingModelAlgorithm::ChildParameterSource fromChildOutput( const QString &childId, const QString &outputName );
|
||||
%Docstring
|
||||
Returns a new ChildParameterSource which takes its value from an output generated by a child algorithm.
|
||||
.. seealso:: fromStaticValue()
|
||||
.. seealso:: fromModelParameter()
|
||||
:rtype: QgsProcessingModelAlgorithm.ChildParameterSource
|
||||
%End
|
||||
|
||||
Source source() const;
|
||||
%Docstring
|
||||
Returns the parameter value's source.
|
||||
:rtype: Source
|
||||
%End
|
||||
|
||||
QVariant staticValue() const;
|
||||
%Docstring
|
||||
Returns the source's static value. This is only used when the source() is StaticValue.
|
||||
.. seealso:: setStaticValue()
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
void setStaticValue( const QVariant &value );
|
||||
%Docstring
|
||||
Sets the source's static value. Calling this will also change the source() to StaticValue.
|
||||
.. seealso:: staticValue()
|
||||
%End
|
||||
|
||||
QString parameterName() const;
|
||||
%Docstring
|
||||
Returns the source's model parameter name. This is only used when the source() is ModelParameter.
|
||||
.. seealso:: setParameterName()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setParameterName( const QString &name );
|
||||
%Docstring
|
||||
Sets the source's model parameter ``name``. Calling this will also change the source() to ModelParameter.
|
||||
.. seealso:: parameterName()
|
||||
%End
|
||||
|
||||
QString outputChildId() const;
|
||||
%Docstring
|
||||
Returns the source's child algorithm ID from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||
.. seealso:: setOutputChildId()
|
||||
.. seealso:: outputName()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setOutputChildId( const QString &id );
|
||||
%Docstring
|
||||
Sets the source's child algorithm ``id`` from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||
.. seealso:: parameterName()
|
||||
.. seealso:: setOutputName()
|
||||
%End
|
||||
|
||||
QString outputName() const;
|
||||
%Docstring
|
||||
Returns the source's child algorithm output name from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||
.. seealso:: setOutputName()
|
||||
.. seealso:: outputChildId()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setOutputName( const QString &name );
|
||||
%Docstring
|
||||
Sets the source's child algorithm output ``name`` from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||
.. seealso:: outputName()
|
||||
.. seealso:: setOutputChildId()
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class Component
|
||||
{
|
||||
%Docstring
|
||||
Represents a component of a model algorithm.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QString description() const;
|
||||
%Docstring
|
||||
Returns the friendly description text for the component.
|
||||
.. seealso:: setDescription()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setDescription( const QString &description );
|
||||
%Docstring
|
||||
Sets the friendly ``description`` text for the component.
|
||||
.. seealso:: description()
|
||||
%End
|
||||
|
||||
QPointF position() const;
|
||||
%Docstring
|
||||
Returns the position of the model component within the graphical modeler.
|
||||
.. seealso:: setPosition()
|
||||
:rtype: QPointF
|
||||
%End
|
||||
|
||||
void setPosition( const QPointF &position );
|
||||
%Docstring
|
||||
Sets the ``position`` of the model component within the graphical modeler.
|
||||
.. seealso:: position()
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
Component( const QString &description = QString() );
|
||||
%Docstring
|
||||
Only subclasses can be created
|
||||
%End
|
||||
|
||||
Component( const QgsProcessingModelAlgorithm::Component &other );
|
||||
%Docstring
|
||||
Copies are protected to avoid slicing
|
||||
%End
|
||||
|
||||
|
||||
};
|
||||
|
||||
class ModelParameter : QgsProcessingModelAlgorithm::Component
|
||||
{
|
||||
%Docstring
|
||||
Represents an input parameter used by the model.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
ModelParameter( const QString ¶meterName = QString() );
|
||||
%Docstring
|
||||
Constructor for ModelParameter. The parameter name should match one of the
|
||||
parameters from the parent model.
|
||||
%End
|
||||
|
||||
QString parameterName() const;
|
||||
%Docstring
|
||||
Returns the associated parameter name. The parameter name should match one of the
|
||||
parameters from the parent model.
|
||||
.. seealso:: parameterName()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setParameterName( const QString &name );
|
||||
%Docstring
|
||||
Sets the associated parameter name. The parameter name should match one of the
|
||||
parameters from the parent model.
|
||||
.. seealso:: parameterName()
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ModelOutput : QgsProcessingModelAlgorithm::Component
|
||||
{
|
||||
%Docstring
|
||||
Represents a final output created by the model.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
ModelOutput( const QString &description = QString() );
|
||||
%Docstring
|
||||
Constructor for ModelOutput with the specified ``description``.
|
||||
%End
|
||||
|
||||
QString childId() const;
|
||||
%Docstring
|
||||
Returns the child algorithm ID from which this output is generated.
|
||||
.. seealso:: setChildId()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setChildId( const QString &id );
|
||||
%Docstring
|
||||
Sets the child algorithm ``id`` from which this output is generated.
|
||||
.. seealso:: childId()
|
||||
%End
|
||||
|
||||
QString outputName() const;
|
||||
%Docstring
|
||||
Returns the child algorithm output name from which this output is generated.
|
||||
.. seealso:: setOutputName()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setOutputName( const QString &name );
|
||||
%Docstring
|
||||
Sets the child algorithm output ``name`` from which this output is generated.
|
||||
.. seealso:: outputName()
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class ChildAlgorithm : QgsProcessingModelAlgorithm::Component
|
||||
{
|
||||
%Docstring
|
||||
Child algorithm representing a single component of a QgsProcessingModelAlgorithm.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
ChildAlgorithm( const QString &algorithmId = QString() );
|
||||
%Docstring
|
||||
Constructor for ChildAlgorithm. The ``algorithmId`` parameter
|
||||
should be set to a QgsProcessingAlgorithm algorithm ID.
|
||||
%End
|
||||
|
||||
QString childId() const;
|
||||
%Docstring
|
||||
Returns the child algorithm's unique ID string, used the identify
|
||||
this child algorithm within its parent model.
|
||||
.. seealso:: setChildId()
|
||||
.. seealso:: generateChildId()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setChildId( const QString &id );
|
||||
%Docstring
|
||||
Sets the child algorithm's unique ``id`` string, used the identify
|
||||
this child algorithm within its parent model.
|
||||
.. seealso:: childId()
|
||||
.. seealso:: generateChildId()
|
||||
%End
|
||||
|
||||
void generateChildId( const QgsProcessingModelAlgorithm &model );
|
||||
%Docstring
|
||||
Automatically generates a unique childId() for the algorithm,
|
||||
avoiding child IDs which are already present in ``model``.
|
||||
.. seealso:: childId()
|
||||
.. seealso:: setChildId()
|
||||
%End
|
||||
|
||||
QString algorithmId() const;
|
||||
%Docstring
|
||||
Returns the underlying child algorithm's ID.
|
||||
.. seealso:: algorithm()
|
||||
.. seealso:: setAlgorithmId()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setAlgorithmId( const QString &algorithmId );
|
||||
%Docstring
|
||||
Sets the underlying child algorithm's ID. This
|
||||
should be set to an existing QgsProcessingAlgorithm algorithm ID.
|
||||
.. seealso:: algorithm()
|
||||
.. seealso:: algorithmId()
|
||||
%End
|
||||
|
||||
const QgsProcessingAlgorithm *algorithm() const;
|
||||
%Docstring
|
||||
Returns the underlying child algorithm, or a None
|
||||
if a matching algorithm is not available.
|
||||
.. seealso:: algorithmId()
|
||||
:rtype: QgsProcessingAlgorithm
|
||||
%End
|
||||
|
||||
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > parameterSources() const;
|
||||
%Docstring
|
||||
Returns a map of parameter sources. The keys are the child algorithm
|
||||
parameter names, the values are the source for that parameter.
|
||||
.. seealso:: setParameterSources()
|
||||
.. seealso:: addParameterSource()
|
||||
:rtype: QMap< str, QgsProcessingModelAlgorithm.ChildParameterSource >
|
||||
%End
|
||||
|
||||
void setParameterSources( const QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > &sources );
|
||||
%Docstring
|
||||
Sets the map of parameter ``sources``. The keys are the child algorithm
|
||||
parameter names, the values are the source for that parameter.
|
||||
.. seealso:: parameterSources()
|
||||
.. seealso:: addParameterSource()
|
||||
%End
|
||||
|
||||
void addParameterSource( const QString &name, const QgsProcessingModelAlgorithm::ChildParameterSource &source );
|
||||
%Docstring
|
||||
Adds a parameter source. The ``name`` argument should match
|
||||
one of the child algorithm's parameter names, and the ``source``
|
||||
argument is used to set the source for that parameter.
|
||||
|
||||
Any existing parameter source with matching name will be replaced.
|
||||
.. seealso:: parameterSources()
|
||||
.. seealso:: setParameterSources()
|
||||
%End
|
||||
|
||||
bool isActive() const;
|
||||
%Docstring
|
||||
Returns true if the child algorithm is active.
|
||||
.. seealso:: setActive()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setActive( bool active );
|
||||
%Docstring
|
||||
Sets whether the child algorithm is active.
|
||||
.. seealso:: isActive()
|
||||
%End
|
||||
|
||||
QStringList 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.
|
||||
.. seealso:: setDependencies()
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
void setDependencies( const QStringList &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.
|
||||
.. seealso:: dependencies()
|
||||
%End
|
||||
|
||||
bool parametersCollapsed() const;
|
||||
%Docstring
|
||||
Returns true if the list of parameters for this algorithm should be collapsed
|
||||
in the graphical modeller.
|
||||
.. seealso:: setParametersCollapsed()
|
||||
.. seealso:: outputsCollapsed()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setParametersCollapsed( bool collapsed );
|
||||
%Docstring
|
||||
Sets whether the list of parameters for this algorithm should be collapsed
|
||||
in the graphical modeller.
|
||||
.. seealso:: parametersCollapsed()
|
||||
.. seealso:: setOutputsCollapsed()
|
||||
%End
|
||||
|
||||
bool outputsCollapsed() const;
|
||||
%Docstring
|
||||
Returns true if the list of outputs for this algorithm should be collapsed
|
||||
in the graphical modeller.
|
||||
.. seealso:: setParametersCollapsed()
|
||||
.. seealso:: parametersCollapsed()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setOutputsCollapsed( bool collapsed );
|
||||
%Docstring
|
||||
Sets whether the list of outputs for this algorithm should be collapsed
|
||||
in the graphical modeller.
|
||||
.. seealso:: outputsCollapsed()
|
||||
.. seealso:: setParametersCollapsed()
|
||||
%End
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> modelOutputs() const;
|
||||
%Docstring
|
||||
Returns 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 are included in this map.
|
||||
.. seealso:: setModelOutputs()
|
||||
.. seealso:: modelOutput()
|
||||
:rtype: QMap<str, QgsProcessingModelAlgorithm.ModelOutput>
|
||||
%End
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelOutput &modelOutput( const QString &name );
|
||||
%Docstring
|
||||
Returns the final model output with matching ``name``. If no output
|
||||
exists with the name, a new one will be created and returned.
|
||||
.. seealso:: modelOutputs()
|
||||
.. seealso:: setModelOutputs()
|
||||
:rtype: QgsProcessingModelAlgorithm.ModelOutput
|
||||
%End
|
||||
|
||||
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.
|
||||
.. seealso:: modelOutputs()
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
QgsProcessingModelAlgorithm( const QString &name = QString(), const QString &group = QString() );
|
||||
%Docstring
|
||||
Constructor for QgsProcessingModelAlgorithm.
|
||||
%End
|
||||
|
||||
virtual QString name() const;
|
||||
|
||||
virtual QString displayName() const;
|
||||
|
||||
virtual QString group() const;
|
||||
|
||||
virtual QIcon icon() const;
|
||||
|
||||
virtual QString svgIconPath() const;
|
||||
|
||||
|
||||
virtual bool canExecute( QString *errorMessage /Out/ = 0 ) const;
|
||||
|
||||
virtual QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> childAlgorithms() const;
|
||||
%Docstring
|
||||
Returns the map of child algorithms contained in the model. The keys
|
||||
are the child algorithm ids (see QgsProcessingModelAlgorithm.ChildAlgorithm.childId()).
|
||||
.. seealso:: childAlgorithm()
|
||||
.. seealso:: setChildAlgorithms()
|
||||
.. seealso:: addChildAlgorithm()
|
||||
:rtype: QMap<str, QgsProcessingModelAlgorithm.ChildAlgorithm>
|
||||
%End
|
||||
|
||||
void setChildAlgorithms( const QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> &childAlgorithms );
|
||||
%Docstring
|
||||
Sets the map of child algorithms contained in the model. The keys
|
||||
are the child algorithm ids (see QgsProcessingModelAlgorithm.ChildAlgorithm.childId()).
|
||||
All existing child algorithms will be replaced.
|
||||
.. seealso:: childAlgorithms()
|
||||
.. seealso:: childAlgorithm()
|
||||
.. seealso:: setChildAlgorithm()
|
||||
.. seealso:: addChildAlgorithm()
|
||||
%End
|
||||
|
||||
void setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||
%Docstring
|
||||
Sets the child ``algorithm`` within the model. If a child algorithm already
|
||||
exists in the model with the same child ID then that algorithm will be replaced.
|
||||
.. seealso:: addChildAlgorithm()
|
||||
.. seealso:: setChildAlgorithms()
|
||||
%End
|
||||
|
||||
QString addChildAlgorithm( QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||
%Docstring
|
||||
Adds a new child ``algorithm`` to the model. If a child algorithm already exists
|
||||
in the model with the same child ID then ``algorithm`` will be assigned a new
|
||||
autogenerated unique ID.
|
||||
The assigned child ID will be returned.
|
||||
.. seealso:: childAlgorithms()
|
||||
.. seealso:: childAlgorithm()
|
||||
.. seealso:: setChildAlgorithm()
|
||||
.. seealso:: setChildAlgorithms()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm &childAlgorithm( const QString &id );
|
||||
%Docstring
|
||||
Returns the child algorithm with matching ``id``. If no child algorithm exists with
|
||||
this ID a new algorithm will be added to the model and returned.
|
||||
.. seealso:: addChildAlgorithm()
|
||||
.. seealso:: childAlgorithms()
|
||||
:rtype: QgsProcessingModelAlgorithm.ChildAlgorithm
|
||||
%End
|
||||
|
||||
void addModelParameter( QgsProcessingParameterDefinition *definition /Transfer/, const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||
%Docstring
|
||||
Adds a new parameter to the model, with the specified ``definition`` and graphical ``component``.
|
||||
Ownership of ``definition`` is transferred to the model.
|
||||
.. seealso:: updateModelParameter()
|
||||
.. seealso:: removeModelParameter()
|
||||
%End
|
||||
|
||||
void updateModelParameter( QgsProcessingParameterDefinition *definition /Transfer/ );
|
||||
%Docstring
|
||||
Replaces the definition of an existing parameter (by parameter name) with a new ``definition``. Ownership of
|
||||
``definition`` is transferred to the model, and any existing parameter is deleted.
|
||||
.. seealso:: addModelParameter()
|
||||
.. seealso:: removeModelParameter()
|
||||
%End
|
||||
|
||||
void removeModelParameter( const QString &name );
|
||||
%Docstring
|
||||
Removes an existing model parameter by ``name``. The definition of the matching parameter
|
||||
is deleted.
|
||||
.. seealso:: addModelParameter()
|
||||
.. seealso:: updateModelParameter()
|
||||
%End
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> parameterComponents() const;
|
||||
%Docstring
|
||||
Returns the map of parameter components used by the model. The keys
|
||||
should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||
.. seealso:: setParameterComponent()
|
||||
.. seealso:: parameterComponent()
|
||||
:rtype: QMap<str, QgsProcessingModelAlgorithm.ModelParameter>
|
||||
%End
|
||||
|
||||
void setParameterComponents( const QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> ¶meterComponents );
|
||||
%Docstring
|
||||
Sets the map of parameter components used by the model. The keys
|
||||
should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||
All existing parameter components will be replaced.
|
||||
.. seealso:: parameterComponents()
|
||||
.. seealso:: setParameterComponent()
|
||||
.. seealso:: parameterComponent()
|
||||
%End
|
||||
|
||||
void setParameterComponent( const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||
%Docstring
|
||||
Sets a parameter ``component`` for the model. If a parameter component already
|
||||
exists in the model with the same parameter name then that component will be replaced.
|
||||
.. seealso:: parameterComponents()
|
||||
.. seealso:: setParameterComponents()
|
||||
.. seealso:: parameterComponent()
|
||||
%End
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelParameter ¶meterComponent( const QString &name );
|
||||
%Docstring
|
||||
Returns the parameter component with matching ``name``. If no parameter component exists with
|
||||
this name a new component will be added to the model and returned.
|
||||
.. seealso:: parameterComponents()
|
||||
.. seealso:: setParameterComponents()
|
||||
.. seealso:: setParameterComponent()
|
||||
:rtype: QgsProcessingModelAlgorithm.ModelParameter
|
||||
%End
|
||||
|
||||
|
||||
|
||||
QStringList dependentChildAlgorithms( const QString &childId ) const;
|
||||
%Docstring
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/processing/qgsprocessingmodelalgorithm.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -65,7 +65,8 @@ from qgis.core import (
|
||||
QgsProcessingOutputRasterLayer,
|
||||
QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputString,
|
||||
QgsProcessingOutputNumber)
|
||||
QgsProcessingOutputNumber,
|
||||
QgsProcessingModelAlgorithm)
|
||||
|
||||
from qgis.PyQt.QtWidgets import (
|
||||
QCheckBox,
|
||||
|
@ -36,6 +36,7 @@ from qgis.PyQt.QtCore import QPointF
|
||||
from operator import attrgetter
|
||||
|
||||
from qgis.core import (QgsApplication,
|
||||
QgsProcessingAlgorithm,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsProcessingParameterBoolean,
|
||||
QgsProcessingParameterCrs,
|
||||
@ -53,10 +54,10 @@ from qgis.core import (QgsApplication,
|
||||
QgsProcessingParameterExpression,
|
||||
QgsProcessingParameterTable,
|
||||
QgsProcessingParameterTableField,
|
||||
QgsProcessingParameterFeatureSource)
|
||||
QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingModelAlgorithm)
|
||||
from qgis.gui import QgsMessageBar
|
||||
from qgis.utils import iface
|
||||
from processing.core.GeoAlgorithm import GeoAlgorithm
|
||||
from processing.modeler.WrongModelException import WrongModelException
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
|
||||
@ -65,85 +66,26 @@ from processing.gui.Help2Html import getHtmlFromDescriptionsDict
|
||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||
|
||||
|
||||
class ModelerParameter(object):
|
||||
class Algorithm(QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
|
||||
def __init__(self, param=None, pos=None):
|
||||
self.param = param
|
||||
self.pos = pos
|
||||
|
||||
def todict(self):
|
||||
return self.__dict__
|
||||
|
||||
@staticmethod
|
||||
def fromdict(d):
|
||||
return ModelerParameter(d["param"], d["pos"])
|
||||
|
||||
|
||||
class ModelerOutput(object):
|
||||
|
||||
def __init__(self, description=""):
|
||||
self.description = description
|
||||
self.pos = None
|
||||
|
||||
def todict(self):
|
||||
return self.__dict__
|
||||
|
||||
|
||||
class Algorithm(object):
|
||||
|
||||
def __init__(self, consoleName=""):
|
||||
|
||||
self.name = None
|
||||
self.description = ""
|
||||
|
||||
# The type of the algorithm, indicated as a string, which corresponds
|
||||
# to the string used to refer to it in the python console
|
||||
self.consoleName = consoleName
|
||||
|
||||
self._algInstance = None
|
||||
|
||||
# A dict of Input object. keys are param names
|
||||
self.params = {}
|
||||
|
||||
# A dict of ModelerOutput with final output descriptions. Keys are output names.
|
||||
# Outputs not final are not stored in this dict
|
||||
self.outputs = {}
|
||||
|
||||
self.pos = None
|
||||
|
||||
self.dependencies = []
|
||||
|
||||
self.paramsFolded = True
|
||||
self.outputsFolded = True
|
||||
self.active = True
|
||||
def __init__(self, consoleName=None):
|
||||
super().__init__(consoleName)
|
||||
|
||||
def todict(self):
|
||||
return {k: v for k, v in list(self.__dict__.items()) if not k.startswith("_")}
|
||||
|
||||
@property
|
||||
def algorithm(self):
|
||||
if self._algInstance is None:
|
||||
self._algInstance = QgsApplication.processingRegistry().algorithmById(self.consoleName)
|
||||
return self._algInstance
|
||||
|
||||
def setName(self, model):
|
||||
if self.name is None:
|
||||
i = 1
|
||||
name = self.consoleName + "_" + str(i)
|
||||
while name in model.algs:
|
||||
i += 1
|
||||
name = self.consoleName + "_" + str(i)
|
||||
self.name = name
|
||||
|
||||
def getOutputType(self, outputName):
|
||||
output = self.algorithm.getOutputFromName(outputName)
|
||||
output = self.algorithm().outputDefinition(outputName)
|
||||
return "output " + output.__class__.__name__.split(".")[-1][6:].lower()
|
||||
|
||||
def toPython(self):
|
||||
s = []
|
||||
params = []
|
||||
for param in self.algorithm.parameters:
|
||||
value = self.params[param.name]
|
||||
if not self.algorithm():
|
||||
return None
|
||||
|
||||
for param in self.algorithm().parameterDefinitions():
|
||||
value = self.parameterSources()[param.name()]
|
||||
|
||||
def _toString(v):
|
||||
if isinstance(v, (ValueFromInput, ValueFromOutput)):
|
||||
@ -155,13 +97,13 @@ class Algorithm(object):
|
||||
else:
|
||||
return str(value)
|
||||
params.append(_toString(value))
|
||||
for out in self.algorithm.outputs:
|
||||
for out in self.algorithm().outputs:
|
||||
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
if out.name() in self.outputs:
|
||||
params.append(safeName(self.outputs[out.name()].description()).lower())
|
||||
else:
|
||||
params.append(str(None))
|
||||
s.append("outputs_%s=processing.run('%s', %s)" % (self.name, self.consoleName, ",".join(params)))
|
||||
s.append("outputs_%s=processing.run('%s', %s)" % (self.childId(), self.algorithmId(), ",".join(params)))
|
||||
return s
|
||||
|
||||
|
||||
@ -230,88 +172,31 @@ class CompoundValue(object):
|
||||
return "" # TODO
|
||||
|
||||
|
||||
class ModelerAlgorithm(GeoAlgorithm):
|
||||
class ModelerAlgorithm(QgsProcessingModelAlgorithm):
|
||||
|
||||
CANVAS_SIZE = 4000
|
||||
|
||||
def __init__(self):
|
||||
self._name = self.tr('Model', 'ModelerAlgorithm')
|
||||
super().__init__()
|
||||
|
||||
# The dialog where this model is being edited
|
||||
self.modelerdialog = None
|
||||
self.descriptionFile = None
|
||||
self.helpContent = {}
|
||||
self._group = ''
|
||||
|
||||
# Geoalgorithms in this model. A dict of Algorithm objects, with names as keys
|
||||
self.algs = {}
|
||||
|
||||
# Input parameters. A dict of Input objects, with names as keys
|
||||
self.inputs = {}
|
||||
GeoAlgorithm.__init__(self)
|
||||
|
||||
classes = [c for c in QgsProcessingParameterDefinition.__subclasses__()]
|
||||
self.parameters = []
|
||||
for c in classes:
|
||||
for inp in list(self.inputs.values()):
|
||||
if isinstance(inp.param, c):
|
||||
self.parameters.append(inp.param)
|
||||
for inp in list(self.inputs.values()):
|
||||
if inp.param not in self.parameters:
|
||||
self.parameters.append(inp.param)
|
||||
self.parameters.sort(key=attrgetter("description"))
|
||||
|
||||
self.outputs = []
|
||||
for alg in list(self.algs.values()):
|
||||
if alg.active:
|
||||
for out in alg.outputs:
|
||||
modelOutput = copy.deepcopy(alg.algorithm.getOutputFromName(out))
|
||||
modelOutput.name = self.getSafeNameForOutput(alg.modeler_name, out)
|
||||
modelOutput.description = alg.outputs[out].description()
|
||||
self.outputs.append(modelOutput)
|
||||
self.outputs.sort(key=attrgetter("description"))
|
||||
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
def displayName(self):
|
||||
return self._name
|
||||
|
||||
def group(self):
|
||||
return self._group
|
||||
|
||||
def icon(self):
|
||||
return QgsApplication.getThemeIcon("/processingModel.svg")
|
||||
|
||||
def svgIconPath(self):
|
||||
return QgsApplication.iconPath("processingModel.svg")
|
||||
|
||||
def addParameter(self, param):
|
||||
self.inputs[param.param.name()] = param
|
||||
|
||||
def updateParameter(self, param):
|
||||
self.inputs[param.name()].param = param
|
||||
|
||||
def addAlgorithm(self, alg):
|
||||
name = self.getNameForAlgorithm(alg)
|
||||
alg.modeler_name = name
|
||||
self.algs[name] = alg
|
||||
|
||||
def getNameForAlgorithm(self, alg):
|
||||
i = 1
|
||||
while alg.consoleName.upper().replace(":", "") + "_" + str(i) in list(self.algs.keys()):
|
||||
i += 1
|
||||
return alg.consoleName.upper().replace(":", "") + "_" + str(i)
|
||||
|
||||
def updateAlgorithm(self, alg):
|
||||
alg.pos = self.algs[alg.modeler_name].pos
|
||||
alg.paramsFolded = self.algs[alg.modeler_name].paramsFolded
|
||||
alg.outputsFolded = self.algs[alg.modeler_name].outputsFolded
|
||||
self.algs[alg.modeler_name] = alg
|
||||
alg.setPosition(self.childAlgorithm(alg.childId()).position())
|
||||
alg.setParametersCollapsed(self.childAlgorithm(alg.childId()).parametersCollapsed())
|
||||
alg.setOutputsCollapsed(self.childAlgorithm(alg.childId()).outputsCollapsed())
|
||||
self.setChildAlgorithm(alg)
|
||||
|
||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||
for i, out in enumerate(alg.outputs):
|
||||
alg.outputs[out].pos = (alg.outputs[out].pos or
|
||||
alg.pos + QPointF(
|
||||
for i, out in enumerate(alg.modelOutputs().keys()):
|
||||
alg.modelOutput(out).setPosition(alg.modelOutput(out).position() or
|
||||
alg.position() + QPointF(
|
||||
ModelerGraphicItem.BOX_WIDTH,
|
||||
(i + 1.5) * ModelerGraphicItem.BOX_HEIGHT))
|
||||
|
||||
@ -331,7 +216,7 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
"""
|
||||
if self.hasDependencies(name):
|
||||
return False
|
||||
del self.inputs[name]
|
||||
self.removeModelParameter(name)
|
||||
self.modelerdialog.hasChanged = True
|
||||
return True
|
||||
|
||||
@ -357,8 +242,8 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
elif isinstance(value, ValueFromOutput):
|
||||
if value.alg == name:
|
||||
return True
|
||||
if alg.modeler_name != name:
|
||||
for dep in alg.dependencies:
|
||||
if alg.childId() != name:
|
||||
for dep in alg.dependencies():
|
||||
if (dep == name):
|
||||
return True
|
||||
return False
|
||||
@ -369,7 +254,7 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
"""
|
||||
alg = self.algs[name]
|
||||
algs = set()
|
||||
algs.update(set(alg.dependencies))
|
||||
algs.update(set(alg.dependencies()))
|
||||
for value in list(alg.params.values()):
|
||||
if value is None:
|
||||
continue
|
||||
@ -402,23 +287,14 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
if isinstance(value, list):
|
||||
for v in value:
|
||||
if isinstance(v, ValueFromOutput) and v.alg == name:
|
||||
algs.update(self.getDependentAlgorithms(alg.modeler_name))
|
||||
algs.update(self.getDependentAlgorithms(alg.childId()))
|
||||
elif isinstance(value, ValueFromOutput) and value.alg == name:
|
||||
algs.update(self.getDependentAlgorithms(alg.modeler_name))
|
||||
algs.update(self.getDependentAlgorithms(alg.childId()))
|
||||
|
||||
return algs
|
||||
|
||||
def setPositions(self, paramPos, algPos, outputsPos):
|
||||
for param, pos in list(paramPos.items()):
|
||||
self.inputs[param].pos = pos
|
||||
for alg, pos in list(algPos.items()):
|
||||
self.algs[alg].pos = pos
|
||||
for alg, positions in list(outputsPos.items()):
|
||||
for output, pos in list(positions.items()):
|
||||
self.algs[alg].outputs[output].pos = pos
|
||||
|
||||
def prepareAlgorithm(self, alg):
|
||||
algInstance = alg.algorithm
|
||||
algInstance = alg.algorithm()
|
||||
for param in algInstance.parameterDefinitions():
|
||||
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
if param.name() in alg.params:
|
||||
@ -441,10 +317,11 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
# )
|
||||
# )
|
||||
|
||||
for out in algInstance.outputs:
|
||||
# note to self - these are parameters, not outputs
|
||||
for out in algInstance.outputDefinitions():
|
||||
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
if out.name() in alg.outputs:
|
||||
name = self.getSafeNameForOutput(alg.modeler_name, out.name())
|
||||
name = self.getSafeNameForOutput(alg.childId(), out.name())
|
||||
modelOut = self.getOutputFromName(name)
|
||||
if modelOut:
|
||||
out.value = modelOut.value
|
||||
@ -456,14 +333,14 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
def deactivateAlgorithm(self, algName):
|
||||
dependent = self.getDependentAlgorithms(algName)
|
||||
for alg in dependent:
|
||||
self.algs[alg].active = False
|
||||
self.algs[alg].setActive(False)
|
||||
|
||||
def activateAlgorithm(self, algName):
|
||||
parents = self.getDependsOnAlgorithms(algName)
|
||||
for alg in parents:
|
||||
if not self.algs[alg].active:
|
||||
if not self.childAlgorithm(alg).isActive():
|
||||
return False
|
||||
self.algs[algName].active = True
|
||||
self.childAlgorithm(algName).setActive(True)
|
||||
return True
|
||||
|
||||
def getSafeNameForOutput(self, algName, outName):
|
||||
@ -479,47 +356,47 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
elif isinstance(value, ValueFromInput):
|
||||
v = self.getParameterFromName(value.name).value
|
||||
elif isinstance(value, ValueFromOutput):
|
||||
v = self.algs[value.alg].algorithm.getOutputFromName(value.output).value
|
||||
v = self.algs[value.alg].algorithm().outputDefinition(value.output).value
|
||||
else:
|
||||
v = value
|
||||
return param.evaluateForModeler(v, self)
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
executed = []
|
||||
toExecute = [alg for alg in list(self.algs.values()) if alg.active]
|
||||
toExecute = [alg for alg in list(self.algs.values()) if alg.isActive()]
|
||||
while len(executed) < len(toExecute):
|
||||
for alg in toExecute:
|
||||
if alg.modeler_name not in executed:
|
||||
if alg.childId() not in executed:
|
||||
canExecute = True
|
||||
required = self.getDependsOnAlgorithms(alg.modeler_name)
|
||||
required = self.getDependsOnAlgorithms(alg.childId())
|
||||
for requiredAlg in required:
|
||||
if requiredAlg != alg.modeler_name and requiredAlg not in executed:
|
||||
if requiredAlg != alg.childId() and requiredAlg not in executed:
|
||||
canExecute = False
|
||||
break
|
||||
if canExecute:
|
||||
try:
|
||||
feedback.pushDebugInfo(
|
||||
self.tr('Prepare algorithm: {0}', 'ModelerAlgorithm').format(alg.modeler_name))
|
||||
self.tr('Prepare algorithm: {0}', 'ModelerAlgorithm').format(alg.childId()))
|
||||
self.prepareAlgorithm(alg)
|
||||
feedback.setProgressText(
|
||||
self.tr('Running {0} [{1}/{2}]', 'ModelerAlgorithm').format(alg.description, len(executed) + 1, len(toExecute)))
|
||||
feedback.pushDebugInfo('Parameters: ' + ', '.join([str(p).strip() +
|
||||
'=' + str(p.value) for p in alg.algorithm.parameters]))
|
||||
t0 = time.time()
|
||||
alg.algorithm.execute(parameters, context, feedback)
|
||||
alg.algorithm().execute(parameters, context, feedback)
|
||||
dt = time.time() - t0
|
||||
|
||||
# copy algorithm output value(s) back to model in case the algorithm modified those
|
||||
for out in alg.algorithm.outputs:
|
||||
for out in alg.algorithm().outputs:
|
||||
if not out.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
if out.name() in alg.outputs:
|
||||
modelOut = self.getOutputFromName(self.getSafeNameForOutput(alg.modeler_name, out.name()))
|
||||
if out.name() in alg.modelOutputs():
|
||||
modelOut = self.getOutputFromName(self.getSafeNameForOutput(alg.childId(), out.name()))
|
||||
if modelOut:
|
||||
modelOut.value = out.value
|
||||
|
||||
executed.append(alg.modeler_name)
|
||||
executed.append(alg.childId())
|
||||
feedback.pushDebugInfo(
|
||||
self.tr('OK. Execution took %{0:.3f} ms ({1} outputs).', 'ModelerAlgorithm').format(dt, len(alg.algorithm.outputs)))
|
||||
self.tr('OK. Execution took %{0:.3f} ms ({1} outputs).', 'ModelerAlgorithm').format(dt, len(alg.algorithm.modelOutputs())))
|
||||
except GeoAlgorithmExecutionException as e:
|
||||
feedback.pushDebugInfo(self.tr('Failed', 'ModelerAlgorithm'))
|
||||
raise GeoAlgorithmExecutionException(
|
||||
@ -534,13 +411,6 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
else:
|
||||
return None
|
||||
|
||||
def canExecute(self):
|
||||
for alg in list(self.algs.values()):
|
||||
algInstance = QgsApplication.processingRegistry().algorithmById(alg.consoleName)
|
||||
if algInstance is None:
|
||||
return False, self.tr("The model you are trying to run contains an algorithm that is not available: <i>{0}</i>").format(alg.consoleName)
|
||||
return True, None
|
||||
|
||||
def setModelerView(self, dialog):
|
||||
self.modelerdialog = dialog
|
||||
|
||||
@ -642,26 +512,26 @@ class ModelerAlgorithm(GeoAlgorithm):
|
||||
|
||||
def toPython(self):
|
||||
s = ['##%s=name' % self.name()]
|
||||
for param in list(self.inputs.values()):
|
||||
for param in list(self.parameterComponents().values()):
|
||||
s.append(param.param.getAsScriptCode())
|
||||
for alg in list(self.algs.values()):
|
||||
for name, out in list(alg.outputs.items()):
|
||||
for name, out in list(alg.modelOutputs().items()):
|
||||
s.append('##%s=%s' % (safeName(out.description()).lower(), alg.getOutputType(name)))
|
||||
|
||||
executed = []
|
||||
toExecute = [alg for alg in list(self.algs.values()) if alg.active]
|
||||
toExecute = [alg for alg in list(self.algs.values()) if alg.isActive()]
|
||||
while len(executed) < len(toExecute):
|
||||
for alg in toExecute:
|
||||
if alg.modeler_name not in executed:
|
||||
if alg.childId() not in executed:
|
||||
canExecute = True
|
||||
required = self.getDependsOnAlgorithms(alg.modeler_name)
|
||||
required = self.getDependsOnAlgorithms(alg.childId())
|
||||
for requiredAlg in required:
|
||||
if requiredAlg != alg.modeler_name and requiredAlg not in executed:
|
||||
if requiredAlg != alg.childId() and requiredAlg not in executed:
|
||||
canExecute = False
|
||||
break
|
||||
if canExecute:
|
||||
s.extend(alg.toPython())
|
||||
executed.append(alg.modeler_name)
|
||||
executed.append(alg.childId())
|
||||
|
||||
return '\n'.join(s)
|
||||
|
||||
|
@ -46,11 +46,11 @@
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
from qgis.core import QgsProcessingModelAlgorithm
|
||||
from qgis.PyQt.QtCore import Qt, QPointF
|
||||
from qgis.PyQt.QtWidgets import QGraphicsPathItem, QGraphicsItem
|
||||
from qgis.PyQt.QtGui import QPen, QPainterPath, QPolygonF, QPainter
|
||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||
from processing.modeler.ModelerAlgorithm import Algorithm
|
||||
|
||||
|
||||
class ModelerArrowItem(QGraphicsPathItem):
|
||||
@ -75,7 +75,7 @@ class ModelerArrowItem(QGraphicsPathItem):
|
||||
controlPoints = []
|
||||
endPt = self.endItem.getLinkPointForParameter(self.endIndex)
|
||||
startPt = self.startItem.getLinkPointForOutput(self.startIndex)
|
||||
if isinstance(self.startItem.element, Algorithm):
|
||||
if isinstance(self.startItem.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
if self.startIndex != -1:
|
||||
controlPoints.append(self.startItem.pos() + startPt)
|
||||
controlPoints.append(self.startItem.pos() + startPt +
|
||||
|
@ -29,6 +29,7 @@ __revision__ = '$Format:%H$'
|
||||
import codecs
|
||||
import sys
|
||||
import os
|
||||
import math
|
||||
|
||||
from qgis.PyQt import uic
|
||||
from qgis.PyQt.QtCore import Qt, QRectF, QMimeData, QPoint, QPointF, QByteArray, QSize, QSizeF, pyqtSignal
|
||||
@ -40,12 +41,13 @@ from qgis.core import (QgsApplication,
|
||||
QgsProcessingAlgorithm,
|
||||
QgsSettings,
|
||||
QgsMessageLog,
|
||||
QgsProcessingUtils)
|
||||
QgsProcessingUtils,
|
||||
QgsProcessingModelAlgorithm)
|
||||
from qgis.gui import QgsMessageBar
|
||||
from processing.gui.HelpEditionDialog import HelpEditionDialog
|
||||
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||
from processing.modeler.ModelerAlgorithm import ModelerAlgorithm, ModelerParameter
|
||||
from processing.modeler.ModelerAlgorithm import ModelerAlgorithm
|
||||
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||
from processing.modeler.ModelerUtils import ModelerUtils
|
||||
from processing.modeler.ModelerScene import ModelerScene
|
||||
@ -62,7 +64,7 @@ class ModelerDialog(BASE, WIDGET):
|
||||
|
||||
update_model = pyqtSignal()
|
||||
|
||||
def __init__(self, alg=None):
|
||||
def __init__(self, model=None):
|
||||
super(ModelerDialog, self).__init__(None)
|
||||
self.setupUi(self)
|
||||
|
||||
@ -128,6 +130,11 @@ class ModelerDialog(BASE, WIDGET):
|
||||
|
||||
settings = QgsSettings()
|
||||
factor = settings.value('/qgis/zoom_favor', 2.0)
|
||||
|
||||
# "Normal" mouse has an angle delta of 120, precision mouses provide data
|
||||
# faster, in smaller steps
|
||||
factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y())
|
||||
|
||||
if (event.modifiers() == Qt.ControlModifier):
|
||||
factor = 1.0 + (factor - 1.0) / 20.0
|
||||
|
||||
@ -135,7 +142,6 @@ class ModelerDialog(BASE, WIDGET):
|
||||
factor = 1 / factor
|
||||
|
||||
self.view.scale(factor, factor)
|
||||
self.repaintModel()
|
||||
|
||||
def _enterEvent(e):
|
||||
QGraphicsView.enterEvent(self.view, e)
|
||||
@ -228,21 +234,21 @@ class ModelerDialog(BASE, WIDGET):
|
||||
self.mActionEditHelp.triggered.connect(self.editHelp)
|
||||
self.mActionRun.triggered.connect(self.runModel)
|
||||
|
||||
if alg is not None:
|
||||
self.alg = alg
|
||||
self.textGroup.setText(alg._group)
|
||||
self.textName.setText(alg.displayName())
|
||||
if model is not None:
|
||||
self.model = model
|
||||
self.textGroup.setText(model.group())
|
||||
self.textName.setText(model.displayName())
|
||||
self.repaintModel()
|
||||
|
||||
else:
|
||||
self.alg = ModelerAlgorithm()
|
||||
self.alg.modelerdialog = self
|
||||
self.model = ModelerAlgorithm()
|
||||
self.model.modelerdialog = self
|
||||
|
||||
self.fillInputsTree()
|
||||
self.fillAlgorithmTree()
|
||||
|
||||
self.view.centerOn(0, 0)
|
||||
self.alg.setModelerView(self)
|
||||
self.model.setModelerView(self)
|
||||
self.help = None
|
||||
|
||||
self.hasChanged = False
|
||||
@ -269,19 +275,19 @@ class ModelerDialog(BASE, WIDGET):
|
||||
evt.accept()
|
||||
|
||||
def editHelp(self):
|
||||
alg = self.alg
|
||||
alg = self.model
|
||||
dlg = HelpEditionDialog(alg)
|
||||
dlg.exec_()
|
||||
if dlg.descriptions:
|
||||
self.alg.helpContent = dlg.descriptions
|
||||
self.model.helpContent = dlg.descriptions
|
||||
self.hasChanged = True
|
||||
|
||||
def runModel(self):
|
||||
if len(self.alg.algs) == 0:
|
||||
if len(self.model.childAlgorithms()) == 0:
|
||||
self.bar.pushMessage("", "Model doesn't contain any algorithm and/or parameter and can't be executed", level=QgsMessageBar.WARNING, duration=5)
|
||||
return
|
||||
|
||||
dlg = AlgorithmDialog(self.alg)
|
||||
dlg = AlgorithmDialog(self.model)
|
||||
dlg.exec_()
|
||||
|
||||
def save(self):
|
||||
@ -399,7 +405,7 @@ class ModelerDialog(BASE, WIDGET):
|
||||
svg.setFileName(filename)
|
||||
svg.setSize(QSize(totalRect.width(), totalRect.height()))
|
||||
svg.setViewBox(svgRect)
|
||||
svg.setTitle(self.alg.displayName())
|
||||
svg.setTitle(self.model.displayName())
|
||||
|
||||
painter = QPainter(svg)
|
||||
self.scene.render(painter, svgRect, totalRect)
|
||||
@ -418,7 +424,7 @@ class ModelerDialog(BASE, WIDGET):
|
||||
if not filename.lower().endswith('.py'):
|
||||
filename += '.py'
|
||||
|
||||
text = self.alg.toPython()
|
||||
text = self.model.toPython()
|
||||
with codecs.open(filename, 'w', encoding='utf-8') as fout:
|
||||
fout.write(text)
|
||||
|
||||
@ -431,10 +437,10 @@ class ModelerDialog(BASE, WIDGET):
|
||||
self, self.tr('Warning'), self.tr('Please enter group and model names before saving')
|
||||
)
|
||||
return
|
||||
self.alg._name = str(self.textName.text())
|
||||
self.alg._group = str(self.textGroup.text())
|
||||
if self.alg.descriptionFile is not None and not saveAs:
|
||||
filename = self.alg.descriptionFile
|
||||
self.model._name = str(self.textName.text())
|
||||
self.model._group = str(self.textGroup.text())
|
||||
if self.model.descriptionFile is not None and not saveAs:
|
||||
filename = self.model.descriptionFile
|
||||
else:
|
||||
filename, filter = QFileDialog.getSaveFileName(self,
|
||||
self.tr('Save Model'),
|
||||
@ -443,9 +449,9 @@ class ModelerDialog(BASE, WIDGET):
|
||||
if filename:
|
||||
if not filename.endswith('.model'):
|
||||
filename += '.model'
|
||||
self.alg.descriptionFile = filename
|
||||
self.model.descriptionFile = filename
|
||||
if filename:
|
||||
text = self.alg.toJson()
|
||||
text = self.model.toJson()
|
||||
try:
|
||||
with codecs.open(filename, 'w', encoding='utf-8') as fout:
|
||||
fout.write(text)
|
||||
@ -473,8 +479,8 @@ class ModelerDialog(BASE, WIDGET):
|
||||
if filename:
|
||||
try:
|
||||
alg = ModelerAlgorithm.fromFile(filename)
|
||||
self.alg = alg
|
||||
self.alg.setModelerView(self)
|
||||
self.model = alg
|
||||
self.model.setModelerView(self)
|
||||
self.textGroup.setText(alg._group)
|
||||
self.textName.setText(alg._name)
|
||||
self.repaintModel()
|
||||
@ -499,7 +505,7 @@ class ModelerDialog(BASE, WIDGET):
|
||||
self.scene = ModelerScene()
|
||||
self.scene.setSceneRect(QRectF(0, 0, ModelerAlgorithm.CANVAS_SIZE,
|
||||
ModelerAlgorithm.CANVAS_SIZE))
|
||||
self.scene.paintModel(self.alg, controls)
|
||||
self.scene.paintModel(self.model, controls)
|
||||
self.view.setScene(self.scene)
|
||||
|
||||
def addInput(self):
|
||||
@ -509,14 +515,16 @@ class ModelerDialog(BASE, WIDGET):
|
||||
|
||||
def addInputOfType(self, paramType, pos=None):
|
||||
if paramType in ModelerParameterDefinitionDialog.paramTypes:
|
||||
dlg = ModelerParameterDefinitionDialog(self.alg, paramType)
|
||||
dlg = ModelerParameterDefinitionDialog(self.model, paramType)
|
||||
dlg.exec_()
|
||||
if dlg.param is not None:
|
||||
if pos is None:
|
||||
pos = self.getPositionForParameterItem()
|
||||
if isinstance(pos, QPoint):
|
||||
pos = QPointF(pos)
|
||||
self.alg.addParameter(ModelerParameter(dlg.param, pos))
|
||||
component = QgsProcessingModelAlgorithm.ModelParameter(dlg.param.name())
|
||||
component.setPosition(pos)
|
||||
self.model.addModelParameter(dlg.param, component)
|
||||
self.repaintModel()
|
||||
# self.view.ensureVisible(self.scene.getLastParameterItem())
|
||||
self.hasChanged = True
|
||||
@ -525,8 +533,8 @@ class ModelerDialog(BASE, WIDGET):
|
||||
MARGIN = 20
|
||||
BOX_WIDTH = 200
|
||||
BOX_HEIGHT = 80
|
||||
if self.alg.inputs:
|
||||
maxX = max([i.pos.x() for i in list(self.alg.inputs.values())])
|
||||
if len(self.model.parameterComponents() > 0):
|
||||
maxX = max([i.position().x() for i in list(self.model.parameterComponents().values())])
|
||||
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
||||
else:
|
||||
newX = MARGIN + BOX_WIDTH / 2
|
||||
@ -554,24 +562,22 @@ class ModelerDialog(BASE, WIDGET):
|
||||
def _addAlgorithm(self, alg, pos=None):
|
||||
dlg = None
|
||||
try:
|
||||
dlg = alg.getCustomModelerParametersDialog(self.alg)
|
||||
dlg = alg.getCustomModelerParametersDialog(self.model)
|
||||
except:
|
||||
pass
|
||||
if not dlg:
|
||||
dlg = ModelerParametersDialog(alg, self.alg)
|
||||
dlg = ModelerParametersDialog(alg, self.model)
|
||||
dlg.exec_()
|
||||
if dlg.alg is not None:
|
||||
if pos is None:
|
||||
dlg.alg.pos = self.getPositionForAlgorithmItem()
|
||||
dlg.alg.setPosition(self.getPositionForAlgorithmItem())
|
||||
else:
|
||||
dlg.alg.pos = pos
|
||||
if isinstance(dlg.alg.pos, QPoint):
|
||||
dlg.alg.pos = QPointF(pos)
|
||||
dlg.alg.setPosition(pos)
|
||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||
for i, out in enumerate(dlg.alg.outputs):
|
||||
dlg.alg.outputs[out].pos = dlg.alg.pos + QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
|
||||
ModelerGraphicItem.BOX_HEIGHT)
|
||||
self.alg.addAlgorithm(dlg.alg)
|
||||
for i, out in enumerate(dlg.alg.modelOutputs()):
|
||||
dlg.alg.modelOutput(out).setPosition(dlg.alg.position() + QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
|
||||
ModelerGraphicItem.BOX_HEIGHT))
|
||||
self.model.addChildAlgorithm(dlg.alg)
|
||||
self.repaintModel()
|
||||
self.hasChanged = True
|
||||
|
||||
@ -579,9 +585,9 @@ class ModelerDialog(BASE, WIDGET):
|
||||
MARGIN = 20
|
||||
BOX_WIDTH = 200
|
||||
BOX_HEIGHT = 80
|
||||
if self.alg.algs:
|
||||
maxX = max([alg.pos.x() for alg in list(self.alg.algs.values())])
|
||||
maxY = max([alg.pos.y() for alg in list(self.alg.algs.values())])
|
||||
if self.model.childAlgorithms():
|
||||
maxX = max([alg.position().x() for alg in list(self.model.childAlgorithms().values())])
|
||||
maxY = max([alg.position().y() for alg in list(self.model.childAlgorithms().values())])
|
||||
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
||||
newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE -
|
||||
BOX_HEIGHT)
|
||||
@ -611,7 +617,7 @@ class ModelerDialog(BASE, WIDGET):
|
||||
for alg in provider.algorithms():
|
||||
if alg.flags() & QgsProcessingAlgorithm.FlagHideFromModeler:
|
||||
continue
|
||||
if alg.id() == self.alg.id():
|
||||
if alg.id() == self.model.id():
|
||||
continue
|
||||
|
||||
item_text = [alg.displayName().lower()]
|
||||
|
@ -33,8 +33,8 @@ from qgis.PyQt.QtCore import Qt, QPointF, QRectF
|
||||
from qgis.PyQt.QtGui import QFont, QFontMetricsF, QPen, QBrush, QColor, QPolygonF, QPicture, QPainter
|
||||
from qgis.PyQt.QtWidgets import QGraphicsItem, QMessageBox, QMenu
|
||||
from qgis.PyQt.QtSvg import QSvgRenderer
|
||||
from qgis.core import QgsProcessingParameterDefinition
|
||||
from processing.modeler.ModelerAlgorithm import ModelerParameter, Algorithm, ModelerOutput
|
||||
from qgis.core import (QgsProcessingParameterDefinition,
|
||||
QgsProcessingModelAlgorithm)
|
||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||
|
||||
@ -51,31 +51,31 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
self.controls = controls
|
||||
self.model = model
|
||||
self.element = element
|
||||
if isinstance(element, ModelerParameter):
|
||||
if isinstance(element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'input.svg'))
|
||||
self.picture = QPicture()
|
||||
painter = QPainter(self.picture)
|
||||
svg.render(painter)
|
||||
self.pixmap = None
|
||||
self.text = element.param.description()
|
||||
elif isinstance(element, ModelerOutput):
|
||||
self.text = self.model.parameterDefinition(element.parameterName()).description()
|
||||
elif isinstance(element, QgsProcessingModelAlgorithm.ModelOutput):
|
||||
# Output name
|
||||
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'output.svg'))
|
||||
self.picture = QPicture()
|
||||
painter = QPainter(self.picture)
|
||||
svg.render(painter)
|
||||
self.pixmap = None
|
||||
self.text = element.description
|
||||
self.text = element.description()
|
||||
else:
|
||||
self.text = element.description
|
||||
self.pixmap = element.algorithm.icon().pixmap(15, 15)
|
||||
self.text = element.description()
|
||||
self.pixmap = element.algorithm().icon().pixmap(15, 15)
|
||||
self.arrows = []
|
||||
self.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
|
||||
self.setZValue(1000)
|
||||
|
||||
if not isinstance(element, ModelerOutput) and controls:
|
||||
if not isinstance(element, QgsProcessingModelAlgorithm.ModelOutput) and controls:
|
||||
svg = QSvgRenderer(os.path.join(pluginPath, 'images', 'edit.svg'))
|
||||
picture = QPicture()
|
||||
painter = QPainter(picture)
|
||||
@ -98,25 +98,27 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
self.removeElement)
|
||||
self.deleteButton.setParentItem(self)
|
||||
|
||||
if isinstance(element, Algorithm):
|
||||
alg = element.algorithm
|
||||
if isinstance(element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
alg = element.algorithm()
|
||||
if [a for a in alg.parameterDefinitions() if not a.isDestination()]:
|
||||
pt = self.getLinkPointForParameter(-1)
|
||||
pt = QPointF(0, pt.y())
|
||||
if controls:
|
||||
self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.paramsFolded)
|
||||
self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.parametersCollapsed())
|
||||
self.inButton.setParentItem(self)
|
||||
if alg.outputDefinitions():
|
||||
pt = self.getLinkPointForOutput(-1)
|
||||
pt = QPointF(0, pt.y())
|
||||
if controls:
|
||||
self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsFolded)
|
||||
self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsCollapsed())
|
||||
self.outButton.setParentItem(self)
|
||||
|
||||
def foldInput(self, folded):
|
||||
self.element.paramsFolded = folded
|
||||
self.element.setParametersCollapsed(folded)
|
||||
#also need to update the model's stored component
|
||||
self.model.childAlgorithm(self.element.childId()).setParametersCollapsed(folded)
|
||||
self.prepareGeometryChange()
|
||||
if self.element.algorithm.outputDefinitions():
|
||||
if self.element.algorithm().outputDefinitions():
|
||||
pt = self.getLinkPointForOutput(-1)
|
||||
pt = QPointF(0, pt.y())
|
||||
self.outButton.position = pt
|
||||
@ -125,7 +127,9 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
self.update()
|
||||
|
||||
def foldOutput(self, folded):
|
||||
self.element.outputsFolded = folded
|
||||
self.element.setOutputsCollapsed(folded)
|
||||
# also need to update the model's stored component
|
||||
self.model.childAlgorithm(self.element.childId()).setOutputsCollapsed(folded)
|
||||
self.prepareGeometryChange()
|
||||
for arrow in self.arrows:
|
||||
arrow.updatePath()
|
||||
@ -138,10 +142,10 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
font = QFont('Verdana', 8)
|
||||
font.setPixelSize(12)
|
||||
fm = QFontMetricsF(font)
|
||||
unfolded = isinstance(self.element, Algorithm) and not self.element.paramsFolded
|
||||
numParams = len([a for a in self.element.algorithm.parameterDefinitions() if not a.isDestination()]) if unfolded else 0
|
||||
unfolded = isinstance(self.element, Algorithm) and not self.element.outputsFolded
|
||||
numOutputs = len(self.element.algorithm.outputDefinitions()) if unfolded else 0
|
||||
unfolded = isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and not self.element.parametersCollapsed()
|
||||
numParams = len([a for a in self.element.algorithm().parameterDefinitions() if not a.isDestination()]) if unfolded else 0
|
||||
unfolded = isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and not self.element.outputsCollapsed()
|
||||
numOutputs = len(self.element.algorithm().outputDefinitions()) if unfolded else 0
|
||||
|
||||
hUp = fm.height() * 1.2 * (numParams + 2)
|
||||
hDown = fm.height() * 1.2 * (numOutputs + 2)
|
||||
@ -155,15 +159,15 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
self.editElement()
|
||||
|
||||
def contextMenuEvent(self, event):
|
||||
if isinstance(self.element, ModelerOutput):
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelOutput):
|
||||
return
|
||||
popupmenu = QMenu()
|
||||
removeAction = popupmenu.addAction('Remove')
|
||||
removeAction.triggered.connect(self.removeElement)
|
||||
editAction = popupmenu.addAction('Edit')
|
||||
editAction.triggered.connect(self.editElement)
|
||||
if isinstance(self.element, Algorithm):
|
||||
if not self.element.active:
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
if not self.element.isActive():
|
||||
removeAction = popupmenu.addAction('Activate')
|
||||
removeAction.triggered.connect(self.activateAlgorithm)
|
||||
else:
|
||||
@ -172,11 +176,11 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
popupmenu.exec_(event.screenPos())
|
||||
|
||||
def deactivateAlgorithm(self):
|
||||
self.model.deactivateAlgorithm(self.element.modeler_name)
|
||||
self.model.deactivateAlgorithm(self.element.childId())
|
||||
self.model.updateModelerView()
|
||||
|
||||
def activateAlgorithm(self):
|
||||
if self.model.activateAlgorithm(self.element.modeler_name):
|
||||
if self.model.activateAlgorithm(self.element.childId()):
|
||||
self.model.updateModelerView()
|
||||
else:
|
||||
QMessageBox.warning(None, 'Could not activate Algorithm',
|
||||
@ -184,39 +188,41 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
'Activate them them before trying to activate it.')
|
||||
|
||||
def editElement(self):
|
||||
if isinstance(self.element, ModelerParameter):
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||
dlg = ModelerParameterDefinitionDialog(self.model,
|
||||
param=self.element.param)
|
||||
param=self.model.parameterDefinition(self.element.parameterName()))
|
||||
dlg.exec_()
|
||||
if dlg.param is not None:
|
||||
self.model.updateParameter(dlg.param)
|
||||
self.element.param = dlg.param
|
||||
self.model.updateModelParameter(dlg.param)
|
||||
self.element.setParameterName(dlg.param.name())
|
||||
# also need to update the model's stored component
|
||||
self.model.childAlgorithm(self.element.childId()).setParameterName(dlg.param.name())
|
||||
self.text = dlg.param.description()
|
||||
self.update()
|
||||
elif isinstance(self.element, Algorithm):
|
||||
elif isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
dlg = None
|
||||
try:
|
||||
dlg = self.element.algorithm.getCustomModelerParametersDialog(self.model, self.element.modeler_name)
|
||||
dlg = self.element.algorithm().getCustomModelerParametersDialog(self.model, self.element.childId())
|
||||
except:
|
||||
pass
|
||||
if not dlg:
|
||||
dlg = ModelerParametersDialog(self.element.algorithm, self.model, self.element.modeler_name)
|
||||
dlg = ModelerParametersDialog(self.element.algorithm(), self.model, self.element.childId())
|
||||
dlg.exec_()
|
||||
if dlg.alg is not None:
|
||||
dlg.alg.modeler_name = self.element.modeler_name
|
||||
dlg.alg.setChildId(self.element.childId())
|
||||
self.model.updateAlgorithm(dlg.alg)
|
||||
self.model.updateModelerView()
|
||||
|
||||
def removeElement(self):
|
||||
if isinstance(self.element, ModelerParameter):
|
||||
if not self.model.removeParameter(self.element.param.name):
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||
if not self.model.removeParameter(self.element.parameterName()):
|
||||
QMessageBox.warning(None, 'Could not remove element',
|
||||
'Other elements depend on the selected one.\n'
|
||||
'Remove them before trying to remove it.')
|
||||
else:
|
||||
self.model.updateModelerView()
|
||||
elif isinstance(self.element, Algorithm):
|
||||
if not self.model.removeAlgorithm(self.element.modeler_name):
|
||||
elif isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
if not self.model.removeAlgorithm(self.element.childId()):
|
||||
QMessageBox.warning(None, 'Could not remove element',
|
||||
'Other elements depend on the selected one.\n'
|
||||
'Remove them before trying to remove it.')
|
||||
@ -244,11 +250,11 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
ModelerGraphicItem.BOX_WIDTH + 2,
|
||||
ModelerGraphicItem.BOX_HEIGHT + 2)
|
||||
|
||||
if isinstance(self.element, ModelerParameter):
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ModelParameter):
|
||||
color = QColor(238, 242, 131)
|
||||
stroke = QColor(234, 226, 118)
|
||||
selected = QColor(116, 113, 68)
|
||||
elif isinstance(self.element, Algorithm):
|
||||
elif isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
color = QColor(255, 255, 255)
|
||||
stroke = Qt.gray
|
||||
selected = QColor(50, 50, 50)
|
||||
@ -267,7 +273,7 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
painter.setFont(font)
|
||||
painter.setPen(QPen(Qt.black))
|
||||
text = self.getAdjustedText(self.text)
|
||||
if isinstance(self.element, Algorithm) and not self.element.active:
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and not self.element.isActive():
|
||||
painter.setPen(QPen(Qt.gray))
|
||||
text = text + "\n(deactivated)"
|
||||
fm = QFontMetricsF(font)
|
||||
@ -276,14 +282,14 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, ModelerGraphicItem.BOX_HEIGHT / 2.0 - h + 1)
|
||||
painter.drawText(pt, text)
|
||||
painter.setPen(QPen(Qt.black))
|
||||
if isinstance(self.element, Algorithm):
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
h = -(fm.height() * 1.2)
|
||||
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
|
||||
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
|
||||
painter.drawText(pt, 'In')
|
||||
i = 1
|
||||
if not self.element.paramsFolded:
|
||||
for param in [p for p in self.element.algorithm.parameterDefinitions() if not p.isDestination()]:
|
||||
if not self.element.parametersCollapsed():
|
||||
for param in [p for p in self.element.algorithm().parameterDefinitions() if not p.isDestination()]:
|
||||
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
text = self.getAdjustedText(param.description())
|
||||
h = -(fm.height() * 1.2) * (i + 1)
|
||||
@ -295,8 +301,8 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
|
||||
pt = QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h)
|
||||
painter.drawText(pt, 'Out')
|
||||
if not self.element.outputsFolded:
|
||||
for i, out in enumerate(self.element.algorithm.outputDefinitions()):
|
||||
if not self.element.outputsCollapsed():
|
||||
for i, out in enumerate(self.element.algorithm().outputDefinitions()):
|
||||
text = self.getAdjustedText(out.description())
|
||||
h = fm.height() * 1.2 * (i + 2)
|
||||
h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0
|
||||
@ -311,13 +317,13 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
|
||||
def getLinkPointForParameter(self, paramIndex):
|
||||
offsetX = 25
|
||||
if isinstance(self.element, Algorithm) and self.element.paramsFolded:
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and self.element.parametersCollapsed():
|
||||
paramIndex = -1
|
||||
offsetX = 17
|
||||
font = QFont('Verdana', 8)
|
||||
font.setPixelSize(12)
|
||||
fm = QFontMetricsF(font)
|
||||
if isinstance(self.element, Algorithm):
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
h = -(fm.height() * 1.2) * (paramIndex + 2) - fm.height() / 2.0 + 8
|
||||
h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0
|
||||
else:
|
||||
@ -325,9 +331,9 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
return QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + offsetX, h)
|
||||
|
||||
def getLinkPointForOutput(self, outputIndex):
|
||||
if isinstance(self.element, Algorithm) and self.element.algorithm.outputDefinitions():
|
||||
outputIndex = (outputIndex if not self.element.outputsFolded else -1)
|
||||
text = self.getAdjustedText(self.element.algorithm.outputDefinitions()[outputIndex].description())
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm) and self.element.algorithm().outputDefinitions():
|
||||
outputIndex = (outputIndex if not self.element.outputsCollapsed() else -1)
|
||||
text = self.getAdjustedText(self.element.algorithm().outputDefinitions()[outputIndex].description())
|
||||
font = QFont('Verdana', 8)
|
||||
font.setPixelSize(12)
|
||||
fm = QFontMetricsF(font)
|
||||
@ -335,7 +341,7 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
h = fm.height() * 1.2 * (outputIndex + 1) + fm.height() / 2.0
|
||||
y = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5
|
||||
x = (-ModelerGraphicItem.BOX_WIDTH / 2 + 33 + w + 5
|
||||
if not self.element.outputsFolded
|
||||
if not self.element.outputsCollapsed()
|
||||
else 10)
|
||||
return QPointF(x, y)
|
||||
else:
|
||||
@ -345,7 +351,15 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
if change == QGraphicsItem.ItemPositionHasChanged:
|
||||
for arrow in self.arrows:
|
||||
arrow.updatePath()
|
||||
self.element.pos = self.pos()
|
||||
self.element.setPosition(self.pos())
|
||||
|
||||
# also need to update the model's stored component's position
|
||||
if isinstance(self.element, QgsProcessingModelAlgorithm.ChildAlgorithm):
|
||||
self.model.childAlgorithm(self.element.childId()).setPosition(self.pos())
|
||||
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.name()).setPosition(self.pos())
|
||||
|
||||
return value
|
||||
|
||||
|
@ -127,11 +127,12 @@ class ModelerParameterDefinitionDialog(QDialog):
|
||||
self.verticalLayout.addWidget(QLabel(self.tr('Parent layer')))
|
||||
self.parentCombo = QComboBox()
|
||||
idx = 0
|
||||
for param in list(self.alg.inputs.values()):
|
||||
if isinstance(param.param, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
||||
self.parentCombo.addItem(param.param.description(), param.param.name())
|
||||
for param in list(self.alg.parameterComponents().values()):
|
||||
definition = self.alg.parameterDefinition(param.parameterName())
|
||||
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
||||
self.parentCombo.addItem(definition.description(), definition.name())
|
||||
if self.param is not None:
|
||||
if self.param.parentLayerParameter() == param.param.name():
|
||||
if self.param.parentLayerParameter() == definition.name():
|
||||
self.parentCombo.setCurrentIndex(idx)
|
||||
idx += 1
|
||||
self.verticalLayout.addWidget(self.parentCombo)
|
||||
@ -215,11 +216,12 @@ class ModelerParameterDefinitionDialog(QDialog):
|
||||
self.parentCombo = QComboBox()
|
||||
self.parentCombo.addItem(self.tr("None"), None)
|
||||
idx = 1
|
||||
for param in list(self.alg.inputs.values()):
|
||||
if isinstance(param.param, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
||||
self.parentCombo.addItem(param.param.description(), param.param.name())
|
||||
for param in list(self.alg.parameterComponents().values()):
|
||||
definition = self.alg.parameterDefinition(param.parameterName())
|
||||
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
|
||||
self.parentCombo.addItem(definition.description(), definition.name())
|
||||
if self.param is not None:
|
||||
if self.param.parentLayerParameter() == param.param.name():
|
||||
if self.param.parentLayerParameter() == definition.name():
|
||||
self.parentCombo.setCurrentIndex(idx)
|
||||
idx += 1
|
||||
self.verticalLayout.addWidget(self.parentCombo)
|
||||
@ -290,8 +292,9 @@ class ModelerParameterDefinitionDialog(QDialog):
|
||||
safeName = ''.join(c for c in description if c in validChars)
|
||||
name = safeName.lower()
|
||||
i = 2
|
||||
while name in self.alg.inputs:
|
||||
while self.alg.parameterDefinition(name):
|
||||
name = safeName.lower() + str(i)
|
||||
i += 1
|
||||
else:
|
||||
name = self.param.name()
|
||||
if (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN or
|
||||
|
@ -36,7 +36,8 @@ from qgis.PyQt.QtWidgets import (QDialog, QDialogButtonBox, QLabel, QLineEdit,
|
||||
|
||||
from qgis.core import (QgsProcessingParameterDefinition,
|
||||
QgsProcessingParameterPoint,
|
||||
QgsProcessingParameterExtent)
|
||||
QgsProcessingParameterExtent,
|
||||
QgsProcessingModelAlgorithm)
|
||||
|
||||
from qgis.gui import (QgsMessageBar,
|
||||
QgsScrollArea)
|
||||
@ -52,11 +53,6 @@ from processing.core.outputs import (OutputRaster,
|
||||
OutputDirectory)
|
||||
from processing.core.parameters import ParameterPoint, ParameterExtent
|
||||
|
||||
from processing.modeler.ModelerAlgorithm import (ValueFromInput,
|
||||
ValueFromOutput,
|
||||
Algorithm,
|
||||
ModelerOutput)
|
||||
|
||||
|
||||
class ModelerParametersDialog(QDialog):
|
||||
|
||||
@ -206,8 +202,8 @@ class ModelerParametersDialog(QDialog):
|
||||
else:
|
||||
dependent = self.model.getDependentAlgorithms(self._algName)
|
||||
opts = []
|
||||
for alg in list(self.model.algs.values()):
|
||||
if alg.modeler_name not in dependent:
|
||||
for alg in list(self.model.childAlgorithms().values()):
|
||||
if alg.childId() not in dependent:
|
||||
opts.append(alg)
|
||||
return opts
|
||||
|
||||
@ -237,16 +233,16 @@ class ModelerParametersDialog(QDialog):
|
||||
outTypes = [outTypes]
|
||||
|
||||
values = []
|
||||
inputs = self.model.inputs
|
||||
inputs = self.model.parameterComponents()
|
||||
for i in list(inputs.values()):
|
||||
param = i.param
|
||||
param = self.model.parameterDefinition(i.parameterName())
|
||||
for t in paramType:
|
||||
if isinstance(param, t):
|
||||
if dataType is not None:
|
||||
if param.datatype in dataType:
|
||||
values.append(ValueFromInput(param.name()))
|
||||
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromModelParameter(param.name()))
|
||||
else:
|
||||
values.append(ValueFromInput(param.name()))
|
||||
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromModelParameter(param.name()))
|
||||
break
|
||||
if not outTypes:
|
||||
return values
|
||||
@ -254,73 +250,81 @@ class ModelerParametersDialog(QDialog):
|
||||
dependent = []
|
||||
else:
|
||||
dependent = self.model.getDependentAlgorithms(self._algName)
|
||||
for alg in list(self.model.algs.values()):
|
||||
if alg.modeler_name not in dependent:
|
||||
for out in alg.algorithm.outputDefinitions():
|
||||
for alg in list(self.model.childAlgorithms().values()):
|
||||
if alg.childId() not in dependent:
|
||||
for out in alg.algorithm().outputDefinitions():
|
||||
for t in outTypes:
|
||||
if isinstance(out, t):
|
||||
if dataType is not None and out.datatype in dataType:
|
||||
values.append(ValueFromOutput(alg.modeler_name, out.name()))
|
||||
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromChildOutput(alg.childId(), out.name()))
|
||||
else:
|
||||
values.append(ValueFromOutput(alg.modeler_name, out.name()))
|
||||
values.append(QgsProcessingModelAlgorithm.ChildParameterSource.fromChildOutput(alg.childId(), out.name()))
|
||||
|
||||
return values
|
||||
|
||||
def resolveValueDescription(self, value):
|
||||
if isinstance(value, ValueFromInput):
|
||||
return self.model.inputs[value.name].param.description()
|
||||
else:
|
||||
alg = self.model.algs[value.alg]
|
||||
return self.tr("'{0}' from algorithm '{1}'").format(alg.algorithm.outputDefinition(value.output).description(), alg.description)
|
||||
if isinstance(value, QgsProcessingModelAlgorithm.ChildParameterSource):
|
||||
if value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.StaticValue:
|
||||
return value.staticValue()
|
||||
elif value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ModelParameter:
|
||||
return self.model.parameterDefinition(value.parameterName()).description()
|
||||
elif value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ChildOutput:
|
||||
alg = self.model.childAlgorithm(value.outputChildId())
|
||||
return self.tr("'{0}' from algorithm '{1}'").format(alg.algorithm().outputDefinition(value.outputName()).description(), alg.description())
|
||||
|
||||
return value
|
||||
|
||||
def setPreviousValues(self):
|
||||
if self._algName is not None:
|
||||
alg = self.model.algs[self._algName]
|
||||
self.descriptionBox.setText(alg.description)
|
||||
for param in alg.algorithm.parameterDefinitions():
|
||||
alg = self.model.childAlgorithm(self._algName)
|
||||
self.descriptionBox.setText(alg.description())
|
||||
for param in alg.algorithm().parameterDefinitions():
|
||||
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
continue
|
||||
if param.name() in alg.params:
|
||||
value = alg.params[param.name()]
|
||||
if param.name() in alg.parameterSources():
|
||||
value = alg.parameterSources()[param.name()]
|
||||
else:
|
||||
value = param.defaultValue()
|
||||
self.wrappers[param.name()].setValue(value)
|
||||
for name, out in list(alg.outputs.items()):
|
||||
for name, out in list(alg.modelOutputs().items()):
|
||||
self.valueItems[name].setText(out.description())
|
||||
|
||||
selected = []
|
||||
dependencies = self.getAvailableDependencies() # spellok
|
||||
for idx, dependency in enumerate(dependencies):
|
||||
if dependency.modeler_name in alg.dependencies:
|
||||
if dependency.childId() in alg.dependencies():
|
||||
selected.append(idx)
|
||||
|
||||
self.dependenciesPanel.setSelectedItems(selected)
|
||||
|
||||
def createAlgorithm(self):
|
||||
alg = Algorithm(self._alg.id())
|
||||
alg.setName(self.model)
|
||||
alg.description = self.descriptionBox.text()
|
||||
alg = QgsProcessingModelAlgorithm.ChildAlgorithm(self._alg.id())
|
||||
alg.generateChildId(self.model)
|
||||
alg.setDescription(self.descriptionBox.text())
|
||||
for param in self._alg.parameterDefinitions():
|
||||
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
continue
|
||||
val = self.wrappers[param.name()].value()
|
||||
if not isinstance(val, ValueFromInput) and not isinstance(val, ValueFromOutput) and not param.checkValueIsAcceptable(val):
|
||||
if ( isinstance(val, QgsProcessingModelAlgorithm.ChildParameterSource) and val.source() == QgsProcessingModelAlgorithm.ChildParameterSource.StaticValue and not param.checkValueIsAcceptable(val.staticValue())) \
|
||||
or (not isinstance(val, QgsProcessingModelAlgorithm.ChildParameterSource) and not param.checkValueIsAcceptable(val)):
|
||||
self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description(),
|
||||
level=QgsMessageBar.WARNING)
|
||||
return None
|
||||
alg.params[param.name()] = val
|
||||
alg.addParameterSource(param.name(), val)
|
||||
|
||||
# outputs = self._alg.outputDefinitions()
|
||||
#for output in outputs:
|
||||
# if not output.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
# name = str(self.valueItems[output.name()].text())
|
||||
# if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME:
|
||||
# alg.outputs[output.name()] = ModelerOutput(name)
|
||||
# alg.outputs[output.name()] = QgsProcessingModelAlgorithm.ModelOutput(name)
|
||||
|
||||
selectedOptions = self.dependenciesPanel.selectedoptions
|
||||
availableDependencies = self.getAvailableDependencies() # spellok
|
||||
dep_ids = []
|
||||
for selected in selectedOptions:
|
||||
alg.dependencies.append(availableDependencies[selected].modeler_name) # spellok
|
||||
dep_ids.append(availableDependencies[selected].childId()) # spellok
|
||||
alg.setDependencies(dep_ids)
|
||||
|
||||
try:
|
||||
self._alg.processBeforeAddingToModeler(alg, self.model)
|
||||
|
@ -28,10 +28,11 @@ __revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.PyQt.QtCore import QPointF, Qt
|
||||
from qgis.PyQt.QtWidgets import QGraphicsItem, QGraphicsScene
|
||||
from qgis.core import QgsProcessingParameterDefinition
|
||||
from qgis.core import (QgsProcessingParameterDefinition,
|
||||
QgsProcessingModelAlgorithm)
|
||||
from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
|
||||
from processing.modeler.ModelerArrowItem import ModelerArrowItem
|
||||
from processing.modeler.ModelerAlgorithm import ValueFromInput, ValueFromOutput, CompoundValue
|
||||
from processing.modeler.ModelerAlgorithm import CompoundValue
|
||||
|
||||
|
||||
class ModelerScene(QGraphicsScene):
|
||||
@ -66,93 +67,93 @@ class ModelerScene(QGraphicsScene):
|
||||
if isinstance(value, list):
|
||||
for v in value:
|
||||
items.extend(self.getItemsFromParamValue(v))
|
||||
elif isinstance(value, QgsProcessingModelAlgorithm.ChildParameterSource):
|
||||
if value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ModelParameter:
|
||||
items.append((self.paramItems[value.parameterName()], 0))
|
||||
elif value.source() == QgsProcessingModelAlgorithm.ChildParameterSource.ChildOutput:
|
||||
outputs = self.model.childAlgorithm(value.outputChildId()).algorithm().outputDefinitions()
|
||||
for i, out in enumerate(outputs):
|
||||
if out.name() == value.outputName():
|
||||
break
|
||||
if value.outputChildId() in self.algItems:
|
||||
items.append((self.algItems[value.outputChildId()], i))
|
||||
elif isinstance(value, CompoundValue):
|
||||
for v in value.values:
|
||||
items.extend(self.getItemsFromParamValue(v))
|
||||
elif isinstance(value, ValueFromInput):
|
||||
items.append((self.paramItems[value.name], 0))
|
||||
elif isinstance(value, ValueFromOutput):
|
||||
outputs = self.model.algs[value.alg].algorithm.outputDefinitions()
|
||||
for i, out in enumerate(outputs):
|
||||
if out.name() == value.output:
|
||||
break
|
||||
if value.alg in self.algItems:
|
||||
items.append((self.algItems[value.alg], i))
|
||||
return items
|
||||
|
||||
def paintModel(self, model, controls=True):
|
||||
self.model = model
|
||||
# Inputs
|
||||
for inp in list(model.inputs.values()):
|
||||
for inp in list(model.parameterComponents().values()):
|
||||
item = ModelerGraphicItem(inp, model, controls)
|
||||
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||
self.addItem(item)
|
||||
item.setPos(inp.pos.x(), inp.pos.y())
|
||||
self.paramItems[inp.param.name()] = item
|
||||
item.setPos(inp.position().x(), inp.position().y())
|
||||
self.paramItems[inp.parameterName()] = item
|
||||
|
||||
# We add the algs
|
||||
for alg in list(model.algs.values()):
|
||||
for alg in list(model.childAlgorithms().values()):
|
||||
item = ModelerGraphicItem(alg, model, controls)
|
||||
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||
self.addItem(item)
|
||||
item.setPos(alg.pos.x(), alg.pos.y())
|
||||
self.algItems[alg.modeler_name] = item
|
||||
item.setPos(alg.position().x(), alg.position().y())
|
||||
self.algItems[alg.childId()] = item
|
||||
|
||||
# And then the arrows
|
||||
for alg in list(model.algs.values()):
|
||||
for alg in list(model.childAlgorithms().values()):
|
||||
idx = 0
|
||||
for parameter in alg.algorithm.parameterDefinitions():
|
||||
for parameter in alg.algorithm().parameterDefinitions():
|
||||
if not parameter.isDestination() and not parameter.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
if parameter.name() in alg.params:
|
||||
value = alg.params[parameter.name()]
|
||||
if parameter.name() in alg.parameterSources():
|
||||
value = alg.parameterSources()[parameter.name()]
|
||||
else:
|
||||
value = None
|
||||
sourceItems = self.getItemsFromParamValue(value)
|
||||
for sourceItem, sourceIdx in sourceItems:
|
||||
arrow = ModelerArrowItem(sourceItem, sourceIdx, self.algItems[alg.modeler_name], idx)
|
||||
arrow = ModelerArrowItem(sourceItem, sourceIdx, self.algItems[alg.childId()], idx)
|
||||
sourceItem.addArrow(arrow)
|
||||
self.algItems[alg.modeler_name].addArrow(arrow)
|
||||
self.algItems[alg.childId()].addArrow(arrow)
|
||||
arrow.updatePath()
|
||||
self.addItem(arrow)
|
||||
idx += 1
|
||||
for depend in alg.dependencies:
|
||||
for depend in alg.dependencies():
|
||||
arrow = ModelerArrowItem(self.algItems[depend], -1,
|
||||
self.algItems[alg.modeler_name], -1)
|
||||
self.algItems[alg.childId()], -1)
|
||||
self.algItems[depend].addArrow(arrow)
|
||||
self.algItems[alg.modeler_name].addArrow(arrow)
|
||||
self.algItems[alg.childId()].addArrow(arrow)
|
||||
arrow.updatePath()
|
||||
self.addItem(arrow)
|
||||
|
||||
# And finally the outputs
|
||||
for alg in list(model.algs.values()):
|
||||
outputs = alg.outputs
|
||||
for alg in list(model.childAlgorithms().values()):
|
||||
outputs = alg.modelOutputs()
|
||||
outputItems = {}
|
||||
idx = 0
|
||||
for key in outputs:
|
||||
out = outputs[key]
|
||||
for key, out in outputs.items():
|
||||
if out is not None:
|
||||
item = ModelerGraphicItem(out, model, controls)
|
||||
item.setFlag(QGraphicsItem.ItemIsMovable, True)
|
||||
item.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
||||
self.addItem(item)
|
||||
pos = alg.outputs[key].pos
|
||||
pos = out.position()
|
||||
if pos is None:
|
||||
pos = (alg.pos + QPointF(ModelerGraphicItem.BOX_WIDTH, 0) +
|
||||
self.algItems[alg.modeler_name].getLinkPointForOutput(idx))
|
||||
item.setPos(pos)
|
||||
pos = (alg.position() + QPointF(ModelerGraphicItem.BOX_WIDTH, 0) +
|
||||
self.algItems[alg.childId()].getLinkPointForOutput(idx))
|
||||
item.setPosition(pos)
|
||||
outputItems[key] = item
|
||||
arrow = ModelerArrowItem(self.algItems[alg.modeler_name], idx, item,
|
||||
arrow = ModelerArrowItem(self.algItems[alg.childId()], idx, item,
|
||||
-1)
|
||||
self.algItems[alg.modeler_name].addArrow(arrow)
|
||||
self.algItems[alg.childId()].addArrow(arrow)
|
||||
item.addArrow(arrow)
|
||||
arrow.updatePath()
|
||||
self.addItem(arrow)
|
||||
idx += 1
|
||||
else:
|
||||
outputItems[key] = None
|
||||
self.outputItems[alg.modeler_name] = outputItems
|
||||
self.outputItems[alg.childId()] = outputItems
|
||||
|
||||
def mousePressEvent(self, mouseEvent):
|
||||
if mouseEvent.button() != Qt.LeftButton:
|
||||
|
@ -96,6 +96,7 @@ SET(QGIS_CORE_SRCS
|
||||
processing/qgsnativealgorithms.cpp
|
||||
processing/qgsprocessingalgorithm.cpp
|
||||
processing/qgsprocessingalgrunnertask.cpp
|
||||
processing/qgsprocessingmodelalgorithm.cpp
|
||||
processing/qgsprocessingoutputs.cpp
|
||||
processing/qgsprocessingparameters.cpp
|
||||
processing/qgsprocessingprovider.cpp
|
||||
@ -896,6 +897,7 @@ SET(QGIS_CORE_HDRS
|
||||
processing/qgsnativealgorithms.h
|
||||
processing/qgsprocessingalgorithm.h
|
||||
processing/qgsprocessingcontext.h
|
||||
processing/qgsprocessingmodelalgorithm.h
|
||||
processing/qgsprocessingoutputs.h
|
||||
processing/qgsprocessingparameters.h
|
||||
processing/qgsprocessingutils.h
|
||||
|
@ -218,6 +218,16 @@ bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *def
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsProcessingAlgorithm::removeParameter( const QString &name )
|
||||
{
|
||||
const QgsProcessingParameterDefinition *def = parameterDefinition( name );
|
||||
if ( def )
|
||||
{
|
||||
delete def;
|
||||
mParameters.removeAll( def );
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsProcessingAlgorithm::addOutput( QgsProcessingOutputDefinition *definition )
|
||||
{
|
||||
if ( !definition )
|
||||
|
@ -272,6 +272,12 @@ class CORE_EXPORT QgsProcessingAlgorithm
|
||||
*/
|
||||
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* Removes the parameter with matching \a name from the algorithm, and deletes any existing
|
||||
* definition.
|
||||
*/
|
||||
void removeParameter( const QString &name );
|
||||
|
||||
/**
|
||||
* Adds an output \a definition to the algorithm. Ownership of the definition is transferred to the algorithm.
|
||||
* Returns true if the output could be successfully added, or false if the output could not be added (e.g.
|
||||
|
370
src/core/processing/qgsprocessingmodelalgorithm.cpp
Normal file
370
src/core/processing/qgsprocessingmodelalgorithm.cpp
Normal file
@ -0,0 +1,370 @@
|
||||
/***************************************************************************
|
||||
qgsprocessingmodelalgorithm.cpp
|
||||
------------------------------
|
||||
begin : June 2017
|
||||
copyright : (C) 2017 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
#include "qgsprocessingregistry.h"
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm::ChildAlgorithm( const QString &algorithmId )
|
||||
: mAlgorithmId( algorithmId )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const QgsProcessingAlgorithm *QgsProcessingModelAlgorithm::ChildAlgorithm::algorithm() const
|
||||
{
|
||||
return QgsApplication::processingRegistry()->algorithmById( mAlgorithmId );
|
||||
}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::Component::description() const
|
||||
{
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::Component::setDescription( const QString &description )
|
||||
{
|
||||
mDescription = description;
|
||||
}
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildParameterSource> QgsProcessingModelAlgorithm::ChildAlgorithm::parameterSources() const
|
||||
{
|
||||
return mParams;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setParameterSources( const QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > ¶ms )
|
||||
{
|
||||
mParams = params;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::addParameterSource( const QString &name, const ChildParameterSource &source )
|
||||
{
|
||||
mParams.insert( name, source );
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ChildAlgorithm::isActive() const
|
||||
{
|
||||
return mActive;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setActive( bool active )
|
||||
{
|
||||
mActive = active;
|
||||
}
|
||||
|
||||
QPointF QgsProcessingModelAlgorithm::Component::position() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::Component::setPosition( const QPointF &position )
|
||||
{
|
||||
mPosition = position;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::Component::Component( const QString &description )
|
||||
: mDescription( description )
|
||||
{}
|
||||
|
||||
QStringList QgsProcessingModelAlgorithm::ChildAlgorithm::dependencies() const
|
||||
{
|
||||
return mDependencies;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setDependencies( const QStringList &dependencies )
|
||||
{
|
||||
mDependencies = dependencies;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ChildAlgorithm::outputsCollapsed() const
|
||||
{
|
||||
return mOutputsCollapsed;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setOutputsCollapsed( bool outputsCollapsed )
|
||||
{
|
||||
mOutputsCollapsed = outputsCollapsed;
|
||||
}
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> QgsProcessingModelAlgorithm::ChildAlgorithm::modelOutputs() const
|
||||
{
|
||||
return mModelOutputs;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelOutput &QgsProcessingModelAlgorithm::ChildAlgorithm::modelOutput( const QString &name )
|
||||
{
|
||||
return mModelOutputs[ name ];
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &modelOutputs )
|
||||
{
|
||||
mModelOutputs = modelOutputs;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ChildAlgorithm::parametersCollapsed() const
|
||||
{
|
||||
return mParametersCollapsed;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setParametersCollapsed( bool parametersCollapsed )
|
||||
{
|
||||
mParametersCollapsed = parametersCollapsed;
|
||||
}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::ChildAlgorithm::childId() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setChildId( const QString &id )
|
||||
{
|
||||
mId = id;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::generateChildId( const QgsProcessingModelAlgorithm &model )
|
||||
{
|
||||
int i = 1;
|
||||
QString id;
|
||||
while ( true )
|
||||
{
|
||||
id = QStringLiteral( "%1_%2" ).arg( mAlgorithmId ).arg( i );
|
||||
if ( !model.childAlgorithms().contains( id ) )
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
mId = id;
|
||||
}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::ChildAlgorithm::algorithmId() const
|
||||
{
|
||||
return mAlgorithmId;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::ChildAlgorithm::setAlgorithmId( const QString &algorithmId )
|
||||
{
|
||||
mAlgorithmId = algorithmId;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// QgsProcessingModelAlgorithm
|
||||
//
|
||||
|
||||
QgsProcessingModelAlgorithm::QgsProcessingModelAlgorithm( const QString &name, const QString &group )
|
||||
: QgsProcessingAlgorithm()
|
||||
, mModelName( name.isEmpty() ? QObject::tr( "model" ) : name )
|
||||
, mModelGroup( group )
|
||||
{}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::name() const
|
||||
{
|
||||
return mModelName;
|
||||
}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::displayName() const
|
||||
{
|
||||
return mModelName;
|
||||
}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::group() const
|
||||
{
|
||||
return mModelGroup;
|
||||
}
|
||||
|
||||
QIcon QgsProcessingModelAlgorithm::icon() const
|
||||
{
|
||||
return QgsApplication::getThemeIcon( QStringLiteral( "/processingModel.svg" ) );
|
||||
}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::svgIconPath() const
|
||||
{
|
||||
return QgsApplication::iconPath( QStringLiteral( "processingModel.svg" ) );
|
||||
}
|
||||
|
||||
QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
|
||||
{
|
||||
Q_UNUSED( parameters );
|
||||
Q_UNUSED( context );
|
||||
Q_UNUSED( feedback );
|
||||
return QVariantMap();
|
||||
}
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms() const
|
||||
{
|
||||
return mChildAlgorithms;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::setParameterComponents( const QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> ¶meterComponents )
|
||||
{
|
||||
mParameterComponents = parameterComponents;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::setParameterComponent( const QgsProcessingModelAlgorithm::ModelParameter &component )
|
||||
{
|
||||
mParameterComponents.insert( component.parameterName(), component );
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelParameter &QgsProcessingModelAlgorithm::parameterComponent( const QString &name )
|
||||
{
|
||||
if ( !mParameterComponents.contains( name ) )
|
||||
{
|
||||
QgsProcessingModelAlgorithm::ModelParameter &component = mParameterComponents[ name ];
|
||||
component.setParameterName( name );
|
||||
return component;
|
||||
}
|
||||
return mParameterComponents[ name ];
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::setChildAlgorithms( const QMap<QString, ChildAlgorithm> &childAlgorithms )
|
||||
{
|
||||
mChildAlgorithms = childAlgorithms;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm )
|
||||
{
|
||||
mChildAlgorithms.insert( algorithm.childId(), algorithm );
|
||||
}
|
||||
|
||||
QString QgsProcessingModelAlgorithm::addChildAlgorithm( ChildAlgorithm &algorithm )
|
||||
{
|
||||
if ( algorithm.childId().isEmpty() || mChildAlgorithms.contains( algorithm.childId() ) )
|
||||
algorithm.generateChildId( *this );
|
||||
|
||||
mChildAlgorithms.insert( algorithm.childId(), algorithm );
|
||||
return algorithm.childId();
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm &QgsProcessingModelAlgorithm::childAlgorithm( const QString &childId )
|
||||
{
|
||||
return mChildAlgorithms[ childId ];
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::addModelParameter( QgsProcessingParameterDefinition *definition, const QgsProcessingModelAlgorithm::ModelParameter &component )
|
||||
{
|
||||
addParameter( definition );
|
||||
mParameterComponents.insert( definition->name(), component );
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::updateModelParameter( QgsProcessingParameterDefinition *definition )
|
||||
{
|
||||
removeParameter( definition->name() );
|
||||
addParameter( definition );
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::removeModelParameter( const QString &name )
|
||||
{
|
||||
removeParameter( name );
|
||||
mParameterComponents.remove( name );
|
||||
}
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> QgsProcessingModelAlgorithm::parameterComponents() const
|
||||
{
|
||||
return mParameterComponents;
|
||||
}
|
||||
|
||||
QStringList QgsProcessingModelAlgorithm::dependentChildAlgorithms( const QString &childId ) const
|
||||
{
|
||||
QSet< QString > algs;
|
||||
QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
|
||||
for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
|
||||
{
|
||||
if ( childIt->childId() == childId )
|
||||
continue;
|
||||
|
||||
// does alg have a direct dependency on this child?
|
||||
if ( childIt->dependencies().contains( childId ) )
|
||||
algs << childIt->childId();
|
||||
|
||||
|
||||
|
||||
}
|
||||
return algs.toList();
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::canExecute( QString *errorMessage ) const
|
||||
{
|
||||
QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
|
||||
for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
|
||||
{
|
||||
if ( !childIt->algorithm() )
|
||||
{
|
||||
if ( errorMessage )
|
||||
{
|
||||
*errorMessage = QObject::tr( "The model you are trying to run contains an algorithm that is not available: <i>%1</i>" ).arg( childIt->algorithmId() );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ChildParameterSource::operator==( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const
|
||||
{
|
||||
if ( mSource != other.mSource )
|
||||
return false;
|
||||
|
||||
switch ( mSource )
|
||||
{
|
||||
case StaticValue:
|
||||
return mStaticValue == other.mStaticValue;
|
||||
case ChildOutput:
|
||||
return mChildId == other.mChildId && mOutputName == other.mOutputName;
|
||||
case ModelParameter:
|
||||
return mParameterName == other.mParameterName;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( const QVariant &value )
|
||||
{
|
||||
ChildParameterSource src;
|
||||
src.mSource = StaticValue;
|
||||
src.mStaticValue = value;
|
||||
return src;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( const QString ¶meterName )
|
||||
{
|
||||
ChildParameterSource src;
|
||||
src.mSource = ModelParameter;
|
||||
src.mParameterName = parameterName;
|
||||
return src;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( const QString &childId, const QString &outputName )
|
||||
{
|
||||
ChildParameterSource src;
|
||||
src.mSource = ChildOutput;
|
||||
src.mChildId = childId;
|
||||
src.mOutputName = outputName;
|
||||
return src;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::Source QgsProcessingModelAlgorithm::ChildParameterSource::source() const
|
||||
{
|
||||
return mSource;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelOutput::ModelOutput( const QString &description )
|
||||
: QgsProcessingModelAlgorithm::Component( description )
|
||||
{}
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelParameter::ModelParameter( const QString ¶meterName )
|
||||
: QgsProcessingModelAlgorithm::Component()
|
||||
, mParameterName( parameterName )
|
||||
{
|
||||
|
||||
}
|
622
src/core/processing/qgsprocessingmodelalgorithm.h
Normal file
622
src/core/processing/qgsprocessingmodelalgorithm.h
Normal file
@ -0,0 +1,622 @@
|
||||
/***************************************************************************
|
||||
qgsprocessingmodelalgorithm.h
|
||||
-----------------------------
|
||||
begin : June 2017
|
||||
copyright : (C) 2017 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 QGSPROCESSINGMODELALGORITHM_H
|
||||
#define QGSPROCESSINGMODELALGORITHM_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis.h"
|
||||
#include "qgsprocessingalgorithm.h"
|
||||
|
||||
|
||||
/**
|
||||
* \class QgsProcessingModelAlgorithm
|
||||
* \ingroup core
|
||||
* Model based algorithm with processing.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Source for the value of a parameter for a child algorithm within a model.
|
||||
* \since QGIS 3.0
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT ChildParameterSource
|
||||
{
|
||||
public:
|
||||
|
||||
//! Possible parameter value sources
|
||||
enum Source
|
||||
{
|
||||
ModelParameter, //!< Parameter value is taken from a parent model parameter
|
||||
ChildOutput, //!< Parameter value is taken from an output generated by a child algorithm
|
||||
StaticValue, //!< Parameter value is a static value
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for ChildParameterSource. It is recommended that the static methods
|
||||
* fromStaticValue(), fromModelParameter() and fromChildOutput() are used instead.
|
||||
*/
|
||||
ChildParameterSource() = default;
|
||||
|
||||
bool operator==( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const;
|
||||
bool operator!=( const QgsProcessingModelAlgorithm::ChildParameterSource &other ) const
|
||||
{
|
||||
return !operator==( other );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ChildParameterSource which takes its value from a static \a value.
|
||||
* \see fromModelParameter()
|
||||
* \see fromChildOutput()
|
||||
*/
|
||||
static QgsProcessingModelAlgorithm::ChildParameterSource fromStaticValue( const QVariant &value );
|
||||
|
||||
/**
|
||||
* Returns a new ChildParameterSource which takes its value from a parent model parameter.
|
||||
* \see fromStaticValue()
|
||||
* \see fromChildOutput()
|
||||
*/
|
||||
static QgsProcessingModelAlgorithm::ChildParameterSource fromModelParameter( const QString ¶meterName );
|
||||
|
||||
/**
|
||||
* Returns a new ChildParameterSource which takes its value from an output generated by a child algorithm.
|
||||
* \see fromStaticValue()
|
||||
* \see fromModelParameter()
|
||||
*/
|
||||
static QgsProcessingModelAlgorithm::ChildParameterSource fromChildOutput( const QString &childId, const QString &outputName );
|
||||
|
||||
/**
|
||||
* Returns the parameter value's source.
|
||||
*/
|
||||
Source source() const;
|
||||
|
||||
/**
|
||||
* Returns the source's static value. This is only used when the source() is StaticValue.
|
||||
* \see setStaticValue()
|
||||
*/
|
||||
QVariant staticValue() const { return mStaticValue; }
|
||||
|
||||
/**
|
||||
* Sets the source's static value. Calling this will also change the source() to StaticValue.
|
||||
* \see staticValue()
|
||||
*/
|
||||
void setStaticValue( const QVariant &value ) { mStaticValue = value; mSource = StaticValue; }
|
||||
|
||||
/**
|
||||
* Returns the source's model parameter name. This is only used when the source() is ModelParameter.
|
||||
* \see setParameterName()
|
||||
*/
|
||||
QString parameterName() const { return mParameterName; }
|
||||
|
||||
/**
|
||||
* Sets the source's model parameter \a name. Calling this will also change the source() to ModelParameter.
|
||||
* \see parameterName()
|
||||
*/
|
||||
void setParameterName( const QString &name ) { mParameterName = name; mSource = ModelParameter; }
|
||||
|
||||
/**
|
||||
* Returns the source's child algorithm ID from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||
* \see setOutputChildId()
|
||||
* \see outputName()
|
||||
*/
|
||||
QString outputChildId() const { return mChildId; }
|
||||
|
||||
/**
|
||||
* Sets the source's child algorithm \a id from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||
* \see parameterName()
|
||||
* \see setOutputName()
|
||||
*/
|
||||
void setOutputChildId( const QString &id ) { mChildId = id; mSource = ChildOutput; }
|
||||
|
||||
/**
|
||||
* Returns the source's child algorithm output name from which the output value will be taken. This is only used when the source() is ChildOutput.
|
||||
* \see setOutputName()
|
||||
* \see outputChildId()
|
||||
*/
|
||||
QString outputName() const { return mOutputName; }
|
||||
|
||||
/**
|
||||
* Sets the source's child algorithm output \a name from which the output value will be taken. Calling this will also change the source() to ChildOutput.
|
||||
* \see outputName()
|
||||
* \see setOutputChildId()
|
||||
*/
|
||||
void setOutputName( const QString &name ) { mOutputName = name; mSource = ChildOutput; }
|
||||
|
||||
private:
|
||||
|
||||
Source mSource = StaticValue;
|
||||
QVariant mStaticValue;
|
||||
QString mParameterName;
|
||||
QString mChildId;
|
||||
QString mOutputName;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a component of a model algorithm.
|
||||
* \since QGIS 3.0
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT Component
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Returns the friendly description text for the component.
|
||||
* \see setDescription()
|
||||
*/
|
||||
QString description() const;
|
||||
|
||||
/**
|
||||
* Sets the friendly \a description text for the component.
|
||||
* \see description()
|
||||
*/
|
||||
void setDescription( const QString &description );
|
||||
|
||||
/**
|
||||
* Returns the position of the model component within the graphical modeler.
|
||||
* \see setPosition()
|
||||
*/
|
||||
QPointF position() const;
|
||||
|
||||
/**
|
||||
* Sets the \a position of the model component within the graphical modeler.
|
||||
* \see position()
|
||||
*/
|
||||
void setPosition( const QPointF &position );
|
||||
|
||||
protected:
|
||||
|
||||
//! Only subclasses can be created
|
||||
Component( const QString &description = QString() );
|
||||
|
||||
//! Copies are protected to avoid slicing
|
||||
Component( const QgsProcessingModelAlgorithm::Component &other ) = default;
|
||||
|
||||
//! Copies are protected to avoid slicing
|
||||
Component &operator=( const QgsProcessingModelAlgorithm::Component &other ) = default;
|
||||
|
||||
private:
|
||||
|
||||
//! Position of component within model
|
||||
QPointF mPosition;
|
||||
|
||||
QString mDescription;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an input parameter used by the model.
|
||||
* \since QGIS 3.0
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT ModelParameter : public QgsProcessingModelAlgorithm::Component
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for ModelParameter. The parameter name should match one of the
|
||||
* parameters from the parent model.
|
||||
*/
|
||||
ModelParameter( const QString ¶meterName = QString() );
|
||||
|
||||
/**
|
||||
* Returns the associated parameter name. The parameter name should match one of the
|
||||
* parameters from the parent model.
|
||||
* \see parameterName()
|
||||
*/
|
||||
QString parameterName() const { return mParameterName; }
|
||||
|
||||
/**
|
||||
* Sets the associated parameter name. The parameter name should match one of the
|
||||
* parameters from the parent model.
|
||||
* \see parameterName()
|
||||
*/
|
||||
void setParameterName( const QString &name ) { mParameterName = name; }
|
||||
|
||||
private:
|
||||
|
||||
QString mParameterName;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents a final output created by the model.
|
||||
* \since QGIS 3.0
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT ModelOutput : public QgsProcessingModelAlgorithm::Component
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for ModelOutput with the specified \a description.
|
||||
*/
|
||||
ModelOutput( const QString &description = QString() );
|
||||
|
||||
/**
|
||||
* Returns the child algorithm ID from which this output is generated.
|
||||
* \see setChildId()
|
||||
*/
|
||||
QString childId() const { return mChildId; }
|
||||
|
||||
/**
|
||||
* Sets the child algorithm \a id from which this output is generated.
|
||||
* \see childId()
|
||||
*/
|
||||
void setChildId( const QString &id ) { mChildId = id; }
|
||||
|
||||
/**
|
||||
* Returns the child algorithm output name from which this output is generated.
|
||||
* \see setOutputName()
|
||||
*/
|
||||
QString outputName() 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; }
|
||||
|
||||
private:
|
||||
|
||||
QString mChildId;
|
||||
QString mOutputName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Child algorithm representing a single component of a QgsProcessingModelAlgorithm.
|
||||
* \since QGIS 3.0
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT ChildAlgorithm : public QgsProcessingModelAlgorithm::Component
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for ChildAlgorithm. The \a algorithmId parameter
|
||||
* should be set to a QgsProcessingAlgorithm algorithm ID.
|
||||
*/
|
||||
ChildAlgorithm( const QString &algorithmId = QString() );
|
||||
|
||||
/**
|
||||
* Returns the child algorithm's unique ID string, used the identify
|
||||
* this child algorithm within its parent model.
|
||||
* \see setChildId()
|
||||
* \see generateChildId()
|
||||
*/
|
||||
QString childId() const;
|
||||
|
||||
/**
|
||||
* Sets the child algorithm's unique \a id string, used the identify
|
||||
* this child algorithm within its parent model.
|
||||
* \see childId()
|
||||
* \see generateChildId()
|
||||
*/
|
||||
void setChildId( const QString &id );
|
||||
|
||||
/**
|
||||
* Automatically generates a unique childId() for the algorithm,
|
||||
* avoiding child IDs which are already present in \a model.
|
||||
* \see childId()
|
||||
* \see setChildId()
|
||||
*/
|
||||
void generateChildId( const QgsProcessingModelAlgorithm &model );
|
||||
|
||||
/**
|
||||
* Returns the underlying child algorithm's ID.
|
||||
* \see algorithm()
|
||||
* \see setAlgorithmId()
|
||||
*/
|
||||
QString algorithmId() const;
|
||||
|
||||
/**
|
||||
* Sets the underlying child algorithm's ID. This
|
||||
* should be set to an existing QgsProcessingAlgorithm algorithm ID.
|
||||
* \see algorithm()
|
||||
* \see algorithmId()
|
||||
*/
|
||||
void setAlgorithmId( const QString &algorithmId );
|
||||
|
||||
/**
|
||||
* Returns the underlying child algorithm, or a nullptr
|
||||
* if a matching algorithm is not available.
|
||||
* \see algorithmId()
|
||||
*/
|
||||
const QgsProcessingAlgorithm *algorithm() const;
|
||||
|
||||
/**
|
||||
* Returns a map of parameter sources. The keys are the child algorithm
|
||||
* parameter names, the values are the source for that parameter.
|
||||
* \see setParameterSources()
|
||||
* \see addParameterSource()
|
||||
*/
|
||||
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > parameterSources() const;
|
||||
|
||||
/**
|
||||
* Sets the map of parameter \a sources. The keys are the child algorithm
|
||||
* parameter names, the values are the source for that parameter.
|
||||
* \see parameterSources()
|
||||
* \see addParameterSource()
|
||||
*/
|
||||
void setParameterSources( const QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > &sources );
|
||||
|
||||
/**
|
||||
* Adds a parameter source. The \a name argument should match
|
||||
* one of the child algorithm's parameter names, and the \a source
|
||||
* argument is used to set the source for that parameter.
|
||||
*
|
||||
* Any existing parameter source with matching name will be replaced.
|
||||
* \see parameterSources()
|
||||
* \see setParameterSources()
|
||||
*/
|
||||
void addParameterSource( const QString &name, const QgsProcessingModelAlgorithm::ChildParameterSource &source );
|
||||
|
||||
/**
|
||||
* Returns true if the child algorithm is active.
|
||||
* \see setActive()
|
||||
*/
|
||||
bool isActive() const;
|
||||
|
||||
/**
|
||||
* Sets whether the child algorithm is active.
|
||||
* \see isActive()
|
||||
*/
|
||||
void setActive( bool active );
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* \see setDependencies()
|
||||
*/
|
||||
QStringList dependencies() const;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* \see dependencies()
|
||||
*/
|
||||
void setDependencies( const QStringList &dependencies );
|
||||
|
||||
/**
|
||||
* Returns true if the list of parameters for this algorithm should be collapsed
|
||||
* in the graphical modeller.
|
||||
* \see setParametersCollapsed()
|
||||
* \see outputsCollapsed()
|
||||
*/
|
||||
bool parametersCollapsed() const;
|
||||
|
||||
/**
|
||||
* Sets whether the list of parameters for this algorithm should be collapsed
|
||||
* in the graphical modeller.
|
||||
* \see parametersCollapsed()
|
||||
* \see setOutputsCollapsed()
|
||||
*/
|
||||
void setParametersCollapsed( bool collapsed );
|
||||
|
||||
/**
|
||||
* Returns true if the list of outputs for this algorithm should be collapsed
|
||||
* in the graphical modeller.
|
||||
* \see setParametersCollapsed()
|
||||
* \see parametersCollapsed()
|
||||
*/
|
||||
bool outputsCollapsed() const;
|
||||
|
||||
/**
|
||||
* Sets whether the list of outputs for this algorithm should be collapsed
|
||||
* in the graphical modeller.
|
||||
* \see outputsCollapsed()
|
||||
* \see setParametersCollapsed()
|
||||
*/
|
||||
void setOutputsCollapsed( bool collapsed );
|
||||
|
||||
/**
|
||||
* Returns 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 are included in this map.
|
||||
* \see setModelOutputs()
|
||||
* \see modelOutput()
|
||||
*/
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> modelOutputs() const;
|
||||
|
||||
/**
|
||||
* Returns the final model output with matching \a name. If no output
|
||||
* exists with the name, a new one will be created and returned.
|
||||
* \see modelOutputs()
|
||||
* \see setModelOutputs()
|
||||
*/
|
||||
QgsProcessingModelAlgorithm::ModelOutput &modelOutput( const QString &name );
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* \see modelOutputs()
|
||||
*/
|
||||
void setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &outputs );
|
||||
|
||||
private:
|
||||
|
||||
QString mId;
|
||||
|
||||
QString mAlgorithmId;
|
||||
|
||||
//! A map of parameter sources. Keys are algorithm parameter names.
|
||||
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > mParams;
|
||||
|
||||
//! A map of ModelOutput for final model outputs generated by this child algorithm. Keys are output names from the child algorithm.
|
||||
QMap< QString, QgsProcessingModelAlgorithm::ModelOutput > mModelOutputs;
|
||||
|
||||
bool mActive = true;
|
||||
|
||||
//! List of child algorithms from the parent model on which this algorithm is dependent
|
||||
QStringList mDependencies;
|
||||
|
||||
//! Whether list of parameters should be collapsed in the graphical modeller
|
||||
bool mParametersCollapsed = true;
|
||||
//! Whether list of outputs should be collapsed in the graphical modeller
|
||||
bool mOutputsCollapsed = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for QgsProcessingModelAlgorithm.
|
||||
*/
|
||||
QgsProcessingModelAlgorithm( const QString &name = QString(), const QString &group = QString() );
|
||||
|
||||
QString name() const override;
|
||||
QString displayName() const override;
|
||||
QString group() const override;
|
||||
QIcon icon() const override;
|
||||
QString svgIconPath() const override;
|
||||
|
||||
bool canExecute( QString *errorMessage SIP_OUT = nullptr ) const override;
|
||||
QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
|
||||
|
||||
/**
|
||||
* Returns the map of child algorithms contained in the model. The keys
|
||||
* are the child algorithm ids (see QgsProcessingModelAlgorithm::ChildAlgorithm::childId()).
|
||||
* \see childAlgorithm()
|
||||
* \see setChildAlgorithms()
|
||||
* \see addChildAlgorithm()
|
||||
*/
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> childAlgorithms() const;
|
||||
|
||||
/**
|
||||
* Sets the map of child algorithms contained in the model. The keys
|
||||
* are the child algorithm ids (see QgsProcessingModelAlgorithm::ChildAlgorithm::childId()).
|
||||
* All existing child algorithms will be replaced.
|
||||
* \see childAlgorithms()
|
||||
* \see childAlgorithm()
|
||||
* \see setChildAlgorithm()
|
||||
* \see addChildAlgorithm()
|
||||
*/
|
||||
void setChildAlgorithms( const QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> &childAlgorithms );
|
||||
|
||||
/**
|
||||
* Sets the child \a algorithm within the model. If a child algorithm already
|
||||
* exists in the model with the same child ID then that algorithm will be replaced.
|
||||
* \see addChildAlgorithm()
|
||||
* \see setChildAlgorithms()
|
||||
*/
|
||||
void setChildAlgorithm( const QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||
|
||||
/**
|
||||
* Adds a new child \a algorithm to the model. If a child algorithm already exists
|
||||
* in the model with the same child ID then \a algorithm will be assigned a new
|
||||
* autogenerated unique ID.
|
||||
* The assigned child ID will be returned.
|
||||
* \see childAlgorithms()
|
||||
* \see childAlgorithm()
|
||||
* \see setChildAlgorithm()
|
||||
* \see setChildAlgorithms()
|
||||
*/
|
||||
QString addChildAlgorithm( QgsProcessingModelAlgorithm::ChildAlgorithm &algorithm );
|
||||
|
||||
/**
|
||||
* Returns the child algorithm with matching \a id. If no child algorithm exists with
|
||||
* this ID a new algorithm will be added to the model and returned.
|
||||
* \see addChildAlgorithm()
|
||||
* \see childAlgorithms()
|
||||
*/
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm &childAlgorithm( const QString &id );
|
||||
|
||||
/**
|
||||
* Adds a new parameter to the model, with the specified \a definition and graphical \a component.
|
||||
* Ownership of \a definition is transferred to the model.
|
||||
* \see updateModelParameter()
|
||||
* \see removeModelParameter()
|
||||
*/
|
||||
void addModelParameter( QgsProcessingParameterDefinition *definition SIP_TRANSFER, const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||
|
||||
/**
|
||||
* Replaces the definition of an existing parameter (by parameter name) with a new \a definition. Ownership of
|
||||
* \a definition is transferred to the model, and any existing parameter is deleted.
|
||||
* \see addModelParameter()
|
||||
* \see removeModelParameter()
|
||||
*/
|
||||
void updateModelParameter( QgsProcessingParameterDefinition *definition SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* Removes an existing model parameter by \a name. The definition of the matching parameter
|
||||
* is deleted.
|
||||
* \see addModelParameter()
|
||||
* \see updateModelParameter()
|
||||
*/
|
||||
void removeModelParameter( const QString &name );
|
||||
|
||||
/**
|
||||
* Returns the map of parameter components used by the model. The keys
|
||||
* should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||
* \see setParameterComponent()
|
||||
* \see parameterComponent()
|
||||
*/
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> parameterComponents() const;
|
||||
|
||||
/**
|
||||
* Sets the map of parameter components used by the model. The keys
|
||||
* should match the algorithm's parameter names (see parameterDefinitions() ).
|
||||
* All existing parameter components will be replaced.
|
||||
* \see parameterComponents()
|
||||
* \see setParameterComponent()
|
||||
* \see parameterComponent()
|
||||
*/
|
||||
void setParameterComponents( const QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> ¶meterComponents );
|
||||
|
||||
/**
|
||||
* Sets a parameter \a component for the model. If a parameter component already
|
||||
* exists in the model with the same parameter name then that component will be replaced.
|
||||
* \see parameterComponents()
|
||||
* \see setParameterComponents()
|
||||
* \see parameterComponent()
|
||||
*/
|
||||
void setParameterComponent( const QgsProcessingModelAlgorithm::ModelParameter &component );
|
||||
|
||||
/**
|
||||
* Returns the parameter component with matching \a name. If no parameter component exists with
|
||||
* this name a new component will be added to the model and returned.
|
||||
* \see parameterComponents()
|
||||
* \see setParameterComponents()
|
||||
* \see setParameterComponent()
|
||||
*/
|
||||
QgsProcessingModelAlgorithm::ModelParameter ¶meterComponent( const QString &name );
|
||||
|
||||
|
||||
|
||||
QStringList dependentChildAlgorithms( const QString &childId ) const;
|
||||
|
||||
private:
|
||||
|
||||
QString mModelName;
|
||||
QString mModelGroup;
|
||||
|
||||
QMap< QString, ChildAlgorithm > mChildAlgorithms;
|
||||
|
||||
//! Map of parameter name to model parameter component
|
||||
QMap< QString, ModelParameter > mParameterComponents;
|
||||
};
|
||||
|
||||
#endif // QGSPROCESSINGMODELALGORITHM_H
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "qgsprocessingutils.h"
|
||||
#include "qgsprocessingalgorithm.h"
|
||||
#include "qgsprocessingcontext.h"
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
#include <QObject>
|
||||
#include <QtTest/QSignalSpy>
|
||||
#include "qgis.h"
|
||||
@ -103,6 +104,13 @@ class DummyAlgorithm : public QgsProcessingAlgorithm
|
||||
QgsProcessingParameterFeatureSink *p6 = new QgsProcessingParameterFeatureSink( "p6" );
|
||||
QVERIFY( addParameter( p6 ) );
|
||||
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 << p6 );
|
||||
|
||||
// remove parameter
|
||||
removeParameter( "non existent" );
|
||||
removeParameter( "p6" );
|
||||
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 );
|
||||
removeParameter( "p5" );
|
||||
QVERIFY( destinationParameterDefinitions().isEmpty() );
|
||||
}
|
||||
|
||||
void runOutputChecks()
|
||||
@ -318,6 +326,7 @@ class TestQgsProcessing: public QObject
|
||||
void validateInputCrs();
|
||||
void generateIteratingDestination();
|
||||
void asPythonCommand();
|
||||
void modelerAlgorithm();
|
||||
|
||||
private:
|
||||
|
||||
@ -2918,5 +2927,250 @@ void TestQgsProcessing::asPythonCommand()
|
||||
alg.runAsPythonCommandChecks();
|
||||
}
|
||||
|
||||
void TestQgsProcessing::modelerAlgorithm()
|
||||
{
|
||||
//static value source
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource svSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||
QCOMPARE( svSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||
QCOMPARE( svSource.staticValue().toInt(), 5 );
|
||||
svSource.setStaticValue( 7 );
|
||||
QCOMPARE( svSource.staticValue().toInt(), 7 );
|
||||
svSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "a" );
|
||||
// check that calling setStaticValue flips source to StaticValue
|
||||
QCOMPARE( svSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ModelParameter );
|
||||
svSource.setStaticValue( 7 );
|
||||
QCOMPARE( svSource.staticValue().toInt(), 7 );
|
||||
QCOMPARE( svSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||
|
||||
// model parameter source
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource mpSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "a" );
|
||||
QCOMPARE( mpSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ModelParameter );
|
||||
QCOMPARE( mpSource.parameterName(), QStringLiteral( "a" ) );
|
||||
mpSource.setParameterName( "b" );
|
||||
QCOMPARE( mpSource.parameterName(), QStringLiteral( "b" ) );
|
||||
mpSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||
// check that calling setParameterName flips source to ModelParameter
|
||||
QCOMPARE( mpSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||
mpSource.setParameterName( "c" );
|
||||
QCOMPARE( mpSource.parameterName(), QStringLiteral( "c" ) );
|
||||
QCOMPARE( mpSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ModelParameter );
|
||||
|
||||
// child alg output source
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource oSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( "a", "b" );
|
||||
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ChildOutput );
|
||||
QCOMPARE( oSource.outputChildId(), QStringLiteral( "a" ) );
|
||||
QCOMPARE( oSource.outputName(), QStringLiteral( "b" ) );
|
||||
oSource.setOutputChildId( "c" );
|
||||
QCOMPARE( oSource.outputChildId(), QStringLiteral( "c" ) );
|
||||
oSource.setOutputName( "d" );
|
||||
QCOMPARE( oSource.outputName(), QStringLiteral( "d" ) );
|
||||
oSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||
// check that calling setOutputChildId flips source to ChildOutput
|
||||
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||
oSource.setOutputChildId( "c" );
|
||||
QCOMPARE( oSource.outputChildId(), QStringLiteral( "c" ) );
|
||||
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ChildOutput );
|
||||
oSource = QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 );
|
||||
// check that calling setOutputName flips source to ChildOutput
|
||||
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||
oSource.setOutputName( "d" );
|
||||
QCOMPARE( oSource.outputName(), QStringLiteral( "d" ) );
|
||||
QCOMPARE( oSource.source(), QgsProcessingModelAlgorithm::ChildParameterSource::ChildOutput );
|
||||
|
||||
// source equality operator
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) ==
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) !=
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 7 ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) !=
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) ==
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) !=
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "b" ) ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( QStringLiteral( "a" ) ) !=
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) ==
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) !=
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg2" ), QStringLiteral( "out" ) ) );
|
||||
QVERIFY( QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out" ) ) !=
|
||||
QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( QStringLiteral( "alg" ), QStringLiteral( "out2" ) ) );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm child( QStringLiteral( "some_id" ) );
|
||||
QCOMPARE( child.algorithmId(), QStringLiteral( "some_id" ) );
|
||||
QVERIFY( !child.algorithm() );
|
||||
child.setAlgorithmId( QStringLiteral( "native:centroids" ) );
|
||||
QVERIFY( child.algorithm() );
|
||||
QCOMPARE( child.algorithm()->id(), QStringLiteral( "native:centroids" ) );
|
||||
child.setDescription( QStringLiteral( "desc" ) );
|
||||
QCOMPARE( child.description(), QStringLiteral( "desc" ) );
|
||||
QVERIFY( child.isActive() );
|
||||
child.setActive( false );
|
||||
QVERIFY( !child.isActive() );
|
||||
child.setPosition( QPointF( 1, 2 ) );
|
||||
QCOMPARE( child.position(), QPointF( 1, 2 ) );
|
||||
QVERIFY( child.parametersCollapsed() );
|
||||
child.setParametersCollapsed( false );
|
||||
QVERIFY( !child.parametersCollapsed() );
|
||||
QVERIFY( child.outputsCollapsed() );
|
||||
child.setOutputsCollapsed( false );
|
||||
QVERIFY( !child.outputsCollapsed() );
|
||||
|
||||
child.setChildId( QStringLiteral( "my_id" ) );
|
||||
QCOMPARE( child.childId(), QStringLiteral( "my_id" ) );
|
||||
|
||||
child.setDependencies( QStringList() << "a" << "b" );
|
||||
QCOMPARE( child.dependencies(), QStringList() << "a" << "b" );
|
||||
|
||||
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource > sources;
|
||||
sources.insert( QStringLiteral( "a" ), QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) );
|
||||
child.setParameterSources( sources );
|
||||
QCOMPARE( child.parameterSources().value( QStringLiteral( "a" ) ).staticValue().toInt(), 5 );
|
||||
child.addParameterSource( QStringLiteral( "b" ), QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 7 ) );
|
||||
QCOMPARE( child.parameterSources().value( QStringLiteral( "a" ) ).staticValue().toInt(), 5 );
|
||||
QCOMPARE( child.parameterSources().value( QStringLiteral( "b" ) ).staticValue().toInt(), 7 );
|
||||
|
||||
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" ) );
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs;
|
||||
QgsProcessingModelAlgorithm::ModelOutput out1;
|
||||
out1.setDescription( QStringLiteral( "my output" ) );
|
||||
outputs.insert( QStringLiteral( "a" ), out1 );
|
||||
child.setModelOutputs( outputs );
|
||||
QCOMPARE( child.modelOutputs().count(), 1 );
|
||||
QCOMPARE( child.modelOutputs().value( QStringLiteral( "a" ) ).description(), QStringLiteral( "my output" ) );
|
||||
QCOMPARE( child.modelOutput( "a" ).description(), QStringLiteral( "my output" ) );
|
||||
child.modelOutput( "a" ).setDescription( QStringLiteral( "my output 2" ) );
|
||||
QCOMPARE( child.modelOutput( "a" ).description(), QStringLiteral( "my output 2" ) );
|
||||
// no existent
|
||||
child.modelOutput( "b" ).setDescription( QStringLiteral( "my output 3" ) );
|
||||
QCOMPARE( child.modelOutput( "b" ).description(), QStringLiteral( "my output 3" ) );
|
||||
QCOMPARE( child.modelOutputs().count(), 2 );
|
||||
|
||||
|
||||
|
||||
// model algorithm tests
|
||||
|
||||
|
||||
QgsProcessingModelAlgorithm alg( "test", "testGroup" );
|
||||
QCOMPARE( alg.name(), QStringLiteral( "test" ) );
|
||||
QCOMPARE( alg.displayName(), QStringLiteral( "test" ) );
|
||||
QCOMPARE( alg.group(), QStringLiteral( "testGroup" ) );
|
||||
|
||||
// child algorithms
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> algs;
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm a1;
|
||||
a1.setDescription( QStringLiteral( "alg1" ) );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm a2;
|
||||
a2.setDescription( QStringLiteral( "alg2" ) );
|
||||
algs.insert( QStringLiteral( "a" ), a1 );
|
||||
algs.insert( QStringLiteral( "b" ), a2 );
|
||||
alg.setChildAlgorithms( algs );
|
||||
QCOMPARE( alg.childAlgorithms().count(), 2 );
|
||||
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "a" ) ).description(), QStringLiteral( "alg1" ) );
|
||||
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "b" ) ).description(), QStringLiteral( "alg2" ) );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm a3;
|
||||
a3.setChildId( QStringLiteral( "c" ) );
|
||||
a3.setDescription( QStringLiteral( "alg3" ) );
|
||||
QCOMPARE( alg.addChildAlgorithm( a3 ), QStringLiteral( "c" ) );
|
||||
QCOMPARE( alg.childAlgorithms().count(), 3 );
|
||||
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "a" ) ).description(), QStringLiteral( "alg1" ) );
|
||||
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "b" ) ).description(), QStringLiteral( "alg2" ) );
|
||||
QCOMPARE( alg.childAlgorithms().value( QStringLiteral( "c" ) ).description(), QStringLiteral( "alg3" ) );
|
||||
QCOMPARE( alg.childAlgorithm( "a" ).description(), QStringLiteral( "alg1" ) );
|
||||
QCOMPARE( alg.childAlgorithm( "b" ).description(), QStringLiteral( "alg2" ) );
|
||||
QCOMPARE( alg.childAlgorithm( "c" ).description(), QStringLiteral( "alg3" ) );
|
||||
// initially non-existent
|
||||
QVERIFY( alg.childAlgorithm( "d" ).description().isEmpty() );
|
||||
alg.childAlgorithm( "d" ).setDescription( QStringLiteral( "alg4" ) );
|
||||
QCOMPARE( alg.childAlgorithm( "d" ).description(), QStringLiteral( "alg4" ) );
|
||||
// overwrite existing
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm a4a;
|
||||
a4a.setChildId( "d" );
|
||||
a4a.setDescription( "new" );
|
||||
alg.setChildAlgorithm( a4a );
|
||||
QCOMPARE( alg.childAlgorithm( "d" ).description(), QStringLiteral( "new" ) );
|
||||
|
||||
// generating child ids
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm c1;
|
||||
c1.setAlgorithmId( QStringLiteral( "buffer" ) );
|
||||
c1.generateChildId( alg );
|
||||
QCOMPARE( c1.childId(), QStringLiteral( "buffer_1" ) );
|
||||
QCOMPARE( alg.addChildAlgorithm( c1 ), QStringLiteral( "buffer_1" ) );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm c2;
|
||||
c2.setAlgorithmId( QStringLiteral( "buffer" ) );
|
||||
c2.generateChildId( alg );
|
||||
QCOMPARE( c2.childId(), QStringLiteral( "buffer_2" ) );
|
||||
QCOMPARE( alg.addChildAlgorithm( c2 ), QStringLiteral( "buffer_2" ) );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm c3;
|
||||
c3.setAlgorithmId( QStringLiteral( "centroid" ) );
|
||||
c3.generateChildId( alg );
|
||||
QCOMPARE( c3.childId(), QStringLiteral( "centroid_1" ) );
|
||||
QCOMPARE( alg.addChildAlgorithm( c3 ), QStringLiteral( "centroid_1" ) );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm c4;
|
||||
c4.setAlgorithmId( QStringLiteral( "centroid" ) );
|
||||
c4.setChildId( QStringLiteral( "centroid_1" ) );// dupe id
|
||||
QCOMPARE( alg.addChildAlgorithm( c4 ), QStringLiteral( "centroid_2" ) );
|
||||
QCOMPARE( alg.childAlgorithm( QStringLiteral( "centroid_2" ) ).childId(), QStringLiteral( "centroid_2" ) );
|
||||
|
||||
// parameter components
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> pComponents;
|
||||
QgsProcessingModelAlgorithm::ModelParameter pc1;
|
||||
pc1.setParameterName( QStringLiteral( "my_param" ) );
|
||||
QCOMPARE( pc1.parameterName(), QStringLiteral( "my_param" ) );
|
||||
pComponents.insert( QStringLiteral( "my_param" ), pc1 );
|
||||
alg.setParameterComponents( pComponents );
|
||||
QCOMPARE( alg.parameterComponents().count(), 1 );
|
||||
QCOMPARE( alg.parameterComponents().value( QStringLiteral( "my_param" ) ).parameterName(), QStringLiteral( "my_param" ) );
|
||||
QCOMPARE( alg.parameterComponent( "my_param" ).parameterName(), QStringLiteral( "my_param" ) );
|
||||
alg.parameterComponent( "my_param" ).setDescription( QStringLiteral( "my param 2" ) );
|
||||
QCOMPARE( alg.parameterComponent( "my_param" ).description(), QStringLiteral( "my param 2" ) );
|
||||
// no existent
|
||||
alg.parameterComponent( "b" ).setDescription( QStringLiteral( "my param 3" ) );
|
||||
QCOMPARE( alg.parameterComponent( "b" ).description(), QStringLiteral( "my param 3" ) );
|
||||
QCOMPARE( alg.parameterComponent( "b" ).parameterName(), QStringLiteral( "b" ) );
|
||||
QCOMPARE( alg.parameterComponents().count(), 2 );
|
||||
|
||||
// parameter definitions
|
||||
QgsProcessingModelAlgorithm alg1a( "test", "testGroup" );
|
||||
QgsProcessingModelAlgorithm::ModelParameter bool1;
|
||||
bool1.setPosition( QPointF( 1, 2 ) );
|
||||
alg1a.addModelParameter( new QgsProcessingParameterBoolean( "p1", "desc" ), bool1 );
|
||||
QCOMPARE( alg1a.parameterDefinitions().count(), 1 );
|
||||
QCOMPARE( alg1a.parameterDefinition( "p1" )->type(), QStringLiteral( "boolean" ) );
|
||||
QCOMPARE( alg1a.parameterComponent( "p1" ).position().x(), 1.0 );
|
||||
QCOMPARE( alg1a.parameterComponent( "p1" ).position().y(), 2.0 );
|
||||
alg1a.updateModelParameter( new QgsProcessingParameterBoolean( "p1", "descx" ) );
|
||||
QCOMPARE( alg1a.parameterDefinition( "p1" )->description(), QStringLiteral( "descx" ) );
|
||||
alg1a.removeModelParameter( "bad" );
|
||||
QCOMPARE( alg1a.parameterDefinitions().count(), 1 );
|
||||
alg1a.removeModelParameter( "p1" );
|
||||
QVERIFY( alg1a.parameterDefinitions().isEmpty() );
|
||||
QVERIFY( alg1a.parameterComponents().isEmpty() );
|
||||
|
||||
|
||||
// test canExecute
|
||||
QgsProcessingModelAlgorithm alg2( "test", "testGroup" );
|
||||
QVERIFY( alg2.canExecute() );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm c5;
|
||||
c5.setAlgorithmId( "native:centroids" );
|
||||
alg2.addChildAlgorithm( c5 );
|
||||
QVERIFY( alg2.canExecute() );
|
||||
// non-existing alg
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm c6;
|
||||
c6.setAlgorithmId( "i'm not an alg" );
|
||||
alg2.addChildAlgorithm( c6 );
|
||||
QVERIFY( !alg2.canExecute() );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsProcessing )
|
||||
#include "testqgsprocessing.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user