Skip to content

Commit a69b358

Browse files
arnaud-morvanvolaya
authored andcommitted
Create dedicated widget wrapper for modeler
1 parent 6158e9b commit a69b358

File tree

2 files changed

+113
-43
lines changed

2 files changed

+113
-43
lines changed

python/plugins/processing/gui/wrappers.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
DIALOG_MODELER = 'modeler'
4242

4343

44-
def wrapper_from_param(param, dialog=DIALOG_STANDARD, extra_values=[]):
44+
def wrapper_from_param(param, dialog=DIALOG_STANDARD):
4545
wrapper = param.metadata.get('widget_wrapper', None)
4646
# wrapper metadata should be a class path
4747
if isinstance(wrapper, basestring):
@@ -50,7 +50,7 @@ def wrapper_from_param(param, dialog=DIALOG_STANDARD, extra_values=[]):
5050
wrapper = getattr(mod, tokens[-1])
5151
# or directly a class object
5252
if isclass(wrapper):
53-
wrapper = wrapper(param=param, dialog=dialog, extra_values=extra_values)
53+
wrapper = wrapper(param=param, dialog=dialog)
5454
# or a wrapper instance
5555
return wrapper
5656

@@ -70,59 +70,63 @@ class WidgetWrapper():
7070

7171
implemented = True # TODO: Should be removed at the end
7272

73-
def __init__(self, param, dialog=DIALOG_STANDARD, extra_values=[]):
73+
def __init__(self, param, dialog=DIALOG_STANDARD):
7474
self.param = param
7575
self.dialog = dialog
76-
self.widget = self.createWidget(extra_values)
76+
self.widget = self.createWidget()
7777
self.setValue(param.default)
7878

79-
def createWidget(self, extra_values=[]):
79+
def comboValue(self):
80+
return self.widget.itemData(self.widget.currentIndex())
81+
82+
def createWidget(self):
8083
pass
8184

8285
def setValue(self, value):
8386
pass
8487

88+
def setComboValue(self, value):
89+
values = [self.widget.itemData(i) for i in range(self.widget.count())]
90+
try:
91+
idx = values.index(value)
92+
self.widget.setCurrentIndex(idx)
93+
except ValueError:
94+
pass
95+
8596
def value(self):
8697
pass
8798

8899

89100
class BooleanWidgetWrapper(WidgetWrapper):
90101

91-
def createWidget(self, extra_values=[]):
102+
def createWidget(self):
92103
if self.dialog == DIALOG_STANDARD:
93104
return QCheckBox()
94105

95106
if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
96107
widget = QComboBox()
97108
widget.addItem(widget.tr('Yes'), True)
98109
widget.addItem(widget.tr('No'), False)
99-
for text, value in extra_values:
100-
widget.addItem(text, value)
101110
return widget
102111

103112
def setValue(self, value):
104113
if self.dialog == DIALOG_STANDARD:
105114
self.widget.setChecked(value)
106115

107116
if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
108-
values = [self.widget.itemData(i) for i in range(self.widget.count())]
109-
try:
110-
idx = values.index(value)
111-
self.widget.setCurrentIndex(idx)
112-
except ValueError:
113-
pass
117+
self.setComboValue(value)
114118

115119
def value(self):
116120
if self.dialog == DIALOG_STANDARD:
117121
return self.widget.isChecked()
118122

119123
if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
120-
return self.widget.itemData(self.widget.currentIndex())
124+
return self.comboValue()
121125

122126

123127
class CrsWidgetWrapper(WidgetWrapper):
124128

125-
def createWidget(self, extra_values=[]):
129+
def createWidget(self):
126130
return CrsSelectionPanel()
127131

128132
def setValue(self, value):

python/plugins/processing/modeler/ModelerParametersDialog.py

Lines changed: 93 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,77 @@
8686
from processing.modeler.MultilineTextPanel import MultilineTextPanel
8787
from processing.tools import dataobjects
8888

89+
from qgis.core import QgsApplication
90+
from qgis.PyQt.QtGui import QToolButton, QMenu, QAction
91+
92+
93+
class ModelerWidgetWrapper(QWidget):
94+
95+
def __init__(self, wrapper, model_values):
96+
super(ModelerWidgetWrapper, self).__init__()
97+
98+
self.wrapper = wrapper
99+
self.widget = wrapper.widget
100+
self.implemented = wrapper.implemented
101+
self.model_values = model_values
102+
103+
menu = QMenu()
104+
fixed_value_action = QAction(self.tr('Fixed value'), menu)
105+
fixed_value_action.triggered.connect(self.on_fixedValue)
106+
menu.addAction(fixed_value_action)
107+
menu.addSeparator()
108+
for text, value in model_values:
109+
model_value_action = QAction(text, menu)
110+
model_value_action.setData(value)
111+
model_value_action.triggered.connect(self.on_modelValue)
112+
menu.addAction(model_value_action)
113+
114+
self.mIconDataDefine = QgsApplication.getThemeIcon("/mIconDataDefine.svg")
115+
self.mIconDataDefineOn = QgsApplication.getThemeIcon("/mIconDataDefineOn.svg")
116+
117+
button = QToolButton()
118+
button.setIcon(self.mIconDataDefine)
119+
button.setPopupMode(QToolButton.InstantPopup)
120+
button.setMenu(menu)
121+
self.button = button
122+
123+
label = QLabel()
124+
label.hide()
125+
self.label = label
126+
127+
layout = QHBoxLayout()
128+
layout.addWidget(button, 0)
129+
layout.addWidget(label, 1)
130+
layout.addWidget(wrapper.widget, 1)
131+
self.setLayout(layout)
132+
133+
def on_fixedValue(self):
134+
self.button.setIcon(self.mIconDataDefine)
135+
self.label.hide()
136+
self.wrapper.widget.show()
137+
138+
def on_modelValue(self):
139+
action = self.sender()
140+
self.setValue(action.data())
141+
142+
def setValue(self, value):
143+
for text, val in self.model_values:
144+
if val == value:
145+
self.model_value = value
146+
self.button.setIcon(self.mIconDataDefineOn)
147+
self.label.setText(text)
148+
self.label.show()
149+
self.wrapper.widget.hide()
150+
return
151+
self.wrapper.setValue(value)
152+
self.on_fixedValue()
153+
154+
def value(self):
155+
if self.label.isVisible():
156+
return self.model_value
157+
else:
158+
return self.wrapper.value()
159+
89160

90161
class ModelerParametersDialog(QDialog):
91162

@@ -166,8 +237,10 @@ def setupUi(self):
166237
desc += self.tr('(x, y)')
167238
label = QLabel(desc)
168239
self.labels[param.name] = label
240+
169241
wrapper = self.getWidgetWrapperFromParameter(param)
170242
self.widget_wrappers[param.name] = wrapper
243+
171244
widget = wrapper.widget
172245
self.valueItems[param.name] = widget
173246
if param.name in list(tooltips.keys()):
@@ -178,10 +251,11 @@ def setupUi(self):
178251
widget.setToolTip(tooltip)
179252
if param.isAdvanced:
180253
label.setVisible(self.showAdvanced)
181-
widget.setVisible(self.showAdvanced)
254+
wrapper.setVisible(self.showAdvanced)
182255
self.widgets[param.name] = widget
256+
183257
self.verticalLayout.addWidget(label)
184-
self.verticalLayout.addWidget(widget)
258+
self.verticalLayout.addWidget(wrapper)
185259

186260
for output in self._alg.outputs:
187261
if output.hidden:
@@ -282,6 +356,12 @@ def showAdvancedParametersClicked(self):
282356
self.labels[param.name].setVisible(self.showAdvanced)
283357
self.widgets[param.name].setVisible(self.showAdvanced)
284358

359+
def getAvailableValuesForParam(self, param):
360+
outputType = None
361+
if isinstance(param, ParameterCrs):
362+
outputType = OutputCrs
363+
return self.getAvailableValuesOfType(param.__class__, outputType)
364+
285365
def getAvailableValuesOfType(self, paramType, outType=None, dataType=None):
286366
values = []
287367
inputs = self.model.inputs
@@ -317,18 +397,19 @@ def resolveValueDescription(self, value):
317397
return self.tr("'%s' from algorithm '%s'") % (alg.algorithm.getOutputFromName(value.output).description, alg.description)
318398

319399
def getWidgetWrapperFromParameter(self, param):
320-
extra_values = []
321-
values = self.getAvailableValuesOfType(param.__class__, None)
400+
wrapper = wrapper_from_param(param, DIALOG_MODELER)
401+
if wrapper is None:
402+
widget = self.getWidgetFromParameter(param)
403+
wrapper = NotYetImplementedWidgetWrapper(param, widget)
404+
405+
model_values = []
406+
values = self.getAvailableValuesForParam(param)
322407
for value in values:
323-
extra_values.append((self.resolveValueDescription(value), value))
408+
model_values.append((self.resolveValueDescription(value), value))
324409

325-
wrapper = wrapper_from_param(param, DIALOG_MODELER, extra_values)
326-
if wrapper is not None:
327-
return wrapper
410+
input_wrapper = ModelerWidgetWrapper(wrapper, model_values)
411+
return input_wrapper
328412

329-
widget = self.getWidgetFromParameter(param)
330-
wrapper = NotYetImplementedWidgetWrapper(param, widget)
331-
return wrapper
332413

333414
def getWidgetFromParameter(self, param):
334415
if isinstance(param, ParameterRaster):
@@ -411,11 +492,6 @@ def getWidgetFromParameter(self, param):
411492
for n in numbers:
412493
item.addItem(self.resolveValueDescription(n), n)
413494
item.setEditText(str(param.default))
414-
elif isinstance(param, ParameterCrs):
415-
item = QComboBox()
416-
values = self.getAvailableValuesOfType(ParameterCrs, OutputCrs)
417-
for v in values:
418-
item.addItem(self.resolveValueDescription(v), v)
419495
elif isinstance(param, ParameterExtent):
420496
item = QComboBox()
421497
item.setEditable(True)
@@ -514,6 +590,7 @@ def setPreviousValues(self):
514590
wrapper = self.widget_wrappers[param.name]
515591
if wrapper.implemented:
516592
wrapper.setValue(value)
593+
continue
517594

518595
widget = wrapper.widget
519596
if isinstance(param, (
@@ -724,15 +801,6 @@ def setParamPointValue(self, alg, param, widget):
724801
alg.params[param.name] = value
725802
return True
726803

727-
def setParamCrsValue(self, alg, param, widget):
728-
idx = widget.currentIndex()
729-
if idx < 0:
730-
return False
731-
else:
732-
value = widget.itemData(widget.currentIndex())
733-
alg.params[param.name] = value
734-
return True
735-
736804
def setParamValue(self, alg, param, wrapper):
737805
if wrapper.implemented:
738806
alg.params[param.name] = wrapper.value()
@@ -758,8 +826,6 @@ def setParamValue(self, alg, param, wrapper):
758826
elif isinstance(param, ParameterRange):
759827
alg.params[param.name] = widget.getValue()
760828
return True
761-
elif isinstance(param, ParameterCrs):
762-
return self.setParamCrsValue(alg, param, widget)
763829
elif isinstance(param, ParameterFixedTable):
764830
table = widget.table
765831
if not bool(table) and not param.optional:

0 commit comments

Comments
 (0)