Skip to content

Commit

Permalink
fixed #5566
Browse files Browse the repository at this point in the history
added deactivation of algorithms in modeler

git-svn-id: http://sextante.googlecode.com/svn/trunk/soft/bindings/qgis-plugin@182 881b9c09-3ef8-f3c2-ec3d-21d735c97f4d
  • Loading branch information
volayaf@gmail.com committed May 16, 2012
1 parent fa8c9e6 commit 38b3212
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 61 deletions.
167 changes: 109 additions & 58 deletions src/sextante/modeler/ModelerAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ def __init__(self):
self.algPos = []
self.paramPos = []

#deactivated algorithms that should not be executed
self.deactivated = []


def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/model.png")
Expand Down Expand Up @@ -137,6 +140,97 @@ def addAlgorithm(self, alg, parametersMap, valuesMap, outputsMap):
self.paramValues[value] = valuesMap[value]
self.algPos.append(self.getPositionForAlgorithmItem())

def removeAlgorithm(self, index):
if self.hasDependencies(self.algs[index], index):
return False
for out in self.algs[index].outputs:
val = self.algOutputs[index][out.name]
if val:
name = self.getSafeNameForOutput(index, out)
self.removeOutputFromName(name)
del self.algs[index]
del self.algParameters[index]
del self.algOutputs[index]
del self.algPos[index]
self.updateModelerView()
return True

def removeParameter(self, index):
if self.hasDependencies(self.parameters[index], index):
return False
del self.parameters[index]
del self.paramPos[index]
self.updateModelerView()
return True

def hasDependencies(self, element, elementIndex):
'''This method returns true if some other element depends on the passed one'''
if isinstance(element, Parameter):
for alg in self.algParameters:
for aap in alg.values():
if aap.alg == AlgorithmAndParameter.PARENT_MODEL_ALGORITHM:
if aap.param == element.name:
return True
elif aap.param in self.paramValues: #check for multiple inputs
aap2 = self.paramValues[aap.param]
if element.name in aap2:
return True
if isinstance(element, ParameterVector):
for param in self.parameters:
if isinstance(param, ParameterTableField):
if param.parent == element.name:
return True
else:
for alg in self.algParameters:
for aap in alg.values():
if aap.alg == elementIndex:
return True

return False

def deactivateAlgorithm(self, algIndex, update = False):
if algIndex not in self.deactivated:
self.deactivated.append(algIndex)
dependent = self.getDependentAlgorithms(algIndex)
for alg in dependent:
self.deactivateAlgorithm(alg)
if update:
self.updateModelerView()

def activateAlgorithm(self, algIndex, update = False):
if algIndex in self.deactivated:
dependsOn = self.getDependsOnAlgorithms(algIndex)
for alg in dependsOn:
if alg in self.deactivated:
return False
self.deactivated.remove(algIndex)
dependent = self.getDependentAlgorithms(algIndex)
for alg in dependent:
self.activateAlgorithm(alg)
if update:
self.updateModelerView()
return True

def getDependsOnAlgorithms(self, algIndex):
'''This method returns a list with the indexes of algorithm a given one depends on'''
algs = []
for aap in self.algParameters[algIndex].values():
if aap.alg not in algs:
algs.append(aap.alg)
return algs

def getDependentAlgorithms(self, algIndex):
'''This method returns a list with the indexes of algorithm depending on a given one'''
dependent = []
index = -1
for alg in self.algParameters:
index += 1
for aap in alg.values():
if aap.alg == algIndex:
dependent.append(index)
break
return dependent

def getPositionForAlgorithmItem(self):
MARGIN = 20
BOX_WIDTH = 200
Expand Down Expand Up @@ -233,18 +327,22 @@ def processAlgorithm(self, progress):
self.producedOutputs = []
iAlg = 0
for alg in self.algs:
try:
alg = alg.getCopy()#copy.deepcopy(alg)
self.prepareAlgorithm(alg, iAlg)
progress.setText("Running " + alg.name + " [" + str(iAlg+1) + "/" + str(len(self.algs)) +"]")
outputs = {}
alg.execute(progress)
for out in alg.outputs:
outputs[out.name] = out.value
self.producedOutputs.append(outputs)
if iAlg in self.deactivated:
iAlg += 1
except GeoAlgorithmExecutionException, e :
raise GeoAlgorithmExecutionException("Error executing algorithm " + str(iAlg) + "\n" + e.msg)
else:
try:
alg = alg.getCopy()#copy.deepcopy(alg)
self.prepareAlgorithm(alg, iAlg)
progress.setText("Running " + alg.name + " [" + str(iAlg+1) + "/"
+ str(len(self.algs) - len(self.deactivated)) +"]")
outputs = {}
alg.execute(progress)
for out in alg.outputs:
outputs[out.name] = out.value
self.producedOutputs.append(outputs)
iAlg += 1
except GeoAlgorithmExecutionException, e :
raise GeoAlgorithmExecutionException("Error executing algorithm " + str(iAlg) + "\n" + e.msg)


def getOutputType(self, i, outname):
Expand Down Expand Up @@ -341,53 +439,6 @@ def updateModelerView(self):
if self.modelerdialog:
self.modelerdialog.repaintModel()

def removeAlgorithm(self, index):
if self.hasDependencies(self.algs[index], index):
return False
for out in self.algs[index].outputs:
val = self.algOutputs[index][out.name]
if val:
name = self.getSafeNameForOutput(index, out)
self.removeOutputFromName(name)
del self.algs[index]
del self.algParameters[index]
del self.algOutputs[index]
del self.algPos[index]
self.updateModelerView()
return True

def removeParameter(self, index):
if self.hasDependencies(self.parameters[index], index):
return False
del self.parameters[index]
del self.paramPos[index]
self.updateModelerView()
return True

def hasDependencies(self, element, elementIndex):
'''returns true if some other element depends on the passed one'''
if isinstance(element, Parameter):
for alg in self.algParameters:
for aap in alg.values():
if aap.alg == AlgorithmAndParameter.PARENT_MODEL_ALGORITHM:
if aap.param == element.name:
return True
elif aap.param in self.paramValues: #check for multiple inputs
aap2 = self.paramValues[aap.param]
if element.name in aap2:
return True
if isinstance(element, ParameterVector):
for param in self.parameters:
if isinstance(param, ParameterTableField):
if param.parent == element.name:
return True
else:
for alg in self.algParameters:
for aap in alg.values():
if aap.alg == elementIndex:
return True

return False

def helpfile(self):
helpfile = self.descriptionFile + ".help"
Expand Down
2 changes: 2 additions & 0 deletions src/sextante/modeler/ModelerArrowItem.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ def paint(self, painter, option, widget=None):
self.setLine(QtCore.QLineF(intersectPoint, myStartItem.pos()))
line = self.line()

if line.length() == 0: #division by zero might occur if arrow has no length
return
angle = math.acos(line.dx() / line.length())
if line.dy() >= 0:
angle = (math.pi * 2.0) - angle
Expand Down
25 changes: 23 additions & 2 deletions src/sextante/modeler/ModelerGraphicItem.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from PyQt4 import QtCore, QtGui
from sextante.parameters.Parameter import Parameter
import os
from sextante.core.GeoAlgorithm import GeoAlgorithm

class ModelerGraphicItem(QtGui.QGraphicsItem):

Expand Down Expand Up @@ -36,17 +37,31 @@ def contextMenuEvent(self, event):
popupmenu = QtGui.QMenu()
removeAction = popupmenu.addAction("Remove")
removeAction.triggered.connect(self.removeElement)
if isinstance(self.element, GeoAlgorithm):
if self.elementIndex in self.model.deactivated:
removeAction = popupmenu.addAction("Activate")
removeAction.triggered.connect(self.activateAlgorithm)
else:
deactivateAction = popupmenu.addAction("Deactivate")
deactivateAction.triggered.connect(self.deactivateAlgorithm)
popupmenu.exec_(event.screenPos())

def deactivateAlgorithm(self):
self.model.deactivateAlgorithm(self.elementIndex, True)

def activateAlgorithm(self):
if not self.model.activateAlgorithm(self.elementIndex, True):
QtGui.QMessageBox.warning(None, "Could not activate Algorithm",
"The selected algorithm depends on other currently non-active algorithms.\nActivate them them before trying to activate it.")
def removeElement(self):
if isinstance(self.element, Parameter):
if not self.model.removeParameter(self.elementIndex):
QtGui.QMessageBox.warning(None, "Could not remove element",
"Other elements depend on this one.\nRemove them before trying to remove it.")
"Other elements depend on the selected one.\nRemove them before trying to remove it.")
else:
if not self.model.removeAlgorithm(self.elementIndex):
QtGui.QMessageBox.warning(None, "Could not remove element",
"Other elements depend on this one.\nRemove them before trying to remove it.")
"Other elements depend on the selected one.\nRemove them before trying to remove it.")

def getAdjustedText(self, text):
return text
Expand All @@ -66,6 +81,12 @@ def paint(self, painter, option, widget=None):
h = fm.height()
pt = QtCore.QPointF(-w/2, h/2)
painter.drawText(pt, self.text)
if isinstance(self.element, GeoAlgorithm):
if self.elementIndex in self.model.deactivated:
painter.setPen(QtGui.QPen(QtCore.Qt.red))
w = fm.width(QtCore.QString("[deactivated]"))
pt = QtCore.QPointF(-w/2, h+h/2)
painter.drawText(pt, "[deactivated]")
painter.drawPixmap(-10 , -(ModelerGraphicItem.BOX_HEIGHT )/3,self.pixmap)


Expand Down
1 change: 0 additions & 1 deletion src/sextante/modeler/ModelerScene.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ def getLastAlgorithmItem(self):
else:
return None


def getItemsFromAAP(self, aap, isMultiple):
items = []
start = int(aap.alg)
Expand Down

0 comments on commit 38b3212

Please sign in to comment.