Skip to content

Commit

Permalink
Move QgsVectorLayerExporter.ExportError to Qgis and promote to enum
Browse files Browse the repository at this point in the history
class

This avoids an ugly include of qgsvectorlayerexporter.h in
qgsproviderregistry.h/qgsprovidermetadata.h, which in turn
triggers an inclusion of qgsvectorlayer.h and a bunch of
other heavy dependencies.
  • Loading branch information
nyalldawson committed May 20, 2021
1 parent a05921a commit de40669
Show file tree
Hide file tree
Showing 44 changed files with 268 additions and 226 deletions.
29 changes: 29 additions & 0 deletions python/core/auto_additions/qgis.py
Expand Up @@ -59,3 +59,32 @@
QgsSymbol.FlagIncludeCrosshairsForMarkerSymbols.__doc__ = "Include a crosshairs reference image in the background of marker symbol previews"
Qgis.SymbolPreviewFlag.__doc__ = 'Flags for controlling how symbol preview images are generated.\n\n.. versionadded:: 3.20\n\n' + '* ``FlagIncludeCrosshairsForMarkerSymbols``: ' + Qgis.SymbolPreviewFlag.FlagIncludeCrosshairsForMarkerSymbols.__doc__
# --
QgsVectorLayerExporter.ExportError = Qgis.VectorExportResult
# monkey patching scoped based enum
QgsVectorLayerExporter.NoError = Qgis.VectorExportResult.Success
QgsVectorLayerExporter.NoError.__doc__ = "No errors were encountered"
QgsVectorLayerExporter.ErrCreateDataSource = Qgis.VectorExportResult.ErrorCreatingDataSource
QgsVectorLayerExporter.ErrCreateDataSource.__doc__ = "Could not create the destination data source"
QgsVectorLayerExporter.ErrCreateLayer = Qgis.VectorExportResult.ErrorCreatingLayer
QgsVectorLayerExporter.ErrCreateLayer.__doc__ = "Could not create destination layer"
QgsVectorLayerExporter.ErrAttributeTypeUnsupported = Qgis.VectorExportResult.ErrorAttributeTypeUnsupported
QgsVectorLayerExporter.ErrAttributeTypeUnsupported.__doc__ = "Source layer has an attribute type which could not be handled by destination"
QgsVectorLayerExporter.ErrAttributeCreationFailed = Qgis.VectorExportResult.ErrorAttributeCreationFailed
QgsVectorLayerExporter.ErrAttributeCreationFailed.__doc__ = "Destination provider was unable to create an attribute"
QgsVectorLayerExporter.ErrProjection = Qgis.VectorExportResult.ErrorProjectingFeatures
QgsVectorLayerExporter.ErrProjection.__doc__ = "An error occurred while reprojecting features to destination CRS"
QgsVectorLayerExporter.ErrFeatureWriteFailed = Qgis.VectorExportResult.ErrorFeatureWriteFailed
QgsVectorLayerExporter.ErrFeatureWriteFailed.__doc__ = "An error occurred while writing a feature to the destination"
QgsVectorLayerExporter.ErrInvalidLayer = Qgis.VectorExportResult.ErrorInvalidLayer
QgsVectorLayerExporter.ErrInvalidLayer.__doc__ = "Could not access newly created destination layer"
QgsVectorLayerExporter.ErrInvalidProvider = Qgis.VectorExportResult.ErrorInvalidProvider
QgsVectorLayerExporter.ErrInvalidProvider.__doc__ = "Could not find a matching provider key"
QgsVectorLayerExporter.ErrProviderUnsupportedFeature = Qgis.VectorExportResult.ErrorProviderUnsupportedFeature
QgsVectorLayerExporter.ErrProviderUnsupportedFeature.__doc__ = "Provider does not support creation of empty layers"
QgsVectorLayerExporter.ErrConnectionFailed = Qgis.VectorExportResult.ErrorConnectionFailed
QgsVectorLayerExporter.ErrConnectionFailed.__doc__ = "Could not connect to destination"
QgsVectorLayerExporter.ErrUserCanceled = Qgis.VectorExportResult.UserCanceled
QgsVectorLayerExporter.ErrUserCanceled.__doc__ = "User canceled the export"
Qgis.VectorExportResult.__doc__ = 'Vector layer export result codes.\n\n.. versionadded:: 3.20\n\n' + '* ``NoError``: ' + Qgis.VectorExportResult.Success.__doc__ + '\n' + '* ``ErrCreateDataSource``: ' + Qgis.VectorExportResult.ErrorCreatingDataSource.__doc__ + '\n' + '* ``ErrCreateLayer``: ' + Qgis.VectorExportResult.ErrorCreatingLayer.__doc__ + '\n' + '* ``ErrAttributeTypeUnsupported``: ' + Qgis.VectorExportResult.ErrorAttributeTypeUnsupported.__doc__ + '\n' + '* ``ErrAttributeCreationFailed``: ' + Qgis.VectorExportResult.ErrorAttributeCreationFailed.__doc__ + '\n' + '* ``ErrProjection``: ' + Qgis.VectorExportResult.ErrorProjectingFeatures.__doc__ + '\n' + '* ``ErrFeatureWriteFailed``: ' + Qgis.VectorExportResult.ErrorFeatureWriteFailed.__doc__ + '\n' + '* ``ErrInvalidLayer``: ' + Qgis.VectorExportResult.ErrorInvalidLayer.__doc__ + '\n' + '* ``ErrInvalidProvider``: ' + Qgis.VectorExportResult.ErrorInvalidProvider.__doc__ + '\n' + '* ``ErrProviderUnsupportedFeature``: ' + Qgis.VectorExportResult.ErrorProviderUnsupportedFeature.__doc__ + '\n' + '* ``ErrConnectionFailed``: ' + Qgis.VectorExportResult.ErrorConnectionFailed.__doc__ + '\n' + '* ``ErrUserCanceled``: ' + Qgis.VectorExportResult.UserCanceled.__doc__
# --
Qgis.VectorExportResult.baseClass = Qgis
16 changes: 16 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -145,6 +145,22 @@ The development version
typedef QFlags<Qgis::SymbolPreviewFlag> SymbolPreviewFlags;


enum class VectorExportResult
{
Success,
ErrorCreatingDataSource,
ErrorCreatingLayer,
ErrorAttributeTypeUnsupported,
ErrorAttributeCreationFailed,
ErrorProjectingFeatures,
ErrorFeatureWriteFailed,
ErrorInvalidLayer,
ErrorInvalidProvider,
ErrorProviderUnsupportedFeature,
ErrorConnectionFailed,
UserCanceled,
};

static const double DEFAULT_SEARCH_RADIUS_MM;

static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
Expand Down
1 change: 1 addition & 0 deletions python/core/auto_generated/qgsmapclippingregion.sip.in
Expand Up @@ -8,6 +8,7 @@




class QgsMapClippingRegion
{
%Docstring(signature="appended")
Expand Down
38 changes: 11 additions & 27 deletions python/core/auto_generated/vector/qgsvectorlayerexporter.sip.in
Expand Up @@ -30,31 +30,15 @@ A convenience class for exporting vector layers to a destination data provider.
%End
public:

enum ExportError
{
NoError,
ErrCreateDataSource,
ErrCreateLayer,
ErrAttributeTypeUnsupported,
ErrAttributeCreationFailed,
ErrProjection,
ErrFeatureWriteFailed,
ErrInvalidLayer,
ErrInvalidProvider,
ErrProviderUnsupportedFeature,
ErrConnectionFailed,
ErrUserCanceled,
};

static ExportError exportLayer( QgsVectorLayer *layer,
const QString &uri,
const QString &providerKey,
const QgsCoordinateReferenceSystem &destCRS,
bool onlySelected = false,
QString *errorMessage /Out/ = 0,
const QMap<QString, QVariant> &options = QMap<QString, QVariant>(),
QgsFeedback *feedback = 0
);

static Qgis::VectorExportResult exportLayer( QgsVectorLayer *layer,
const QString &uri,
const QString &providerKey,
const QgsCoordinateReferenceSystem &destCRS,
bool onlySelected = false,
QString *errorMessage /Out/ = 0,
const QMap<QString, QVariant> &options = QMap<QString, QVariant>(),
QgsFeedback *feedback = 0 );
%Docstring
Writes the contents of vector layer to a different datasource.

Expand Down Expand Up @@ -94,7 +78,7 @@ Constructor for QgsVectorLayerExporter.
%End


ExportError errorCode() const;
Qgis::VectorExportResult errorCode() const;
%Docstring
Returns any encountered error code, or ``False`` if no error was encountered.

Expand Down Expand Up @@ -192,7 +176,7 @@ and export ``options`` must be specified.
Emitted when exporting the layer is successfully completed.
%End

void errorOccurred( int error, const QString &errorMessage );
void errorOccurred( Qgis::VectorExportResult error, const QString &errorMessage );
%Docstring
Emitted when an error occurs which prevented the layer being exported (or if
the task is canceled). The export ``error`` and ``errorMessage`` will be reported.
Expand Down
25 changes: 13 additions & 12 deletions scripts/sipify.pl
Expand Up @@ -1072,32 +1072,33 @@ sub detect_non_method_member{
next if ($LINE =~ m/^\s*\w+\s*\|/); # multi line declaration as sum of enums

do {no warnings 'uninitialized';
my $enum_decl = $LINE =~ s/^(\s*(?<em>\w+))(\s+SIP_\w+(?:\([^()]+\))?)?(?:\s*=\s*(?:[\w\s\d|+-]|::|<<)+)?(,?)(:?\s*\/\/!<\s*(?<co>.*)|.*)$/$1$3$4/r;
my $enum_decl = $LINE =~ s/^(\s*(?<em>\w+))(\s+SIP_\w+(?:\(\s*(?<compat>[^() ]+)\s*\)\s*)?)?(?:\s*=\s*(?:[\w\s\d|+-]|::|<<)+)?(,?)(:?\s*\/\/!<\s*(?<co>.*)|.*)$/$1$5/r;
my $enum_member = $+{em};
my $comment = $+{co};
my $compat_name = $+{compat} ? $+{compat} : $enum_member;
dbg_info("is_scope_based:$is_scope_based enum_mk_base:$enum_mk_base monkeypatch:$monkeypatch");
if ($is_scope_based eq "1" and $enum_member ne "") {
if ( $monkeypatch eq 1 and $enum_mk_base ne ""){
if ( $ACTUAL_CLASS ne "" ) {
push @OUTPUT_PYTHON, "$enum_mk_base.$enum_member = $ACTUAL_CLASS.$enum_qualname.$enum_member\n";
push @OUTPUT_PYTHON, "$enum_mk_base.$enum_member.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$enum_member``: ' + $ACTUAL_CLASS.$enum_qualname.$enum_member.__doc__";
push @OUTPUT_PYTHON, "$enum_mk_base.$compat_name = $ACTUAL_CLASS.$enum_qualname.$enum_member\n";
push @OUTPUT_PYTHON, "$enum_mk_base.$compat_name.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$compat_name``: ' + $ACTUAL_CLASS.$enum_qualname.$enum_member.__doc__";
} else {
push @OUTPUT_PYTHON, "$enum_mk_base.$enum_member = $enum_qualname.$enum_member\n";
push @OUTPUT_PYTHON, "$enum_mk_base.$enum_member.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$enum_member``: ' + $enum_qualname.$enum_member.__doc__";
push @OUTPUT_PYTHON, "$enum_mk_base.$compat_name = $enum_qualname.$enum_member\n";
push @OUTPUT_PYTHON, "$enum_mk_base.$compat_name.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$compat_name``: ' + $enum_qualname.$enum_member.__doc__";
}
} else {
if ( $monkeypatch eq 1 )
{
push @OUTPUT_PYTHON, "$ACTUAL_CLASS.$enum_member = $ACTUAL_CLASS.$enum_qualname.$enum_member\n";
push @OUTPUT_PYTHON, "$ACTUAL_CLASS.$compat_name = $ACTUAL_CLASS.$enum_qualname.$enum_member\n";
}
if ( $ACTUAL_CLASS ne "" ){
push @OUTPUT_PYTHON, "$ACTUAL_CLASS.$enum_qualname.$enum_member.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$enum_member``: ' + $ACTUAL_CLASS.$enum_qualname.$enum_member.__doc__";
push @OUTPUT_PYTHON, "$ACTUAL_CLASS.$enum_qualname.$compat_name.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$compat_name``: ' + $ACTUAL_CLASS.$enum_qualname.$enum_member.__doc__";
} else {
push @OUTPUT_PYTHON, "$enum_qualname.$enum_member.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$enum_member``: ' + $enum_qualname.$enum_member.__doc__";
push @OUTPUT_PYTHON, "$enum_qualname.$compat_name.__doc__ = \"$comment\"\n";
push @enum_members_doc, "'* ``$compat_name``: ' + $enum_qualname.$enum_member.__doc__";
}
}
}
Expand Down
Expand Up @@ -19,6 +19,7 @@
#include "qgsproviderregistry.h"
#include "qgsprovidermetadata.h"
#include "qgsabstractdatabaseproviderconnection.h"
#include "qgsvectorlayer.h"

///@cond PRIVATE

Expand Down
2 changes: 1 addition & 1 deletion src/core/processing/qgsprocessingutils.cpp
Expand Up @@ -841,7 +841,7 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, Qgs
{
//create empty layer
std::unique_ptr< QgsVectorLayerExporter > exporter = std::make_unique<QgsVectorLayerExporter>( uri, providerKey, newFields, geometryType, crs, true, options, sinkFlags );
if ( exporter->errorCode() )
if ( exporter->errorCode() != Qgis::VectorExportResult::Success )
{
throw QgsProcessingException( QObject::tr( "Could not create layer %1: %2" ).arg( destination, exporter->errorMessage() ) );
}
Expand Down
23 changes: 12 additions & 11 deletions src/core/providers/ogr/qgsgeopackageproviderconnection.cpp
Expand Up @@ -20,6 +20,7 @@
#include "qgsmessagelog.h"
#include "qgsproviderregistry.h"
#include "qgsapplication.h"
#include "qgsvectorlayer.h"

QgsGeoPackageProviderConnection::QgsGeoPackageProviderConnection( const QString &name )
: QgsAbstractDatabaseProviderConnection( name )
Expand Down Expand Up @@ -96,17 +97,17 @@ void QgsGeoPackageProviderConnection::createVectorTable( const QString &schema,
opts[ QStringLiteral( "update" ) ] = true;
QMap<int, int> map;
QString errCause;
QgsVectorLayerExporter::ExportError errCode = QgsOgrProvider::createEmptyLayer(
uri(),
fields,
wkbType,
srs,
overwrite,
&map,
&errCause,
&opts
);
if ( errCode != QgsVectorLayerExporter::ExportError::NoError )
Qgis::VectorExportResult errCode = QgsOgrProvider::createEmptyLayer(
uri(),
fields,
wkbType,
srs,
overwrite,
&map,
&errCause,
&opts
);
if ( errCode != Qgis::VectorExportResult::Success )
{
throw QgsProviderConnectionException( QObject::tr( "An error occurred while creating the vector layer: %1" ).arg( errCause ) );
}
Expand Down
12 changes: 6 additions & 6 deletions src/core/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -271,7 +271,7 @@ void QgsOgrProvider::repack()
}


QgsVectorLayerExporter::ExportError QgsOgrProviderMetadata::createEmptyLayer( const QString &uri,
Qgis::VectorExportResult QgsOgrProviderMetadata::createEmptyLayer( const QString &uri,
const QgsFields &fields,
QgsWkbTypes::Type wkbType,
const QgsCoordinateReferenceSystem &srs,
Expand Down Expand Up @@ -343,7 +343,7 @@ static QString AnalyzeURI( QString const &uri,
return fullPath;
}

QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QString &uri,
Qgis::VectorExportResult QgsOgrProvider::createEmptyLayer( const QString &uri,
const QgsFields &fields,
QgsWkbTypes::Type wkbType,
const QgsCoordinateReferenceSystem &srs,
Expand Down Expand Up @@ -397,7 +397,7 @@ QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QStr
if ( errorMessage )
*errorMessage += QObject::tr( "Layer %2 of %1 exists and overwrite flag is false." )
.arg( uri, layerName );
return QgsVectorLayerExporter::ErrCreateDataSource;
return Qgis::VectorExportResult::ErrorCreatingDataSource;
}
}
}
Expand All @@ -413,7 +413,7 @@ QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QStr
if ( errorMessage )
*errorMessage += QObject::tr( "Unable to create the datasource. %1 exists and overwrite flag is false." )
.arg( uri );
return QgsVectorLayerExporter::ErrCreateDataSource;
return Qgis::VectorExportResult::ErrorCreatingDataSource;
}
}

Expand All @@ -436,7 +436,7 @@ QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QStr
if ( errorMessage )
*errorMessage += writer->errorMessage();

return static_cast<QgsVectorLayerExporter::ExportError>( error );
return static_cast<Qgis::VectorExportResult>( error );
}

QMap<int, int> attrIdxMap = writer->attrIdxToOgrIdx();
Expand Down Expand Up @@ -484,7 +484,7 @@ QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QStr

QgsOgrProviderUtils::invalidateCachedLastModifiedDate( uri );

return QgsVectorLayerExporter::NoError;
return Qgis::VectorExportResult::Success;
}

QgsOgrProvider::QgsOgrProvider( QString const &uri, const ProviderOptions &options, QgsDataProvider::ReadFlags flags )
Expand Down
5 changes: 2 additions & 3 deletions src/core/providers/ogr/qgsogrprovider.h
Expand Up @@ -23,7 +23,6 @@ email : sherman at mrcc.com
#include "qgsrectangle.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorfilewriter.h"
#include "qgsvectorlayerexporter.h"
#include "qgsprovidermetadata.h"
#include "qgis_sip.h"
#include "qgis.h"
Expand Down Expand Up @@ -70,7 +69,7 @@ class QgsOgrProvider final: public QgsVectorDataProvider
public:

//! Convert a vector layer to a vector file
static QgsVectorLayerExporter::ExportError createEmptyLayer(
static Qgis::VectorExportResult createEmptyLayer(
const QString &uri,
const QgsFields &fields,
QgsWkbTypes::Type wkbType,
Expand Down Expand Up @@ -802,7 +801,7 @@ class QgsOgrProviderMetadata final: public QgsProviderMetadata
QString filters( FilterType type ) override;
ProviderCapabilities providerCapabilities() const override;
bool uriIsBlocklisted( const QString &uri ) const override;
QgsVectorLayerExporter::ExportError createEmptyLayer(
Qgis::VectorExportResult createEmptyLayer(
const QString &uri,
const QgsFields &fields,
QgsWkbTypes::Type wkbType,
Expand Down
4 changes: 2 additions & 2 deletions src/core/providers/qgsprovidermetadata.cpp
Expand Up @@ -161,14 +161,14 @@ QString QgsProviderMetadata::encodeUri( const QVariantMap & ) const
return QString();
}

QgsVectorLayerExporter::ExportError QgsProviderMetadata::createEmptyLayer(
Qgis::VectorExportResult QgsProviderMetadata::createEmptyLayer(
const QString &, const QgsFields &,
QgsWkbTypes::Type, const QgsCoordinateReferenceSystem &,
bool, QMap<int, int> &,
QString &errorMessage, const QMap<QString, QVariant> * )
{
errorMessage = QObject::tr( "Provider %1 has no %2 method" ).arg( key(), QStringLiteral( "createEmptyLayer" ) );
return QgsVectorLayerExporter::ExportError::ErrProviderUnsupportedFeature;
return Qgis::VectorExportResult::ErrorProviderUnsupportedFeature;
}

QgsRasterDataProvider *QgsProviderMetadata::createRasterDataProvider(
Expand Down
3 changes: 1 addition & 2 deletions src/core/providers/qgsprovidermetadata.h
Expand Up @@ -31,7 +31,6 @@
#include "qgsdataprovider.h"
#include "qgis_core.h"
#include <functional>
#include "qgsvectorlayerexporter.h"
#include "qgsabstractproviderconnection.h"
#include "qgsfields.h"
#include "qgsexception.h"
Expand Down Expand Up @@ -362,7 +361,7 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
* \note not available in Python bindings
* \since QGIS 3.10
*/
virtual QgsVectorLayerExporter::ExportError createEmptyLayer( const QString &uri,
virtual Qgis::VectorExportResult createEmptyLayer( const QString &uri,
const QgsFields &fields,
QgsWkbTypes::Type wkbType,
const QgsCoordinateReferenceSystem &srs,
Expand Down
8 changes: 2 additions & 6 deletions src/core/providers/qgsproviderregistry.cpp
Expand Up @@ -535,7 +535,7 @@ QString QgsProviderRegistry::encodeUri( const QString &providerKey, const QVaria
return QString();
}

QgsVectorLayerExporter::ExportError QgsProviderRegistry::createEmptyLayer( const QString &providerKey,
Qgis::VectorExportResult QgsProviderRegistry::createEmptyLayer( const QString &providerKey,
const QString &uri,
const QgsFields &fields,
QgsWkbTypes::Type wkbType,
Expand All @@ -544,18 +544,14 @@ QgsVectorLayerExporter::ExportError QgsProviderRegistry::createEmptyLayer( const
QString &errorMessage,
const QMap<QString, QVariant> *options )
{
QgsVectorLayerExporter::ExportError ret;

QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
if ( meta )
return meta->createEmptyLayer( uri, fields, wkbType, srs, overwrite, oldToNewAttrIdxMap, errorMessage, options );
else
{
ret = QgsVectorLayerExporter::ErrInvalidProvider;
errorMessage = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
return Qgis::VectorExportResult::ErrorInvalidProvider;
}

return ret;
}

QgsRasterDataProvider *QgsProviderRegistry::createRasterDataProvider( const QString &providerKey, const QString &uri, const QString &format,
Expand Down

0 comments on commit de40669

Please sign in to comment.