[processing] fix handling of the "selection" type settings

This commit is contained in:
Alexander Bruy 2017-01-12 12:51:08 +02:00
parent b823874f8e
commit 03eaad5bfd
2 changed files with 76 additions and 30 deletions

View File

@ -31,10 +31,9 @@ import os
from qgis.PyQt.QtCore import QCoreApplication, QSettings, QObject, pyqtSignal
from qgis.PyQt.QtGui import QIcon
from qgis.core import (NULL,
QgsApplication)
from qgis.core import NULL, QgsApplication
from processing.tools.system import defaultOutputFolder
import processing.tools.dataobjects
from processing.tools import dataobjects
class SettingsWatcher(QObject):
@ -87,14 +86,6 @@ class ProcessingConfig(object):
ProcessingConfig.tr('General'),
ProcessingConfig.USE_SELECTED,
ProcessingConfig.tr('Use only selected features'), True))
invalidFeaturesOptions = [ProcessingConfig.tr('Do not filter (better performance'),
ProcessingConfig.tr('Ignore features with invalid geometries'),
ProcessingConfig.tr('Stop algorithm execution when a geometry is invalid')]
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.FILTER_INVALID_GEOMETRIES,
ProcessingConfig.tr('Invalid features filtering'), invalidFeaturesOptions[2],
valuetype=Setting.SELECTION, options=invalidFeaturesOptions))
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.USE_FILENAME_AS_LAYER_NAME,
@ -163,18 +154,35 @@ class ProcessingConfig(object):
ProcessingConfig.MODELS_SCRIPTS_REPO,
ProcessingConfig.tr('Scripts and models repository'),
'https://raw.githubusercontent.com/qgis/QGIS-Processing/master'))
extensions = processing.tools.dataobjects.getSupportedOutputVectorLayerExtensions()
invalidFeaturesOptions = [ProcessingConfig.tr('Do not filter (better performance'),
ProcessingConfig.tr('Ignore features with invalid geometries'),
ProcessingConfig.tr('Stop algorithm execution when a geometry is invalid')]
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.FILTER_INVALID_GEOMETRIES,
ProcessingConfig.tr('Invalid features filtering'),
invalidFeaturesOptions[2],
valuetype=Setting.SELECTION,
options=invalidFeaturesOptions))
extensions = dataobjects.getSupportedOutputVectorLayerExtensions()
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT,
ProcessingConfig.tr('Default output vector layer extension'), extensions[0],
valuetype=Setting.SELECTION, options=extensions))
extensions = processing.tools.dataobjects.getSupportedOutputRasterLayerExtensions()
ProcessingConfig.tr('Default output vector layer extension'),
extensions[0],
valuetype=Setting.SELECTION,
options=extensions))
extensions = dataobjects.getSupportedOutputRasterLayerExtensions()
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT,
ProcessingConfig.tr('Default output raster layer extension'), extensions[0],
valuetype=Setting.SELECTION, options=extensions))
ProcessingConfig.tr('Default output raster layer extension'),
extensions[0],
valuetype=Setting.SELECTION,
options=extensions))
@staticmethod
def setGroupIcon(group, icon):
@ -224,14 +232,20 @@ class ProcessingConfig(object):
v = None
except:
pass
return v
if ProcessingConfig.settings[name].valuetype == Setting.SELECTION:
return ProcessingConfig.settings[name].options.index(v)
else:
return v
else:
return None
@staticmethod
def setSettingValue(name, value):
if name in list(ProcessingConfig.settings.keys()):
ProcessingConfig.settings[name].setValue(value)
if ProcessingConfig.settings[name].valuetype == Setting.SELECTION:
ProcessingConfig.settings[name].setValue(ProcessingConfig.settings[name].options[value])
else:
ProcessingConfig.settings[name].setValue(value)
ProcessingConfig.settings[name].save()
@staticmethod
@ -261,34 +275,36 @@ class Setting(object):
self.description = description
self.default = default
self.hidden = hidden
if valuetype is None:
if isinstance(default, int):
valuetype = self.INT
elif isinstance(default, float):
valuetype = self.FLOAT
self.valuetype = valuetype
self.options = options
if self.valuetype is None:
if isinstance(default, int):
self.valuetype = self.INT
elif isinstance(default, float):
self.valuetype = self.FLOAT
if validator is None:
if valuetype == self.FLOAT:
if self.valuetype == self.FLOAT:
def checkFloat(v):
try:
float(v)
except ValueError:
raise ValueError(self.tr('Wrong parameter value:\n%s') % str(v))
validator = checkFloat
elif valuetype == self.INT:
elif self.valuetype == self.INT:
def checkInt(v):
try:
int(v)
except ValueError:
raise ValueError(self.tr('Wrong parameter value:\n%s') % str(v))
validator = checkInt
elif valuetype in [self.FILE, self.FOLDER]:
elif self.valuetype in [self.FILE, self.FOLDER]:
def checkFileOrFolder(v):
if v and not os.path.exists(v):
raise ValueError(self.tr('Specified path does not exist:\n%s') % str(v))
validator = checkFileOrFolder
elif valuetype == self.MULTIPLE_FOLDERS:
elif self.valuetype == self.MULTIPLE_FOLDERS:
def checkMultipleFolders(v):
folders = v.split(';')
for f in folders:
@ -310,10 +326,17 @@ class Setting(object):
if value is not None:
if isinstance(self.value, bool):
value = str(value).lower() == str(True).lower()
self.value = value
if self.valuetype == self.SELECTION:
self.value = self.options[int(value)]
else:
self.value = value
def save(self, qsettings=QSettings()):
qsettings.setValue(self.qname, self.value)
if self.valuetype == self.SELECTION:
qsettings.setValue(self.qname, self.options.index(self.value))
else:
qsettings.setValue(self.qname, self.value)
def __str__(self):
return self.name + '=' + str(self.value)

View File

@ -59,6 +59,10 @@ class VectorTest(unittest.TestCase):
test_data = points()
test_layer = QgsVectorLayer(test_data, 'test', 'ogr')
# disable check for geometry validity
prevInvalidGeoms = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, 0)
# test with all features
features = vector.features(test_layer)
self.assertEqual(len(features), 9)
@ -101,9 +105,22 @@ class VectorTest(unittest.TestCase):
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value)
# test exception is raised when filtering invalid geoms
#ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, 2)
#test_layer_invalid_geoms = QgsVectorLayer(invalid_geometries(), 'test', 'ogr')
#with self.assertRaises(GeoAlgorithmExecutionException):
# features = vector.features(test_layer_invalid_geoms)
# feats = [f for f in features]
ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, prevInvalidGeoms)
def testValues(self):
ProcessingConfig.initialize()
# disable check for geometry validity
prevInvalidGeoms = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, 0)
test_data = points()
test_layer = QgsVectorLayer(test_data, 'test', 'ogr')
@ -138,10 +155,15 @@ class VectorTest(unittest.TestCase):
self.assertEqual(set(res[1]), set([5, 7, 3]))
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value)
ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, prevInvalidGeoms)
def testUniqueValues(self):
ProcessingConfig.initialize()
# disable check for geometry validity
prevInvalidGeoms = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, 0)
test_data = points()
test_layer = QgsVectorLayer(test_data, 'test', 'ogr')
@ -164,6 +186,7 @@ class VectorTest(unittest.TestCase):
self.assertEqual(set(v), set([5, 7, 3]))
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value)
ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, prevInvalidGeoms)
def testOgrLayerNameExtraction(self):
outdir = tempfile.mkdtemp()