[GRASS-SVN] r58557 - in grass/trunk/gui/wxpython: core gmodeler xml

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Dec 30 03:21:30 PST 2013


Author: martinl
Date: 2013-12-30 03:21:30 -0800 (Mon, 30 Dec 2013)
New Revision: 58557

Modified:
   grass/trunk/gui/wxpython/core/settings.py
   grass/trunk/gui/wxpython/gmodeler/frame.py
   grass/trunk/gui/wxpython/gmodeler/model.py
   grass/trunk/gui/wxpython/gmodeler/preferences.py
   grass/trunk/gui/wxpython/gmodeler/toolbars.py
   grass/trunk/gui/wxpython/xml/menudata_modeler.xml
Log:
wxGUI/modeler: implement new objects to hold comments


Modified: grass/trunk/gui/wxpython/core/settings.py
===================================================================
--- grass/trunk/gui/wxpython/core/settings.py	2013-12-30 10:43:41 UTC (rev 58556)
+++ grass/trunk/gui/wxpython/core/settings.py	2013-12-30 11:21:30 UTC (rev 58557)
@@ -788,6 +788,13 @@
                         'height' : 40,
                         },
                     },
+                'comment' : {
+                    'color' : (255, 233, 208, 255), # light yellow
+                    'size' : {
+                        'width' : 200,
+                        'height' : 100,
+                        },
+                    },
                 },
             'mapswipe' : {
                 'cursor': {

Modified: grass/trunk/gui/wxpython/gmodeler/frame.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/frame.py	2013-12-30 10:43:41 UTC (rev 58556)
+++ grass/trunk/gui/wxpython/gmodeler/frame.py	2013-12-30 11:21:30 UTC (rev 58557)
@@ -713,6 +713,28 @@
         
         self.canvas.Refresh()
 
+    def OnAddComment(self, event):
+        """!Add comment to the model"""
+        dlg = wx.TextEntryDialog(parent = self, message = _("Comment:"), caption = _("Add comment"),
+                                 style = wx.OK | wx.CANCEL | wx.CENTRE | wx.TE_MULTILINE)
+        if dlg.ShowModal() == wx.ID_OK:
+            comment = dlg.GetValue()
+            if not comment:
+                GError(_("Empty comment. Nothing to add to the model."), parent = self)
+            else:
+                x, y = self.canvas.GetNewShapePos()
+                commentObj = ModelComment(self.model, x = x + self._randomShift(), y = y + self._randomShift(),
+                                          id = self.model.GetNextId(), label = comment)
+                self.canvas.diagram.AddShape(commentObj)
+                commentObj.Show(True)
+                self._addEvent(commentObj)
+                self.model.AddItem(commentObj)
+                
+                self.canvas.Refresh()
+                self.ModelChanged()
+        
+        dlg.Destroy()
+        
     def _switchPageHandler(self, event, notification):
         self._switchPage(notification=notification)
         event.Skip()
@@ -870,6 +892,12 @@
             # connect items in the condition
             self.DefineCondition(item)
         
+        # load comments
+        for item in self.model.GetItems(objType = ModelComment):
+            self._addEvent(item)
+            self.canvas.diagram.AddShape(item)
+            item.Show(True)
+        
         # load variables
         self.variablePanel.Update()
         self.itemPanel.Update()

Modified: grass/trunk/gui/wxpython/gmodeler/model.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/model.py	2013-12-30 10:43:41 UTC (rev 58556)
+++ grass/trunk/gui/wxpython/gmodeler/model.py	2013-12-30 11:21:30 UTC (rev 58557)
@@ -12,12 +12,13 @@
  - model::ModelItem
  - model::ModelLoop
  - model::ModelCondition
+ - model::ModelComment
  - model::ProcessModelFile
  - model::WriteModelFile
  - model::WritePythonFile
  - model::ModelParamDialog
 
-(C) 2010-2012 by the GRASS Development Team
+(C) 2010-2013 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.
@@ -296,7 +297,7 @@
         self.properties = gxmXml.properties
         self.variables  = gxmXml.variables
         
-        # load model.GetActions()
+        # load actions
         for action in gxmXml.actions:
             actionItem = ModelAction(parent = self, 
                                      x = action['pos'][0],
@@ -311,11 +312,11 @@
             if action['disabled']:
                 actionItem.Enable(False)
             
-            self.AddItem(actionItem)
+            self.AddItem(actionItem, pos = actionItem.GetId()-1)
             
             actionItem.SetValid(actionItem.GetTask().get_options())
             actionItem.GetLog() # substitute variables (-> valid/invalid)
-        
+
         # load data & relations
         for data in gxmXml.data:
             dataItem = ModelData(parent = self, 
@@ -329,6 +330,7 @@
             
             for rel in data['rels']:
                 actionItem = self.FindAction(rel['id'])
+                
                 if rel['dir'] == 'from':
                     relation = ModelRelation(parent = self, fromShape = dataItem,
                                              toShape = actionItem, param = rel['name'])
@@ -351,7 +353,7 @@
                                  height = loop['size'][1],
                                  label = loop['text'],
                                  id = loop['id'])
-            self.AddItem(loopItem)
+            self.AddItem(loopItem, pos = loopItem.GetId()-1)
         
         # load conditions
         for condition in gxmXml.conditions:
@@ -362,7 +364,7 @@
                                            height = condition['size'][1],
                                            label = condition['text'],
                                            id = condition['id'])
-            self.AddItem(conditionItem)
+            self.AddItem(conditionItem, pos = conditionItem.GetId()-1)
 
         # define loops & if/else items
         for loop in gxmXml.loops:
@@ -385,6 +387,18 @@
             for b in items.keys():
                 for action in items[b]:
                     action.SetBlock(conditionItem)
+
+        # load comments
+        for comment in gxmXml.comments:
+            commentItem = ModelComment(parent = self, 
+                                       x = comment['pos'][0],
+                                       y = comment['pos'][1],
+                                       width = comment['size'][0],
+                                       height = comment['size'][1],
+                                       id = comment['id'],
+                                       label = comment['text'])
+            
+            self.AddItem(commentItem, pos = commentItem.GetId()-1)
         
     def AddItem(self, newItem, pos = -1):
         """!Add item to the list"""
@@ -392,10 +406,10 @@
             self.items.insert(pos, newItem)
         else:
             self.items.append(newItem)
-        i = 1
-        for item in self.items:
-            item.SetId(i)
-            i += 1
+        # i = 1
+        # for item in self.items:
+        #     item.SetId(i)
+        #     i += 1
         
     def IsValid(self):
         """Return True if model is valid"""
@@ -912,7 +926,7 @@
         self.parent  = parent
         self.task    = task
         self.comment = comment
-
+        
         if not width:
             width = UserSettings.Get(group='modeler', key='action', subkey=('size', 'width'))
         if not height:
@@ -939,10 +953,8 @@
             self.SetCanvas(self.parent)
             self.SetX(x)
             self.SetY(y)
-            self.SetPen(wx.BLACK_PEN)
             self._setPen()
             self._setBrush()
-            self.SetId(id)
             self.SetLabel(label)
 
         if self.task:
@@ -974,8 +986,7 @@
         else:
             width = int(UserSettings.Get(group='modeler', key='action',
                                          subkey=('width', 'default')))
-        pen = self.GetPen()
-        pen.SetWidth(width)
+        pen = wx.Pen(wx.BLACK, width, wx.SOLID)
         self.SetPen(pen)
 
     def SetLabel(self, label=None):
@@ -1202,12 +1213,9 @@
         self.intermediate = im
   
     def OnDraw(self, dc):
-        pen = self.GetPen()
-        pen.SetWidth(1)
+        pen = wx.Pen(wx.BLACK, 1, wx.SOLID)
         if self.intermediate:
             pen.SetStyle(wx.SHORT_DASH)
-        else:
-            pen.SetStyle(wx.SOLID)
         self.SetPen(pen)
         
         ogl.EllipseShape.OnDraw(self, dc)
@@ -1307,8 +1315,8 @@
         else:
             width = int(UserSettings.Get(group = 'modeler', key = 'action',
                                          subkey = ('width', 'default')))
-        pen = self.GetPen()
-        pen.SetWidth(width)
+            
+        pen = wx.Pen(wx.BLACK, width, wx.SOLID)
         self.SetPen(pen)
         
     def SetLabel(self):
@@ -1389,9 +1397,7 @@
     
     def _setPen(self):
         """!Set pen"""
-        pen = self.GetPen()
-        pen.SetWidth(1)
-        pen.SetStyle(wx.SOLID)
+        pen = wx.Pen(wx.BLACK, 1, wx.SOLID)
         self.SetPen(pen)
         
     def OnDraw(self, dc):
@@ -1565,6 +1571,53 @@
         if branch in ['if', 'else']:
             self.itemIds[branch] = items
 
+class ModelComment(ModelObject, ogl.RectangleShape):
+    def __init__(self, parent, x, y, id = -1, width = None, height = None, label = ''):
+        """!Defines a model comment"""
+        ModelObject.__init__(self, id, label)
+
+        if not width:
+            width = UserSettings.Get(group='modeler', key='comment', subkey=('size', 'width'))
+        if not height:
+            height = UserSettings.Get(group='modeler', key='comment', subkey=('size', 'height'))
+        
+        if parent.GetCanvas():
+            ogl.RectangleShape.__init__(self, width, height)
+            self.SetCanvas(parent)
+            self.SetX(x)
+            self.SetY(y)
+            self._setPen()
+            self._setBrush()
+            self.SetLabel(label)
+
+    def _setBrush(self, running = False):
+        """!Set brush"""
+        color = UserSettings.Get(group='modeler', key='comment',
+                                     subkey='color')
+        wxColor = wx.Colour(color[0], color[1], color[2])
+        self.SetBrush(wx.Brush(wxColor))
+
+    def _setPen(self):
+        """!Set pen"""
+        pen = wx.Pen(wx.BLACK, 1, wx.DOT)
+        self.SetPen(pen)
+
+    def SetLabel(self, label=None):
+        """!Set label
+
+        @param label if None use command string instead
+        """
+        if label:
+            self.label = label 
+        elif self.label:
+            label = self.label
+        else:
+            label = ''
+        idx = self.GetId()
+        
+        self.ClearText()
+        self.AddText('(%d) %s' % (idx, label))
+
 class ProcessModelFile:
     """!Process GRASS model file (gxm)"""
     def __init__(self, tree):
@@ -1581,7 +1634,8 @@
         self.data    = list()
         self.loops   = list()
         self.conditions = list()
-        
+        self.comments = list()
+
         self._processWindow()
         self._processProperties()
         self._processVariables()
@@ -1664,7 +1718,8 @@
         self._processActions()
         self._processLoops()
         self._processConditions()
-        
+        self._processComments()
+
     def _processActions(self):
         """!Process model file"""
         for action in self.root.findall('action'):
@@ -1694,7 +1749,7 @@
                                   'disabled' : disabled,
                                   'label'    : label,
                                   'comment'  : commentString})
-            
+
     def _getDim(self, node):
         """!Get position and size of shape"""
         pos = size = None
@@ -1837,6 +1892,18 @@
                                      'text'    : text,
                                      'id'      : int(node.get('id', -1)),
                                      'items'   : aid })
+
+    def _processComments(self):
+        """!Process model comments"""
+        for node in self.root.findall('comment'):
+            pos, size = self._getDim(node)
+            text = self._filterValue(node.text)
+
+            self.comments.append({ 'pos'     : pos,
+                                   'size'    : size,
+                                   'text'    : text,
+                                   'id'      : int(node.get('id', -1)),
+                                   'text'    : text })
         
 class WriteModelFile:
     """!Generic class for writing model file"""
@@ -1947,6 +2014,8 @@
                 self._loop(item)
             elif isinstance(item, ModelCondition):
                 self._condition(item)
+            elif isinstance(item, ModelComment):
+                self._comment(item)
         
     def _action(self, action):
         """!Write actions"""
@@ -2076,6 +2145,12 @@
         
         self.indent -= 4
         self.fd.write('%s</if-else>\n' % (' ' * self.indent))
+
+    def _comment(self, comment):
+        """!Write comment"""
+        self.fd.write('%s<comment id="%d" pos="%d,%d" size="%d,%d">%s</comment>\n' % \
+                          (' ' * self.indent, comment.GetId(), comment.GetX(), comment.GetY(),
+                           comment.GetWidth(), comment.GetHeight(), EncodeString(comment.GetLabel())))
         
 class WritePythonFile:
     def __init__(self, fd, model):
@@ -2192,7 +2267,7 @@
                 for action in item.GetItems(self.model.GetItems(objType=ModelAction)):
                     self._writePythonItem(action, ignoreBlock = False, variables = [condVar])
                 self.indent -= 4
-            else: # ModelCondition
+            if isinstance(item, ModelCondition):
                 self.fd.write('%sif %s:\n' % (' ' * self.indent, cond))
                 self.indent += 4
                 condItems = item.GetItems()
@@ -2205,6 +2280,8 @@
                     for action in condItems['else']:
                         self._writePythonItem(action, ignoreBlock = False)
                 self.indent += 4
+        if isinstance(item, ModelComment):
+            self._writePythonComment(item)
         
     def _writePythonAction(self, item, variables = []):
         """!Write model action to Python file"""
@@ -2252,6 +2329,11 @@
         
         return ret
 
+    def _writePythonComment(self, item):
+        """!Write model comment to Python file"""
+        for line in item.GetLabel().splitlines():
+            self.fd.write('#' + line + '\n')
+
 class ModelParamDialog(wx.Dialog):
     def __init__(self, parent, params, id = wx.ID_ANY, title = _("Model parameters"),
                  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):

Modified: grass/trunk/gui/wxpython/gmodeler/preferences.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/preferences.py	2013-12-30 10:43:41 UTC (rev 58556)
+++ grass/trunk/gui/wxpython/gmodeler/preferences.py	2013-12-30 11:21:30 UTC (rev 58557)
@@ -7,7 +7,7 @@
  - preferences::PreferencesDialog
  - preferences::PropertiesDialog
 
-(C) 2010-2012 by the GRASS Development Team
+(C) 2010-2013 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.
@@ -36,6 +36,7 @@
         self._createActionPage(self.notebook)
         self._createDataPage(self.notebook)
         self._createLoopPage(self.notebook)
+        self._createCommentPage(self.notebook)
         
         self.SetMinSize(self.GetBestSize())
         self.SetSize(self.size)
@@ -81,7 +82,7 @@
     def _createActionPage(self, notebook):
         """!Create notebook page for action settings"""
         panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
-        notebook.AddPage(page = panel, text = _("Action"))
+        notebook.AddPage(page = panel, text = _("Command"))
         
         # colors
         border = wx.BoxSizer(wx.VERTICAL)
@@ -401,6 +402,91 @@
         
         return panel
 
+    def _createCommentPage(self, notebook):
+        """!Create notebook page for comment settings"""
+        panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+        notebook.AddPage(page = panel, text = _("Comment"))
+        
+        # colors
+        border = wx.BoxSizer(wx.VERTICAL)
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+                              label = " %s " % _("Color"))
+        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        
+        gridSizer = wx.GridBagSizer (hgap = 3, vgap = 3)
+        
+        row = 0
+        gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+                                         label = _("Valid:")),
+                      flag = wx.ALIGN_LEFT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos = (row, 0))
+        vColor = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
+                                   colour = self.settings.Get(group='modeler', key='comment', subkey='color'),
+                                   size = globalvar.DIALOG_COLOR_SIZE)
+        vColor.SetName('GetColour')
+        self.winId['modeler:comment:color'] = vColor.GetId()
+        
+        gridSizer.Add(item = vColor,
+                      flag = wx.ALIGN_RIGHT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos = (row, 1))
+        
+        gridSizer.AddGrowableCol(0)
+        sizer.Add(item = gridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
+        border.Add(item = sizer, proportion = 0, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
+        
+        # size
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+                              label = " %s " % _("Shape size"))
+        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        
+        gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
+
+        row = 0
+        gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+                                         label = _("Width:")),
+                      flag = wx.ALIGN_LEFT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos = (row, 0))
+        
+        width = wx.SpinCtrl(parent = panel, id = wx.ID_ANY,
+                            min = 0, max = 500,
+                            initial = self.settings.Get(group='modeler', key='comment', subkey=('size', 'width')))
+        width.SetName('GetValue')
+        self.winId['modeler:comment:size:width'] = width.GetId()
+        
+        gridSizer.Add(item = width,
+                      flag = wx.ALIGN_RIGHT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos = (row, 1))
+
+        row += 1
+        gridSizer.Add(item = wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Height:")),
+                      flag = wx.ALIGN_LEFT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos=(row, 0))
+        
+        height = wx.SpinCtrl(parent = panel, id = wx.ID_ANY,
+                             min = 0, max = 500,
+                             initial = self.settings.Get(group='modeler', key='comment', subkey=('size', 'height')))
+        height.SetName('GetValue')
+        self.winId['modeler:comment:size:height'] = height.GetId()
+        
+        gridSizer.Add(item = height,
+                      flag = wx.ALIGN_RIGHT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos = (row, 1))
+        
+        gridSizer.AddGrowableCol(0)
+        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
+        border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
+                
+        panel.SetSizer(border)
+        
+        return panel
+
     def OnApply(self, event):
         """!Button 'Apply' pressed"""
         PreferencesBaseDialog.OnApply(self, event)

Modified: grass/trunk/gui/wxpython/gmodeler/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/toolbars.py	2013-12-30 10:43:41 UTC (rev 58556)
+++ grass/trunk/gui/wxpython/gmodeler/toolbars.py	2013-12-30 11:21:30 UTC (rev 58557)
@@ -56,7 +56,9 @@
             'relation'   : MetaIcon(img = 'relation-create',
                                     label = _('Manually define relation between data and commands')),
             'loop'       : MetaIcon(img = 'loop-add',
-                                    label = _('Add loop/series')),
+                                    label = _('Add loop/series to model')),
+            'comment'    : MetaIcon(img = 'label-add',
+                                    label = _('Add comment to model')),
             'run'        : MetaIcon(img = 'execute',
                                     label = _('Run model')),
             'validate'   : MetaIcon(img = 'check',
@@ -90,6 +92,8 @@
                                       self.parent.OnDefineRelation),
                                      ('loop', icons['loop'],
                                       self.parent.OnDefineLoop),
+                                     ('comment', icons['comment'],
+                                      self.parent.OnAddComment),
                                      (None, ),
                                      ('redraw', icons['redraw'],
                                       self.parent.OnCanvasRefresh),

Modified: grass/trunk/gui/wxpython/xml/menudata_modeler.xml
===================================================================
--- grass/trunk/gui/wxpython/xml/menudata_modeler.xml	2013-12-30 10:43:41 UTC (rev 58556)
+++ grass/trunk/gui/wxpython/xml/menudata_modeler.xml	2013-12-30 11:21:30 UTC (rev 58557)
@@ -95,6 +95,12 @@
 	  <shortcut>Ctrl+I</shortcut>
 	</menuitem>
 	<menuitem>
+	  <label>Add comment</label>
+	  <help>Adds comment to model</help>
+	  <handler>OnAddComment</handler>
+	  <shortcut>Ctrl+#</shortcut>
+	</menuitem>
+	<menuitem>
 	  <label>Remove item</label>
 	  <help>Remove action/data from model</help>
 	  <handler>OnRemoveItem</handler>



More information about the grass-commit mailing list