Explorar el Código

wxGUI/modeler: conditions implemented (initial)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@42749 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa hace 15 años
padre
commit
c39ce49700

+ 91 - 30
gui/wxpython/gui_modules/gmodeler.py

@@ -25,6 +25,7 @@ Classes:
  - ModelLoopDialog
  - ModelLoopDialog
  - ActionPanel
  - ActionPanel
  - ActionListCtrl
  - ActionListCtrl
+ - ModelCondition
 
 
 (C) 2010 by the GRASS Development Team
 (C) 2010 by the GRASS Development Team
 This program is free software under the GNU General Public License
 This program is free software under the GNU General Public License
@@ -304,7 +305,7 @@ class Model(object):
                                  actions = alist,
                                  actions = alist,
                                  id = loop['id'])
                                  id = loop['id'])
             
             
-            for action in loopItem.GetActions():
+            for action in loopItem.GetItems():
                 action.SetLoop(loopItem)
                 action.SetLoop(loopItem)
             
             
             self.AddItem(loopItem)
             self.AddItem(loopItem)
@@ -895,7 +896,7 @@ class ModelFrame(wx.Frame):
                 # split condition
                 # split condition
                 condVar, condText = re.split('\s*in\s*', cond)
                 condVar, condText = re.split('\s*in\s*', cond)
                 
                 
-                for action in item.GetActions():
+                for action in item.GetItems():
                     for vars()[condVar] in eval(condText):
                     for vars()[condVar] in eval(condText):
                         self._runAction(action, params)
                         self._runAction(action, params)
         
         
@@ -1101,14 +1102,28 @@ r"""    grass.run_command('g.remove',
             fd.write('    pass\n')
             fd.write('    pass\n')
         
         
         fd.write("\ndef main():\n")
         fd.write("\ndef main():\n")
+        indent = 4
         for item in self.model.GetItems():
         for item in self.model.GetItems():
             if isinstance(item, ModelAction):
             if isinstance(item, ModelAction):
-                self._writePythonAction(fd, item)
+                if item.GetLoopId():
+                    continue
+                self._writePythonAction(fd, item, indent)
             elif isinstance(item, ModelLoop):
             elif isinstance(item, ModelLoop):
-                # for action in item.GetActions():
-                #     fd.write('for %s:\n' % item.GetText())
-                #     self._writePythonAction(fd, action)
-                pass
+                # substitute conditiond
+                variables = self.model.GetVariables()
+                cond = item.GetText()
+                for variable in variables:
+                    pattern= re.compile('%' + variable)
+                    if pattern.search(cond):
+                        value = variables[variable].get('value', '')
+                        if variables[variable].get('type', 'string') == 'string':
+                            value = '"' + value + '"'
+                        cond = pattern.sub(value, cond)
+                fd.write('%sfor %s:\n' % (' ' * indent, cond))
+                indent += 4
+                for action in item.GetItems():
+                    self._writePythonAction(fd, action, indent)
+                indent -= 4
         
         
         fd.write("\n    return 0\n")
         fd.write("\n    return 0\n")
         
         
@@ -1120,14 +1135,14 @@ if __name__ == "__main__":
     sys.exit(main())
     sys.exit(main())
 """)
 """)
         
         
-    def _writePythonAction(self, fd, item):
+    def _writePythonAction(self, fd, item, indent):
         task = menuform.GUI().ParseCommand(cmd = item.GetLog(string = False),
         task = menuform.GUI().ParseCommand(cmd = item.GetLog(string = False),
                                            show = None)
                                            show = None)
         opts = task.get_options()
         opts = task.get_options()
         flags = ''
         flags = ''
         params = list()
         params = list()
-        strcmd = "    grass.run_command("
-        indent = len(strcmd)
+        strcmd = "%sgrass.run_command(" % (' ' * indent)
+        cmdIndent = len(strcmd)
         for f in opts['flags']:
         for f in opts['flags']:
             if f.get('value', False) == True:
             if f.get('value', False) == True:
                 name = f.get('name', '')
                 name = f.get('name', '')
@@ -1148,12 +1163,12 @@ if __name__ == "__main__":
         
         
         fd.write(strcmd + '"%s"' % task.get_name())
         fd.write(strcmd + '"%s"' % task.get_name())
         if flags:
         if flags:
-            fd.write(",\n%sflags = '%s'" % (' ' * indent, flags))
+            fd.write(",\n%sflags = '%s'" % (' ' * cmdIndent, flags))
         if len(params) > 0:
         if len(params) > 0:
             fd.write(",\n")
             fd.write(",\n")
             for opt in params[:-1]:
             for opt in params[:-1]:
-                fd.write("%s%s,\n" % (' ' * indent, opt))
-            fd.write("%s%s)\n" % (' ' * indent, params[-1]))
+                fd.write("%s%s,\n" % (' ' * cmdIndent, opt))
+            fd.write("%s%s)\n" % (' ' * cmdIndent, params[-1]))
         else:
         else:
             fd.write(")\n")
             fd.write(")\n")
         
         
@@ -1178,14 +1193,29 @@ if __name__ == "__main__":
         self.ModelChanged()
         self.ModelChanged()
         
         
         width, height = self.canvas.GetSize()
         width, height = self.canvas.GetSize()
-        loop = ModelLoop(self, x = width/2, y = height/2)
+        loop = ModelLoop(self, x = width/2, y = height/2,
+                         id = len(self.model.GetActions()) + 1)
         self.canvas.diagram.AddShape(loop)
         self.canvas.diagram.AddShape(loop)
         loop.Show(True)
         loop.Show(True)
         
         
         self._addEvent(loop)
         self._addEvent(loop)
         
         
         self.canvas.Refresh()
         self.canvas.Refresh()
-
+        
+    def OnDefineCondition(self, event):
+        """!Define new condition in the model"""
+        self.ModelChanged()
+        
+        width, height = self.canvas.GetSize()
+        cond = ModelCondition(self, x = width/2, y = height/2,
+                              id = len(self.model.GetActions()) + 1)
+        self.canvas.diagram.AddShape(cond)
+        loop.Show(True)
+        
+        self._addEvent(cond)
+        
+        self.canvas.Refresh()
+    
     def OnAddAction(self, event):
     def OnAddAction(self, event):
         """!Add action to model"""
         """!Add action to model"""
         if self.searchDialog is None:
         if self.searchDialog is None:
@@ -1461,17 +1491,17 @@ if __name__ == "__main__":
     def DefineLoop(self, loop):
     def DefineLoop(self, loop):
         """!Define loop with given list of actions"""
         """!Define loop with given list of actions"""
         parent = loop
         parent = loop
-        actions = loop.GetActions()
+        actions = loop.GetItems()
         if not actions:
         if not actions:
             return
             return
         
         
-        for action in loop.GetActions():
+        for action in loop.GetItems():
             rel = ModelRelation(parent, action)
             rel = ModelRelation(parent, action)
             self.AddLine(rel)
             self.AddLine(rel)
             parent = action
             parent = action
         
         
         # close loop
         # close loop
-        action = loop.GetActions()[-1]
+        action = loop.GetItems()[-1]
         rel = ModelRelation(action, loop)
         rel = ModelRelation(action, loop)
         self.AddLine(rel)
         self.AddLine(rel)
         dx = loop.GetWidth() / 2 + 50
         dx = loop.GetWidth() / 2 + 50
@@ -2083,7 +2113,7 @@ class ModelEvtHandler(ogl.ShapeEvtHandler):
                 alist = list()
                 alist = list()
                 for aId in dlg.GetActions():
                 for aId in dlg.GetActions():
                     alist.append(self.frame.GetModel().GetAction(aId))
                     alist.append(self.frame.GetModel().GetAction(aId))
-                shape.SetActions(alist)
+                shape.SetItems(alist)
                 self.frame.DefineLoop(shape)
                 self.frame.DefineLoop(shape)
             self.frame.GetCanvas().Refresh()
             self.frame.GetCanvas().Refresh()
             
             
@@ -2823,7 +2853,7 @@ class WriteModelFile:
         if text:
         if text:
             self.fd.write('%s<condition>%s</condition>\n' %
             self.fd.write('%s<condition>%s</condition>\n' %
                           (' ' * self.indent, self._filterValue(text)))
                           (' ' * self.indent, self._filterValue(text)))
-        for action in loop.GetActions():
+        for action in loop.GetItems():
             self.fd.write('%s<loop-action>%d</loop-action>\n' %
             self.fd.write('%s<loop-action>%d</loop-action>\n' %
                           (' ' * self.indent, action.GetId()))
                           (' ' * self.indent, action.GetId()))
         self.indent -= 4
         self.indent -= 4
@@ -3625,7 +3655,7 @@ class VariableListCtrl(ModelListCtrl):
         menu.Destroy()
         menu.Destroy()
         
         
 class ModelLoop(ModelObject, ogl.RectangleShape):
 class ModelLoop(ModelObject, ogl.RectangleShape):
-    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = None, actions = []):
+    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = None, items = []):
         """!Defines a loop"""
         """!Defines a loop"""
         ModelObject.__init__(self, id)
         ModelObject.__init__(self, id)
         
         
@@ -3635,7 +3665,7 @@ class ModelLoop(ModelObject, ogl.RectangleShape):
             width = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'width'))
             width = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'width'))
         if not height:
         if not height:
             height = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'height'))
             height = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'height'))
-        self.actions = actions # list of actions in the loop
+        self.items = items # list of items in the loop
         
         
         if self.parent.GetCanvas():
         if self.parent.GetCanvas():
             ogl.RectangleShape.__init__(self, width, height)
             ogl.RectangleShape.__init__(self, width, height)
@@ -3645,23 +3675,26 @@ class ModelLoop(ModelObject, ogl.RectangleShape):
             self.SetY(y)
             self.SetY(y)
             self.SetPen(wx.BLACK_PEN)
             self.SetPen(wx.BLACK_PEN)
             self.SetCornerRadius(100)
             self.SetCornerRadius(100)
-            self.AddText('(' + str(self.id) + ') ' + text)
+            if text:
+                self.AddText('(' + str(self.id) + ') ' + text)
+            else:
+                self.AddText('(' + str(self.id) + ')')
         
         
     def GetText(self):
     def GetText(self):
         """!Get loop text"""
         """!Get loop text"""
         return self.text
         return self.text
 
 
-    def GetActions(self):
-        """!Get actions (id)"""
-        return self.actions
+    def GetItems(self):
+        """!Get items (id)"""
+        return self.items
 
 
     def SetId(self, id):
     def SetId(self, id):
         """!Set loop id"""
         """!Set loop id"""
         self.id = id
         self.id = id
 
 
-    def SetActions(self, actions):
-        """!Set actions (id)"""
-        self.actions = actions
+    def SetItems(self, items):
+        """!Set items (id)"""
+        self.items = items
 
 
     def SetText(self, cond):
     def SetText(self, cond):
         """!Set loop text (condition)"""
         """!Set loop text (condition)"""
@@ -3685,7 +3718,7 @@ class ModelLoopDialog(wx.Dialog):
         self.condText = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
         self.condText = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
                                     value = shape.GetText())
                                     value = shape.GetText())
         self.listBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
         self.listBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
-                                    label=" %s " % _("List of actions in loop"))
+                                    label=" %s " % _("List of items in loop"))
         self.actionList = ActionCheckListCtrl(parent = self.panel,
         self.actionList = ActionCheckListCtrl(parent = self.panel,
                                               columns = [_("ID"), _("Name"),
                                               columns = [_("ID"), _("Name"),
                                                          _("Command")])
                                                          _("Command")])
@@ -3948,6 +3981,34 @@ class ActionCheckListCtrl(ActionListCtrl, listmix.CheckListCtrlMixin):
     def OnBeginEdit(self, event):
     def OnBeginEdit(self, event):
         """!Disable editing"""
         """!Disable editing"""
         event.Veto()
         event.Veto()
+
+class ModelCondition(ModelObject, ogl.PolygonShape):
+    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = None, items = []):
+        """!Defines a condition"""
+        ModelObject.__init__(self, id)
+        
+        self.parent  = parent
+        self.text    = text
+        if not width:
+            width = UserSettings.Get(group='modeler', key='condition', subkey=('size', 'width'))
+        if not height:
+            height = UserSettings.Get(group='modeler', key='condition', subkey=('size', 'height'))
+        self.items = items # list of items in the loop
+        
+        if self.parent.GetCanvas():
+            ogl.PolygonShape.__init__(self)
+            points = [(x, y - height / 2),
+                      (x + width / 2, y),
+                      (x, y + height / 2),
+                      (x - width / 2, y)]
+            self.Create(points)
+            
+            self.SetCanvas(self.parent)
+            self.SetPen(wx.BLACK_PEN)
+            if text:
+                self.AddText('(' + str(self.id) + ') ' + text)
+            else:
+                self.AddText('(' + str(self.id) + ')')
         
         
 def main():
 def main():
     app = wx.PySimpleApp()
     app = wx.PySimpleApp()

+ 6 - 0
gui/wxpython/gui_modules/preferences.py

@@ -558,6 +558,12 @@ class Settings:
                         'height' : 50,
                         'height' : 50,
                         },
                         },
                     },
                     },
+                'condition' : {
+                    'size' : {
+                        'width' : 100,
+                        'height' : 50,
+                        },
+                    },
                 },
                 },
             }
             }
         
         

+ 8 - 1
gui/wxpython/xml/menudata_modeler.xml

@@ -41,6 +41,7 @@
 	  <label>Export to Python</label>
 	  <label>Export to Python</label>
 	  <help>Export model to Python script</help>
 	  <help>Export model to Python script</help>
 	  <handler>OnExportPython</handler>
 	  <handler>OnExportPython</handler>
+	  <shortcut>Ctrl+E</shortcut>
 	</menuitem>
 	</menuitem>
 	<separator />
 	<separator />
 	<menuitem>
 	<menuitem>
@@ -83,11 +84,17 @@
 	</menuitem>
 	</menuitem>
 	<menuitem>
 	<menuitem>
 	  <label>Add loop</label>
 	  <label>Add loop</label>
-	  <help>Adds loop to model</help>
+	  <help>Adds loop (for) to model</help>
 	  <handler>OnDefineLoop</handler>
 	  <handler>OnDefineLoop</handler>
 	  <shortcut>Ctrl+L</shortcut>
 	  <shortcut>Ctrl+L</shortcut>
 	</menuitem>
 	</menuitem>
 	<menuitem>
 	<menuitem>
+	  <label>Add condition</label>
+	  <help>Adds condition (if/else) to model</help>
+	  <handler>OnDefineCondition</handler>
+	  <shortcut>Ctrl+I</shortcut>
+	</menuitem>
+	<menuitem>
 	  <label>Remove item</label>
 	  <label>Remove item</label>
 	  <help>Remove action/data from model</help>
 	  <help>Remove action/data from model</help>
 	  <handler>OnRemoveItem</handler>
 	  <handler>OnRemoveItem</handler>