diff --git a/python/core/processing/models/qgsprocessingmodelalgorithm.sip b/python/core/processing/models/qgsprocessingmodelalgorithm.sip index a940fcbf7b2..bb4dd8e70e6 100644 --- a/python/core/processing/models/qgsprocessingmodelalgorithm.sip +++ b/python/core/processing/models/qgsprocessingmodelalgorithm.sip @@ -46,7 +46,7 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm virtual QString asPythonCommand( const QVariantMap ¶meters, QgsProcessingContext &context ) const; - virtual QgsProcessingModelAlgorithm *create() const /Factory/; + virtual QgsProcessingModelAlgorithm *createInstance() const /Factory/; void setName( const QString &name ); diff --git a/python/core/processing/qgsprocessingalgorithm.sip b/python/core/processing/qgsprocessingalgorithm.sip index a6a39c7fa0d..017c77624ba 100644 --- a/python/core/processing/qgsprocessingalgorithm.sip +++ b/python/core/processing/qgsprocessingalgorithm.sip @@ -43,8 +43,7 @@ class QgsProcessingAlgorithm virtual ~QgsProcessingAlgorithm(); - - virtual QgsProcessingAlgorithm *create() const = 0 /Factory/; + QgsProcessingAlgorithm *create() const /Factory/; %Docstring Creates a copy of the algorithm, ready for execution. :rtype: QgsProcessingAlgorithm @@ -332,6 +331,14 @@ class QgsProcessingAlgorithm protected: + virtual QgsProcessingAlgorithm *createInstance() const = 0 /Factory/; +%Docstring + Creates a new instance of the algorithm class. + + This method should return a 'pristine' instance of the algorithm class. + :rtype: QgsProcessingAlgorithm +%End + bool addParameter( QgsProcessingParameterDefinition *parameterDefinition /Transfer/ ); %Docstring Adds a parameter ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm. diff --git a/python/plugins/processing/algs/qgis/QgisAlgorithm.py b/python/plugins/processing/algs/qgis/QgisAlgorithm.py index 8576a06618d..1321e6b7d70 100755 --- a/python/plugins/processing/algs/qgis/QgisAlgorithm.py +++ b/python/plugins/processing/algs/qgis/QgisAlgorithm.py @@ -48,5 +48,5 @@ class QgisAlgorithm(QgsProcessingAlgorithm): context = self.__class__.__name__ return string, QCoreApplication.translate(context, string) - def create(self): + def createInstance(self): return type(self)() diff --git a/python/plugins/processing/script/ScriptAlgorithm.py b/python/plugins/processing/script/ScriptAlgorithm.py index 631f8f06295..add5d336e2a 100644 --- a/python/plugins/processing/script/ScriptAlgorithm.py +++ b/python/plugins/processing/script/ScriptAlgorithm.py @@ -79,7 +79,7 @@ class ScriptAlgorithm(QgsProcessingAlgorithm): self.cleaned_script = None self.results = {} - def create(self): + def createInstance(self): return ScriptAlgorithm(self.descriptionFile) def icon(self): diff --git a/python/plugins/processing/tests/QgisAlgorithmsTest.py b/python/plugins/processing/tests/QgisAlgorithmsTest.py index ea8c028c47c..02f5a20c0d7 100644 --- a/python/plugins/processing/tests/QgisAlgorithmsTest.py +++ b/python/plugins/processing/tests/QgisAlgorithmsTest.py @@ -48,7 +48,7 @@ class TestAlg(QgsProcessingAlgorithm): def displayName(self): return 'testalg' - def create(self): + def createInstance(self): return TestAlg() def processAlgorithm(self, parameters, context, feedback): diff --git a/src/core/processing/models/qgsprocessingmodelalgorithm.cpp b/src/core/processing/models/qgsprocessingmodelalgorithm.cpp index 845196d051d..6b121d9b53d 100644 --- a/src/core/processing/models/qgsprocessingmodelalgorithm.cpp +++ b/src/core/processing/models/qgsprocessingmodelalgorithm.cpp @@ -1100,7 +1100,7 @@ QString QgsProcessingModelAlgorithm::asPythonCommand( const QVariantMap ¶met return QgsProcessingAlgorithm::asPythonCommand( parameters, context ); } -QgsProcessingModelAlgorithm *QgsProcessingModelAlgorithm::create() const +QgsProcessingAlgorithm *QgsProcessingModelAlgorithm::createInstance() const { QgsProcessingModelAlgorithm *alg = new QgsProcessingModelAlgorithm(); alg->loadVariant( toVariant() ); diff --git a/src/core/processing/models/qgsprocessingmodelalgorithm.h b/src/core/processing/models/qgsprocessingmodelalgorithm.h index c39b975c224..46c2511fe34 100644 --- a/src/core/processing/models/qgsprocessingmodelalgorithm.h +++ b/src/core/processing/models/qgsprocessingmodelalgorithm.h @@ -52,7 +52,7 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm bool canExecute( QString *errorMessage SIP_OUT = nullptr ) const override; QString asPythonCommand( const QVariantMap ¶meters, QgsProcessingContext &context ) const override; - QgsProcessingModelAlgorithm *create() const override SIP_FACTORY; + QgsProcessingAlgorithm *createInstance() const override SIP_FACTORY; /** * Sets the model \a name. diff --git a/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp b/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp index 76a28c55707..96e13f44f3c 100644 --- a/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp +++ b/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp @@ -208,10 +208,6 @@ void QgsProcessingModelChildAlgorithm::setAlgorithmId( const QString &algorithmI { mAlgorithmId = algorithmId; mAlgorithm.reset( QgsApplication::processingRegistry()->createAlgorithmById( mAlgorithmId ) ); - if ( mAlgorithm ) - { - mAlgorithm->init( QVariantMap() ); - } } ///@endcond diff --git a/src/core/processing/qgsnativealgorithms.cpp b/src/core/processing/qgsnativealgorithms.cpp index f262d2b280e..8655764f504 100644 --- a/src/core/processing/qgsnativealgorithms.cpp +++ b/src/core/processing/qgsnativealgorithms.cpp @@ -84,7 +84,7 @@ QString QgsCentroidAlgorithm::shortHelpString() const "The attributes associated to each point in the output layer are the same ones associated to the original features." ); } -QgsCentroidAlgorithm *QgsCentroidAlgorithm::create() const +QgsCentroidAlgorithm *QgsCentroidAlgorithm::createInstance() const { return new QgsCentroidAlgorithm(); } @@ -164,7 +164,7 @@ QString QgsBufferAlgorithm::shortHelpString() const "The mitre limit parameter is only applicable for mitre join styles, and controls the maximum distance from the offset curve to use when creating a mitred join." ); } -QgsBufferAlgorithm *QgsBufferAlgorithm::create() const +QgsBufferAlgorithm *QgsBufferAlgorithm::createInstance() const { return new QgsBufferAlgorithm(); } @@ -273,7 +273,7 @@ QString QgsDissolveAlgorithm::shortHelpString() const "In case the input is a polygon layer, common boundaries of adjacent polygons being dissolved will get erased." ); } -QgsDissolveAlgorithm *QgsDissolveAlgorithm::create() const +QgsDissolveAlgorithm *QgsDissolveAlgorithm::createInstance() const { return new QgsDissolveAlgorithm(); } @@ -430,7 +430,7 @@ QString QgsClipAlgorithm::shortHelpString() const "be manually updated." ); } -QgsClipAlgorithm *QgsClipAlgorithm::create() const +QgsClipAlgorithm *QgsClipAlgorithm::createInstance() const { return new QgsClipAlgorithm(); } @@ -583,7 +583,7 @@ QString QgsTransformAlgorithm::shortHelpString() const "Attributes are not modified by this algorithm." ); } -QgsTransformAlgorithm *QgsTransformAlgorithm::create() const +QgsTransformAlgorithm *QgsTransformAlgorithm::createInstance() const { return new QgsTransformAlgorithm(); } @@ -652,7 +652,7 @@ QString QgsSubdivideAlgorithm::shortHelpString() const "Curved geometries will be segmentized before subdivision." ); } -QgsSubdivideAlgorithm *QgsSubdivideAlgorithm::create() const +QgsSubdivideAlgorithm *QgsSubdivideAlgorithm::createInstance() const { return new QgsSubdivideAlgorithm(); } @@ -723,7 +723,7 @@ QString QgsMultipartToSinglepartAlgorithm::shortHelpString() const "contain, and the same attributes are used for each of them." ); } -QgsMultipartToSinglepartAlgorithm *QgsMultipartToSinglepartAlgorithm::create() const +QgsMultipartToSinglepartAlgorithm *QgsMultipartToSinglepartAlgorithm::createInstance() const { return new QgsMultipartToSinglepartAlgorithm(); } @@ -810,7 +810,7 @@ QString QgsExtractByExpressionAlgorithm::shortHelpString() const "For more information about expressions see the user manual" ); } -QgsExtractByExpressionAlgorithm *QgsExtractByExpressionAlgorithm::create() const +QgsExtractByExpressionAlgorithm *QgsExtractByExpressionAlgorithm::createInstance() const { return new QgsExtractByExpressionAlgorithm(); } @@ -941,7 +941,7 @@ QString QgsExtractByAttributeAlgorithm::shortHelpString() const "of an attribute from the input layer." ); } -QgsExtractByAttributeAlgorithm *QgsExtractByAttributeAlgorithm::create() const +QgsExtractByAttributeAlgorithm *QgsExtractByAttributeAlgorithm::createInstance() const { return new QgsExtractByAttributeAlgorithm(); } diff --git a/src/core/processing/qgsnativealgorithms.h b/src/core/processing/qgsnativealgorithms.h index 8327f77caf5..5c9aca4ee6e 100644 --- a/src/core/processing/qgsnativealgorithms.h +++ b/src/core/processing/qgsnativealgorithms.h @@ -60,7 +60,7 @@ class QgsCentroidAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "centroid,center,average,point,middle" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector geometry tools" ); } QString shortHelpString() const override; - QgsCentroidAlgorithm *create() const override SIP_FACTORY; + QgsCentroidAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -84,7 +84,7 @@ class QgsTransformAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "transform,reproject,crs,srs,warp" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector general tools" ); } QString shortHelpString() const override; - QgsTransformAlgorithm *create() const override SIP_FACTORY; + QgsTransformAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -108,7 +108,7 @@ class QgsBufferAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "buffer,grow" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector geometry tools" ); } QString shortHelpString() const override; - QgsBufferAlgorithm *create() const override SIP_FACTORY; + QgsBufferAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -132,7 +132,7 @@ class QgsDissolveAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "dissolve,union,combine,collect" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector geometry tools" ); } QString shortHelpString() const override; - QgsDissolveAlgorithm *create() const override SIP_FACTORY; + QgsDissolveAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -171,7 +171,7 @@ class QgsExtractByAttributeAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "extract,filter,attribute,value,contains,null,field" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector selection tools" ); } QString shortHelpString() const override; - QgsExtractByAttributeAlgorithm *create() const override SIP_FACTORY; + QgsExtractByAttributeAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -195,7 +195,7 @@ class QgsExtractByExpressionAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "extract,filter,expression,field" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector selection tools" ); } QString shortHelpString() const override; - QgsExtractByExpressionAlgorithm *create() const override SIP_FACTORY; + QgsExtractByExpressionAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -219,7 +219,7 @@ class QgsClipAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "clip,intersect,intersection,mask" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector overlay tools" ); } QString shortHelpString() const override; - QgsClipAlgorithm *create() const override SIP_FACTORY; + QgsClipAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -244,7 +244,7 @@ class QgsSubdivideAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "subdivide,segmentize,split,tesselate" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector geometry tools" ); } QString shortHelpString() const override; - QgsSubdivideAlgorithm *create() const override SIP_FACTORY; + QgsSubdivideAlgorithm *createInstance() const override SIP_FACTORY; protected: @@ -268,7 +268,7 @@ class QgsMultipartToSinglepartAlgorithm : public QgsProcessingAlgorithm virtual QStringList tags() const override { return QObject::tr( "multi,single,multiple,split,dump" ).split( ',' ); } QString group() const override { return QObject::tr( "Vector geometry tools" ); } QString shortHelpString() const override; - QgsMultipartToSinglepartAlgorithm *create() const override SIP_FACTORY; + QgsMultipartToSinglepartAlgorithm *createInstance() const override SIP_FACTORY; protected: diff --git a/src/core/processing/qgsprocessingalgorithm.cpp b/src/core/processing/qgsprocessingalgorithm.cpp index 9a0432a10be..09f71e93828 100644 --- a/src/core/processing/qgsprocessingalgorithm.cpp +++ b/src/core/processing/qgsprocessingalgorithm.cpp @@ -33,6 +33,13 @@ QgsProcessingAlgorithm::~QgsProcessingAlgorithm() qDeleteAll( mOutputs ); } +QgsProcessingAlgorithm *QgsProcessingAlgorithm::create() const +{ + std::unique_ptr< QgsProcessingAlgorithm > creation( createInstance() ); + creation->setProvider( provider() ); + return creation.release(); +} + QString QgsProcessingAlgorithm::id() const { if ( mProvider ) diff --git a/src/core/processing/qgsprocessingalgorithm.h b/src/core/processing/qgsprocessingalgorithm.h index 35eb6351721..22f22c004cb 100644 --- a/src/core/processing/qgsprocessingalgorithm.h +++ b/src/core/processing/qgsprocessingalgorithm.h @@ -70,7 +70,7 @@ class CORE_EXPORT QgsProcessingAlgorithm /** * Creates a copy of the algorithm, ready for execution. */ - virtual QgsProcessingAlgorithm *create() const = 0 SIP_FACTORY; + QgsProcessingAlgorithm *create() const SIP_FACTORY; /** * Returns the algorithm name, used for identifying the algorithm. This string @@ -317,6 +317,13 @@ class CORE_EXPORT QgsProcessingAlgorithm protected: + /** + * Creates a new instance of the algorithm class. + * + * This method should return a 'pristine' instance of the algorithm class. + */ + virtual QgsProcessingAlgorithm *createInstance() const = 0 SIP_FACTORY; + /** * Adds a parameter \a definition to the algorithm. Ownership of the definition is transferred to the algorithm. * Returns true if parameter could be successfully added, or false if the parameter could not be added (e.g. diff --git a/tests/src/core/testqgsprocessing.cpp b/tests/src/core/testqgsprocessing.cpp index ecefb97458f..54a77cd4a6d 100644 --- a/tests/src/core/testqgsprocessing.cpp +++ b/tests/src/core/testqgsprocessing.cpp @@ -45,7 +45,7 @@ class DummyAlgorithm : public QgsProcessingAlgorithm QVariantMap processAlgorithm( const QVariantMap &, QgsProcessingContext &, QgsProcessingFeedback * ) override { return QVariantMap(); } virtual Flags flags() const override { return mFlags; } - DummyAlgorithm *create() const override { return new DummyAlgorithm( name() ); } + DummyAlgorithm *createInstance() const override { return new DummyAlgorithm( name() ); } QString mName; @@ -334,6 +334,7 @@ class TestQgsProcessing: public QObject void modelAcceptableValues(); void tempUtils(); void convertCompatible(); + void create(); private: @@ -5126,5 +5127,16 @@ void TestQgsProcessing::convertCompatible() QVERIFY( out.startsWith( QgsProcessingUtils::tempFolder() ) ); } +void TestQgsProcessing::create() +{ + DummyAlgorithm alg( QStringLiteral( "test" ) ); + DummyProvider p( QStringLiteral( "test_provider" ) ); + alg.setProvider( &p ); + + std::unique_ptr< QgsProcessingAlgorithm > newInstance( alg.create() ); + QVERIFY( newInstance.get() ); + QCOMPARE( newInstance->provider(), &p ); +} + QGSTEST_MAIN( TestQgsProcessing ) #include "testqgsprocessing.moc"