Skip to content
Permalink
Browse files

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

  • Loading branch information
alexbruy committed Jan 12, 2017
1 parent b823874 commit 03eaad5bfd6b5b47ad20be0e573bd7d0c18ab05b
Showing with 76 additions and 30 deletions.
  1. +53 −30 python/plugins/processing/core/ProcessingConfig.py
  2. +23 −0 python/plugins/processing/tests/ToolsTest.py
@@ -31,10 +31,9 @@

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 @@ def initialize():
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 @@ def initialize():
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 @@ def getSetting(name):
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 @@ def __init__(self, group, name, description, default, hidden=False, valuetype=No
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 @@ def read(self, qsettings=QSettings()):
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)
@@ -59,6 +59,10 @@ def testFeatures(self):
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 @@ def testFeatures(self):

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 @@ def testValues(self):
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 @@ def testUniqueValues(self):
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()

3 comments on commit 03eaad5

@m-kuhn

This comment has been minimized.

Copy link
Member

@m-kuhn m-kuhn replied Jan 13, 2017

This fails for me with

ValueError: invalid literal for int() with base 10: 'tif'
@alexbruy

This comment has been minimized.

Copy link
Contributor Author

@alexbruy alexbruy replied Jan 13, 2017

Probably you have settings file from previous installation. I will add code to handle this.

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn replied Jan 17, 2017

@alexbruy , I'm pretty sure that has broken getDefaultFileExtension() -- try gdal's build virtual raster (and leave the output as temporary file). It'll fail (while it used to work OK >1 week ago).

Please sign in to comment.
You can’t perform that action at this time.