Skip to content

Commit 31f98da

Browse files
authoredNov 5, 2017
Merge pull request #5534 from nyalldawson/format
Add flags to QgsVectorFileWriter methods which return lists of drivers
2 parents bfe0355 + 2df5332 commit 31f98da

File tree

8 files changed

+309
-78
lines changed

8 files changed

+309
-78
lines changed
 

‎doc/api_break.dox

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2672,6 +2672,8 @@ for consistency with other parts of the QGIS API.
26722672
- The addFeature which takes a renderer argument was renamed to addFeatureWithStyle.
26732673
- static `writeAsVectorFormat` calls no longer take a errorMessage argument in
26742674
python and instead return a `(errorCode, errorMessage)` tuple.
2675+
- ogrDriverList now returns a list of QgsVectorFileWriter.DriverDetails structs, instead of a map
2676+
- supportedFiltersAndFormats now returns a list of QgsVectorFileWriter.FilterFormatDetails structs, instead of a map
26752677

26762678

26772679
QgsWMSLegendNode {#qgis_api_break_3_0_QgsWMSLegendNode}

‎python/core/qgsvectorfilewriter.sip

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111

1212

13-
14-
1513
class QgsVectorFileWriter : QgsFeatureSink
1614
{
1715
%Docstring
@@ -145,6 +143,15 @@ Some formats require a compulsory encoding, typically UTF-8. If no compulsory en
145143
SymbolLayerSymbology
146144
};
147145

146+
147+
enum VectorFormatOption
148+
{
149+
SortRecommended,
150+
SkipNonSpatialFormats,
151+
};
152+
typedef QFlags<QgsVectorFileWriter::VectorFormatOption> VectorFormatOptions;
153+
154+
148155
class FieldValueConverter
149156
{
150157
%Docstring
@@ -460,27 +467,67 @@ Create a new vector file writer
460467

461468

462469

463-
static QMap< QString, QString> supportedFiltersAndFormats();
470+
struct FilterFormatDetails
471+
{
472+
QString driverName;
473+
%Docstring
474+
Unique driver name
475+
%End
476+
477+
QString filterString;
478+
%Docstring
479+
Filter string for file picker dialogs
480+
%End
481+
};
482+
483+
static QList< QgsVectorFileWriter::FilterFormatDetails > supportedFiltersAndFormats( VectorFormatOptions options = SortRecommended );
464484
%Docstring
465-
Returns a map with format filter string as key and OGR format key as value.
485+
Returns a list or pairs, with format filter string as first element and OGR format key as second element.
486+
487+
The ``options`` argument can be used to control the sorting and filtering of
488+
returned formats.
489+
466490
.. seealso:: supportedOutputVectorLayerExtensions()
467-
:rtype: QMap< str, QString>
491+
:rtype: list of QgsVectorFileWriter.FilterFormatDetails
468492
%End
469493

470-
static QStringList supportedFormatExtensions();
494+
static QStringList supportedFormatExtensions( VectorFormatOptions options = SortRecommended );
471495
%Docstring
472496
Returns a list of file extensions for supported formats.
497+
498+
The ``options`` argument can be used to control the sorting and filtering of
499+
returned formats.
500+
473501
.. versionadded:: 3.0
474502
.. seealso:: supportedFiltersAndFormats()
475503
:rtype: list of str
476504
%End
477505

478-
static QMap< QString, QString> ogrDriverList();
506+
struct DriverDetails
507+
{
508+
QString longName;
509+
%Docstring
510+
Descriptive, user friendly name for the driver
511+
%End
512+
513+
QString driverName;
479514
%Docstring
480-
Returns driver list that can be used for dialogs. It contains all OGR drivers
481-
+ some additional internal QGIS driver names to distinguish between more
482-
supported formats of the same OGR driver
483-
:rtype: QMap< str, QString>
515+
Unique driver name
516+
%End
517+
};
518+
519+
static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList( VectorFormatOptions options = SortRecommended );
520+
%Docstring
521+
Returns the driver list that can be used for dialogs. It contains all OGR drivers
522+
plus some additional internal QGIS driver names to distinguish between more
523+
supported formats of the same OGR driver.
524+
525+
The returned list consists of structs containing the driver long name (e.g. user-friendly
526+
display name for the format) and internal driver short name.
527+
528+
The ``options`` argument can be used to control the sorting and filtering of
529+
returned drivers.
530+
:rtype: list of QgsVectorFileWriter.DriverDetails
484531
%End
485532

486533
static QString driverForExtension( const QString &extension );
@@ -492,9 +539,12 @@ Create a new vector file writer
492539
:rtype: str
493540
%End
494541

495-
static QString fileFilterString();
542+
static QString fileFilterString( VectorFormatOptions options = SortRecommended );
496543
%Docstring
497-
Returns filter string that can be used for dialogs
544+
Returns filter string that can be used for dialogs.
545+
546+
The ``options`` argument can be used to control the sorting and filtering of
547+
returned drivers.
498548
:rtype: str
499549
%End
500550

@@ -639,6 +689,8 @@ Close opened shapefile for writing
639689

640690
QFlags<QgsVectorFileWriter::EditionCapability> operator|(QgsVectorFileWriter::EditionCapability f1, QFlags<QgsVectorFileWriter::EditionCapability> f2);
641691

692+
QFlags<QgsVectorFileWriter::VectorFormatOption> operator|(QgsVectorFileWriter::VectorFormatOption f1, QFlags<QgsVectorFileWriter::VectorFormatOption> f2);
693+
642694

643695

644696
/************************************************************************

‎python/plugins/processing/algs/gdal/GdalUtils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ def getVectorDriverFromFileName(filename):
174174
return 'ESRI Shapefile'
175175

176176
formats = QgsVectorFileWriter.supportedFiltersAndFormats()
177-
for k, v in list(formats.items()):
178-
if ext in k:
179-
return v
177+
for format in formats:
178+
if ext in format.filterString:
179+
return format.driverName
180180
return 'ESRI Shapefile'
181181

182182
@staticmethod

‎src/core/qgsvectorfilewriter.cpp

Lines changed: 100 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,13 +2681,16 @@ void QgsVectorFileWriter::setSymbologyScale( double d )
26812681
mRenderContext.setRendererScale( mSymbologyScale );
26822682
}
26832683

2684-
QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats()
2684+
QList< QgsVectorFileWriter::FilterFormatDetails > QgsVectorFileWriter::supportedFiltersAndFormats( const VectorFormatOptions options )
26852685
{
2686-
QMap<QString, QString> resultMap;
2686+
QList< FilterFormatDetails > results;
26872687

26882688
QgsApplication::registerOgrDrivers();
26892689
int const drvCount = OGRGetDriverCount();
26902690

2691+
FilterFormatDetails shapeFormat;
2692+
FilterFormatDetails gpkgFormat;
2693+
26912694
for ( int i = 0; i < drvCount; ++i )
26922695
{
26932696
OGRSFDriverH drv = OGRGetDriver( i );
@@ -2696,58 +2699,87 @@ QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats()
26962699
QString drvName = OGR_Dr_GetName( drv );
26972700
if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
26982701
{
2702+
if ( options & SkipNonSpatialFormats )
2703+
{
2704+
// skip non-spatial formats
2705+
// TODO - use GDAL metadata to determine this, when support exists in GDAL
2706+
if ( drvName == QLatin1String( "ODS" ) || drvName == QLatin1String( "XLSX" ) || drvName == QLatin1String( "XLS" ) )
2707+
continue;
2708+
}
2709+
26992710
QString filterString = filterForDriver( drvName );
27002711
if ( filterString.isEmpty() )
27012712
continue;
27022713

2703-
resultMap.insert( filterString, drvName );
2714+
FilterFormatDetails details;
2715+
details.driverName = drvName;
2716+
details.filterString = filterString;
2717+
2718+
if ( options & SortRecommended )
2719+
{
2720+
if ( drvName == QLatin1String( "ESRI Shapefile" ) )
2721+
{
2722+
shapeFormat = details;
2723+
continue;
2724+
}
2725+
else if ( drvName == QLatin1String( "GPKG" ) )
2726+
{
2727+
gpkgFormat = details;
2728+
continue;
2729+
}
2730+
}
2731+
2732+
results << details;
27042733
}
27052734
}
27062735
}
27072736

2708-
return resultMap;
2737+
std::sort( results.begin(), results.end(), []( const FilterFormatDetails & a, const FilterFormatDetails & b ) -> bool
2738+
{
2739+
return a.driverName < b.driverName;
2740+
} );
2741+
2742+
if ( options & SortRecommended )
2743+
{
2744+
if ( !shapeFormat.filterString.isEmpty() )
2745+
{
2746+
results.insert( 0, shapeFormat );
2747+
}
2748+
if ( !gpkgFormat.filterString.isEmpty() )
2749+
{
2750+
results.insert( 0, gpkgFormat );
2751+
}
2752+
}
2753+
2754+
return results;
27092755
}
27102756

2711-
QStringList QgsVectorFileWriter::supportedFormatExtensions()
2757+
QStringList QgsVectorFileWriter::supportedFormatExtensions( const VectorFormatOptions options )
27122758
{
2713-
QgsStringMap formats = supportedFiltersAndFormats();
2759+
const auto formats = supportedFiltersAndFormats( options );
27142760
QStringList extensions;
27152761

27162762
QRegularExpression rx( QStringLiteral( "\\*\\.([a-zA-Z0-9]*)" ) );
27172763

2718-
QgsStringMap::const_iterator formatIt = formats.constBegin();
2719-
for ( ; formatIt != formats.constEnd(); ++formatIt )
2764+
for ( const FilterFormatDetails &format : formats )
27202765
{
2721-
QString ext = formatIt.key();
2766+
QString ext = format.filterString;
27222767
QRegularExpressionMatch match = rx.match( ext );
27232768
if ( !match.hasMatch() )
27242769
continue;
27252770

27262771
QString matched = match.captured( 1 );
2727-
2728-
// special handling for the two main contenders for glory
2729-
if ( matched.compare( QStringLiteral( "gpkg" ), Qt::CaseInsensitive ) == 0 )
2730-
continue;
2731-
if ( matched.compare( QStringLiteral( "shp" ), Qt::CaseInsensitive ) == 0 )
2732-
continue;
2733-
27342772
extensions << matched;
27352773
}
2736-
2737-
std::sort( extensions.begin(), extensions.end() );
2738-
2739-
// Make https://twitter.com/shapefiIe a sad little fellow
2740-
extensions.insert( 0, QStringLiteral( "gpkg" ) );
2741-
extensions.insert( 1, QStringLiteral( "shp" ) );
27422774
return extensions;
27432775
}
27442776

2745-
QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
2777+
QList< QgsVectorFileWriter::DriverDetails > QgsVectorFileWriter::ogrDriverList( const VectorFormatOptions options )
27462778
{
2747-
QMap<QString, QString> resultMap;
2779+
QList< QgsVectorFileWriter::DriverDetails > results;
27482780

27492781
QgsApplication::registerOgrDrivers();
2750-
int const drvCount = OGRGetDriverCount();
2782+
const int drvCount = OGRGetDriverCount();
27512783

27522784
QStringList writableDrivers;
27532785
for ( int i = 0; i < drvCount; ++i )
@@ -2756,6 +2788,19 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
27562788
if ( drv )
27572789
{
27582790
QString drvName = OGR_Dr_GetName( drv );
2791+
2792+
if ( options & SkipNonSpatialFormats )
2793+
{
2794+
// skip non-spatial formats
2795+
// TODO - use GDAL metadata to determine this, when support exists in GDAL
2796+
if ( drvName == QLatin1String( "ODS" ) || drvName == QLatin1String( "XLSX" ) || drvName == QLatin1String( "XLS" ) )
2797+
continue;
2798+
}
2799+
2800+
if ( drvName == QLatin1String( "ESRI Shapefile" ) )
2801+
{
2802+
writableDrivers << QStringLiteral( "DBF file" );
2803+
}
27592804
if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
27602805
{
27612806
// Add separate format for Mapinfo MIF (MITAB is OGR default)
@@ -2786,25 +2831,39 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
27862831
}
27872832
CPLFree( options[0] );
27882833
}
2789-
else if ( drvName == QLatin1String( "ESRI Shapefile" ) )
2790-
{
2791-
writableDrivers << QStringLiteral( "DBF file" );
2792-
}
27932834
writableDrivers << drvName;
27942835
}
27952836
}
27962837
}
2838+
std::sort( writableDrivers.begin(), writableDrivers.end() );
2839+
if ( options & SortRecommended )
2840+
{
2841+
// recommended order sorting, so we shift certain formats to the top
2842+
if ( writableDrivers.contains( QStringLiteral( "ESRI Shapefile" ) ) )
2843+
{
2844+
writableDrivers.removeAll( QStringLiteral( "ESRI Shapefile" ) );
2845+
writableDrivers.insert( 0, QStringLiteral( "ESRI Shapefile" ) );
2846+
}
2847+
if ( writableDrivers.contains( QStringLiteral( "GPKG" ) ) )
2848+
{
2849+
// Make https://twitter.com/shapefiIe a sad little fellow
2850+
writableDrivers.removeAll( QStringLiteral( "GPKG" ) );
2851+
writableDrivers.insert( 0, QStringLiteral( "GPKG" ) );
2852+
}
2853+
}
27972854

2798-
Q_FOREACH ( const QString &drvName, writableDrivers )
2855+
for ( const QString &drvName : qgis::as_const( writableDrivers ) )
27992856
{
28002857
MetaData metadata;
28012858
if ( driverMetadata( drvName, metadata ) && !metadata.trLongName.isEmpty() )
28022859
{
2803-
resultMap.insert( metadata.trLongName, drvName );
2860+
DriverDetails details;
2861+
details.driverName = drvName;
2862+
details.longName = metadata.trLongName;
2863+
results << details;
28042864
}
28052865
}
2806-
2807-
return resultMap;
2866+
return results;
28082867
}
28092868

28102869
QString QgsVectorFileWriter::driverForExtension( const QString &extension )
@@ -2841,17 +2900,16 @@ QString QgsVectorFileWriter::driverForExtension( const QString &extension )
28412900
return QString();
28422901
}
28432902

2844-
QString QgsVectorFileWriter::fileFilterString()
2903+
QString QgsVectorFileWriter::fileFilterString( const VectorFormatOptions options )
28452904
{
28462905
QString filterString;
2847-
QMap< QString, QString> driverFormatMap = supportedFiltersAndFormats();
2848-
QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
2849-
for ( ; it != driverFormatMap.constEnd(); ++it )
2906+
const auto driverFormats = supportedFiltersAndFormats( options );
2907+
for ( const FilterFormatDetails &details : driverFormats )
28502908
{
28512909
if ( !filterString.isEmpty() )
28522910
filterString += QLatin1String( ";;" );
28532911

2854-
filterString += it.key();
2912+
filterString += details.filterString;
28552913
}
28562914
return filterString;
28572915
}
@@ -2860,9 +2918,11 @@ QString QgsVectorFileWriter::filterForDriver( const QString &driverName )
28602918
{
28612919
MetaData metadata;
28622920
if ( !driverMetadata( driverName, metadata ) || metadata.trLongName.isEmpty() || metadata.glob.isEmpty() )
2863-
return QLatin1String( "" );
2921+
return QString();
28642922

2865-
return metadata.trLongName + " [OGR] (" + metadata.glob.toLower() + ' ' + metadata.glob.toUpper() + ')';
2923+
return QStringLiteral( "%1 (%2 %3)" ).arg( metadata.trLongName,
2924+
metadata.glob.toLower(),
2925+
metadata.glob.toUpper() );
28662926
}
28672927

28682928
QString QgsVectorFileWriter::convertCodecNameForEncodingOption( const QString &codecName )

‎src/core/qgsvectorfilewriter.h

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929
#include "qgsogrutils.h"
3030
#include <ogr_api.h>
3131

32-
#include <QPair>
33-
34-
3532
class QgsSymbolLayer;
3633
class QTextCodec;
3734
class QgsFeatureIterator;
@@ -186,6 +183,18 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
186183
SymbolLayerSymbology //Exports one feature per symbol layer (considering symbol levels)
187184
};
188185

186+
187+
/**
188+
* Options for sorting and filtering vector formats.
189+
* \since QGIS 3.0
190+
*/
191+
enum VectorFormatOption
192+
{
193+
SortRecommended = 1 << 1, //!< Use recommended sort order, with extremely commonly used formats listed first
194+
SkipNonSpatialFormats = 1 << 2, //!< Filter out any formats which do not have spatial support (e.g. those which cannot save geometries)
195+
};
196+
Q_DECLARE_FLAGS( VectorFormatOptions, VectorFormatOption )
197+
189198
/**
190199
* \ingroup core
191200
* Interface to convert raw field values to their user-friendly value.
@@ -496,24 +505,64 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
496505
QgsVectorFileWriter &operator=( const QgsVectorFileWriter &rh ) = delete;
497506

498507
/**
499-
* Returns a map with format filter string as key and OGR format key as value.
508+
* Details of available filters and formats.
509+
* \since QGIS 3.0
510+
*/
511+
struct FilterFormatDetails
512+
{
513+
//! Unique driver name
514+
QString driverName;
515+
516+
//! Filter string for file picker dialogs
517+
QString filterString;
518+
};
519+
520+
/**
521+
* Returns a list or pairs, with format filter string as first element and OGR format key as second element.
522+
*
523+
* The \a options argument can be used to control the sorting and filtering of
524+
* returned formats.
525+
*
500526
* \see supportedOutputVectorLayerExtensions()
501527
*/
502-
static QMap< QString, QString> supportedFiltersAndFormats();
528+
static QList< QgsVectorFileWriter::FilterFormatDetails > supportedFiltersAndFormats( VectorFormatOptions options = SortRecommended );
503529

504530
/**
505531
* Returns a list of file extensions for supported formats.
532+
*
533+
* The \a options argument can be used to control the sorting and filtering of
534+
* returned formats.
535+
*
506536
* \since QGIS 3.0
507537
* \see supportedFiltersAndFormats()
508538
*/
509-
static QStringList supportedFormatExtensions();
539+
static QStringList supportedFormatExtensions( VectorFormatOptions options = SortRecommended );
540+
541+
/**
542+
* Details of available driver formats.
543+
* \since QGIS 3.0
544+
*/
545+
struct DriverDetails
546+
{
547+
//! Descriptive, user friendly name for the driver
548+
QString longName;
549+
550+
//! Unique driver name
551+
QString driverName;
552+
};
510553

511554
/**
512-
* Returns driver list that can be used for dialogs. It contains all OGR drivers
513-
* + some additional internal QGIS driver names to distinguish between more
514-
* supported formats of the same OGR driver
555+
* Returns the driver list that can be used for dialogs. It contains all OGR drivers
556+
* plus some additional internal QGIS driver names to distinguish between more
557+
* supported formats of the same OGR driver.
558+
*
559+
* The returned list consists of structs containing the driver long name (e.g. user-friendly
560+
* display name for the format) and internal driver short name.
561+
*
562+
* The \a options argument can be used to control the sorting and filtering of
563+
* returned drivers.
515564
*/
516-
static QMap< QString, QString> ogrDriverList();
565+
static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList( VectorFormatOptions options = SortRecommended );
517566

518567
/**
519568
* Returns the OGR driver name for a specified file \a extension. E.g. the
@@ -523,8 +572,13 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
523572
*/
524573
static QString driverForExtension( const QString &extension );
525574

526-
//! Returns filter string that can be used for dialogs
527-
static QString fileFilterString();
575+
/**
576+
* Returns filter string that can be used for dialogs.
577+
*
578+
* The \a options argument can be used to control the sorting and filtering of
579+
* returned drivers.
580+
*/
581+
static QString fileFilterString( VectorFormatOptions options = SortRecommended );
528582

529583
//! Creates a filter for an OGR driver key
530584
static QString filterForDriver( const QString &driverName );
@@ -701,6 +755,7 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
701755
};
702756

703757
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsVectorFileWriter::EditionCapabilities )
758+
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsVectorFileWriter::VectorFormatOptions )
704759

705760
// clazy:excludeall=qstring-allocations
706761

‎src/gui/ogr/qgsvectorlayersaveasdialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ void QgsVectorLayerSaveAsDialog::setup()
8787
QgsSettings settings;
8888
restoreGeometry( settings.value( QStringLiteral( "Windows/VectorLayerSaveAs/geometry" ) ).toByteArray() );
8989

90-
QMap<QString, QString> map = QgsVectorFileWriter::ogrDriverList();
90+
const QList< QgsVectorFileWriter::DriverDetails > drivers = QgsVectorFileWriter::ogrDriverList();
9191
mFormatComboBox->blockSignals( true );
92-
for ( QMap< QString, QString>::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
92+
for ( const QgsVectorFileWriter::DriverDetails &driver : drivers )
9393
{
94-
mFormatComboBox->addItem( it.key(), it.value() );
94+
mFormatComboBox->addItem( driver.longName, driver.driverName );
9595
}
9696

9797
QString format = settings.value( QStringLiteral( "UI/lastVectorFormat" ), "GPKG" ).toString();

‎src/plugins/geometry_checker/qgsgeometrycheckersetuptab.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ QgsGeometryCheckerSetupTab::QgsGeometryCheckerSetupTab( QgisInterface *iface, QD
5454
mAbortButton = new QPushButton( tr( "Abort" ) );
5555
mRunButton->setEnabled( false );
5656

57-
QMap<QString, QString> filterFormatMap = QgsVectorFileWriter::supportedFiltersAndFormats();
58-
for ( const QString &filter : filterFormatMap.keys() )
57+
const auto filterFormatMap = QgsVectorFileWriter::supportedFiltersAndFormats( QgsVectorFileWriter::SortRecommended | QgsVectorFileWriter::SkipNonSpatialFormats );
58+
for ( const QgsVectorFileWriter::FilterFormatDetails &filter : filterFormatMap )
5959
{
60-
QString driverName = filterFormatMap.value( filter );
60+
QString driverName = filter.driverName;
6161
ui.comboBoxOutputFormat->addItem( driverName );
6262
if ( driverName == QLatin1String( "ESRI Shapefile" ) )
6363
{
@@ -216,13 +216,13 @@ void QgsGeometryCheckerSetupTab::validateInput()
216216
void QgsGeometryCheckerSetupTab::selectOutputDirectory()
217217
{
218218
QString filterString = QgsVectorFileWriter::filterForDriver( QStringLiteral( "GPKG" ) );
219-
QMap<QString, QString> filterFormatMap = QgsVectorFileWriter::supportedFiltersAndFormats();
220-
for ( const QString &filter : filterFormatMap.keys() )
219+
const auto filterFormatMap = QgsVectorFileWriter::supportedFiltersAndFormats( QgsVectorFileWriter::SortRecommended | QgsVectorFileWriter::SkipNonSpatialFormats );
220+
for ( const QgsVectorFileWriter::FilterFormatDetails &filter : filterFormatMap )
221221
{
222-
QString driverName = filterFormatMap.value( filter );
222+
QString driverName = filter.driverName;
223223
if ( driverName != QLatin1String( "ESRI Shapefile" ) ) // Default entry, first in list (see above)
224224
{
225-
filterString += ";;" + filter;
225+
filterString += ";;" + filter.filterString;
226226
}
227227
}
228228
QString initialdir = ui.lineEditOutputDirectory->text();

‎tests/src/python/test_qgsvectorfilewriter.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,12 +723,74 @@ def testOverwriteLayer(self):
723723

724724
gdal.Unlink(filename)
725725

726+
def testSupportedFiltersAndFormat(self):
727+
# test with formats in recommended order
728+
formats = QgsVectorFileWriter.supportedFiltersAndFormats(QgsVectorFileWriter.SortRecommended)
729+
self.assertEqual(formats[0].filterString, 'GeoPackage (*.gpkg *.GPKG)')
730+
self.assertEqual(formats[0].driverName, 'GPKG')
731+
self.assertEqual(formats[1].filterString, 'ESRI Shapefile (*.shp *.SHP)')
732+
self.assertEqual(formats[1].driverName, 'ESRI Shapefile')
733+
self.assertTrue('ODS' in [f.driverName for f in formats])
734+
735+
# alphabetical sorting
736+
formats2 = QgsVectorFileWriter.supportedFiltersAndFormats(QgsVectorFileWriter.VectorFormatOptions())
737+
self.assertTrue(formats2[0].driverName < formats2[1].driverName)
738+
self.assertCountEqual([f.driverName for f in formats], [f.driverName for f in formats2])
739+
self.assertNotEqual(formats2[0].driverName, 'GeoPackage')
740+
741+
# skip non-spatial
742+
formats = QgsVectorFileWriter.supportedFiltersAndFormats(QgsVectorFileWriter.SkipNonSpatialFormats)
743+
self.assertFalse('ODS' in [f.driverName for f in formats])
744+
745+
def testOgrDriverList(self):
746+
# test with drivers in recommended order
747+
drivers = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.SortRecommended)
748+
self.assertEqual(drivers[0].longName, 'GeoPackage')
749+
self.assertEqual(drivers[0].driverName, 'GPKG')
750+
self.assertEqual(drivers[1].longName, 'ESRI Shapefile')
751+
self.assertEqual(drivers[1].driverName, 'ESRI Shapefile')
752+
self.assertTrue('ODS' in [f.driverName for f in drivers])
753+
# alphabetical sorting
754+
drivers2 = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.VectorFormatOptions())
755+
self.assertTrue(drivers2[0].longName < drivers2[1].longName)
756+
self.assertCountEqual([d.driverName for d in drivers], [d.driverName for d in drivers2])
757+
self.assertNotEqual(drivers2[0].driverName, 'GPKG')
758+
759+
# skip non-spatial
760+
formats = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.SkipNonSpatialFormats)
761+
self.assertFalse('ODS' in [f.driverName for f in formats])
762+
726763
def testSupportedFormatExtensions(self):
727764
formats = QgsVectorFileWriter.supportedFormatExtensions()
728765
self.assertTrue('gpkg' in formats)
729766
self.assertFalse('exe' in formats)
730767
self.assertEqual(formats[0], 'gpkg')
731768
self.assertEqual(formats[1], 'shp')
769+
self.assertTrue('ods' in formats)
770+
771+
# alphabetical sorting
772+
formats2 = QgsVectorFileWriter.supportedFormatExtensions(QgsVectorFileWriter.VectorFormatOptions())
773+
self.assertTrue(formats2[0] < formats2[1])
774+
self.assertCountEqual(formats, formats2)
775+
self.assertNotEqual(formats2[0], 'gpkg')
776+
777+
formats = QgsVectorFileWriter.supportedFormatExtensions(QgsVectorFileWriter.SkipNonSpatialFormats)
778+
self.assertFalse('ods' in formats)
779+
780+
def testFileFilterString(self):
781+
formats = QgsVectorFileWriter.fileFilterString()
782+
self.assertTrue('gpkg' in formats)
783+
self.assertTrue('shp' in formats)
784+
self.assertTrue(formats.index('gpkg') < formats.index('shp'))
785+
self.assertTrue('ods' in formats)
786+
787+
# alphabetical sorting
788+
formats2 = QgsVectorFileWriter.fileFilterString(QgsVectorFileWriter.VectorFormatOptions())
789+
self.assertNotEqual(formats.index('gpkg'), formats2.index('gpkg'))
790+
791+
# hide non spatial
792+
formats = QgsVectorFileWriter.fileFilterString(QgsVectorFileWriter.SkipNonSpatialFormats)
793+
self.assertFalse('ods' in formats)
732794

733795
def testDriverForExtension(self):
734796
self.assertEqual(QgsVectorFileWriter.driverForExtension('shp'), 'ESRI Shapefile')

0 commit comments

Comments
 (0)
Please sign in to comment.