Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Algorithms in modeler can now be edited with a double click (not yet …
…finished)

git-svn-id: http://sextante.googlecode.com/svn/trunk/soft/bindings/qgis-plugin@188 881b9c09-3ef8-f3c2-ec3d-21d735c97f4d
  • Loading branch information
volayaf@gmail.com committed May 24, 2012
1 parent 3608452 commit 3ff9a30
Show file tree
Hide file tree
Showing 16 changed files with 263 additions and 38 deletions.
50 changes: 50 additions & 0 deletions src/sextante/algs/AutoincrementalField.py
@@ -0,0 +1,50 @@
from sextante.core.GeoAlgorithm import GeoAlgorithm
from PyQt4.QtCore import *
from qgis.core import *
from sextante.parameters.ParameterVector import ParameterVector
from sextante.core.QGisLayers import QGisLayers
from sextante.outputs.OutputVector import OutputVector
import os
from PyQt4 import QtGui

class AutoincrementalField(GeoAlgorithm):

INPUT = "INPUT"
OUTPUT = "OUTPUT"

def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/toolbox.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(self.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
fields[len(fields)] = QgsField("AUTO", QVariant.Int)
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
nFeat = vprovider.featureCount()
nElement = 0
while vprovider.nextFeature(inFeat):
progress.setPercentage(int((100 * nElement)/nFeat))
nElement += 1
inGeom = inFeat.geometry()
outFeat.setGeometry( inGeom )
atMap = inFeat.attributeMap()
outFeat.setAttributeMap( atMap )
outFeat.addAttribute( len(vprovider.fields()), QVariant(nElement) )
writer.addFeature( outFeat )
del writer

def defineCharacteristics(self):
self.name = "Add autoincremental field"
self.group = "Algorithms for vector layers"
self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
self.addOutput(OutputVector(self.OUTPUT, "Output layer"))

62 changes: 62 additions & 0 deletions src/sextante/algs/EquivalentNumField.py
@@ -0,0 +1,62 @@
from sextante.core.GeoAlgorithm import GeoAlgorithm
from PyQt4.QtCore import *
from qgis.core import *
from sextante.parameters.ParameterVector import ParameterVector
from sextante.core.QGisLayers import QGisLayers
from sextante.outputs.OutputVector import OutputVector
import os
from PyQt4 import QtGui
from sextante.parameters.ParameterTableField import ParameterTableField

class AutoincrementalField(GeoAlgorithm):

INPUT = "INPUT"
OUTPUT = "OUTPUT"
FIELD = "FIELD"

def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/toolbox.png")

def processAlgorithm(self, progress):
field_index = self.getParameterValue(self.FIELD)
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(self.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
fields[len(fields)] = QgsField("NUM_FIELD", QVariant.Int)
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
nFeat = vprovider.featureCount()
nElement = 0
classes = {}
while vprovider.nextFeature(inFeat):
progress.setPercentage(int((100 * nElement)/nFeat))
nElement += 1
atMap = inFeat.attributeMap()
clazz = atMap[field_index]
if not clazz in classes.keys:
classes[clazz] = len(classes.keys())
while vprovider.nextFeature(inFeat):
progress.setPercentage(int((100 * nElement)/nFeat))
nElement += 1
inGeom = inFeat.geometry()
outFeat.setGeometry( inGeom )
atMap = inFeat.attributeMap()
outFeat.setAttributeMap( atMap )
outFeat.addAttribute( len(vprovider.fields()), QVariant(nElement) )
writer.addFeature( outFeat )
del writer

def defineCharacteristics(self):
self.name = "Add autoincremental field"
self.group = "Algorithms for vector layers"
self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
self.addParameter(ParameterTableField(self.FIELD, "Unique ID Field", self.INPUT))
self.addOutput(OutputVector(self.OUTPUT, "Output layer"))

4 changes: 3 additions & 1 deletion src/sextante/algs/SextanteAlgorithmProvider.py
Expand Up @@ -5,12 +5,14 @@
from sextante.algs.FieldsCalculator import FieldsCalculator
from sextante.algs.SaveSelectedFeatures import SaveSelectedFeatures
from sextante.algs.Explode import Explode
from sextante.algs.AutoincrementalField import AutoincrementalField

class SextanteAlgorithmProvider(AlgorithmProvider):

def __init__(self):
AlgorithmProvider.__init__(self)
self.alglist = [AddTableField(), FieldsCalculator(), SaveSelectedFeatures(), Explode()]
self.alglist = [AddTableField(), FieldsCalculator(), SaveSelectedFeatures(),
AutoincrementalField(), Explode()]

def initializeSettings(self):
AlgorithmProvider.initializeSettings(self)
Expand Down
2 changes: 1 addition & 1 deletion src/sextante/core/GeoAlgorithm.py
Expand Up @@ -71,7 +71,7 @@ def getCustomParametersDialog(self):
here, ready to be executed'''
return None

def getCustomModelerParametersDialog(self, modelAlg):
def getCustomModelerParametersDialog(self, modelAlg, algIndex = None):
'''if the algorithm has a custom parameters dialog when called from the modeler,
it should be returned here, ready to be executed'''
return None
Expand Down
9 changes: 4 additions & 5 deletions src/sextante/gui/ParametersDialog.py
Expand Up @@ -48,11 +48,10 @@ def setupUi(self, dialog, alg):
self.buttonBox = QtGui.QDialogButtonBox()
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
if self.alg.helpFile():
self.showHelpButton = QtGui.QPushButton()
self.showHelpButton.setText("Show help")
self.buttonBox.addButton(self.showHelpButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.showHelpButton, QtCore.SIGNAL("clicked()"), self.showHelp)
self.showHelpButton = QtGui.QPushButton()
self.showHelpButton.setText("Show help")
self.buttonBox.addButton(self.showHelpButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.showHelpButton, QtCore.SIGNAL("clicked()"), self.showHelp)
self.paramTable = ParametersPanel(self.alg, self.dialog)
self.scrollArea = QtGui.QScrollArea()
self.scrollArea.setWidget(self.paramTable)
Expand Down
4 changes: 2 additions & 2 deletions src/sextante/modeler/CalculatorModelerAlgorithm.py
Expand Up @@ -35,5 +35,5 @@ def processAlgorithm(self, progress):
raise GeoAlgorithmExecutionException("Wrong formula: " + formula)


def getCustomModelerParametersDialog(self, modelAlg):
return CalculatorModelerParametersDialog(self, modelAlg)
def getCustomModelerParametersDialog(self, modelAlg, algIndex = None):
return CalculatorModelerParametersDialog(self, modelAlg, algIndex)
15 changes: 11 additions & 4 deletions src/sextante/modeler/CalculatorModelerParametersDialog.py
Expand Up @@ -7,11 +7,12 @@

class CalculatorModelerParametersDialog(QtGui.QDialog):

def __init__(self, alg, model):
def __init__(self, alg, model, algIndex):
QtGui.QDialog.__init__(self)
self.setModal(True)
self.alg = alg
self.model = model
self.algIndex = algIndex
self.setupUi()
self.params = None

Expand Down Expand Up @@ -54,11 +55,17 @@ def getNumbers(self):
if isinstance(param, ParameterNumber):
numbers.append(AlgorithmAndParameter(AlgorithmAndParameter.PARENT_MODEL_ALGORITHM, param.name, "", param.description))

if self.algIndex is None:
dependent = []
else:
dependent = self.model.getDependentAlgorithms(self.algIndex)

i=0
for alg in self.model.algs:
for out in alg.outputs:
if isinstance(out, OutputNumber):
numbers.append(AlgorithmAndParameter(i, out.name, alg.name, out.description))
if i not in dependent:
for out in alg.outputs:
if isinstance(out, OutputNumber):
numbers.append(AlgorithmAndParameter(i, out.name, alg.name, out.description))
i+=1
return numbers

Expand Down
25 changes: 17 additions & 8 deletions src/sextante/modeler/ModelerAlgorithm.py
Expand Up @@ -140,6 +140,13 @@ def addAlgorithm(self, alg, parametersMap, valuesMap, outputsMap):
self.paramValues[value] = valuesMap[value]
self.algPos.append(self.getPositionForAlgorithmItem())

def updateAlgorithm(self, algIndex, parametersMap, valuesMap, outputsMap):
self.algParameters[algIndex] = parametersMap
self.algOutputs[algIndex] = outputsMap
for value in valuesMap.keys():
self.paramValues[value] = valuesMap[value]


def removeAlgorithm(self, index):
if self.hasDependencies(self.algs[index], index):
return False
Expand Down Expand Up @@ -168,13 +175,14 @@ def hasDependencies(self, element, elementIndex):
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:
if aap:
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):
Expand All @@ -183,8 +191,9 @@ def hasDependencies(self, element, elementIndex):
else:
for alg in self.algParameters:
for aap in alg.values():
if aap.alg == elementIndex:
return True
if aap:
if aap.alg == elementIndex:
return True

return False

Expand Down
19 changes: 19 additions & 0 deletions src/sextante/modeler/ModelerGraphicItem.py
Expand Up @@ -2,6 +2,7 @@
from sextante.parameters.Parameter import Parameter
import os
from sextante.core.GeoAlgorithm import GeoAlgorithm
from sextante.modeler.ModelerParametersDialog import ModelerParametersDialog

class ModelerGraphicItem(QtGui.QGraphicsItem):

Expand Down Expand Up @@ -33,10 +34,15 @@ def boundingRect(self):
ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + 2)
return rect

def mouseDoubleClickEvent(self, event):
self.editElement()

def contextMenuEvent(self, event):
popupmenu = QtGui.QMenu()
removeAction = popupmenu.addAction("Remove")
removeAction.triggered.connect(self.removeElement)
editAction = popupmenu.addAction("Edit")
editAction.triggered.connect(self.editElement)
if isinstance(self.element, GeoAlgorithm):
if self.elementIndex in self.model.deactivated:
removeAction = popupmenu.addAction("Activate")
Expand All @@ -54,6 +60,19 @@ def activateAlgorithm(self):
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 editElement(self):
if isinstance(self.element, Parameter):
pass
#TODO
else:
dlg = self.element.getCustomModelerParametersDialog(self.model, self.elementIndex)
if not dlg:
dlg = ModelerParametersDialog(self.element, self.model, self.elementIndex)
dlg.exec_()
if dlg.params != None:
self.model.updateAlgorithm(self.elementIndex, dlg.params, dlg.values, dlg.outputs)
self.model.updateModelerView()

def removeElement(self):
if isinstance(self.element, Parameter):
if not self.model.removeParameter(self.elementIndex):
Expand Down

0 comments on commit 3ff9a30

Please sign in to comment.