[processing] Add method for providers to specify a different list

of supported output formats when an output has no geometry
This commit is contained in:
Nyall Dawson 2018-12-03 13:05:00 +10:00
parent 583b602e76
commit 4bca7838bf
6 changed files with 147 additions and 24 deletions

View File

@ -113,11 +113,31 @@ Returns a list of the raster format file extensions supported by this provider.
%Docstring
Returns a list of the vector format file extensions supported by this provider.
.. seealso:: :py:func:`supportedOutputTableExtensions`
.. seealso:: :py:func:`defaultVectorFileExtension`
.. seealso:: :py:func:`supportedOutputRasterLayerExtensions`
.. seealso:: :py:func:`supportsNonFileBasedOutput`
%End
virtual QStringList supportedOutputTableExtensions() const;
%Docstring
Returns a list of the table (geometry-less vector layers) file extensions supported by this provider.
By default this is the same as supportedOutputVectorLayerExtensions(). Providers which utilize different
formats for geometry-less layers can override this method to return a different list of supported formats.
.. seealso:: :py:func:`supportedOutputVectorLayerExtensions`
.. seealso:: :py:func:`defaultVectorFileExtension`
.. seealso:: :py:func:`supportedOutputRasterLayerExtensions`
.. seealso:: :py:func:`supportsNonFileBasedOutput`
.. versionadded:: 3.4.3
%End
virtual QString defaultVectorFileExtension( bool hasGeometry = true ) const;

View File

@ -3728,11 +3728,17 @@ QStringList QgsProcessingParameterFeatureSink::supportedOutputVectorLayerExtensi
{
if ( originalProvider() )
{
return originalProvider()->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return originalProvider()->supportedOutputVectorLayerExtensions();
else
return originalProvider()->supportedOutputTableExtensions();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return p->supportedOutputVectorLayerExtensions();
else
return p->supportedOutputTableExtensions();
}
else
{
@ -4288,11 +4294,17 @@ QStringList QgsProcessingParameterVectorDestination::supportedOutputVectorLayerE
{
if ( originalProvider() )
{
return originalProvider()->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return originalProvider()->supportedOutputVectorLayerExtensions();
else
return originalProvider()->supportedOutputTableExtensions();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return p->supportedOutputVectorLayerExtensions();
else
return p->supportedOutputTableExtensions();
}
else
{

View File

@ -102,6 +102,11 @@ QStringList QgsProcessingProvider::supportedOutputVectorLayerExtensions() const
return QgsVectorFileWriter::supportedFormatExtensions();
}
QStringList QgsProcessingProvider::supportedOutputTableExtensions() const
{
return supportedOutputVectorLayerExtensions();
}
QString QgsProcessingProvider::defaultVectorFileExtension( bool hasGeometry ) const
{
QgsSettings settings;

View File

@ -118,12 +118,28 @@ class CORE_EXPORT QgsProcessingProvider : public QObject
/**
* Returns a list of the vector format file extensions supported by this provider.
* \see supportedOutputTableExtensions()
* \see defaultVectorFileExtension()
* \see supportedOutputRasterLayerExtensions()
* \see supportsNonFileBasedOutput()
*/
virtual QStringList supportedOutputVectorLayerExtensions() const;
/**
* Returns a list of the table (geometry-less vector layers) file extensions supported by this provider.
*
* By default this is the same as supportedOutputVectorLayerExtensions(). Providers which utilize different
* formats for geometry-less layers can override this method to return a different list of supported formats.
*
* \see supportedOutputVectorLayerExtensions()
* \see defaultVectorFileExtension()
* \see supportedOutputRasterLayerExtensions()
* \see supportsNonFileBasedOutput()
*
* \since QGIS 3.4.3
*/
virtual QStringList supportedOutputTableExtensions() const;
/**
* Returns the default file extension to use for vector outputs created by the
* provider.

View File

@ -385,27 +385,7 @@ class DummyProviderNoLoad : public DummyProvider
};
class DummyProvider3 : public QgsProcessingProvider
{
public:
DummyProvider3() = default;
QString id() const override { return QStringLiteral( "dummy3" ); }
QString name() const override { return QStringLiteral( "dummy3" ); }
QStringList supportedOutputVectorLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mif" ) << QStringLiteral( "tab" );
}
QStringList supportedOutputRasterLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mig" ) << QStringLiteral( "asc" );
}
void loadAlgorithms() override {}
};
class DummyAlgorithm2 : public QgsProcessingAlgorithm
{
@ -433,6 +413,36 @@ class DummyAlgorithm2 : public QgsProcessingAlgorithm
};
class DummyProvider3 : public QgsProcessingProvider
{
public:
DummyProvider3() = default;
QString id() const override { return QStringLiteral( "dummy3" ); }
QString name() const override { return QStringLiteral( "dummy3" ); }
QStringList supportedOutputVectorLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mif" ) << QStringLiteral( "tab" );
}
QStringList supportedOutputTableExtensions() const override
{
return QStringList() << QStringLiteral( "dbf" );
}
QStringList supportedOutputRasterLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mig" ) << QStringLiteral( "asc" );
}
void loadAlgorithms() override
{
QVERIFY( addAlgorithm( new DummyAlgorithm2( "alg1" ) ) );
}
};
class DummyProvider4 : public QgsProcessingProvider
{
public:
@ -564,6 +574,7 @@ class TestQgsProcessing: public QObject
void indicesToFields();
void stringToPythonLiteral();
void defaultExtensionsForProvider();
void supportedExtensions();
void supportsNonFileBasedOutput();
void addParameterType();
void removeParameterType();
@ -4678,6 +4689,30 @@ void TestQgsProcessing::parameterFeatureSink()
QCOMPARE( QgsProcessingAlgorithm::invalidSinkError( params, QStringLiteral( "OUTPUT" ) ), QStringLiteral( "Could not create destination layer for OUTPUT: d:/test3.shp" ) );
params.insert( QStringLiteral( "OUTPUT" ), QgsProcessingFeatureSourceDefinition( QStringLiteral( "source" ) ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSinkError( params, QStringLiteral( "OUTPUT" ) ), QStringLiteral( "Could not create destination layer for OUTPUT: invalid value" ) );
// test supported output vector layer extensions
def.reset( new QgsProcessingParameterFeatureSink( "with_geom", QString(), QgsProcessing::TypeVectorAnyGeometry, QString(), true ) );
DummyProvider3 provider;
provider.loadAlgorithms();
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );
def.reset( new QgsProcessingParameterFeatureSink( "no_geom", QString(), QgsProcessing::TypeVector, QString(), true ) );
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
}
void TestQgsProcessing::parameterVectorOut()
@ -4811,6 +4846,30 @@ void TestQgsProcessing::parameterVectorOut()
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).name, QStringLiteral( "my_dest" ) );
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).outputName, QStringLiteral( "x" ) );
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).layerTypeHint, QgsProcessingUtils::Vector );
// test supported output vector layer extensions
def.reset( new QgsProcessingParameterVectorDestination( "with_geom", QString(), QgsProcessing::TypeVectorAnyGeometry, QString(), true ) );
DummyProvider3 provider;
provider.loadAlgorithms();
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );
def.reset( new QgsProcessingParameterVectorDestination( "no_geom", QString(), QgsProcessing::TypeVector, QString(), true ) );
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
}
void TestQgsProcessing::parameterRasterOut()
@ -6971,6 +7030,17 @@ void TestQgsProcessing::defaultExtensionsForProvider()
QCOMPARE( provider.defaultRasterFileExtension(), QStringLiteral( "mig" ) );
}
void TestQgsProcessing::supportedExtensions()
{
DummyProvider4 provider;
QCOMPARE( provider.supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( provider.supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
// if supportedOutputTableExtensions is not implemented, supportedOutputVectorLayerExtensions should be used instead
QCOMPARE( provider.supportedOutputTableExtensions().count(), 1 );
QCOMPARE( provider.supportedOutputTableExtensions().at( 0 ), QStringLiteral( "mif" ) );
}
void TestQgsProcessing::supportsNonFileBasedOutput()
{
DummyAlgorithm alg( QStringLiteral( "test" ) );

Binary file not shown.