Skip to content

Commit 3ff9a30

Browse files
author
volayaf@gmail.com
committed
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
1 parent 3608452 commit 3ff9a30

16 files changed

+263
-38
lines changed
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from sextante.core.GeoAlgorithm import GeoAlgorithm
2+
from PyQt4.QtCore import *
3+
from qgis.core import *
4+
from sextante.parameters.ParameterVector import ParameterVector
5+
from sextante.core.QGisLayers import QGisLayers
6+
from sextante.outputs.OutputVector import OutputVector
7+
import os
8+
from PyQt4 import QtGui
9+
10+
class AutoincrementalField(GeoAlgorithm):
11+
12+
INPUT = "INPUT"
13+
OUTPUT = "OUTPUT"
14+
15+
def getIcon(self):
16+
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/toolbox.png")
17+
18+
def processAlgorithm(self, progress):
19+
settings = QSettings()
20+
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
21+
output = self.getOutputValue(self.OUTPUT)
22+
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
23+
vprovider = vlayer.dataProvider()
24+
allAttrs = vprovider.attributeIndexes()
25+
vprovider.select( allAttrs )
26+
fields = vprovider.fields()
27+
fields[len(fields)] = QgsField("AUTO", QVariant.Int)
28+
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
29+
inFeat = QgsFeature()
30+
outFeat = QgsFeature()
31+
inGeom = QgsGeometry()
32+
nFeat = vprovider.featureCount()
33+
nElement = 0
34+
while vprovider.nextFeature(inFeat):
35+
progress.setPercentage(int((100 * nElement)/nFeat))
36+
nElement += 1
37+
inGeom = inFeat.geometry()
38+
outFeat.setGeometry( inGeom )
39+
atMap = inFeat.attributeMap()
40+
outFeat.setAttributeMap( atMap )
41+
outFeat.addAttribute( len(vprovider.fields()), QVariant(nElement) )
42+
writer.addFeature( outFeat )
43+
del writer
44+
45+
def defineCharacteristics(self):
46+
self.name = "Add autoincremental field"
47+
self.group = "Algorithms for vector layers"
48+
self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
49+
self.addOutput(OutputVector(self.OUTPUT, "Output layer"))
50+
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from sextante.core.GeoAlgorithm import GeoAlgorithm
2+
from PyQt4.QtCore import *
3+
from qgis.core import *
4+
from sextante.parameters.ParameterVector import ParameterVector
5+
from sextante.core.QGisLayers import QGisLayers
6+
from sextante.outputs.OutputVector import OutputVector
7+
import os
8+
from PyQt4 import QtGui
9+
from sextante.parameters.ParameterTableField import ParameterTableField
10+
11+
class AutoincrementalField(GeoAlgorithm):
12+
13+
INPUT = "INPUT"
14+
OUTPUT = "OUTPUT"
15+
FIELD = "FIELD"
16+
17+
def getIcon(self):
18+
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/toolbox.png")
19+
20+
def processAlgorithm(self, progress):
21+
field_index = self.getParameterValue(self.FIELD)
22+
settings = QSettings()
23+
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
24+
output = self.getOutputValue(self.OUTPUT)
25+
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
26+
vprovider = vlayer.dataProvider()
27+
allAttrs = vprovider.attributeIndexes()
28+
vprovider.select( allAttrs )
29+
fields = vprovider.fields()
30+
fields[len(fields)] = QgsField("NUM_FIELD", QVariant.Int)
31+
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
32+
inFeat = QgsFeature()
33+
outFeat = QgsFeature()
34+
inGeom = QgsGeometry()
35+
nFeat = vprovider.featureCount()
36+
nElement = 0
37+
classes = {}
38+
while vprovider.nextFeature(inFeat):
39+
progress.setPercentage(int((100 * nElement)/nFeat))
40+
nElement += 1
41+
atMap = inFeat.attributeMap()
42+
clazz = atMap[field_index]
43+
if not clazz in classes.keys:
44+
classes[clazz] = len(classes.keys())
45+
while vprovider.nextFeature(inFeat):
46+
progress.setPercentage(int((100 * nElement)/nFeat))
47+
nElement += 1
48+
inGeom = inFeat.geometry()
49+
outFeat.setGeometry( inGeom )
50+
atMap = inFeat.attributeMap()
51+
outFeat.setAttributeMap( atMap )
52+
outFeat.addAttribute( len(vprovider.fields()), QVariant(nElement) )
53+
writer.addFeature( outFeat )
54+
del writer
55+
56+
def defineCharacteristics(self):
57+
self.name = "Add autoincremental field"
58+
self.group = "Algorithms for vector layers"
59+
self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
60+
self.addParameter(ParameterTableField(self.FIELD, "Unique ID Field", self.INPUT))
61+
self.addOutput(OutputVector(self.OUTPUT, "Output layer"))
62+

src/sextante/algs/SextanteAlgorithmProvider.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
from sextante.algs.FieldsCalculator import FieldsCalculator
66
from sextante.algs.SaveSelectedFeatures import SaveSelectedFeatures
77
from sextante.algs.Explode import Explode
8+
from sextante.algs.AutoincrementalField import AutoincrementalField
89

910
class SextanteAlgorithmProvider(AlgorithmProvider):
1011

1112
def __init__(self):
1213
AlgorithmProvider.__init__(self)
13-
self.alglist = [AddTableField(), FieldsCalculator(), SaveSelectedFeatures(), Explode()]
14+
self.alglist = [AddTableField(), FieldsCalculator(), SaveSelectedFeatures(),
15+
AutoincrementalField(), Explode()]
1416

1517
def initializeSettings(self):
1618
AlgorithmProvider.initializeSettings(self)

src/sextante/core/GeoAlgorithm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def getCustomParametersDialog(self):
7171
here, ready to be executed'''
7272
return None
7373

74-
def getCustomModelerParametersDialog(self, modelAlg):
74+
def getCustomModelerParametersDialog(self, modelAlg, algIndex = None):
7575
'''if the algorithm has a custom parameters dialog when called from the modeler,
7676
it should be returned here, ready to be executed'''
7777
return None

src/sextante/gui/ParametersDialog.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@ def setupUi(self, dialog, alg):
4848
self.buttonBox = QtGui.QDialogButtonBox()
4949
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
5050
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
51-
if self.alg.helpFile():
52-
self.showHelpButton = QtGui.QPushButton()
53-
self.showHelpButton.setText("Show help")
54-
self.buttonBox.addButton(self.showHelpButton, QtGui.QDialogButtonBox.ActionRole)
55-
QtCore.QObject.connect(self.showHelpButton, QtCore.SIGNAL("clicked()"), self.showHelp)
51+
self.showHelpButton = QtGui.QPushButton()
52+
self.showHelpButton.setText("Show help")
53+
self.buttonBox.addButton(self.showHelpButton, QtGui.QDialogButtonBox.ActionRole)
54+
QtCore.QObject.connect(self.showHelpButton, QtCore.SIGNAL("clicked()"), self.showHelp)
5655
self.paramTable = ParametersPanel(self.alg, self.dialog)
5756
self.scrollArea = QtGui.QScrollArea()
5857
self.scrollArea.setWidget(self.paramTable)

src/sextante/modeler/CalculatorModelerAlgorithm.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ def processAlgorithm(self, progress):
3535
raise GeoAlgorithmExecutionException("Wrong formula: " + formula)
3636

3737

38-
def getCustomModelerParametersDialog(self, modelAlg):
39-
return CalculatorModelerParametersDialog(self, modelAlg)
38+
def getCustomModelerParametersDialog(self, modelAlg, algIndex = None):
39+
return CalculatorModelerParametersDialog(self, modelAlg, algIndex)

src/sextante/modeler/CalculatorModelerParametersDialog.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77

88
class CalculatorModelerParametersDialog(QtGui.QDialog):
99

10-
def __init__(self, alg, model):
10+
def __init__(self, alg, model, algIndex):
1111
QtGui.QDialog.__init__(self)
1212
self.setModal(True)
1313
self.alg = alg
1414
self.model = model
15+
self.algIndex = algIndex
1516
self.setupUi()
1617
self.params = None
1718

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

58+
if self.algIndex is None:
59+
dependent = []
60+
else:
61+
dependent = self.model.getDependentAlgorithms(self.algIndex)
62+
5763
i=0
5864
for alg in self.model.algs:
59-
for out in alg.outputs:
60-
if isinstance(out, OutputNumber):
61-
numbers.append(AlgorithmAndParameter(i, out.name, alg.name, out.description))
65+
if i not in dependent:
66+
for out in alg.outputs:
67+
if isinstance(out, OutputNumber):
68+
numbers.append(AlgorithmAndParameter(i, out.name, alg.name, out.description))
6269
i+=1
6370
return numbers
6471

src/sextante/modeler/ModelerAlgorithm.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ def addAlgorithm(self, alg, parametersMap, valuesMap, outputsMap):
140140
self.paramValues[value] = valuesMap[value]
141141
self.algPos.append(self.getPositionForAlgorithmItem())
142142

143+
def updateAlgorithm(self, algIndex, parametersMap, valuesMap, outputsMap):
144+
self.algParameters[algIndex] = parametersMap
145+
self.algOutputs[algIndex] = outputsMap
146+
for value in valuesMap.keys():
147+
self.paramValues[value] = valuesMap[value]
148+
149+
143150
def removeAlgorithm(self, index):
144151
if self.hasDependencies(self.algs[index], index):
145152
return False
@@ -168,13 +175,14 @@ def hasDependencies(self, element, elementIndex):
168175
if isinstance(element, Parameter):
169176
for alg in self.algParameters:
170177
for aap in alg.values():
171-
if aap.alg == AlgorithmAndParameter.PARENT_MODEL_ALGORITHM:
172-
if aap.param == element.name:
173-
return True
174-
elif aap.param in self.paramValues: #check for multiple inputs
175-
aap2 = self.paramValues[aap.param]
176-
if element.name in aap2:
178+
if aap:
179+
if aap.alg == AlgorithmAndParameter.PARENT_MODEL_ALGORITHM:
180+
if aap.param == element.name:
177181
return True
182+
elif aap.param in self.paramValues: #check for multiple inputs
183+
aap2 = self.paramValues[aap.param]
184+
if element.name in aap2:
185+
return True
178186
if isinstance(element, ParameterVector):
179187
for param in self.parameters:
180188
if isinstance(param, ParameterTableField):
@@ -183,8 +191,9 @@ def hasDependencies(self, element, elementIndex):
183191
else:
184192
for alg in self.algParameters:
185193
for aap in alg.values():
186-
if aap.alg == elementIndex:
187-
return True
194+
if aap:
195+
if aap.alg == elementIndex:
196+
return True
188197

189198
return False
190199

src/sextante/modeler/ModelerGraphicItem.py

+19
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from sextante.parameters.Parameter import Parameter
33
import os
44
from sextante.core.GeoAlgorithm import GeoAlgorithm
5+
from sextante.modeler.ModelerParametersDialog import ModelerParametersDialog
56

67
class ModelerGraphicItem(QtGui.QGraphicsItem):
78

@@ -33,10 +34,15 @@ def boundingRect(self):
3334
ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + 2)
3435
return rect
3536

37+
def mouseDoubleClickEvent(self, event):
38+
self.editElement()
39+
3640
def contextMenuEvent(self, event):
3741
popupmenu = QtGui.QMenu()
3842
removeAction = popupmenu.addAction("Remove")
3943
removeAction.triggered.connect(self.removeElement)
44+
editAction = popupmenu.addAction("Edit")
45+
editAction.triggered.connect(self.editElement)
4046
if isinstance(self.element, GeoAlgorithm):
4147
if self.elementIndex in self.model.deactivated:
4248
removeAction = popupmenu.addAction("Activate")
@@ -54,6 +60,19 @@ def activateAlgorithm(self):
5460
QtGui.QMessageBox.warning(None, "Could not activate Algorithm",
5561
"The selected algorithm depends on other currently non-active algorithms.\nActivate them them before trying to activate it.")
5662

63+
def editElement(self):
64+
if isinstance(self.element, Parameter):
65+
pass
66+
#TODO
67+
else:
68+
dlg = self.element.getCustomModelerParametersDialog(self.model, self.elementIndex)
69+
if not dlg:
70+
dlg = ModelerParametersDialog(self.element, self.model, self.elementIndex)
71+
dlg.exec_()
72+
if dlg.params != None:
73+
self.model.updateAlgorithm(self.elementIndex, dlg.params, dlg.values, dlg.outputs)
74+
self.model.updateModelerView()
75+
5776
def removeElement(self):
5877
if isinstance(self.element, Parameter):
5978
if not self.model.removeParameter(self.elementIndex):

0 commit comments

Comments
 (0)