[GRASS-SVN] r42528 - in grass/trunk/gui/wxpython: gui_modules xml
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Jun 8 20:39:34 EDT 2010
Author: martinl
Date: 2010-06-08 20:39:33 -0400 (Tue, 08 Jun 2010)
New Revision: 42528
Modified:
grass/trunk/gui/wxpython/gui_modules/gmodeler.py
grass/trunk/gui/wxpython/gui_modules/vdigit.py
grass/trunk/gui/wxpython/xml/grass-gxm.dtd
Log:
wxGUI/modeler: dialog for managing variables implemented
Modified: grass/trunk/gui/wxpython/gui_modules/gmodeler.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gmodeler.py 2010-06-08 23:58:08 UTC (rev 42527)
+++ grass/trunk/gui/wxpython/gui_modules/gmodeler.py 2010-06-09 00:39:33 UTC (rev 42528)
@@ -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/trunk/gui/wxpython/gui_modules/vdigit.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/vdigit.py 2010-06-08 23:58:08 UTC (rev 42527)
+++ grass/trunk/gui/wxpython/gui_modules/vdigit.py 2010-06-09 00:39:33 UTC (rev 42528)
@@ -16,6 +16,7 @@
- CDisplayDriver
- VDigitSettingsDialog
- VDigitCategoryDialog
+ - CategoryListCtrl
- VDigitZBulkDialog
- VDigitDuplicatesDialog
- VDigitVBuildDialog
Modified: grass/trunk/gui/wxpython/xml/grass-gxm.dtd
===================================================================
--- grass/trunk/gui/wxpython/xml/grass-gxm.dtd 2010-06-08 23:58:08 UTC (rev 42527)
+++ grass/trunk/gui/wxpython/xml/grass-gxm.dtd 2010-06-09 00:39:33 UTC (rev 42528)
@@ -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