Skip to content

Commit e91aed6

Browse files
committed
[processing] Force model outputs to respect constraints set by
their underlying algorithm's provider E.g. for model outputs generated by a saga algorithm, only sdat and shp files are valid outputs. So only give users choices of these instead of all formats. Also fixes temporary file names generated as part of model execution may use formats which are not compatible with the algorithm's provider. Fixes #18908
1 parent b856538 commit e91aed6

6 files changed

Lines changed: 273 additions & 12 deletions

File tree

python/core/auto_generated/processing/qgsprocessingparameters.sip.in

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,19 @@ Sets whether the destination should be created by default. For optional paramete
19011901
a value of false indicates that the destination should not be created by default.
19021902

19031903
.. seealso:: :py:func:`createByDefault`
1904+
%End
1905+
1906+
protected:
1907+
1908+
QgsProcessingProvider *originalProvider() const;
1909+
%Docstring
1910+
Original (source) provider which this parameter has been derived from.
1911+
In the case of destination parameters which are part of model algorithms, this
1912+
will reflect the child algorithm's provider which actually generates the
1913+
parameter, as opposed to the provider which this parameter belongs to (i.e.
1914+
the model provider)
1915+
1916+
.. versionadded:: 3.2
19041917
%End
19051918

19061919
};
@@ -1948,6 +1961,15 @@ Returns the type name for the parameter class.
19481961
virtual QString defaultFileExtension() const;
19491962

19501963

1964+
virtual QStringList supportedOutputVectorLayerExtensions() const;
1965+
%Docstring
1966+
Returns a list of the vector format file extensions supported by this parameter.
1967+
1968+
.. seealso:: :py:func:`defaultFileExtension`
1969+
1970+
.. versionadded:: 3.2
1971+
%End
1972+
19511973
QgsProcessing::SourceType dataType() const;
19521974
%Docstring
19531975
Returns the layer type for sinks associated with the parameter.
@@ -2029,6 +2051,15 @@ Returns the type name for the parameter class.
20292051
virtual QString defaultFileExtension() const;
20302052

20312053

2054+
virtual QStringList supportedOutputVectorLayerExtensions() const;
2055+
%Docstring
2056+
Returns a list of the vector format file extensions supported by this parameter.
2057+
2058+
.. seealso:: :py:func:`defaultFileExtension`
2059+
2060+
.. versionadded:: 3.2
2061+
%End
2062+
20322063
QgsProcessing::SourceType dataType() const;
20332064
%Docstring
20342065
Returns the layer type for this created vector layer.
@@ -2103,6 +2134,15 @@ Returns the type name for the parameter class.
21032134
virtual QString defaultFileExtension() const;
21042135

21052136

2137+
virtual QStringList supportedOutputRasterLayerExtensions() const;
2138+
%Docstring
2139+
Returns a list of the raster format file extensions supported for this parameter.
2140+
2141+
.. seealso:: :py:func:`defaultFileExtension`
2142+
2143+
.. versionadded:: 3.2
2144+
%End
2145+
21062146
static QgsProcessingParameterRasterDestination *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) /Factory/;
21072147
%Docstring
21082148
Creates a new parameter using the definition from a script code.

python/plugins/processing/gui/ParameterGuiUtils.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,12 @@ def getFileFilter(param):
6868
elif param.type() == 'raster':
6969
return QgsProviderRegistry.instance().fileRasterFilters()
7070
elif param.type() == 'rasterDestination':
71-
if param.provider() is not None:
72-
exts = param.provider().supportedOutputRasterLayerExtensions()
73-
else:
74-
exts = QgsRasterFileWriter.supportedFormatExtensions()
71+
exts = param.supportedOutputRasterLayerExtensions()
7572
for i in range(len(exts)):
7673
exts[i] = tr('{0} files (*.{1})', 'ParameterRaster').format(exts[i].upper(), exts[i].lower())
7774
return ';;'.join(exts) + ';;' + tr('All files (*.*)')
7875
elif param.type() in ('sink', 'vectorDestination'):
79-
if param.provider() is not None:
80-
exts = param.provider().supportedOutputVectorLayerExtensions()
81-
else:
82-
exts = QgsVectorFileWriter.supportedFormatExtensions()
76+
exts = param.supportedOutputVectorLayerExtensions()
8377
for i in range(len(exts)):
8478
exts[i] = tr('{0} files (*.{1})', 'ParameterVector').format(exts[i].upper(), exts[i].lower())
8579
return ';;'.join(exts) + ';;' + tr('All files (*.*)')

src/core/processing/models/qgsprocessingmodelalgorithm.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,18 @@ void QgsProcessingModelAlgorithm::updateDestinationParameters()
791791
param->setName( outputIt->childId() + ':' + outputIt->name() );
792792
param->setDescription( outputIt->description() );
793793
param->setDefaultValue( outputIt->defaultValue() );
794-
addParameter( param.release() );
794+
795+
QgsProcessingDestinationParameter *newDestParam = dynamic_cast< QgsProcessingDestinationParameter * >( param.get() );
796+
if ( addParameter( param.release() ) && newDestParam )
797+
{
798+
if ( QgsProcessingProvider *provider = childIt->algorithm()->provider() )
799+
{
800+
// we need to copy the constraints given by the provider which creates this output across
801+
// and replace those which have been set to match the model provider's constraints
802+
newDestParam->setSupportsNonFileBasedOutput( provider->supportsNonFileBasedOutput() );
803+
newDestParam->mOriginalProvider = provider;
804+
}
805+
}
795806
}
796807
}
797808
}

src/core/processing/qgsprocessingparameters.cpp

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "qgsreferencedgeometry.h"
2828
#include "qgsprocessingregistry.h"
2929
#include "qgsprocessingparametertype.h"
30+
#include "qgsrasterfilewriter.h"
3031
#include <functional>
3132

3233

@@ -3366,7 +3367,11 @@ QgsProcessingOutputDefinition *QgsProcessingParameterFeatureSink::toOutputDefini
33663367

33673368
QString QgsProcessingParameterFeatureSink::defaultFileExtension() const
33683369
{
3369-
if ( QgsProcessingProvider *p = provider() )
3370+
if ( originalProvider() )
3371+
{
3372+
return originalProvider()->defaultVectorFileExtension( hasGeometry() );
3373+
}
3374+
else if ( QgsProcessingProvider *p = provider() )
33703375
{
33713376
return p->defaultVectorFileExtension( hasGeometry() );
33723377
}
@@ -3384,6 +3389,22 @@ QString QgsProcessingParameterFeatureSink::defaultFileExtension() const
33843389
}
33853390
}
33863391

3392+
QStringList QgsProcessingParameterFeatureSink::supportedOutputVectorLayerExtensions() const
3393+
{
3394+
if ( originalProvider() )
3395+
{
3396+
return originalProvider()->supportedOutputVectorLayerExtensions();
3397+
}
3398+
else if ( QgsProcessingProvider *p = provider() )
3399+
{
3400+
return p->supportedOutputVectorLayerExtensions();
3401+
}
3402+
else
3403+
{
3404+
return QgsVectorFileWriter::supportedFormatExtensions();
3405+
}
3406+
}
3407+
33873408
QgsProcessing::SourceType QgsProcessingParameterFeatureSink::dataType() const
33883409
{
33893410
return mDataType;
@@ -3538,7 +3559,11 @@ QgsProcessingOutputDefinition *QgsProcessingParameterRasterDestination::toOutput
35383559

35393560
QString QgsProcessingParameterRasterDestination::defaultFileExtension() const
35403561
{
3541-
if ( QgsProcessingProvider *p = provider() )
3562+
if ( originalProvider() )
3563+
{
3564+
return originalProvider()->defaultRasterFileExtension();
3565+
}
3566+
else if ( QgsProcessingProvider *p = provider() )
35423567
{
35433568
return p->defaultRasterFileExtension();
35443569
}
@@ -3549,6 +3574,22 @@ QString QgsProcessingParameterRasterDestination::defaultFileExtension() const
35493574
}
35503575
}
35513576

3577+
QStringList QgsProcessingParameterRasterDestination::supportedOutputRasterLayerExtensions() const
3578+
{
3579+
if ( originalProvider() )
3580+
{
3581+
return originalProvider()->supportedOutputRasterLayerExtensions();
3582+
}
3583+
else if ( QgsProcessingProvider *p = provider() )
3584+
{
3585+
return p->supportedOutputRasterLayerExtensions();
3586+
}
3587+
else
3588+
{
3589+
return QgsRasterFileWriter::supportedFormatExtensions();
3590+
}
3591+
}
3592+
35523593
QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
35533594
{
35543595
return new QgsProcessingParameterRasterDestination( name, description, definition.isEmpty() ? QVariant() : definition, isOptional );
@@ -3886,7 +3927,11 @@ QgsProcessingOutputDefinition *QgsProcessingParameterVectorDestination::toOutput
38863927

38873928
QString QgsProcessingParameterVectorDestination::defaultFileExtension() const
38883929
{
3889-
if ( QgsProcessingProvider *p = provider() )
3930+
if ( originalProvider() )
3931+
{
3932+
return originalProvider()->defaultVectorFileExtension( hasGeometry() );
3933+
}
3934+
else if ( QgsProcessingProvider *p = provider() )
38903935
{
38913936
return p->defaultVectorFileExtension( hasGeometry() );
38923937
}
@@ -3904,6 +3949,22 @@ QString QgsProcessingParameterVectorDestination::defaultFileExtension() const
39043949
}
39053950
}
39063951

3952+
QStringList QgsProcessingParameterVectorDestination::supportedOutputVectorLayerExtensions() const
3953+
{
3954+
if ( originalProvider() )
3955+
{
3956+
return originalProvider()->supportedOutputVectorLayerExtensions();
3957+
}
3958+
else if ( QgsProcessingProvider *p = provider() )
3959+
{
3960+
return p->supportedOutputVectorLayerExtensions();
3961+
}
3962+
else
3963+
{
3964+
return QgsVectorFileWriter::supportedFormatExtensions();
3965+
}
3966+
}
3967+
39073968
QgsProcessing::SourceType QgsProcessingParameterVectorDestination::dataType() const
39083969
{
39093970
return mDataType;

src/core/processing/qgsprocessingparameters.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,11 +1831,34 @@ class CORE_EXPORT QgsProcessingDestinationParameter : public QgsProcessingParame
18311831
*/
18321832
void setCreateByDefault( bool createByDefault );
18331833

1834+
protected:
1835+
1836+
/**
1837+
* Original (source) provider which this parameter has been derived from.
1838+
* In the case of destination parameters which are part of model algorithms, this
1839+
* will reflect the child algorithm's provider which actually generates the
1840+
* parameter, as opposed to the provider which this parameter belongs to (i.e.
1841+
* the model provider)
1842+
* \since QGIS 3.2
1843+
*/
1844+
QgsProcessingProvider *originalProvider() const { return mOriginalProvider; }
1845+
18341846
private:
18351847

1848+
/**
1849+
* Original (source) provider which this parameter has been derived from.
1850+
* In the case of destination parameters which are part of model algorithms, this
1851+
* will reflect the child algorithm's provider which actually generates the
1852+
* parameter, as opposed to the provider which this parameter belongs to (i.e.
1853+
* the model provider)
1854+
*/
1855+
QgsProcessingProvider *mOriginalProvider = nullptr;
1856+
18361857
bool mSupportsNonFileBasedOutputs = true;
18371858
bool mCreateByDefault = true;
18381859

1860+
friend class QgsProcessingModelAlgorithm;
1861+
friend class TestQgsProcessing;
18391862
};
18401863

18411864

@@ -1872,6 +1895,13 @@ class CORE_EXPORT QgsProcessingParameterFeatureSink : public QgsProcessingDestin
18721895
QgsProcessingOutputDefinition *toOutputDefinition() const override SIP_FACTORY;
18731896
QString defaultFileExtension() const override;
18741897

1898+
/**
1899+
* Returns a list of the vector format file extensions supported by this parameter.
1900+
* \see defaultFileExtension()
1901+
* \since QGIS 3.2
1902+
*/
1903+
virtual QStringList supportedOutputVectorLayerExtensions() const;
1904+
18751905
/**
18761906
* Returns the layer type for sinks associated with the parameter.
18771907
* \see setDataType()
@@ -1940,6 +1970,13 @@ class CORE_EXPORT QgsProcessingParameterVectorDestination : public QgsProcessing
19401970
QgsProcessingOutputDefinition *toOutputDefinition() const override SIP_FACTORY;
19411971
QString defaultFileExtension() const override;
19421972

1973+
/**
1974+
* Returns a list of the vector format file extensions supported by this parameter.
1975+
* \see defaultFileExtension()
1976+
* \since QGIS 3.2
1977+
*/
1978+
virtual QStringList supportedOutputVectorLayerExtensions() const;
1979+
19431980
/**
19441981
* Returns the layer type for this created vector layer.
19451982
* \see setDataType()
@@ -2005,6 +2042,13 @@ class CORE_EXPORT QgsProcessingParameterRasterDestination : public QgsProcessing
20052042
QgsProcessingOutputDefinition *toOutputDefinition() const override SIP_FACTORY;
20062043
QString defaultFileExtension() const override;
20072044

2045+
/**
2046+
* Returns a list of the raster format file extensions supported for this parameter.
2047+
* \see defaultFileExtension()
2048+
* \since QGIS 3.2
2049+
*/
2050+
virtual QStringList supportedOutputRasterLayerExtensions() const;
2051+
20082052
/**
20092053
* Creates a new parameter using the definition from a script code.
20102054
*/

0 commit comments

Comments
 (0)