Skip to content

Commit 058271b

Browse files
committedJul 11, 2017
Auto create corresponding outputs when adding destination style
parameters to an algorithm QgsProcessingAlgorithm::addParameter() has a new createOuput argument (true by default). If the createOutput argument is true, then a corresponding output definition will also be created (and added to the algorithm) where appropriate. E.g. when adding a QgsProcessingParameterVectorDestination and createOutput is true, then a QgsProcessingOutputVectorLayer output will be created and added to the algorithm. There is no need to call addOutput() to manually add a corresponding output for this vector. If createOutput is false then this automatic output creation will not occur. This should simplify declaration of outputs for algorithms as it avoids the need to manually declare these corresponding outputs.
1 parent 18b52b2 commit 058271b

File tree

4 files changed

+69
-7
lines changed

4 files changed

+69
-7
lines changed
 

‎python/core/processing/qgsprocessingalgorithm.sip

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,14 +392,21 @@ class QgsProcessingAlgorithm
392392
.. seealso:: addOutput()
393393
%End
394394

395-
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition /Transfer/ );
395+
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition /Transfer/, bool createOutput = true );
396396
%Docstring
397397
Adds a parameter ``definition`` to the algorithm. Ownership of the definition is transferred to the algorithm.
398398
Returns true if parameter could be successfully added, or false if the parameter could not be added (e.g.
399399
as a result of a duplicate name).
400400

401401
This should usually be called from a subclass' initAlgorithm() implementation.
402402

403+
If the ``createOutput`` argument is true, then a corresponding output definition will also be created
404+
(and added to the algorithm) where appropriate. E.g. when adding a QgsProcessingParameterVectorDestination
405+
and ``createOutput`` is true, then a QgsProcessingOutputVectorLayer output will be created and
406+
added to the algorithm. There is no need to call addOutput() to manually add a corresponding output
407+
for this vector. If ``createOutput`` is false then this automatic output creation will not
408+
occur.
409+
403410
.. seealso:: initAlgorithm()
404411
.. seealso:: addOutput()
405412
:rtype: bool
@@ -419,6 +426,9 @@ class QgsProcessingAlgorithm
419426

420427
This should usually be called from a subclass' initAlgorithm() implementation.
421428

429+
Note that in some cases output creation can be automatically performed when calling addParameter().
430+
See the notes in addParameter() for a description of when this occurs.
431+
422432
.. seealso:: addParameter()
423433
.. seealso:: initAlgorithm()
424434
:rtype: bool

‎src/core/processing/qgsprocessingalgorithm.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ QString QgsProcessingAlgorithm::asPythonCommand( const QVariantMap &parameters,
226226
return s;
227227
}
228228

229-
bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *definition )
229+
bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *definition, bool createOutput )
230230
{
231231
if ( !definition )
232232
return false;
@@ -242,7 +242,11 @@ bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *def
242242
}
243243

244244
mParameters << definition;
245-
return true;
245+
246+
if ( createOutput )
247+
return createAutoOutputForParameter( definition );
248+
else
249+
return true;
246250
}
247251

248252
void QgsProcessingAlgorithm::removeParameter( const QString &name )
@@ -581,4 +585,26 @@ QStringList QgsProcessingAlgorithm::parameterAsFields( const QVariantMap &parame
581585
return QgsProcessingParameters::parameterAsFields( parameterDefinition( name ), parameters, context );
582586
}
583587

588+
bool QgsProcessingAlgorithm::createAutoOutputForParameter( QgsProcessingParameterDefinition *parameter )
589+
{
590+
if ( !parameter->isDestination() )
591+
return true; // nothing created, but nothing went wrong - so return true
592+
593+
QgsProcessingDestinationParameter *dest = static_cast< QgsProcessingDestinationParameter * >( parameter );
594+
QgsProcessingOutputDefinition *output( dest->toOutputDefinition() );
595+
if ( !output )
596+
return true; // nothing created - but nothing went wrong - so return true
597+
598+
if ( !addOutput( output ) )
599+
{
600+
// couldn't add output - probably a duplicate name
601+
delete output;
602+
return false;
603+
}
604+
else
605+
{
606+
return true;
607+
}
608+
}
609+
584610

‎src/core/processing/qgsprocessingalgorithm.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,10 +391,17 @@ class CORE_EXPORT QgsProcessingAlgorithm
391391
*
392392
* This should usually be called from a subclass' initAlgorithm() implementation.
393393
*
394+
* If the \a createOutput argument is true, then a corresponding output definition will also be created
395+
* (and added to the algorithm) where appropriate. E.g. when adding a QgsProcessingParameterVectorDestination
396+
* and \a createOutput is true, then a QgsProcessingOutputVectorLayer output will be created and
397+
* added to the algorithm. There is no need to call addOutput() to manually add a corresponding output
398+
* for this vector. If \a createOutput is false then this automatic output creation will not
399+
* occur.
400+
*
394401
* \see initAlgorithm()
395402
* \see addOutput()
396403
*/
397-
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition SIP_TRANSFER );
404+
bool addParameter( QgsProcessingParameterDefinition *parameterDefinition SIP_TRANSFER, bool createOutput = true );
398405

399406
/**
400407
* Removes the parameter with matching \a name from the algorithm, and deletes any existing
@@ -409,6 +416,9 @@ class CORE_EXPORT QgsProcessingAlgorithm
409416
*
410417
* This should usually be called from a subclass' initAlgorithm() implementation.
411418
*
419+
* Note that in some cases output creation can be automatically performed when calling addParameter().
420+
* See the notes in addParameter() for a description of when this occurs.
421+
*
412422
* \see addParameter()
413423
* \see initAlgorithm()
414424
*/
@@ -672,7 +682,8 @@ class CORE_EXPORT QgsProcessingAlgorithm
672682
bool mHasPostProcessed = false;
673683
std::unique_ptr< QgsProcessingContext > mLocalContext;
674684

675-
// friend class to access setProvider() - we do not want this public!
685+
bool createAutoOutputForParameter( QgsProcessingParameterDefinition *parameter );
686+
676687
friend class QgsProcessingProvider;
677688
friend class TestQgsProcessing;
678689
friend class QgsProcessingModelAlgorithm;

‎tests/src/core/testqgsprocessing.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ class DummyAlgorithm : public QgsProcessingAlgorithm
101101
//destination styleparameters
102102
QVERIFY( destinationParameterDefinitions().isEmpty() );
103103
QgsProcessingParameterFeatureSink *p5 = new QgsProcessingParameterFeatureSink( "p5" );
104-
QVERIFY( addParameter( p5 ) );
104+
QVERIFY( addParameter( p5, false ) );
105105
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 );
106106
QgsProcessingParameterFeatureSink *p6 = new QgsProcessingParameterFeatureSink( "p6" );
107-
QVERIFY( addParameter( p6 ) );
107+
QVERIFY( addParameter( p6, false ) );
108108
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 << p6 );
109109

110110
// remove parameter
@@ -113,6 +113,21 @@ class DummyAlgorithm : public QgsProcessingAlgorithm
113113
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p5 );
114114
removeParameter( "p5" );
115115
QVERIFY( destinationParameterDefinitions().isEmpty() );
116+
117+
// try with auto output creation
118+
QgsProcessingParameterVectorDestination *p7 = new QgsProcessingParameterVectorDestination( "p7", "my output" );
119+
QVERIFY( addParameter( p7 ) );
120+
QCOMPARE( destinationParameterDefinitions(), QgsProcessingParameterDefinitions() << p7 );
121+
QVERIFY( outputDefinition( "p7" ) );
122+
QCOMPARE( outputDefinition( "p7" )->name(), QStringLiteral( "p7" ) );
123+
QCOMPARE( outputDefinition( "p7" )->type(), QStringLiteral( "outputVector" ) );
124+
QCOMPARE( outputDefinition( "p7" )->description(), QStringLiteral( "my output" ) );
125+
126+
// duplicate output name
127+
QVERIFY( addOutput( new QgsProcessingOutputVectorLayer( "p8" ) ) );
128+
QgsProcessingParameterVectorDestination *p8 = new QgsProcessingParameterVectorDestination( "p8" );
129+
// this should fail - it would result in a duplicate output name
130+
QVERIFY( !addParameter( p8 ) );
116131
}
117132

118133
void runOutputChecks()

0 commit comments

Comments
 (0)
Please sign in to comment.