Skip to content

Commit

Permalink
[processing] Support options as (value, text) in ParameterSelection
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaud-morvan committed Dec 12, 2016
1 parent e135e79 commit 65a4e97
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 23 deletions.
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/grass7/Grass7Algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ def processCommand(self):
command += ' ' + param.name
elif isinstance(param, ParameterSelection):
idx = int(param.value)
command += ' ' + param.name + '=' + str(param.options[idx])
command += ' ' + param.name + '=' + str(param.options[idx][1])
elif isinstance(param, ParameterString):
command += ' ' + param.name + '="' + str(param.value) + '"'
elif isinstance(param, ParameterPoint):
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/otb/OTBAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def processAlgorithm(self, progress):
elif isinstance(param, ParameterSelection):
commands.append(param.name)
idx = int(param.value)
commands.append(str(param.options[idx]))
commands.append(str(param.options[idx][1]))
elif isinstance(param, ParameterBoolean):
if param.value:
commands.append(param.name)
Expand Down
39 changes: 28 additions & 11 deletions python/plugins/processing/core/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1061,41 +1061,58 @@ def __init__(self, name='', description='', options=[], default=None, isSource=F
elif isinstance(self.options, str):
self.options = self.options.split(";")

# compute options as (value, text)
options = []
for i, option in enumerate(self.options):
if option is None or isinstance(option, basestring):
options.append((i, option))
else:
options.append((option[0], option[1]))
self.options = options
self.values = [option[0] for option in options]

self.value = None
if default is not None:
try:
self.default = int(default)
except:
self.default = 0
self.value = self.default
self.setValue(self.default)

def setValue(self, value):
if value is None:
if not self.optional:
return False
self.value = 0
self.value = None
return True

if isinstance(value, list):
if not self.multiple:
return False
values = []
for v in value:
if v in self.values:
values.append(v)
continue
try:
n = int(v)
values.append(n)
v = int(v)
except:
pass
if not v in self.values:
return False
values.append(v)
if not self.optional and len(values) == 0:
return False
self.value = values
return True
else:
try:
n = int(value)
self.value = n
if value in self.values:
self.value = value
return True
try:
value = int(value)
except:
pass
if not value in self.values:
return False
self.value = value
return True

@classmethod
def fromScriptCode(self, line):
Expand Down
9 changes: 5 additions & 4 deletions python/plugins/processing/gui/MultipleInputDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ def __init__(self, options, selectedoptions=None):

def populateList(self):
model = QStandardItemModel()
for i, option in enumerate(self.options):
item = QStandardItem(option)
item.setCheckState(Qt.Checked if i in self.selectedoptions else Qt.Unchecked)
for value, text in self.options:
item = QStandardItem(text)
item.setData(value, Qt.UserRole)
item.setCheckState(Qt.Checked if value in self.selectedoptions else Qt.Unchecked)
item.setCheckable(True)
model.appendRow(item)

Expand All @@ -82,7 +83,7 @@ def accept(self):
for i in range(model.rowCount()):
item = model.item(i)
if item.checkState() == Qt.Checked:
self.selectedoptions.append(i)
self.selectedoptions.append(item.data(Qt.UserRole))
QDialog.accept(self)

def reject(self):
Expand Down
9 changes: 5 additions & 4 deletions python/plugins/processing/gui/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,22 +652,23 @@ def createWidget(self):
return MultipleInputPanel(options=self.param.options)
else:
widget = QComboBox()
widget.addItems(self.param.options)
for option in self.param.options:
widget.addItem(option[1], option[0])
if self.param.default:
widget.setCurrentIndex(self.param.default)
widget.setCurrentIndex(widget.findData(self.param.default))
return widget

def setValue(self, value):
if self.param.multiple:
self.widget.setSelectedItems(value)
else:
self.widget.setCurrentIndex(int(value))
self.widget.setCurrentIndex(self.widget.findData(value))

def value(self):
if self.param.multiple:
return self.widget.selectedoptions
else:
return self.widget.currentIndex()
return self.widget.currentData()


class VectorWidgetWrapper(WidgetWrapper):
Expand Down
20 changes: 18 additions & 2 deletions python/plugins/processing/tests/ParametersTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,15 @@ def testDefault(self):
parameter = ParameterSelection('myName', 'myDesc', ['option1', 'option2', 'option3'], default=0.0)
self.assertEqual(parameter.value, 0)
parameter = ParameterSelection('myName', 'myDesc', ['option1', 'option2', 'option3'], default='a')
self.assertEqual(parameter.value, 0)
self.assertEqual(parameter.value, None)

def testOptional(self):
optionalParameter = ParameterSelection('myName', 'myDesc', ['option1', 'option2', 'option3'], default=0, optional=True)
self.assertEqual(optionalParameter.value, 0)
optionalParameter.setValue(1)
self.assertEqual(optionalParameter.value, 1)
self.assertTrue(optionalParameter.setValue(None))
self.assertEqual(optionalParameter.value, 0)
self.assertEqual(optionalParameter.value, None)

requiredParameter = ParameterSelection('myName', 'myDesc', ['option1', 'option2', 'option3'], default=0, optional=False)
self.assertEqual(requiredParameter.value, 0)
Expand All @@ -289,6 +289,22 @@ def testOptional(self):
self.assertFalse(requiredParameter.setValue(None))
self.assertEqual(requiredParameter.value, 1)

def testTupleOptions(self):
options = (
('o1', 'option1'),
('o2', 'option2'),
('o3', 'option3'))

optionalParameter = ParameterSelection('myName', 'myDesc', options, default='o1')
self.assertEqual(optionalParameter.value, 'o1')
optionalParameter.setValue('o2')
self.assertEqual(optionalParameter.value, 'o2')

optionalParameter = ParameterSelection('myName', 'myDesc', options, default=['o1', 'o2'], multiple=True)
self.assertEqual(optionalParameter.value, ['o1', 'o2'])
optionalParameter.setValue(['o2'])
self.assertEqual(optionalParameter.value, ['o2'])


class ParameterFileTest(unittest.TestCase):

Expand Down

3 comments on commit 65a4e97

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 65a4e97 Dec 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arnaud-morvan , this commit broke a large number of algorithms' UI relying on multiple input dialog. For e.g., the [QGIS] Dissolve algorithm throws a stack error if you try to select field(s).

Should probably be reverted until that's fixed.

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 65a4e97 Dec 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arnaud-morvan , (at least) MultipleInputWidgetWrapper and TableFieldWidgetWrapper are broken as they do not return values as (value, text).

@arnaud-morvan
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nirvn for raising this.
Here is a fix : #3882

Please sign in to comment.