|
@@ -7,6 +7,7 @@ Classes:
|
|
|
- Model
|
|
|
- ModelFrame
|
|
|
- ModelCanvas
|
|
|
+ - ModelObject
|
|
|
- ModelAction
|
|
|
- ModelSearchDialog
|
|
|
- ModelData
|
|
@@ -19,7 +20,8 @@ Classes:
|
|
|
- ModelParamDialog
|
|
|
- VariablesDialog
|
|
|
- ValiablesListCtrl
|
|
|
-
|
|
|
+ - ModelLoop
|
|
|
+
|
|
|
(C) 2010 by the GRASS Development Team
|
|
|
This program is free software under the GNU General Public License
|
|
|
(>=v2). Read the file COPYING that comes with GRASS for details.
|
|
@@ -74,6 +76,8 @@ class Model(object):
|
|
|
def __init__(self, canvas = None):
|
|
|
self.actions = list() # list of recorded actions
|
|
|
self.data = list() # list of recorded data items
|
|
|
+ self.loops = list() # list of recorded loops
|
|
|
+
|
|
|
# model properties
|
|
|
self.properties = { 'name' : _("model"),
|
|
|
'description' : _("Script generated by wxGUI Graphical Modeler."),
|
|
@@ -91,6 +95,10 @@ class Model(object):
|
|
|
"""!Return list of actions"""
|
|
|
return self.actions
|
|
|
|
|
|
+ def GetLoops(self):
|
|
|
+ """!Return list of loops"""
|
|
|
+ return self.loops
|
|
|
+
|
|
|
def GetProperties(self):
|
|
|
"""!Get model properties"""
|
|
|
return self.properties
|
|
@@ -222,6 +230,16 @@ class Model(object):
|
|
|
|
|
|
actionItem.AddData(dataItem)
|
|
|
|
|
|
+ # load loops
|
|
|
+ for loop in gxmXml.loops:
|
|
|
+ loopItem = ModelLoop(parent = self,
|
|
|
+ x = loop['pos'][0],
|
|
|
+ y = loop['pos'][1],
|
|
|
+ width = loop['size'][0],
|
|
|
+ height = loop['size'][1],
|
|
|
+ text = loop['text'])
|
|
|
+ self.loops.append(loopItem)
|
|
|
+
|
|
|
def IsValid(self):
|
|
|
"""Return True if model is valid"""
|
|
|
if self.Validate():
|
|
@@ -996,6 +1014,20 @@ if __name__ == "__main__":
|
|
|
self.defineRelation = { 'from' : None,
|
|
|
'to' : None }
|
|
|
|
|
|
+ def OnDefineLoop(self, event):
|
|
|
+ """!Define new loop in the model"""
|
|
|
+ self.ModelChanged()
|
|
|
+
|
|
|
+ width, height = self.canvas.GetSize()
|
|
|
+ loop = ModelLoop(self, x = width/2, y = height/2)
|
|
|
+ self.canvas.diagram.AddShape(loop)
|
|
|
+ loop.Show(True)
|
|
|
+
|
|
|
+ self._addEvent(loop)
|
|
|
+ # self.model.AddAction(action)
|
|
|
+
|
|
|
+ self.canvas.Refresh()
|
|
|
+
|
|
|
def OnAddAction(self, event):
|
|
|
"""!Add action to model"""
|
|
|
if self.searchDialog is None:
|
|
@@ -1224,6 +1256,12 @@ if __name__ == "__main__":
|
|
|
for rel in data.GetRelations():
|
|
|
self.AddLine(rel)
|
|
|
|
|
|
+ # load loops
|
|
|
+ for loop in self.model.GetLoops():
|
|
|
+ self._addEvent(loop)
|
|
|
+ self.canvas.diagram.AddShape(loop)
|
|
|
+ loop.Show(True)
|
|
|
+
|
|
|
self.SetStatusText('', 0)
|
|
|
|
|
|
self.canvas.Refresh(True)
|
|
@@ -1237,11 +1275,7 @@ if __name__ == "__main__":
|
|
|
self.ModelChanged(False)
|
|
|
tmpfile = tempfile.TemporaryFile(mode='w+b')
|
|
|
try:
|
|
|
- WriteModelFile(fd = tmpfile,
|
|
|
- actions = self.model.GetActions(),
|
|
|
- data = self.model.GetData(),
|
|
|
- properties = self.model.GetProperties(),
|
|
|
- variables = self.model.GetVariables())
|
|
|
+ WriteModelFile(fd = tmpfile, model = self.model)
|
|
|
except StandardError:
|
|
|
GMessage(parent = self,
|
|
|
message = _("Writing current settings to model file failed."))
|
|
@@ -1803,6 +1837,12 @@ class ModelEvtHandler(ogl.ShapeEvtHandler):
|
|
|
self.frame.ModelChanged()
|
|
|
if self._previousHandler:
|
|
|
self._previousHandler.OnBeginDragLeft(x, y, keys, attachment)
|
|
|
+
|
|
|
+ def OnEndSize(self, x, y):
|
|
|
+ """!Resize shape"""
|
|
|
+ self.frame.ModelChanged()
|
|
|
+ if self._previousHandler:
|
|
|
+ self._previousHandler.OnEndSize(x, y)
|
|
|
|
|
|
def OnRightClick(self, x, y, keys = 0, attachment = 0):
|
|
|
"""!Right click -> pop-up menu"""
|
|
@@ -2077,11 +2117,13 @@ class ProcessModelFile:
|
|
|
self.variables = dict()
|
|
|
self.actions = list()
|
|
|
self.data = list()
|
|
|
+ self.loops = list()
|
|
|
|
|
|
self._processProperties()
|
|
|
self._processVariables()
|
|
|
self._processActions()
|
|
|
self._processData()
|
|
|
+ self._processLoops()
|
|
|
|
|
|
def _filterValue(self, value):
|
|
|
"""!Filter value
|
|
@@ -2127,7 +2169,10 @@ class ProcessModelFile:
|
|
|
|
|
|
def _processVariables(self):
|
|
|
"""!Process model variables"""
|
|
|
- for node in self.root.findall('variable'):
|
|
|
+ vnode = self.root.find('variables')
|
|
|
+ if vnode is None:
|
|
|
+ return
|
|
|
+ for node in vnode.findall('variable'):
|
|
|
name = node.get('name', '')
|
|
|
if not name:
|
|
|
continue # should not happen
|
|
@@ -2264,15 +2309,26 @@ class ProcessModelFile:
|
|
|
task.set_param(name, True, element = 'parameterized')
|
|
|
|
|
|
return task
|
|
|
-
|
|
|
+
|
|
|
+ def _processLoops(self):
|
|
|
+ """!Process model loops"""
|
|
|
+ for node in self.root.findall('loop'):
|
|
|
+ pos, size = self._getDim(node)
|
|
|
+ text = self._filterValue(self._getNodeText(node, 'value')).strip()
|
|
|
+
|
|
|
+ self.loops.append({ 'pos' : pos,
|
|
|
+ 'size': size,
|
|
|
+ 'text' : text })
|
|
|
+
|
|
|
class WriteModelFile:
|
|
|
"""!Generic class for writing model file"""
|
|
|
- def __init__(self, fd, actions, data, properties, variables):
|
|
|
+ def __init__(self, fd, model):
|
|
|
self.fd = fd
|
|
|
- self.actions = actions
|
|
|
- self.data = data
|
|
|
- self.properties = properties
|
|
|
- self.variables = variables
|
|
|
+ self.actions = model.GetActions()
|
|
|
+ self.data = model.GetData()
|
|
|
+ self.properties = model.GetProperties()
|
|
|
+ self.variables = model.GetVariables()
|
|
|
+ self.loops = model.GetLoops()
|
|
|
|
|
|
self.indent = 0
|
|
|
|
|
@@ -2282,6 +2338,7 @@ class WriteModelFile:
|
|
|
self._variables()
|
|
|
self._actions()
|
|
|
self._data()
|
|
|
+ self._loops()
|
|
|
|
|
|
self._footer()
|
|
|
|
|
@@ -2322,6 +2379,8 @@ class WriteModelFile:
|
|
|
|
|
|
def _variables(self):
|
|
|
"""!Write model variables"""
|
|
|
+ self.fd.write('%s<variables>\n' % (' ' * self.indent))
|
|
|
+ self.indent += 4
|
|
|
for name, values in self.variables.iteritems():
|
|
|
self.fd.write('%s<variable name="%s" type="%s">\n' % \
|
|
|
(' ' * self.indent, name, values['type']))
|
|
@@ -2334,6 +2393,8 @@ class WriteModelFile:
|
|
|
(' ' * self.indent, values['description']))
|
|
|
self.indent -= 4
|
|
|
self.fd.write('%s</variable>\n' % (' ' * self.indent))
|
|
|
+ self.indent -= 4
|
|
|
+ self.fd.write('%s</variables>\n' % (' ' * self.indent))
|
|
|
|
|
|
def _actions(self):
|
|
|
"""!Write actions"""
|
|
@@ -2425,6 +2486,21 @@ class WriteModelFile:
|
|
|
|
|
|
self.indent -= 4
|
|
|
self.fd.write('%s</data>\n' % (' ' * self.indent))
|
|
|
+
|
|
|
+ def _loops(self):
|
|
|
+ """!Write loops"""
|
|
|
+ for loop in self.loops:
|
|
|
+ self.fd.write('%s<loop pos="%d,%d" size="%d,%d">\n' % \
|
|
|
+ (' ' * self.indent, loop.GetX(), loop.GetY(),
|
|
|
+ loop.GetWidth(), loop.GetHeight()))
|
|
|
+ text = loop.GetText()
|
|
|
+ if text:
|
|
|
+ self.indent += 4
|
|
|
+ self.fd.write('%s<value>%s</value>\n' %
|
|
|
+ (' ' * self.indent, self._filterValue(text)))
|
|
|
+ self.indent -= 4
|
|
|
+
|
|
|
+ self.fd.write('%s</loop>\n' % (' ' * self.indent))
|
|
|
|
|
|
class PreferencesDialog(PreferencesBaseDialog):
|
|
|
"""!User preferences dialog"""
|
|
@@ -3189,7 +3265,33 @@ class VariablesListCtrl(wx.ListCtrl,
|
|
|
def OnColClick(self, event):
|
|
|
"""!Click on column header (order by)"""
|
|
|
event.Skip()
|
|
|
+
|
|
|
+class ModelLoop(ogl.RectangleShape):
|
|
|
+ def __init__(self, parent, x, y, width = None, height = None, text = None):
|
|
|
+ """!Defines a loop"""
|
|
|
+ self.parent = parent
|
|
|
+ self.text = text
|
|
|
+ if not width:
|
|
|
+ width = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'width'))
|
|
|
+ if not height:
|
|
|
+ height = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'height'))
|
|
|
|
|
|
+ if self.parent.GetCanvas():
|
|
|
+ ogl.RectangleShape.__init__(self, width, height)
|
|
|
+
|
|
|
+ self.SetCanvas(self.parent)
|
|
|
+ self.SetX(x)
|
|
|
+ self.SetY(y)
|
|
|
+ self.SetPen(wx.BLACK_PEN)
|
|
|
+ self.SetCornerRadius(100)
|
|
|
+
|
|
|
+ if text:
|
|
|
+ self.AddText(text)
|
|
|
+
|
|
|
+ def GetText(self):
|
|
|
+ """!Get loop text"""
|
|
|
+ return self.text
|
|
|
+
|
|
|
def main():
|
|
|
app = wx.PySimpleApp()
|
|
|
wx.InitAllImageHandlers()
|