Skip to content

Commit

Permalink
Create dedicated widget wrapper for modeler
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaud-morvan authored and volaya committed Oct 5, 2016
1 parent 6158e9b commit a69b358
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 43 deletions.
36 changes: 20 additions & 16 deletions python/plugins/processing/gui/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
DIALOG_MODELER = 'modeler'


def wrapper_from_param(param, dialog=DIALOG_STANDARD, extra_values=[]):
def wrapper_from_param(param, dialog=DIALOG_STANDARD):
wrapper = param.metadata.get('widget_wrapper', None)
# wrapper metadata should be a class path
if isinstance(wrapper, basestring):
Expand All @@ -50,7 +50,7 @@ def wrapper_from_param(param, dialog=DIALOG_STANDARD, extra_values=[]):
wrapper = getattr(mod, tokens[-1])
# or directly a class object
if isclass(wrapper):
wrapper = wrapper(param=param, dialog=dialog, extra_values=extra_values)
wrapper = wrapper(param=param, dialog=dialog)
# or a wrapper instance
return wrapper

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

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

def __init__(self, param, dialog=DIALOG_STANDARD, extra_values=[]):
def __init__(self, param, dialog=DIALOG_STANDARD):
self.param = param
self.dialog = dialog
self.widget = self.createWidget(extra_values)
self.widget = self.createWidget()
self.setValue(param.default)

def createWidget(self, extra_values=[]):
def comboValue(self):
return self.widget.itemData(self.widget.currentIndex())

def createWidget(self):
pass

def setValue(self, value):
pass

def setComboValue(self, value):
values = [self.widget.itemData(i) for i in range(self.widget.count())]
try:
idx = values.index(value)
self.widget.setCurrentIndex(idx)
except ValueError:
pass

def value(self):
pass


class BooleanWidgetWrapper(WidgetWrapper):

def createWidget(self, extra_values=[]):
def createWidget(self):
if self.dialog == DIALOG_STANDARD:
return QCheckBox()

if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
widget = QComboBox()
widget.addItem(widget.tr('Yes'), True)
widget.addItem(widget.tr('No'), False)
for text, value in extra_values:
widget.addItem(text, value)
return widget

def setValue(self, value):
if self.dialog == DIALOG_STANDARD:
self.widget.setChecked(value)

if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
values = [self.widget.itemData(i) for i in range(self.widget.count())]
try:
idx = values.index(value)
self.widget.setCurrentIndex(idx)
except ValueError:
pass
self.setComboValue(value)

def value(self):
if self.dialog == DIALOG_STANDARD:
return self.widget.isChecked()

if self.dialog in (DIALOG_BATCH, DIALOG_MODELER):
return self.widget.itemData(self.widget.currentIndex())
return self.comboValue()


class CrsWidgetWrapper(WidgetWrapper):

def createWidget(self, extra_values=[]):
def createWidget(self):
return CrsSelectionPanel()

def setValue(self, value):
Expand Down
120 changes: 93 additions & 27 deletions python/plugins/processing/modeler/ModelerParametersDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,77 @@
from processing.modeler.MultilineTextPanel import MultilineTextPanel
from processing.tools import dataobjects

from qgis.core import QgsApplication
from qgis.PyQt.QtGui import QToolButton, QMenu, QAction


class ModelerWidgetWrapper(QWidget):

def __init__(self, wrapper, model_values):
super(ModelerWidgetWrapper, self).__init__()

self.wrapper = wrapper
self.widget = wrapper.widget
self.implemented = wrapper.implemented
self.model_values = model_values

menu = QMenu()
fixed_value_action = QAction(self.tr('Fixed value'), menu)
fixed_value_action.triggered.connect(self.on_fixedValue)
menu.addAction(fixed_value_action)
menu.addSeparator()
for text, value in model_values:
model_value_action = QAction(text, menu)
model_value_action.setData(value)
model_value_action.triggered.connect(self.on_modelValue)
menu.addAction(model_value_action)

self.mIconDataDefine = QgsApplication.getThemeIcon("/mIconDataDefine.svg")
self.mIconDataDefineOn = QgsApplication.getThemeIcon("/mIconDataDefineOn.svg")

button = QToolButton()
button.setIcon(self.mIconDataDefine)
button.setPopupMode(QToolButton.InstantPopup)
button.setMenu(menu)
self.button = button

label = QLabel()
label.hide()
self.label = label

layout = QHBoxLayout()
layout.addWidget(button, 0)
layout.addWidget(label, 1)
layout.addWidget(wrapper.widget, 1)
self.setLayout(layout)

def on_fixedValue(self):
self.button.setIcon(self.mIconDataDefine)
self.label.hide()
self.wrapper.widget.show()

def on_modelValue(self):
action = self.sender()
self.setValue(action.data())

def setValue(self, value):
for text, val in self.model_values:
if val == value:
self.model_value = value
self.button.setIcon(self.mIconDataDefineOn)
self.label.setText(text)
self.label.show()
self.wrapper.widget.hide()
return
self.wrapper.setValue(value)
self.on_fixedValue()

def value(self):
if self.label.isVisible():
return self.model_value
else:
return self.wrapper.value()


class ModelerParametersDialog(QDialog):

Expand Down Expand Up @@ -166,8 +237,10 @@ def setupUi(self):
desc += self.tr('(x, y)')
label = QLabel(desc)
self.labels[param.name] = label

wrapper = self.getWidgetWrapperFromParameter(param)
self.widget_wrappers[param.name] = wrapper

widget = wrapper.widget
self.valueItems[param.name] = widget
if param.name in list(tooltips.keys()):
Expand All @@ -178,10 +251,11 @@ def setupUi(self):
widget.setToolTip(tooltip)
if param.isAdvanced:
label.setVisible(self.showAdvanced)
widget.setVisible(self.showAdvanced)
wrapper.setVisible(self.showAdvanced)
self.widgets[param.name] = widget

self.verticalLayout.addWidget(label)
self.verticalLayout.addWidget(widget)
self.verticalLayout.addWidget(wrapper)

for output in self._alg.outputs:
if output.hidden:
Expand Down Expand Up @@ -282,6 +356,12 @@ def showAdvancedParametersClicked(self):
self.labels[param.name].setVisible(self.showAdvanced)
self.widgets[param.name].setVisible(self.showAdvanced)

def getAvailableValuesForParam(self, param):
outputType = None
if isinstance(param, ParameterCrs):
outputType = OutputCrs
return self.getAvailableValuesOfType(param.__class__, outputType)

def getAvailableValuesOfType(self, paramType, outType=None, dataType=None):
values = []
inputs = self.model.inputs
Expand Down Expand Up @@ -317,18 +397,19 @@ def resolveValueDescription(self, value):
return self.tr("'%s' from algorithm '%s'") % (alg.algorithm.getOutputFromName(value.output).description, alg.description)

def getWidgetWrapperFromParameter(self, param):
extra_values = []
values = self.getAvailableValuesOfType(param.__class__, None)
wrapper = wrapper_from_param(param, DIALOG_MODELER)
if wrapper is None:
widget = self.getWidgetFromParameter(param)
wrapper = NotYetImplementedWidgetWrapper(param, widget)

model_values = []
values = self.getAvailableValuesForParam(param)
for value in values:
extra_values.append((self.resolveValueDescription(value), value))
model_values.append((self.resolveValueDescription(value), value))

wrapper = wrapper_from_param(param, DIALOG_MODELER, extra_values)
if wrapper is not None:
return wrapper
input_wrapper = ModelerWidgetWrapper(wrapper, model_values)
return input_wrapper

widget = self.getWidgetFromParameter(param)
wrapper = NotYetImplementedWidgetWrapper(param, widget)
return wrapper

def getWidgetFromParameter(self, param):
if isinstance(param, ParameterRaster):
Expand Down Expand Up @@ -411,11 +492,6 @@ def getWidgetFromParameter(self, param):
for n in numbers:
item.addItem(self.resolveValueDescription(n), n)
item.setEditText(str(param.default))
elif isinstance(param, ParameterCrs):
item = QComboBox()
values = self.getAvailableValuesOfType(ParameterCrs, OutputCrs)
for v in values:
item.addItem(self.resolveValueDescription(v), v)
elif isinstance(param, ParameterExtent):
item = QComboBox()
item.setEditable(True)
Expand Down Expand Up @@ -514,6 +590,7 @@ def setPreviousValues(self):
wrapper = self.widget_wrappers[param.name]
if wrapper.implemented:
wrapper.setValue(value)
continue

widget = wrapper.widget
if isinstance(param, (
Expand Down Expand Up @@ -724,15 +801,6 @@ def setParamPointValue(self, alg, param, widget):
alg.params[param.name] = value
return True

def setParamCrsValue(self, alg, param, widget):
idx = widget.currentIndex()
if idx < 0:
return False
else:
value = widget.itemData(widget.currentIndex())
alg.params[param.name] = value
return True

def setParamValue(self, alg, param, wrapper):
if wrapper.implemented:
alg.params[param.name] = wrapper.value()
Expand All @@ -758,8 +826,6 @@ def setParamValue(self, alg, param, wrapper):
elif isinstance(param, ParameterRange):
alg.params[param.name] = widget.getValue()
return True
elif isinstance(param, ParameterCrs):
return self.setParamCrsValue(alg, param, widget)
elif isinstance(param, ParameterFixedTable):
table = widget.table
if not bool(table) and not param.optional:
Expand Down

0 comments on commit a69b358

Please sign in to comment.