[GRASS-SVN] r41806 - in grass/trunk/gui: icons/grass2 wxpython/gui_modules wxpython/icons wxpython/xml

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Apr 11 15:16:33 EDT 2010


Author: martinl
Date: 2010-04-11 15:16:32 -0400 (Sun, 11 Apr 2010)
New Revision: 41806

Added:
   grass/trunk/gui/icons/grass2/move.png
Modified:
   grass/trunk/gui/wxpython/gui_modules/gmodeler.py
   grass/trunk/gui/wxpython/gui_modules/toolbars.py
   grass/trunk/gui/wxpython/icons/grass2_icons.py
   grass/trunk/gui/wxpython/icons/grass_icons.py
   grass/trunk/gui/wxpython/icons/icon.py
   grass/trunk/gui/wxpython/icons/silk_icons.py
   grass/trunk/gui/wxpython/xml/menudata_modeler.xml
Log:
wxGUI: modeler in progress


Added: grass/trunk/gui/icons/grass2/move.png
===================================================================
(Binary files differ)


Property changes on: grass/trunk/gui/icons/grass2/move.png
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Modified: grass/trunk/gui/wxpython/gui_modules/gmodeler.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gmodeler.py	2010-04-11 16:46:09 UTC (rev 41805)
+++ grass/trunk/gui/wxpython/gui_modules/gmodeler.py	2010-04-11 19:16:32 UTC (rev 41806)
@@ -69,6 +69,11 @@
         self.modelFile = None    # loaded model
         self.modelChanged = False
         
+        self.cursors = {
+            "default" : wx.StockCursor(wx.CURSOR_ARROW),
+            "cross"   : wx.StockCursor(wx.CURSOR_CROSS),
+            }
+        
         wx.Frame.__init__(self, parent = parent, id = id, title = title, **kwargs)
         self.SetName("Modeler")
         self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
@@ -88,7 +93,8 @@
         
         self.canvas = ModelCanvas(self)
         self.canvas.SetBackgroundColour(wx.WHITE)
-
+        self.canvas.SetCursor(self.cursors["default"])
+        
         self.goutput = goutput.GMConsole(parent = self, pageid = 1)
                 
         self.modelPage   = self.notebook.AddPage(self.canvas, text=_('Model'))
@@ -121,6 +127,23 @@
         evthandler.SetPreviousHandler(item.GetEventHandler())
         item.SetEventHandler(evthandler)
 
+    def FindAction(self, id):
+        """!Find action by id"""
+        for action in self.actions:
+            if action.GetId() == id:
+                return action
+        
+        return None
+
+    def FindData(self, value, prompt):
+        """!Find data by value, and prompt"""
+        for data in self.data:
+            if data.GetValue() == value and \
+                    data.GetPrompt() == prompt:
+                return data
+        
+        return None
+            
     def ModelChanged(self):
         """!Update window title"""
         if not self.modelChanged:
@@ -292,6 +315,10 @@
         """!Remove item from model"""
         pass
 
+    def OnDefineRelation(self, event):
+        """!Define relation between data and action items"""
+        self.canvas.SetCursor(self.cursors["cross"])
+    
     def OnAddAction(self, event):
         """!Add action to model"""
         if self.searchDialog is None:
@@ -366,18 +393,36 @@
     def GetOptData(self, dcmd, layer, params, propwin):
         """!Process action data"""
         layer.SetProperties(dcmd, params, propwin)
-            
+        
         if params: # add data items
             width, height = self.canvas.GetSize()
             x = [width/2 + 200, width/2 - 200]
             for p in params['params']:
-                if p.get('value', None) and \
-                        p.get('prompt', '') in ('raster', 'vector', 'raster3d'):
+                if p.get('prompt', '') in ('raster', 'vector', 'raster3d') and \
+                        (p.get('value', None) or \
+                             p.get('age', 'old') != 'old'):
                     # create data item
+                    data = layer.FindData(p.get('name', ''))
+                    if data:
+                        data.SetValue(p.get('value', ''))
+                        continue
+                    
+                    data = self.FindData(p.get('value', ''),
+                                         p.get('prompt', ''))
+                    if data:
+                        if p.get('age', 'old') == 'old':
+                            self._addLine(data, layer)
+                            data.AddAction(layer, direction = 'from')
+                        else:
+                            self._addLine(layer, data)
+                            data.AddAction(layer, direction = 'to')
+                        continue
+                    
                     data = ModelData(self, name = p.get('name', ''),
                                      value = p.get('value', ''),
                                      prompt = p.get('prompt', ''),
                                      x = x.pop(), y = height/2)
+                    layer.AddData(data)
                     self.canvas.diagram.AddShape(data)
                     data.Show(True)
                     
@@ -391,10 +436,20 @@
                         self._addLine(layer, data)
                         data.AddAction(layer, direction = 'to')
             
+            # valid ?
+            valid = True
+            for p in params['params']:
+                if p.get('value', '') == '' and \
+                        p.get('default', '') == '':
+                    valid = False
+                    break
+            
+            layer.SetValid(valid)
+            
             self.canvas.Refresh()
         
         self.SetStatusText(layer.GetLog(), 0)
-
+        
     def _addLine(self, fromShape, toShape):
         """!Add connection
 
@@ -446,11 +501,22 @@
                                       width = action['size'][0],
                                       height = action['size'][1],
                                       cmd = action['cmd'])
+            actionShape.SetId(action['id'])
             self.canvas.diagram.AddShape(actionShape)
             actionShape.Show(True)
             
             self._addEvent(actionShape)
             self.actions.append(actionShape)
+            
+            task = menuform.GUI().ParseCommand(cmd = actionShape.GetLog(string = False),
+                                               show = None)
+            valid = True
+            for p in task.get_options()['params']:
+                if p.get('value', '') == '' and \
+                        p.get('default', '') == '':
+                    valid = False
+                    break
+            actionShape.SetValid(valid)
         
         # load data & connections
         for data in gxmXml.data:
@@ -467,14 +533,17 @@
             
             self._addEvent(dataShape)
             self.data.append(dataShape)
+
+            for idx in range(len(data['id'])):
+                actionShape = self.FindAction(data['id'][idx])
+                if data['from'][idx] is True:
+                    self._addLine(dataShape, actionShape)
+                    dataShape.AddAction(actionShape, direction = 'from')
+                elif data['from'][idx] is False:
+                    self._addLine(actionShape, dataShape)
+                    dataShape.AddAction(actionShape, direction = 'to')
             
-            actionShape = self.actions[0]
-            if data['from'] is True:
-                self._addLine(dataShape, actionShape)
-                dataShape.AddAction(actionShape, direction = 'from')
-            elif data['from'] is False:
-                self._addLine(actionShape, dataShape)
-                dataShape.AddAction(actionShape, direction = 'to')
+            actionShape.AddData(dataShape)
         
         self.canvas.Refresh(True)
         
@@ -526,7 +595,15 @@
         self.cmd     = cmd
         self.params  = None
         self.propWin = None
+        self.id      = -1    # used for gxm file
+        
+        self.data = list()   # list of connected data items
 
+        # colors
+        self.colors = dict()
+        self.colors['valid'] = wx.LIGHT_GREY_BRUSH
+        self.colors['invalid'] = wx.WHITE_BRUSH
+        
         ogl.RectangleShape.__init__(self, width, height)
         
         # self.Draggable(True)
@@ -534,12 +611,20 @@
         self.SetX(x)
         self.SetY(y)
         self.SetPen(wx.BLACK_PEN)
-        self.SetBrush(wx.LIGHT_GREY_BRUSH)
+        self.SetBrush(self.colors['invalid'])
         if self.cmd and len(self.cmd) > 0:
             self.AddText(self.cmd[0])
         else:
             self.AddText('<<module>>')
 
+    def GetId(self):
+        """!Get id"""
+        return self.id
+
+    def SetId(self, id):
+        """!Set id"""
+        self.id = id
+    
     def SetProperties(self, dcmd, params, propwin):
         """!Record properties dialog"""
         self.cmd = dcmd
@@ -575,7 +660,27 @@
         """!Set dictionary of parameters"""
         self.params = params
         self.cmd    = cmd
-    
+
+    def SetValid(self, isvalid):
+        """!Set instance to be valid/invalid"""
+        if isvalid:
+            self.SetBrush(self.colors['valid'])
+        else:
+            self.SetBrush(self.colors['invalid'])
+
+    def AddData(self, item):
+        """!Register new data item"""
+        if item not in self.data:
+            self.data.append(item)
+        
+    def FindData(self, name):
+        """!Find data item by name"""
+        for d in self.data:
+            if d.GetName() == name:
+                return d
+        
+        return None
+
 class ModelData(ogl.EllipseShape):
     """!Data item class"""
     def __init__(self, parent, x, y, name = '', value = '', prompt = '', width = 175, height = 50):
@@ -603,9 +708,13 @@
         
         if name:
             self.AddText(name)
+        else:
+            self.AddText(_('unknown'))
+        
+        if value:
             self.AddText(value)
         else:
-            self.AddText(_('unknown'))
+            self.AddText('\n')
 
     def GetLog(self, string = True):
         """!Get logging info"""
@@ -631,7 +740,10 @@
         self.value = value
         self.ClearText()
         self.AddText(self.name)
-        self.AddText(self.value)
+        if value:
+            self.AddText(self.value)
+        else:
+            self.AddText('\n')
         for direction in ('from', 'to'):
             for action in self.actions[direction]:
                 task = menuform.GUI().ParseCommand(cmd = action.GetLog(string = False),
@@ -921,7 +1033,10 @@
         """!Get node text"""
         p = node.find(tag)
         if p is not None:
-            return utils.normalize_whitespace(p.text)
+            if p.text:
+                return utils.normalize_whitespace(p.text)
+            else:
+                return ''
         
         return default
     
@@ -935,10 +1050,13 @@
                 cmd = self._processTask(task)
             else:
                 cmd = None
+
+            aId = int(action.get('id', -1))
             
             self.actions.append({ 'pos' : pos,
                                   'size': size,
-                                  'cmd' : cmd })
+                                  'cmd' : cmd,
+                                  'id'  : aId })
             
     def _getDim(self, node):
         """!Get position and size of shape"""
@@ -972,14 +1090,14 @@
                 prompt = param.get('prompt', None)
                 value = self._filterValue(self._getNodeText(param, 'value'))
                 
-            action = data.find('action')
-            aId = fromDir = None
-            if action is not None:
-                aId = int(action.get('id', None))
+            aId = list()
+            fromDir = list()
+            for action in data.findall('action'):
+                aId.append(int(action.get('id', None)))
                 if action.get('dir', 'to') == 'to':
-                    fromDir = False
+                    fromDir.append(False)
                 else:
-                    fromDir = True
+                    fromDir.append(True)
             
             self.data.append({ 'pos' : pos,
                                'size': size,
@@ -1048,6 +1166,7 @@
         id = 1
         self.indent += 4
         for action in self.actions:
+            action.SetId(id)
             self.fd.write('%s<action id="%d" name="%s" pos="%d,%d" size="%d,%d">\n' % \
                               (' ' * self.indent, id, action.GetName(), action.GetX(), action.GetY(),
                                action.GetWidth(), action.GetHeight()))
@@ -1096,11 +1215,13 @@
             self.fd.write('%s</parameter>\n' % (' ' * self.indent))
             self.indent -= 4
             for action in data.GetActions('from'):
-                self.fd.write('%s<action id="1" dir="from" />\n' % \
-                                  (' ' * self.indent))
+                id = action.GetId()
+                self.fd.write('%s<action id="%d" dir="from" />\n' % \
+                                  (' ' * self.indent, id))
             for action in data.GetActions('to'):
-                self.fd.write('%s<action id="1" dir="to" />\n' % \
-                                  (' ' * self.indent))
+                id = action.GetId()
+                self.fd.write('%s<action id="%d" dir="to" />\n' % \
+                                  (' ' * self.indent, id))
             
             self.fd.write('%s</data>\n' % (' ' * self.indent))
             

Modified: grass/trunk/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/toolbars.py	2010-04-11 16:46:09 UTC (rev 41805)
+++ grass/trunk/gui/wxpython/gui_modules/toolbars.py	2010-04-11 19:16:32 UTC (rev 41806)
@@ -77,9 +77,10 @@
         if label:
             Debug.msg(3, "CreateTool(): tool=%d, label=%s bitmap=%s" % \
                   (tool, label, bitmap))
+            
             toolWin = self.AddLabelTool(tool, label, bitmap,
-                                           bmpDisabled, kind,
-                                           shortHelp, longHelp)
+                                        bmpDisabled, kind,
+                                        shortHelp, longHelp)
             self.Bind(wx.EVT_TOOL, handler, toolWin)
         else: # separator
             self.AddSeparator()
@@ -1393,6 +1394,7 @@
         self.save = wx.NewId()
         self.action = wx.NewId()
         self.data = wx.NewId()
+        self.relation = wx.NewId()
         self.run = wx.NewId()
         self.validate = wx.NewId()
         self.quit = wx.NewId()
@@ -1415,6 +1417,9 @@
             (self.action, 'action', Icons['modelActionAdd'].GetBitmap(),
              wx.ITEM_NORMAL, Icons['modelActionAdd'].GetLabel(), Icons['modelActionAdd'].GetDesc(),
              self.parent.OnAddAction),
+            (self.relation, 'relation', Icons['modelRelation'].GetBitmap(),
+             wx.ITEM_NORMAL, Icons['modelRelation'].GetLabel(), Icons['modelRelation'].GetDesc(),
+             self.parent.OnDefineRelation),
             ('', '', '', '', '', '', ''),
             (self.run, 'run', Icons['modelRun'].GetBitmap(),
              wx.ITEM_NORMAL, Icons['modelRun'].GetLabel(), Icons['modelRun'].GetDesc(),

Modified: grass/trunk/gui/wxpython/icons/grass2_icons.py
===================================================================
--- grass/trunk/gui/wxpython/icons/grass2_icons.py	2010-04-11 16:46:09 UTC (rev 41805)
+++ grass/trunk/gui/wxpython/icons/grass2_icons.py	2010-04-11 19:16:32 UTC (rev 41806)
@@ -107,7 +107,7 @@
     # modeler
     "modelActionAdd" : 'layer-add.png',
     "modelDataAdd"   : 'map-add.png',
+    "modelRelation"  : 'move.png',
     "modelRun"       : 'redo.png',
     "modelValidate"  : 'tools.png',
-    
     }

Modified: grass/trunk/gui/wxpython/icons/grass_icons.py
===================================================================
--- grass/trunk/gui/wxpython/icons/grass_icons.py	2010-04-11 16:46:09 UTC (rev 41805)
+++ grass/trunk/gui/wxpython/icons/grass_icons.py	2010-04-11 19:16:32 UTC (rev 41806)
@@ -109,7 +109,7 @@
     # modeler
     "modelActionAdd" : wx.ART_ERROR,
     "modelDataAdd"   : wx.ART_ERROR,
+    "modelRelation"  : wx.ART_ERROR,
     "modelRun"       : wx.ART_ERROR,
     "modelValidate"  : wx.ART_ERROR,
-
     }

Modified: grass/trunk/gui/wxpython/icons/icon.py
===================================================================
--- grass/trunk/gui/wxpython/icons/icon.py	2010-04-11 16:46:09 UTC (rev 41805)
+++ grass/trunk/gui/wxpython/icons/icon.py	2010-04-11 19:16:32 UTC (rev 41806)
@@ -347,6 +347,8 @@
                                  label=_("Add action (GRASS module) to model")),
     "modelDataAdd" : MetaIcon (img=Icons["modelDataAdd"],
                                  label=_("Add data item to model")),
+    "modelRelation" : MetaIcon (img=Icons["modelRelation"],
+                                label=_("Define relation between data and action items")),
     "modelRun" : MetaIcon (img=Icons["modelRun"],
                            label=_("Run entire model")),
     "modelValidate" : MetaIcon (img=Icons["modelValidate"],

Modified: grass/trunk/gui/wxpython/icons/silk_icons.py
===================================================================
--- grass/trunk/gui/wxpython/icons/silk_icons.py	2010-04-11 16:46:09 UTC (rev 41805)
+++ grass/trunk/gui/wxpython/icons/silk_icons.py	2010-04-11 19:16:32 UTC (rev 41806)
@@ -110,6 +110,7 @@
     # modeler
     "modelActionAdd" : wx.ART_ERROR,
     "modelDataAdd"   : wx.ART_ERROR,
+    "modelRelation"  : wx.ART_ERROR,
     "modelRun"       : wx.ART_ERROR,
     "modelValidate"  : wx.ART_ERROR,
     }

Modified: grass/trunk/gui/wxpython/xml/menudata_modeler.xml
===================================================================
--- grass/trunk/gui/wxpython/xml/menudata_modeler.xml	2010-04-11 16:46:09 UTC (rev 41805)
+++ grass/trunk/gui/wxpython/xml/menudata_modeler.xml	2010-04-11 19:16:32 UTC (rev 41806)
@@ -56,6 +56,11 @@
 	  <shortcut>Ctrl+A</shortcut>
 	</menuitem>
 	<menuitem>
+	  <label>Define relation</label>
+	  <help>Define relation between data and action items</help>
+	  <handler>OnDefineRelation</handler>
+	</menuitem>
+	<menuitem>
 	  <label>Remove item</label>
 	  <help>Remove action/data from model</help>
 	  <handler>OnRemoveItem</handler>



More information about the grass-commit mailing list