123 changes: 96 additions & 27 deletions python/plugins/sextante/modeler/ModelerParametersDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* *
***************************************************************************
"""

from sextante.modeler.MultilineTextPanel import MultilineTextPanel
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
Expand Down Expand Up @@ -127,7 +127,14 @@ def setupUi(self):
self.verticalLayout.addWidget(label)
self.verticalLayout.addWidget(item)
self.valueItems[output.name] = item


label = QtGui.QLabel(" ")
self.verticalLayout.addWidget(label)
label = QtGui.QLabel("Parent algorithms")
self.dependenciesPanel = self.getDependenciesPanel()
self.verticalLayout.addWidget(label)
self.verticalLayout.addWidget(self.dependenciesPanel)

self.verticalLayout.addStretch(1000)
self.setLayout(self.verticalLayout)

Expand Down Expand Up @@ -170,6 +177,24 @@ def setupUi(self):
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.cancelPressed)
QtCore.QMetaObject.connectSlotsByName(self)


def getAvailableDependencies(self):
if self.algIndex is None:
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)
opts = []
i=0
for alg in self.model.algs:
if i not in dependent:
opts.append(str(i+1) + ":" + alg.name)
i+=1
return opts

def getDependenciesPanel(self):
return MultipleInputPanel(self.getAvailableDependencies())


def showAdvancedParametersClicked(self):
self.showAdvanced = not self.showAdvanced
if self.showAdvanced:
Expand All @@ -192,7 +217,7 @@ def getRasterLayers(self):
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)
dependent.append(self.algIndex)
#dependent.append(self.algIndex)

i=0
for alg in self.model.algs:
Expand All @@ -215,7 +240,7 @@ def getVectorLayers(self):
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)
dependent.append(self.algIndex)
#dependent.append(self.algIndex)

i=0
for alg in self.model.algs:
Expand All @@ -238,7 +263,7 @@ def getTables(self):
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)
dependent.append(self.algIndex)
#dependent.append(self.algIndex)

i=0
for alg in self.model.algs:
Expand Down Expand Up @@ -269,7 +294,7 @@ def getNumbers(self):
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)
dependent.append(self.algIndex)
#dependent.append(self.algIndex)

i=0
for alg in self.model.algs:
Expand All @@ -291,7 +316,7 @@ def getFiles(self):
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)
dependent.append(self.algIndex)
#dependent.append(self.algIndex)

i=0
for alg in self.model.algs:
Expand Down Expand Up @@ -321,7 +346,7 @@ def getStrings(self):
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)
dependent.append(self.algIndex)
#dependent.append(self.algIndex)

i=0
for alg in self.model.algs:
Expand Down Expand Up @@ -389,12 +414,16 @@ def getWidgetFromParameter(self, param):
opts.append(opt.name())
item = MultipleInputPanel(opts)
elif isinstance(param, ParameterString):
item = QtGui.QComboBox()
item.setEditable(True)
strings = self.getStrings()
for s in strings:
item.addItem(s.name(), s)
item.setEditText(str(param.default))
if param.multiline:
item = MultilineTextPanel(strings)
item.setText(str(param.default))
else:
item = QtGui.QComboBox()
item.setEditable(True)
for s in strings:
item.addItem(s.name(), s)
item.setEditText(str(param.default))
elif isinstance(param, ParameterTableField):
item = QtGui.QComboBox()
item.setEditable(True)
Expand Down Expand Up @@ -423,7 +452,7 @@ def getWidgetFromParameter(self, param):
item.setEditable(True)
files = self.getFiles()
for f in files:
item.addItem(f.name(), f)
item.addItem(f.name(), f)
else:
item = QtGui.QLineEdit()
try:
Expand Down Expand Up @@ -510,9 +539,14 @@ def setPreviousValues(self):
if isinstance(param, (ParameterRaster, ParameterVector,
ParameterTable, ParameterTableField,
ParameterSelection, ParameterNumber,
ParameterString,ParameterBoolean, ParameterExtent)):
ParameterBoolean, ParameterExtent)):
self.setComboBoxValue(widget, value, param)
elif isinstance(param, ParameterCrs):
elif isinstance(param, ParameterString):
if param.multiline:
widget.setValue(value)
else:
self.setComboBoxValue(widget, value, param)
elif isinstance(param, ParameterCrs):
value = self.model.getValueFromAlgorithmAndParameter(value)
widget.setText(unicode(value))
elif isinstance(param, ParameterFixedTable):
Expand All @@ -539,7 +573,17 @@ def setPreviousValues(self):
value = self.model.algOutputs[self.algIndex][out.name]
if value is not None:
widget = self.valueItems[out.name].setText(unicode(value))


selected = []
dependencies = self.getAvailableDependencies()
index = -1
for dependency in dependencies:
index += 1
n = int(dependency[:dependency.find(":")]) - 1
if n in self.model.dependencies[self.algIndex]:
selected.append(index)

self.dependenciesPanel.setSelectedItems(selected)


def setParamValues(self):
Expand All @@ -563,6 +607,18 @@ def setParamValues(self):
self.outputs[output.name]=name
else:
self.outputs[output.name] = None

selectedOptions = self.dependenciesPanel.selectedoptions
#this index are based on the list of available dependencies.
#we translate them into indices based on the whole set of algorithm in the model
#We just take the values in the begining of the string representing the algorithm
availableDependencies = self.getAvailableDependencies()
self.dependencies = []
for selected in selectedOptions:
s = availableDependencies[selected]
n = int(s[:s.find(":")]) - 1
self.dependencies.append(n);

return True


Expand Down Expand Up @@ -608,17 +664,30 @@ def setParamTableFieldValue(self, param, widget):
return True

def setParamStringValue(self, param, widget):
if widget.currentText() == "":
return False
idx = widget.findText(widget.currentText())
if idx < 0:
name = self.getSafeNameForHarcodedParameter(param)
value = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
self.params[param.name] = value
self.values[name] = str(widget.currentText())
if param.multiline:
option = widget.getOption()
value = widget.getValue()
if option == MultilineTextPanel.USE_TEXT:
if value == "":
return False
name = self.getSafeNameForHarcodedParameter(param)
self.values[name] = value
paramValue = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
self.params[param.name] = paramValue
else:
self.params[param.name] = value
else:
value = widget.itemData(widget.currentIndex()).toPyObject()
self.params[param.name] = value
if widget.currentText() == "":
return False
idx = widget.findText(widget.currentText())
if idx < 0:
name = self.getSafeNameForHarcodedParameter(param)
value = AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, name)
self.params[param.name] = value
self.values[name] = str(widget.currentText())
else:
value = widget.itemData(widget.currentIndex()).toPyObject()
self.params[param.name] = value
return True

def setParamFileValue(self, param, widget):
Expand Down
3 changes: 3 additions & 0 deletions python/plugins/sextante/modeler/ModelerScene.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ def paintModel(self, model):
for sourceItem in sourceItems:
arrow = ModelerArrowItem(sourceItem, self.algItems[iAlg])
self.addItem(arrow)
for depend in model.dependencies[iAlg]:
arrow = ModelerArrowItem(self.algItems[depend], self.algItems[iAlg])
self.addItem(arrow)
iAlg+=1

def mousePressEvent(self, mouseEvent):
Expand Down
78 changes: 78 additions & 0 deletions python/plugins/sextante/modeler/MultilineTextPanel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
MultilineTextPanel.py
---------------------
Date : January 2013
Copyright : (C) 2013 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""

__author__ = 'Victor Olaya'
__date__ = 'January 2013'
__copyright__ = '(C) 2013, Victor Olaya'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

from PyQt4 import QtCore, QtGui

try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s

class MultilineTextPanel(QtGui.QWidget):

USE_TEXT = 0

def __init__(self, options, parent = None):
super(MultilineTextPanel, self).__init__(parent)
self.options = options
self.verticalLayout = QtGui.QVBoxLayout(self)
self.verticalLayout.setSpacing(2)
self.verticalLayout.setMargin(0)
self.combo = QtGui.QComboBox()
self.combo.addItem("[Use text below]")
for option in options:
self.combo.addItem(option.name(), option)
self.combo.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
self.verticalLayout.addWidget(self.combo)
self.textBox = QtGui.QPlainTextEdit()
self.verticalLayout.addWidget(self.textBox)
self.setLayout(self.verticalLayout)

def setText(self, text):
self.textBox.setPlainText(text)

def getOption(self):
return self.combo.currentIndex()

def getValue(self):
if self.combo.currentIndex() == 0:
return unicode(self.textBox.toPlainText())
else:
return self.combo.itemData(self.combo.currentIndex()).toPyObject()

def setValue(self, value):
items = [self.combo.itemData(i).toPyObject() for i in range(1,self.combo.count())]
idx = 0
for item in items:
idx += 1
if item and value:
if item.alg == value.alg and item.param == value.param:
self.combo.setCurrentIndex(idx)
return
self.combo.setCurrentIndex(idx)
value = self.model.getValueFromAlgorithmAndParameter(value)
if value:
self.textBox.setPlainText(str(value))

7 changes: 6 additions & 1 deletion python/plugins/sextante/modeler/models/watersheds.model
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ VALUE:HARDCODEDPARAMVALUE_CONVERGENCE_0===1.0
VALUE:HARDCODEDPARAMVALUE_DIV_CELLS_1===10
ALGORITHM:saga:catchmentarea(parallel)
260.0,172.0
None
-1|RASTERLAYER_DEM
None
None
Expand All @@ -42,6 +43,7 @@ None
None
ALGORITHM:saga:channelnetwork
447.0,291.0
None
-1|RASTERLAYER_DEM
None
0|CAREA
Expand All @@ -56,20 +58,23 @@ None
None
ALGORITHM:saga:watershedbasins
730.0,182.0
None
-1|RASTERLAYER_DEM
1|CHNLNTWRK
None
-1|HARDCODEDPARAMVALUE_MINSIZE_2
None
ALGORITHM:saga:vectorisinggridclasses
864.0,330.0
None
2|BASINS
-1|HARDCODEDPARAMVALUE_CLASS_ALL_3
-1|HARDCODEDPARAMVALUE_CLASS_ID_3
-1|HARDCODEDPARAMVALUE_SPLIT_3
None
ALGORITHM:ftools:export/addgeometrycolumns
ALGORITHM:qgis:export/addgeometrycolumns
655.0,442.0
None
3|POLYGONS
-1|HARDCODEDPARAMVALUE_CALC_METHOD_4
Watersheds
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Grid Normalisation
grid_calculus
ParameterRaster|INPUT|Grid|False
ParameterRange|RANGE_MIN|Target Range
ParameterRange|RANGE_MAX|Target Range
ParameterNumber|RANGE_MIN|Target Range (min)|None|None|0
ParameterNumber|RANGE_MAX|Target Range (max)|None|None|1
OutputRaster|OUTPUT|Normalised Grid