Skip to content
Permalink
Browse files
Move QgsVectorLayerExporter.ExportError to Qgis and promote to enum
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 de406693c76bae650967068a193906e08794d88d
Showing with 268 additions and 226 deletions.
  1. +29 −0 python/core/auto_additions/qgis.py
  2. +16 −0 python/core/auto_generated/qgis.sip.in
  3. +1 −0 python/core/auto_generated/qgsmapclippingregion.sip.in
  4. +11 −27 python/core/auto_generated/vector/qgsvectorlayerexporter.sip.in
  5. +13 −12 scripts/sipify.pl
  6. +1 −0 src/analysis/processing/qgsalgorithmexecutespatialitequery.cpp
  7. +1 −1 src/core/processing/qgsprocessingutils.cpp
  8. +12 −11 src/core/providers/ogr/qgsgeopackageproviderconnection.cpp
  9. +6 −6 src/core/providers/ogr/qgsogrprovider.cpp
  10. +2 −3 src/core/providers/ogr/qgsogrprovider.h
  11. +2 −2 src/core/providers/qgsprovidermetadata.cpp
  12. +1 −2 src/core/providers/qgsprovidermetadata.h
  13. +2 −6 src/core/providers/qgsproviderregistry.cpp
  14. +3 −2 src/core/providers/qgsproviderregistry.h
  15. +22 −0 src/core/qgis.h
  16. +1 −0 src/core/qgis_sip.h
  17. +2 −0 src/core/qgsmapclippingregion.h
  18. +1 −0 src/core/qgsproviderconnectionmodel.cpp
  19. +1 −0 src/core/raster/qgsrasterdataprovider.cpp
  20. +27 −27 src/core/vector/qgsvectorlayerexporter.cpp
  21. +13 −29 src/core/vector/qgsvectorlayerexporter.h
  22. +2 −2 src/gui/providers/ogr/qgsgeopackageitemguiprovider.cpp
  23. +1 −0 src/providers/arcgisrest/qgsarcgisrestprovidergui.cpp
  24. +2 −2 src/providers/db2/qgsdb2dataitems.cpp
  25. +7 −7 src/providers/db2/qgsdb2provider.cpp
  26. +2 −3 src/providers/db2/qgsdb2provider.h
  27. +2 −2 src/providers/mssql/qgsmssqldataitems.cpp
  28. +14 −13 src/providers/mssql/qgsmssqlprovider.cpp
  29. +2 −3 src/providers/mssql/qgsmssqlprovider.h
  30. +13 −13 src/providers/mssql/qgsmssqlproviderconnection.cpp
  31. +0 −1 src/providers/oracle/qgsoracledataitems.h
  32. +0 −1 src/providers/oracle/qgsoracleprovider.h
  33. +3 −2 src/providers/postgres/qgspostgresdataitems.cpp
  34. +0 −1 src/providers/postgres/qgspostgresdataitems.h
  35. +8 −8 src/providers/postgres/qgspostgresprovider.cpp
  36. +2 −3 src/providers/postgres/qgspostgresprovider.h
  37. +14 −11 src/providers/postgres/qgspostgresproviderconnection.cpp
  38. +4 −2 src/providers/spatialite/qgsspatialitedataitemguiprovider.cpp
  39. +8 −9 src/providers/spatialite/qgsspatialiteprovider.cpp
  40. +2 −3 src/providers/spatialite/qgsspatialiteprovider.h
  41. +12 −11 src/providers/spatialite/qgsspatialiteproviderconnection.cpp
  42. +1 −0 src/providers/wms/qgswmsprovidergui.cpp
  43. +1 −0 tests/src/core/testqgsgdalprovider.cpp
  44. +1 −1 tests/src/gui/testqgsnewdatabasetablewidget.cpp
@@ -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
@@ -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;
@@ -8,6 +8,7 @@




class QgsMapClippingRegion
{
%Docstring(signature="appended")
@@ -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.

@@ -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.

@@ -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.
@@ -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__";
}
}
}
@@ -19,6 +19,7 @@
#include "qgsproviderregistry.h"
#include "qgsprovidermetadata.h"
#include "qgsabstractdatabaseproviderconnection.h"
#include "qgsvectorlayer.h"

///@cond PRIVATE

@@ -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() ) );
}
@@ -20,6 +20,7 @@
#include "qgsmessagelog.h"
#include "qgsproviderregistry.h"
#include "qgsapplication.h"
#include "qgsvectorlayer.h"

QgsGeoPackageProviderConnection::QgsGeoPackageProviderConnection( const QString &name )
: QgsAbstractDatabaseProviderConnection( name )
@@ -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 ) );
}
@@ -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,
@@ -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,
@@ -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;
}
}
}
@@ -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;
}
}

@@ -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();
@@ -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 )
@@ -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"
@@ -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,
@@ -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,
@@ -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(
@@ -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"
@@ -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,
@@ -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,
@@ -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,

0 comments on commit de40669

Please sign in to comment.