[GRASS-SVN] r42529 - in grass/branches/develbranch_6/gui/wxpython: gui_modules xml

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jun 8 20:42:19 EDT 2010


Author: martinl
Date: 2010-06-08 20:42:19 -0400 (Tue, 08 Jun 2010)
New Revision: 42529

Modified:
   grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
   grass/branches/develbranch_6/gui/wxpython/xml/grass-gxm.dtd
Log:
wxGUI/modeler: dialog for managing variables implemented
(merge r42528 from trunk)


Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py	2010-06-09 00:39:33 UTC (rev 42528)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py	2010-06-09 00:42:19 UTC (rev 42529)
@@ -17,6 +17,8 @@
  - PreferencesDialog
  - PropertiesDialog
  - ModelParamDialog
+ - VariablesDialog
+ - ValiablesListCtrl
 
 (C) 2010 by the GRASS Development Team
 This program is free software under the GNU General Public License
@@ -45,9 +47,10 @@
 if not os.getenv("GRASS_WXBUNDLED"):
     globalvar.CheckForWx()
 import wx
-import wx.lib.ogl          as ogl
-import wx.lib.flatnotebook as FN
-import wx.lib.colourselect as csel
+import wx.lib.ogl             as ogl
+import wx.lib.flatnotebook    as FN
+import wx.lib.colourselect    as csel
+import wx.lib.mixins.listctrl as listmix
 
 import menu
 import menudata
@@ -74,6 +77,8 @@
         self.properties = { 'name'        : _("model"),
                             'description' : _("Script generated by wxGUI Graphical Modeler."),
                             'author'      : getpass.getuser() }
+        # model variables
+        self.variables = dict()
         
         self.canvas  = canvas
         
@@ -88,7 +93,15 @@
     def GetProperties(self):
         """!Get model properties"""
         return self.properties
+
+    def GetVariables(self):
+        """!Get model variables"""
+        return self.variables
     
+    def SetVariables(self, data):
+        """!Set model variables"""
+        self.variables = data
+    
     def GetData(self):
         """!Return list of data"""
         return self.data
@@ -476,8 +489,10 @@
         
     def OnModelVariables(self, event):
         """!Manage (define) model variables"""
-        pass
-    
+        dlg = VariablesDialog(parent = self, data = self.model.GetVariables())
+        dlg.CentreOnParent()
+        dlg.Show()
+        
     def OnDeleteData(self, event):
         """!Delete intermediate data"""
         rast, vect, rast3d, msg = self.model.GetIntermediateData()
@@ -2015,6 +2030,7 @@
         self.data    = list()
         
         self._processProperties()
+        self._processVariables()
         self._processActions()
         self._processData()
         
@@ -2060,7 +2076,11 @@
             self.properties[name] = node.text
         else:
             self.properties[name] = ''
-            
+
+    def _processVariables(self):
+        for node in self.root.findall('variable'):
+            pass
+        
     def _processActions(self):
         """!Process model file"""
         for action in self.root.findall('action'):
@@ -2788,7 +2808,269 @@
         panel = menuform.cmdPanel(parent = self, id = wx.ID_ANY, task = task)
         
         return panel
+
+class VariablesDialog(wx.Dialog, listmix.ColumnSorterMixin):
+    def __init__(self, parent, id = wx.ID_ANY, title = _("Manage model variables"),
+                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+                 data = dict(), **kwargs):
+        """!Manage model variables dialog
     
+        @param parent
+        @param title dialog title
+        @param style
+        """
+        self.parent = parent
+        
+        wx.Dialog.__init__(self, parent = parent, id = id, title = title,
+                           style = style, **kwargs)
+        
+        self.listBox = wx.StaticBox(parent = self, id = wx.ID_ANY,
+                                    label=" %s " % _("List of variables - right-click to delete"))
+
+        self.list = VariablesListCtrl(parent = self, id = wx.ID_ANY,
+                                      style = wx.LC_REPORT | wx.BORDER_NONE |
+                                      wx.LC_SORT_ASCENDING |wx.LC_HRULES |
+                                      wx.LC_VRULES)
+        if data:
+            self.list.Populate(data)
+        
+        # sorter
+        listmix.ColumnSorterMixin.__init__(self, 2)
+
+        # add new category
+        self.addBox = wx.StaticBox(parent = self, id = wx.ID_ANY,
+                                   label = " %s " % _("Add new variable"))
+        self.name = wx.TextCtrl(parent = self, id = wx.ID_ANY, size = (150, -1))
+        wx.CallAfter(self.name.SetFocus)
+        self.type = wx.Choice(parent = self, id = wx.ID_ANY,
+                              choices = [_("integer"),
+                                         _("float"),
+                                         _("string")])
+        self.value = wx.TextCtrl(parent = self, id = wx.ID_ANY, size = (150, -1))
+        self.desc = wx.TextCtrl(parent = self, id = wx.ID_ANY, size = (350, -1))
+        
+        # buttons
+        self.btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL)
+        self.btnCancel.SetToolTipString(_("Ignore changes and close dialog"))
+        self.btnOk = wx.Button(parent = self, id = wx.ID_OK)
+        self.btnOk.SetToolTipString(_("Apply changes and close dialog"))
+        self.btnOk.SetDefault()
+        self.btnAdd = wx.Button(parent = self, id = wx.ID_ADD)
+        self.btnAdd.SetToolTipString(_("Add new variable to the model"))
+        self.btnAdd.Enable(False)
+        
+        # bindings
+        self.btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
+        self.name.Bind(wx.EVT_TEXT, self.OnText)
+        self.value.Bind(wx.EVT_TEXT, self.OnText)
+        self.desc.Bind(wx.EVT_TEXT, self.OnText)
+        self.btnAdd.Bind(wx.EVT_BUTTON, self.OnAdd)
+        
+        # list
+        self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightUp) #wxMSW
+        self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) #wxGTK
+        # self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list)
+        # self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit, self.list)
+        # self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
+        
+        self._layout()
+
+    def _layout(self):
+        """!Layout dialog"""
+        listSizer = wx.StaticBoxSizer(self.listBox, wx.VERTICAL)
+        listSizer.Add(item = self.list, proportion = 1,
+                      flag = wx.EXPAND)
+        
+        addSizer = wx.StaticBoxSizer(self.addBox, wx.VERTICAL)
+        gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+        gridSizer.AddGrowableCol(3)
+        gridSizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
+                                           label = "%s:" % _("Name")),
+                      flag = wx.ALIGN_CENTER_VERTICAL,
+                      pos = (0, 0))
+        gridSizer.Add(item = self.name,
+                      pos = (0, 1))
+        gridSizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
+                                           label = "%s:" % _("Data type")),
+                      flag = wx.ALIGN_CENTER_VERTICAL,
+                      pos = (0, 2))
+        gridSizer.Add(item = self.type,
+                      pos = (0, 3))
+        gridSizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
+                                           label = "%s:" % _("Default value")),
+                      flag = wx.ALIGN_CENTER_VERTICAL,
+                      pos = (1, 0))
+        gridSizer.Add(item = self.value,
+                      pos = (1, 1))
+        gridSizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
+                                           label = "%s:" % _("Description")),
+                      flag = wx.ALIGN_CENTER_VERTICAL,
+                      pos = (2, 0))
+        gridSizer.Add(item = self.desc,
+                      pos = (2, 1), span = (1, 3))
+        addSizer.Add(item = gridSizer)
+        addSizer.Add(item = self.btnAdd, proportion = 0,
+                     flag = wx.TOP | wx.ALIGN_RIGHT, border = 5)
+
+        btnSizer = wx.StdDialogButtonSizer()
+        btnSizer.AddButton(self.btnCancel)
+        btnSizer.AddButton(self.btnOk)
+        btnSizer.Realize()
+
+        mainSizer = wx.BoxSizer(wx.VERTICAL)
+        mainSizer.Add(item = listSizer, proportion = 1,
+                      flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
+        mainSizer.Add(item = addSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALIGN_CENTER |
+                      wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
+        mainSizer.Add(item = btnSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
+        
+        self.SetSizer(mainSizer)
+        mainSizer.Fit(self)
+        self.SetAutoLayout(True)
+        
+        # set min size for dialog
+        self.SetMinSize(self.GetBestSize())
+        
+    def GetListCtrl(self):
+        """!Used by ColumnSorterMixin"""
+        return self.list
+    
+    def OnText(self, event):
+        """!Text entered"""
+        if self.name.GetValue():
+            self.btnAdd.Enable()
+        else:
+            self.btnAdd.Enable(False)
+        
+    def OnAdd(self, event):
+        """!Add new variable to the list"""
+        msg = self.list.Append(self.name.GetValue(),
+                               self.type.GetStringSelection(),
+                               self.value.GetValue(),
+                               self.desc.GetValue())
+        self.name.SetValue('')
+        self.name.SetFocus()
+        
+        if msg:
+            GMessage(parent = self,
+                     message = msg)
+        else:
+            self.type.SetSelection(0)
+            self.value.SetValue('')
+            self.desc.SetValue('')
+        
+    def OnRightUp(self, event):
+        """!Mouse right button up"""
+        if not hasattr(self, "popupID1"):
+            self.popupID1 = wx.NewId()
+            self.popupID2 = wx.NewId()
+            self.popupID3 = wx.NewId()
+            self.Bind(wx.EVT_MENU, self.list.OnRemove,    id = self.popupID1)
+            self.Bind(wx.EVT_MENU, self.list.OnRemoveAll, id = self.popupID2)
+            self.Bind(wx.EVT_MENU, self.OnReload,    id = self.popupID3)
+        
+        # generate popup-menu
+        menu = wx.Menu()
+        menu.Append(self.popupID1, _("Delete selected"))
+        menu.Append(self.popupID2, _("Delete all"))
+        if self.list.GetFirstSelected() == -1:
+            menu.Enable(self.popupID1, False)
+            menu.Enable(self.popupID2, False)
+        
+        menu.AppendSeparator()
+        menu.Append(self.popupID3, _("Reload"))
+        
+        self.PopupMenu(menu)
+        menu.Destroy()
+
+    def OnReload(self, event):
+        """!Reload list of variables"""
+        self.list.Populate(self.parent.GetModel().GetVariables())
+        
+    def OnOK(self, event):
+        """!Store variables to the model"""
+        self.parent.GetModel().SetVariables(self.list.GetData())
+        self.Destroy()
+        
+class VariablesListCtrl(wx.ListCtrl,
+                        listmix.ListCtrlAutoWidthMixin,
+                        listmix.TextEditMixin):
+    def __init__(self, parent, id = wx.ID_ANY, **kwargs):
+        """!List of model variables"""
+        self.parent = parent
+        
+        wx.ListCtrl.__init__(self, parent, id = id, **kwargs)
+        listmix.ListCtrlAutoWidthMixin.__init__(self)
+        listmix.TextEditMixin.__init__(self)
+
+        self.InsertColumn(0, _("Name"))
+        self.InsertColumn(1, _("Data type"))
+        self.InsertColumn(2, _("Default value"))
+        self.InsertColumn(3, _("Description"))
+        for i in range(0, self.GetColumnCount()):
+            self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER)
+        
+        self.itemData  = {} # requested by sorter
+        self.itemCount = 0
+
+    def GetData(self):
+        """!Get list data"""
+        return self.itemData
+    
+    def Populate(self, data):
+        """!Populate the list"""
+        self.itemData = copy.deepcopy(data)
+        self.itemCount = len(self.itemData.keys())
+        self.DeleteAllItems()
+        i = 0
+        for name, vtype, value, desc in self.itemData.itervalues():
+            index = self.InsertStringItem(sys.maxint, name)
+            self.SetStringItem(index, 0, name)
+            self.SetStringItem(index, 1, vtype)
+            self.SetStringItem(index, 2, value)
+            self.SetStringItem(index, 3, desc)
+            self.SetItemData(index, i)
+            i += 1
+        
+    def Append(self, name, vtype, value, desc):
+        """!Append new item to the list
+
+        @return None on success
+        @return error string
+        """
+        for iname, ivtype, ivalue, idesc in self.itemData.itervalues():
+            if iname == name:
+                return _("Variable <%s> already exists in the model. "
+                         "Adding variable failed.") % name
+        
+        index = self.InsertStringItem(sys.maxint, name)
+        self.SetStringItem(index, 0, name)
+        self.SetStringItem(index, 1, vtype)
+        self.SetStringItem(index, 2, value)
+        self.SetStringItem(index, 3, desc)
+        self.SetItemData(index, self.itemCount)
+        
+        self.itemData[self.itemCount] = (name, vtype, value, desc)
+        self.itemCount += 1
+        
+        return None
+
+    def OnRemove(self, event):
+        """!Remove selected variable(s) from the model"""
+        item = self.GetFirstSelected()
+        while item != -1:
+            self.DeleteItem(item)
+            del self.itemData[item]
+            item = self.GetFirstSelected()
+        event.Skip()
+    
+    def OnRemoveAll(self, event):
+        """!Remove all variable(s) from the model"""
+        self.DeleteAllItems()
+        self.itemData = dict()
+    
 def main():
     app = wx.PySimpleApp()
     wx.InitAllImageHandlers()

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2010-06-09 00:39:33 UTC (rev 42528)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2010-06-09 00:42:19 UTC (rev 42529)
@@ -16,6 +16,7 @@
  - CDisplayDriver
  - VDigitSettingsDialog
  - VDigitCategoryDialog
+ - CategoryListCtrl
  - VDigitZBulkDialog
  - VDigitDuplicatesDialog
  - VDigitVBuildDialog

Modified: grass/branches/develbranch_6/gui/wxpython/xml/grass-gxm.dtd
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/xml/grass-gxm.dtd	2010-06-09 00:39:33 UTC (rev 42528)
+++ grass/branches/develbranch_6/gui/wxpython/xml/grass-gxm.dtd	2010-06-09 00:42:19 UTC (rev 42529)
@@ -14,7 +14,7 @@
 
 <!ELEMENT grass-gxm (gxm)>
 
-<!ELEMENT gxm (action*, data*)>
+<!ELEMENT gxm (action*, data*, properties?, variable*)>
 
 <!--    an action defines action properties (usually GRASS modules)
 -->
@@ -80,3 +80,15 @@
 <!ELEMENT point  (x, y)>
 <!ELEMENT x      (#PCDATA)>
 <!ELEMENT y      (#PCDATA)>
+
+<!--	a properties describes model properties
+-->
+<!ELEMENT properties    (name?, description?, author?, flag*)>
+<!ELEMENT name          (#PCDATA)>
+<!ELEMENT description   (#PCDATA)>
+<!ELEMENT author        (#PCDATA)>
+
+<!--	a variable describes model variable
+-->
+<!ELEMENT variable        (name, description?, value?)>
+<!ATTLIST variable  type  (integer | float | string) #REQUIRED>



More information about the grass-commit mailing list