From 26495dbd819c44e77381c0c185f73ba0bfcc0ec5 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 3 Apr 2017 15:41:32 +1000 Subject: [PATCH] [processing] Move dataobjects.getSupportedOutputVectorLayerExtensions to QgsVectorFileWriter --- python/core/qgsvectorfilewriter.sip | 1 + .../processing/algs/gdal/GdalAlgorithm.py | 5 ++-- .../processing/core/AlgorithmProvider.py | 5 ++-- .../processing/core/ProcessingConfig.py | 7 +++-- python/plugins/processing/core/outputs.py | 10 +++++-- python/plugins/processing/core/parameters.py | 7 +++-- .../plugins/processing/tools/dataobjects.py | 14 --------- src/core/qgsvectorfilewriter.cpp | 29 +++++++++++++++++++ src/core/qgsvectorfilewriter.h | 12 +++++++- tests/src/python/test_qgsvectorfilewriter.py | 8 ++++- 10 files changed, 71 insertions(+), 27 deletions(-) diff --git a/python/core/qgsvectorfilewriter.sip b/python/core/qgsvectorfilewriter.sip index 9a0687db6f3..2c018e9c73c 100644 --- a/python/core/qgsvectorfilewriter.sip +++ b/python/core/qgsvectorfilewriter.sip @@ -357,6 +357,7 @@ class QgsVectorFileWriter /** Returns map with format filter string as key and OGR format key as value*/ static QMap< QString, QString> supportedFiltersAndFormats(); + static QStringList supportedFormatExtensions(); /** Returns driver list that can be used for dialogs. It contains all OGR drivers * + some additional internal QGIS driver names to distinguish between more diff --git a/python/plugins/processing/algs/gdal/GdalAlgorithm.py b/python/plugins/processing/algs/gdal/GdalAlgorithm.py index af10e02a7f2..a138618408c 100644 --- a/python/plugins/processing/algs/gdal/GdalAlgorithm.py +++ b/python/plugins/processing/algs/gdal/GdalAlgorithm.py @@ -30,7 +30,8 @@ import re from qgis.PyQt.QtCore import QUrl -from qgis.core import QgsApplication +from qgis.core import (QgsApplication, + QgsVectorFileWriter) from processing.core.GeoAlgorithm import GeoAlgorithm from processing.algs.gdal.GdalAlgorithmDialog import GdalAlgorithmDialog @@ -58,7 +59,7 @@ class GdalAlgorithm(GeoAlgorithm): def processAlgorithm(self, feedback): commands = self.getConsoleCommands() layers = dataobjects.getVectorLayers() - supported = dataobjects.getSupportedOutputVectorLayerExtensions() + supported = QgsVectorFileWriter.supportedFormatExtensions() for i, c in enumerate(commands): for layer in layers: if layer.source() in c: diff --git a/python/plugins/processing/core/AlgorithmProvider.py b/python/plugins/processing/core/AlgorithmProvider.py index 394a0a83b63..ecb231b0d84 100644 --- a/python/plugins/processing/core/AlgorithmProvider.py +++ b/python/plugins/processing/core/AlgorithmProvider.py @@ -26,7 +26,8 @@ __copyright__ = '(C) 2012, Victor Olaya' __revision__ = '$Format:%H$' from qgis.PyQt.QtCore import QCoreApplication -from qgis.core import QgsProcessingProvider +from qgis.core import (QgsProcessingProvider, + QgsVectorFileWriter) from processing.core.ProcessingConfig import Setting, ProcessingConfig from processing.tools import dataobjects @@ -91,7 +92,7 @@ class AlgorithmProvider(QgsProcessingProvider): return ['tif'] def getSupportedOutputVectorLayerExtensions(self): - return dataobjects.getSupportedOutputVectorLayerExtensions() + return QgsVectorFileWriter.supportedFormatExtensions() def getSupportedOutputTableExtensions(self): return ['csv'] diff --git a/python/plugins/processing/core/ProcessingConfig.py b/python/plugins/processing/core/ProcessingConfig.py index 8e68a416587..c2734e5457c 100644 --- a/python/plugins/processing/core/ProcessingConfig.py +++ b/python/plugins/processing/core/ProcessingConfig.py @@ -30,7 +30,10 @@ __revision__ = '$Format:%H$' import os from qgis.PyQt.QtCore import QCoreApplication, QObject, pyqtSignal -from qgis.core import NULL, QgsApplication, QgsSettings +from qgis.core import (NULL, + QgsApplication, + QgsSettings, + QgsVectorFileWriter) from processing.tools.system import defaultOutputFolder import processing.tools.dataobjects @@ -165,7 +168,7 @@ class ProcessingConfig(object): valuetype=Setting.SELECTION, options=invalidFeaturesOptions)) - extensions = processing.tools.dataobjects.getSupportedOutputVectorLayerExtensions() + extensions = QgsVectorFileWriter.supportedFormatExtensions() ProcessingConfig.addSetting(Setting( ProcessingConfig.tr('General'), ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT, diff --git a/python/plugins/processing/core/outputs.py b/python/plugins/processing/core/outputs.py index 045e1f7de8b..cac05025d76 100644 --- a/python/plugins/processing/core/outputs.py +++ b/python/plugins/processing/core/outputs.py @@ -38,7 +38,13 @@ from processing.tools.system import isWindows, getTempFilenameInTempFolder, getT from processing.tools.vector import VectorWriter, TableWriter from processing.tools import dataobjects -from qgis.core import QgsExpressionContext, QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope, QgsProject, QgsSettings +from qgis.core import (QgsExpressionContext, + QgsExpressionContextUtils, + QgsExpression, + QgsExpressionContextScope, + QgsProject, + QgsSettings, + QgsVectorFileWriter) def _expressionContext(alg): @@ -316,7 +322,7 @@ class OutputVector(Output): return dataobjects.canUseVectorLayer(self.base_layer, [-1]) def getSupportedOutputVectorLayerExtensions(self): - exts = dataobjects.getSupportedOutputVectorLayerExtensions() + exts = QgsVectorFileWriter.supportedFormatExtensions() if not self.hasGeometry(): exts = ['dbf'] + [ext for ext in exts if ext in VectorWriter.nogeometry_extensions] return exts diff --git a/python/plugins/processing/core/parameters.py b/python/plugins/processing/core/parameters.py index 9f840980c82..7421a0f5ce7 100644 --- a/python/plugins/processing/core/parameters.py +++ b/python/plugins/processing/core/parameters.py @@ -40,7 +40,8 @@ from qgis.utils import iface from qgis.PyQt.QtCore import QCoreApplication from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinateReferenceSystem, QgsExpressionContext, QgsExpressionContextUtils, QgsExpression, QgsExpressionContextScope, - QgsProject) + QgsProject, + QgsVectorFileWriter) from processing.tools.vector import resolveFieldIndex, features from processing.tools import dataobjects @@ -751,7 +752,7 @@ class ParameterMultipleInput(ParameterDataObject): elif self.datatype == dataobjects.TYPE_FILE: return self.tr('All files (*.*)', 'ParameterMultipleInput') else: - exts = dataobjects.getSupportedOutputVectorLayerExtensions() + exts = QgsVectorFileWriter.supportedFormatExtensions() for i in range(len(exts)): exts[i] = self.tr('{0} files (*.{1})', 'ParameterMultipleInput').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) @@ -1523,7 +1524,7 @@ class ParameterVector(ParameterDataObject): return self.exported def getFileFilter(self): - exts = dataobjects.getSupportedOutputVectorLayerExtensions() + exts = QgsVectorFileWriter.supportedFormatExtensions() for i in range(len(exts)): exts[i] = self.tr('{0} files (*.{1})', 'ParameterVector').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) diff --git a/python/plugins/processing/tools/dataobjects.py b/python/plugins/processing/tools/dataobjects.py index 7670a371162..4e1cfa3a663 100644 --- a/python/plugins/processing/tools/dataobjects.py +++ b/python/plugins/processing/tools/dataobjects.py @@ -65,20 +65,6 @@ def resetLoadedLayers(): _loadedLayers = {} -def getSupportedOutputVectorLayerExtensions(): - formats = QgsVectorFileWriter.supportedFiltersAndFormats() - exts = [] - for extension in list(formats.keys()): - extension = str(extension) - extension = extension[extension.find('*.') + 2:] - extension = extension[:extension.find(' ')] - if extension.lower() != 'shp': - exts.append(extension) - exts.sort() - exts.insert(0, 'shp') # shp is the default, should be the first - return exts - - def getSupportedOutputRasterLayerExtensions(): allexts = [] for exts in list(GdalUtils.getSupportedRasters().values()): diff --git a/src/core/qgsvectorfilewriter.cpp b/src/core/qgsvectorfilewriter.cpp index 38b2ef92492..d1428a902aa 100644 --- a/src/core/qgsvectorfilewriter.cpp +++ b/src/core/qgsvectorfilewriter.cpp @@ -2604,6 +2604,35 @@ QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats() return resultMap; } +QStringList QgsVectorFileWriter::supportedFormatExtensions() +{ + QgsStringMap formats = supportedFiltersAndFormats(); + QStringList extensions; + + QRegularExpression rx( "\\*\\.([a-zA-Z0-9]*)" ); + + QgsStringMap::const_iterator formatIt = formats.constBegin(); + for ( ; formatIt != formats.constEnd(); ++formatIt ) + { + QString ext = formatIt.key(); + QRegularExpressionMatch match = rx.match( ext ); + if ( !match.hasMatch() ) + continue; + + QString matched = match.captured( 1 ); + if ( matched.compare( QStringLiteral( "shp" ), Qt::CaseInsensitive ) == 0 ) + continue; + + extensions << matched; + } + + std::sort( extensions.begin(), extensions.end() ); + + // Make https://twitter.com/shapefiIe a happy little fellow + extensions.insert( 0, QStringLiteral( "shp" ) ); + return extensions; +} + QMap QgsVectorFileWriter::ogrDriverList() { QMap resultMap; diff --git a/src/core/qgsvectorfilewriter.h b/src/core/qgsvectorfilewriter.h index 31a46765165..4b653818c4b 100644 --- a/src/core/qgsvectorfilewriter.h +++ b/src/core/qgsvectorfilewriter.h @@ -432,9 +432,19 @@ class CORE_EXPORT QgsVectorFileWriter //! QgsVectorFileWriter cannot be copied. QgsVectorFileWriter &operator=( const QgsVectorFileWriter &rh ) = delete; - //! Returns map with format filter string as key and OGR format key as value + /** + * Returns a map with format filter string as key and OGR format key as value. + * \see supportedOutputVectorLayerExtensions() + */ static QMap< QString, QString> supportedFiltersAndFormats(); + /** + * Returns a list of file extensions for supported formats. + * \since QGIS 3.0 + * \see supportedFiltersAndFormats() + */ + static QStringList supportedFormatExtensions(); + /** Returns driver list that can be used for dialogs. It contains all OGR drivers * + some additional internal QGIS driver names to distinguish between more * supported formats of the same OGR driver diff --git a/tests/src/python/test_qgsvectorfilewriter.py b/tests/src/python/test_qgsvectorfilewriter.py index 2e91cf32b9e..6e4cda90946 100644 --- a/tests/src/python/test_qgsvectorfilewriter.py +++ b/tests/src/python/test_qgsvectorfilewriter.py @@ -65,7 +65,7 @@ class TestFieldValueConverter(QgsVectorFileWriter.FieldValueConverter): return 'unexpected_idx' -class TestQgsVectorLayer(unittest.TestCase): +class TestQgsVectorFileWriter(unittest.TestCase): mMemoryLayer = None @@ -656,6 +656,12 @@ class TestQgsVectorLayer(unittest.TestCase): gdal.Unlink(filename) + def testSupportedFormatExtensions(self): + formats = QgsVectorFileWriter.supportedFormatExtensions() + self.assertTrue('gpkg' in formats) + self.assertFalse('exe' in formats) + self.assertEqual(formats[0], 'shp') + if __name__ == '__main__': unittest.main()