[processing] Allow providers to determine default vector/raster file

to use for their algorithm's parameters

Because some providers do not have support for all output types,
we need to give providers a way to restrict the default format
choices to those which are supported by the provider.
This commit is contained in:
Nyall Dawson 2017-11-06 12:44:38 +10:00
parent 2a280d69aa
commit 4ae9241e71
7 changed files with 186 additions and 13 deletions

View File

@ -357,9 +357,18 @@ class QgsProcessingParameterDefinition
%Docstring
Returns a pointer to the algorithm which owns this parameter. May be None
for non-owned parameters.
.. seealso:: provider()
:rtype: QgsProcessingAlgorithm
%End
QgsProcessingProvider *provider() const;
%Docstring
Returns a pointer to the provider for the algorithm which owns this parameter. May be None
for non-owned parameters or algorithms.
.. seealso:: algorithm()
:rtype: QgsProcessingProvider
%End
protected:

View File

@ -101,6 +101,7 @@ class QgsProcessingProvider : QObject
virtual QStringList supportedOutputVectorLayerExtensions() const;
%Docstring
Returns a list of the vector format file extensions supported by this provider.
.. seealso:: defaultVectorFileExtension()
.. seealso:: supportedOutputRasterLayerExtensions()
.. seealso:: supportedOutputTableExtensions()
.. seealso:: supportsNonFileBasedOutput()
@ -115,6 +116,35 @@ class QgsProcessingProvider : QObject
:rtype: list of str
%End
virtual QString defaultVectorFileExtension( bool hasGeometry = true ) const;
%Docstring
Returns the default file extension to use for vector outputs created by the
provider.
If ``hasGeometry`` is true then the output file format must have support for
geometry. If ``hasGeometry`` is false then non-spatial formats can be used.
The default implementation returns the user's default Processing vector output format
setting.
.. seealso:: supportedOutputVectorLayerExtensions()
.. seealso:: defaultRasterFileExtension()
:rtype: str
%End
virtual QString defaultRasterFileExtension() const;
%Docstring
Returns the default file extension to use for raster outputs created by the
provider.
The default implementation returns the user's default Processing raster output format
setting.
.. seealso:: supportedOutputRasterLayerExtensions()
.. seealso:: defaultVectorFileExtension()
:rtype: str
%End
virtual bool supportsNonFileBasedOutput() const;
%Docstring
Returns true if the provider supports non-file based outputs (such as memory layers

View File

@ -16,8 +16,10 @@
***************************************************************************/
#include "qgsprocessingparameters.h"
#include "qgsprocessingprovider.h"
#include "qgsprocessingcontext.h"
#include "qgsprocessingutils.h"
#include "qgsprocessingalgorithm.h"
#include "qgsvectorlayerfeatureiterator.h"
#include "qgsprocessingoutputs.h"
#include "qgssettings.h"
@ -1242,6 +1244,11 @@ QgsProcessingAlgorithm *QgsProcessingParameterDefinition::algorithm() const
return mAlgorithm;
}
QgsProcessingProvider *QgsProcessingParameterDefinition::provider() const
{
return mAlgorithm ? mAlgorithm->provider() : nullptr;
}
QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{}
@ -3091,6 +3098,12 @@ QgsProcessingOutputDefinition *QgsProcessingParameterFeatureSink::toOutputDefini
}
QString QgsProcessingParameterFeatureSink::defaultFileExtension() const
{
if ( QgsProcessingProvider *p = provider() )
{
return p->defaultVectorFileExtension( hasGeometry() );
}
else
{
QgsSettings settings;
if ( hasGeometry() )
@ -3102,6 +3115,7 @@ QString QgsProcessingParameterFeatureSink::defaultFileExtension() const
return QStringLiteral( "dbf" );
}
}
}
QgsProcessing::SourceType QgsProcessingParameterFeatureSink::dataType() const
{
@ -3244,10 +3258,17 @@ QgsProcessingOutputDefinition *QgsProcessingParameterRasterDestination::toOutput
}
QString QgsProcessingParameterRasterDestination::defaultFileExtension() const
{
if ( QgsProcessingProvider *p = provider() )
{
return p->defaultRasterFileExtension();
}
else
{
QgsSettings settings;
return settings.value( QStringLiteral( "Processing/DefaultOutputRasterLayerExt" ), QStringLiteral( "tif" ), QgsSettings::Core ).toString();
}
}
QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
{
@ -3540,6 +3561,12 @@ QgsProcessingOutputDefinition *QgsProcessingParameterVectorDestination::toOutput
}
QString QgsProcessingParameterVectorDestination::defaultFileExtension() const
{
if ( QgsProcessingProvider *p = provider() )
{
return p->defaultVectorFileExtension( hasGeometry() );
}
else
{
QgsSettings settings;
if ( hasGeometry() )
@ -3551,6 +3578,7 @@ QString QgsProcessingParameterVectorDestination::defaultFileExtension() const
return QStringLiteral( "dbf" );
}
}
}
QgsProcessing::SourceType QgsProcessingParameterVectorDestination::dataType() const
{

View File

@ -34,6 +34,7 @@ class QgsFeatureSink;
class QgsProcessingFeatureSource;
class QgsProcessingOutputDefinition;
class QgsProcessingFeedback;
class QgsProcessingProvider;
/**
* \class QgsProcessingFeatureSourceDefinition
@ -394,9 +395,17 @@ class CORE_EXPORT QgsProcessingParameterDefinition
/**
* Returns a pointer to the algorithm which owns this parameter. May be nullptr
* for non-owned parameters.
* \see provider()
*/
QgsProcessingAlgorithm *algorithm() const;
/**
* Returns a pointer to the provider for the algorithm which owns this parameter. May be nullptr
* for non-owned parameters or algorithms.
* \see algorithm()
*/
QgsProcessingProvider *provider() const;
protected:
//! Parameter name

View File

@ -18,6 +18,7 @@
#include "qgsprocessingprovider.h"
#include "qgsapplication.h"
#include "qgsvectorfilewriter.h"
#include "qgssettings.h"
QgsProcessingProvider::QgsProcessingProvider( QObject *parent SIP_TRANSFERTHIS )
: QObject( parent )
@ -84,3 +85,22 @@ QStringList QgsProcessingProvider::supportedOutputVectorLayerExtensions() const
return QgsVectorFileWriter::supportedFormatExtensions();
}
QString QgsProcessingProvider::defaultVectorFileExtension( bool hasGeometry ) const
{
QgsSettings settings;
if ( hasGeometry )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
}
else
{
return QStringLiteral( "dbf" );
}
}
QString QgsProcessingProvider::defaultRasterFileExtension() const
{
QgsSettings settings;
return settings.value( QStringLiteral( "Processing/DefaultOutputRasterLayerExt" ), QStringLiteral( "tif" ), QgsSettings::Core ).toString();
}

View File

@ -110,6 +110,7 @@ class CORE_EXPORT QgsProcessingProvider : public QObject
/**
* Returns a list of the vector format file extensions supported by this provider.
* \see defaultVectorFileExtension()
* \see supportedOutputRasterLayerExtensions()
* \see supportedOutputTableExtensions()
* \see supportsNonFileBasedOutput()
@ -123,6 +124,33 @@ class CORE_EXPORT QgsProcessingProvider : public QObject
*/
virtual QStringList supportedOutputTableExtensions() const { return QStringList() << QStringLiteral( "csv" ); }
/**
* Returns the default file extension to use for vector outputs created by the
* provider.
*
* If \a hasGeometry is true then the output file format must have support for
* geometry. If \a hasGeometry is false then non-spatial formats can be used.
*
* The default implementation returns the user's default Processing vector output format
* setting.
*
* \see supportedOutputVectorLayerExtensions()
* \see defaultRasterFileExtension()
*/
virtual QString defaultVectorFileExtension( bool hasGeometry = true ) const;
/**
* Returns the default file extension to use for raster outputs created by the
* provider.
*
* The default implementation returns the user's default Processing raster output format
* setting.
*
* \see supportedOutputRasterLayerExtensions()
* \see defaultVectorFileExtension()
*/
virtual QString defaultRasterFileExtension() const;
/**
* Returns true if the provider supports non-file based outputs (such as memory layers
* or direct database outputs).

View File

@ -130,6 +130,41 @@ class DummyAlgorithm : public QgsProcessingAlgorithm
QgsProcessingParameterVectorDestination *p8 = new QgsProcessingParameterVectorDestination( "p8" );
// this should fail - it would result in a duplicate output name
QVERIFY( !addParameter( p8 ) );
// default vector format extension
QgsProcessingParameterFeatureSink *sinkParam = new QgsProcessingParameterFeatureSink( "sink" );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "shp" ) ); // before alg is accessible
QVERIFY( !sinkParam->algorithm() );
QVERIFY( !sinkParam->provider() );
addParameter( sinkParam );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "shp" ) );
QCOMPARE( sinkParam->algorithm(), this );
QVERIFY( !sinkParam->provider() );
// default raster format extension
QgsProcessingParameterRasterDestination *rasterParam = new QgsProcessingParameterRasterDestination( "raster" );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "tif" ) ); // before alg is accessible
addParameter( rasterParam );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "tif" ) );
}
void runParameterChecks2()
{
// default vector format extension, taken from provider
QgsProcessingParameterFeatureSink *sinkParam = new QgsProcessingParameterFeatureSink( "sink2" );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "shp" ) ); // before alg is accessible
QVERIFY( !sinkParam->algorithm() );
QVERIFY( !sinkParam->provider() );
addParameter( sinkParam );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "xshp" ) );
QCOMPARE( sinkParam->algorithm(), this );
QCOMPARE( sinkParam->provider(), provider() );
// default raster format extension
QgsProcessingParameterRasterDestination *rasterParam = new QgsProcessingParameterRasterDestination( "raster2" );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "tif" ) ); // before alg is accessible
addParameter( rasterParam );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "pcx" ) );
}
void runOutputChecks()
@ -254,6 +289,16 @@ class DummyProvider : public QgsProcessingProvider
void unload() override { if ( unloaded ) { *unloaded = true; } }
QString defaultVectorFileExtension( bool ) const override
{
return "xshp"; // shape-X. Just like shapefiles, but to the max!
}
QString defaultRasterFileExtension() const override
{
return "pcx"; // next-gen raster storage
}
bool *unloaded = nullptr;
protected:
@ -273,7 +318,7 @@ class DummyProvider : public QgsProcessingProvider
QString mId;
friend class TestQgsProcessing;
};
class DummyProviderNoLoad : public DummyProvider
@ -1419,8 +1464,12 @@ void TestQgsProcessing::parameters()
void TestQgsProcessing::algorithmParameters()
{
DummyAlgorithm alg( "test" );
alg.runParameterChecks();
DummyAlgorithm *alg = new DummyAlgorithm( "test" );
DummyProvider p( "test" );
alg->runParameterChecks();
p.addAlgorithm( alg );
alg->runParameterChecks2();
}
void TestQgsProcessing::algorithmOutputs()