[GRASS-SVN] r38973 - in grass/trunk/gui/wxpython: . gui_modules xml
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Sep 4 13:37:06 EDT 2009
Author: martinl
Date: 2009-09-04 13:37:06 -0400 (Fri, 04 Sep 2009)
New Revision: 38973
Modified:
grass/trunk/gui/wxpython/gui_modules/gdialogs.py
grass/trunk/gui/wxpython/gui_modules/help.py
grass/trunk/gui/wxpython/gui_modules/menudata.py
grass/trunk/gui/wxpython/wxgui.py
grass/trunk/gui/wxpython/xml/menudata.xml
Log:
wxGUI: Menu tree window implemnted
Modified: grass/trunk/gui/wxpython/gui_modules/gdialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gdialogs.py 2009-09-04 17:30:26 UTC (rev 38972)
+++ grass/trunk/gui/wxpython/gui_modules/gdialogs.py 2009-09-04 17:37:06 UTC (rev 38973)
@@ -975,7 +975,7 @@
self.SetMinSize((globalvar.DIALOG_GSELECT_SIZE[0] + 175, 300))
width = self.GetSize()[0]
self.list.SetColumnWidth(col=1, width=width/2 - 50)
-
+
def OnCancel(self, event=None):
"""!Close dialog"""
self.Close()
Modified: grass/trunk/gui/wxpython/gui_modules/help.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/help.py 2009-09-04 17:30:26 UTC (rev 38972)
+++ grass/trunk/gui/wxpython/gui_modules/help.py 2009-09-04 17:37:06 UTC (rev 38973)
@@ -7,6 +7,7 @@
Classes:
- HelpWindow
+ - MenuTreeWindow
(C) 2008-2009 by the GRASS Development Team
@@ -18,7 +19,11 @@
"""
import wx
+import wx.lib.customtreectrl as CT
+import menudata
+import gcmd
+
class HelpWindow(wx.Frame):
"""!GRASS Quickstart help window"""
def __init__(self, parent, id, title, size, file):
@@ -43,3 +48,291 @@
# sizer.Fit(self)
# sizer.SetSizeHints(self)
self.Layout()
+
+class MenuTreeWindow(wx.Frame):
+ """!Show menu tree"""
+ def __init__(self, parent, id = wx.ID_ANY, title = _("Menu tree window"), **kwargs):
+ self.parent = parent # LayerManager
+
+ wx.Frame.__init__(self, parent = parent, id = id, title = title, **kwargs)
+
+ self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
+
+ # tree
+ self.tree = MenuTree(parent = self.panel, data = menudata.Data())
+ self.tree.Load()
+
+ self.searchDict = { _('label') : 'label', # i18n workaround
+ _('help') : 'help',
+ _('command') : 'command',
+ _('keywords') : 'keywords' }
+ # search
+ self.searchBy = wx.Choice(parent = self.panel, id = wx.ID_ANY,
+ choices = [_('label'),
+ _('help'),
+ _('command'),
+ _('keywords')])
+ self.search = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
+ value = "", size = (-1, 25),
+ style = wx.TE_PROCESS_ENTER)
+
+ # statusbar
+ self.statusbar = self.CreateStatusBar(number=1)
+
+ # close on run
+ self.closeOnRun = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
+ label = _("Close dialog on run"))
+ self.closeOnRun.SetValue(True)
+
+ # buttons
+ self.btnRun = wx.Button(self.panel, id = wx.ID_OK, label = _("Run"))
+ self.btnRun.SetToolTipString(_("Run selected command"))
+ self.btnRun.Enable(False)
+ self.btnClose = wx.Button(self.panel, id = wx.ID_CLOSE)
+ self.btnClose.SetToolTipString(_("Close dialog"))
+
+ # bindings
+ self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
+ self.btnRun.Bind(wx.EVT_BUTTON, self.OnRun)
+ self.search.Bind(wx.EVT_TEXT_ENTER, self.OnShowItem)
+ self.search.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
+ self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
+ self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnItemSelected)
+
+ self.__Layout()
+
+ self.search.SetFocus()
+
+ def __Layout(self):
+ """!Do dialog layout"""
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ # body
+ dataBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+ label=" %s " % _("Menu tree (double-click to run command)"))
+
+ dataSizer = wx.StaticBoxSizer(dataBox, wx.HORIZONTAL)
+ dataSizer.Add(item = self.tree, proportion =1,
+ flag = wx.EXPAND)
+
+ # search
+ searchSizer = wx.BoxSizer(wx.HORIZONTAL)
+ searchSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+ label = _("Search:")),
+ proportion = 0,
+ flag = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
+ border = 3)
+ searchSizer.Add(item = self.searchBy, proportion = 0,
+ flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT | wx.RIGHT,
+ border = 5)
+ searchSizer.Add(item = self.search, proportion = 1,
+ flag = wx.EXPAND | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
+ border = 5)
+
+ # buttons
+ btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(item = self.btnRun, proportion = 0,
+ flag = wx.LEFT | wx.RIGHT, border = 5)
+ btnSizer.Add(item = self.btnClose, proportion = 0,
+ flag = wx.LEFT | wx.RIGHT, border = 5)
+
+ sizer.Add(item = dataSizer, proportion = 1,
+ flag = wx.EXPAND | wx.ALL, border = 5)
+
+ sizer.Add(item = searchSizer, proportion=0,
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
+
+ sizer.Add(item = btnSizer, proportion=0,
+ flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
+
+ sizer.Add(item = self.closeOnRun, proportion=0,
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
+
+ self.panel.SetAutoLayout(True)
+ self.panel.SetSizer(sizer)
+ sizer.Fit(self.panel)
+
+ self.Layout()
+ self.SetSize((530, 370))
+
+ def OnCloseWindow(self, event):
+ """!Close window"""
+ self.Destroy()
+
+ def OnRun(self, event):
+ """!Run selected command"""
+ if not self.tree.GetSelected():
+ return # should not happen
+
+ data = self.tree.GetPyData(self.tree.GetSelected())
+ if not data or not data.has_key('command'):
+ return
+
+ gcmd.RunCommand(data['command'])
+
+ if self.closeOnRun.IsChecked():
+ self.OnCloseWindow(None)
+
+ def OnItemActivated(self, event):
+ """!Item activated (double-click)"""
+ item = event.GetItem()
+ if not item or not item.IsOk():
+ return
+
+ data = self.tree.GetPyData(item)
+ if not data or not data.has_key('command'):
+ return
+
+ self.tree.itemSelected = item
+
+ self.OnRun(None)
+
+ def OnItemSelected(self, event):
+ """!Item selected"""
+ item = event.GetItem()
+ if not item or not item.IsOk():
+ return
+
+ data = self.tree.GetPyData(item)
+ if not data or not data.has_key('command'):
+ return
+
+ self.statusbar.SetStatusText(data['command'] + ' -- ' + data['help'], 0)
+
+ def OnShowItem(self, event):
+ """!Highlight first found item in menu tree"""
+ if len(self.tree.itemsMarked) > 0:
+ if self.tree.GetSelected():
+ self.tree.ToggleItemSelection(self.tree.GetSelected())
+ idx = self.tree.itemsMarked.index(self.tree.GetSelected()) + 1
+ else:
+ idx = 0
+ try:
+ self.tree.ToggleItemSelection(self.tree.itemsMarked[idx])
+ self.tree.itemSelected = self.tree.itemsMarked[idx]
+ self.tree.EnsureVisible(self.tree.itemsMarked[idx])
+ except IndexError:
+ self.tree.ToggleItemSelection(self.tree.itemsMarked[0]) # reselect first item
+ self.tree.EnsureVisible(self.tree.itemsMarked[0])
+ self.tree.itemSelected = self.tree.itemsMarked[0]
+ else:
+ for item in self.tree.root.GetChildren():
+ self.tree.Collapse(item)
+ itemSelected = self.tree.GetSelection()
+ if itemSelected:
+ self.tree.ToggleItemSelection(itemSelected)
+ self.tree.itemSelected = None
+
+ def OnUpdateStatusBar(self, event):
+ """!Update statusbar text"""
+ element = self.searchDict[self.searchBy.GetStringSelection()]
+ self.tree.itemsMarked = self.SearchItems(element = element,
+ value = event.GetString())
+ self.tree.itemSelected = None
+
+ nItems = len(self.tree.itemsMarked)
+ if event.GetString():
+ self.statusbar.SetStatusText(_("%d items match") % nItems, 0)
+ else:
+ self.statusbar.SetStatusText("", 0)
+
+ if nItems > 0:
+ self.tree.itemSelected = self.tree.itemsMarked[0]
+ self.btnRun.Enable()
+ else:
+ self.btnRun.Enable(False)
+
+ event.Skip()
+
+ def SearchItems(self, element, value):
+ """!Search item
+
+ @param element element index (see self.searchBy)
+ @param value
+
+ @return list of found tree items
+ """
+ items = list()
+ if not value:
+ return items
+
+ item = self.tree.GetFirstChild(self.tree.root)[0]
+ self.__ProcessItem(item, element, value, items)
+
+ return items
+
+ def __ProcessItem(self, item, element, value, listOfItems):
+ """!Search items (used by SearchItems)
+
+ @param item reference item
+ @param listOfItems list of found items
+ """
+ while item and item.IsOk():
+ subItem = self.tree.GetFirstChild(item)[0]
+ if subItem:
+ self.__ProcessItem(subItem, element, value, listOfItems)
+ data = self.tree.GetPyData(item)
+
+ if data and data.has_key(element) and \
+ value.lower() in data[element].lower():
+ listOfItems.append(item)
+
+ item = self.tree.GetNextSibling(item)
+
+class MenuTree(CT.CustomTreeCtrl):
+ """!Menu tree class"""
+ def __init__(self, parent, data, id = wx.ID_ANY,
+ ctstyle = CT.TR_HIDE_ROOT | CT.TR_FULL_ROW_HIGHLIGHT | CT.TR_HAS_BUTTONS | \
+ CT.TR_LINES_AT_ROOT | CT.TR_SINGLE,
+ **kwargs):
+ self.parent = parent
+ self.menudata = data
+
+ super(MenuTree, self).__init__(parent, id, ctstyle = ctstyle, **kwargs)
+
+ self.root = self.AddRoot(_("Menu tree"))
+ self.itemsMarked = [] # list of marked items
+ self.itemSelected = None
+
+ def Load(self, data = None):
+ """!Load menu data tree
+
+ @param data menu data (None to use self.menudata)
+ """
+ if not data:
+ data = self.menudata
+
+ self.itemsMarked = [] # list of marked items
+ for eachMenuData in data.GetMenu():
+ for label, items in eachMenuData:
+ item = self.AppendItem(parentId = self.root,
+ text = label)
+ self.__AppendItems(item, items)
+
+ def __AppendItems(self, item, data):
+ """!Append items into tree (used by Load()
+
+ @param item tree item (parent)
+ @parent data menu data"""
+ for eachItem in data:
+ if len(eachItem) == 2:
+ if eachItem[0]:
+ itemSub = self.AppendItem(parentId = item,
+ text = eachItem[0])
+ self.__AppendItems(itemSub, eachItem[1])
+ else:
+ if eachItem[0]:
+ itemNew = self.AppendItem(parentId = item,
+ text = eachItem[0])
+
+ data = { 'label' : eachItem[0],
+ 'help' : eachItem[1],
+ 'handler' : eachItem[2],
+ 'command' : eachItem[3],
+ 'keywords' : eachItem[4] }
+
+ self.SetPyData(itemNew, data)
+
+ def GetSelected(self):
+ """!Get selected item"""
+ return self.itemSelected
Modified: grass/trunk/gui/wxpython/gui_modules/menudata.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/menudata.py 2009-09-04 17:30:26 UTC (rev 38972)
+++ grass/trunk/gui/wxpython/gui_modules/menudata.py 2009-09-04 17:37:06 UTC (rev 38973)
@@ -5,6 +5,7 @@
Classes:
- Data
+ - MenuTree
(C) 2007-2009 by the GRASS Development Team
This program is free software under the GNU General Public
@@ -33,17 +34,22 @@
def getMenuItem(self, mi):
if mi.tag == 'separator':
- return ('', '', '', '')
+ return ('', '', '', '', '')
elif mi.tag == 'menuitem':
- label = _(mi.find('label').text)
- help = _(mi.find('help').text)
- handler = mi.find('handler').text
- gcmd = mi.find('command')
+ label = _(mi.find('label').text)
+ help = _(mi.find('help').text)
+ handler = mi.find('handler').text
+ gcmd = mi.find('command') # optional
+ keywords = mi.find('keywords') # optional
if gcmd != None:
gcmd = gcmd.text
else:
gcmd = ""
- return (label, help, handler, gcmd)
+ if keywords != None:
+ keywords = keywords.text
+ else:
+ keywords = ""
+ return (label, help, handler, gcmd, keywords)
elif mi.tag == 'menu':
return self.getMenu(mi)
else:
@@ -64,12 +70,40 @@
return self.getMenuData(self.tree.getroot())
def PrintStrings(self, fh):
+ """!Print menu strings to file (used for localization)
+
+ @param fh file descriptor"""
fh.write('menustrings = [\n')
for node in self.tree.getiterator():
if node.tag in ['label', 'help']:
fh.write(' _(%r),\n' % node.text)
fh.write(' \'\']\n')
+ def PrintTree(self, fh):
+ """!Print menu tree to file
+
+ @param fh file descriptor"""
+ level = 0
+ for eachMenuData in self.GetMenu():
+ for label, items in eachMenuData:
+ print >> fh, '-', label
+ self.__PrintTreeItems(fh, level + 1, items)
+
+ def __PrintTreeItems(self, fh, level, menuData):
+ """!Print menu tree items to file (used by PrintTree)
+
+ @param fh file descriptor
+ @param level menu level
+ @param menuData menu data to print out"""
+ for eachItem in menuData:
+ if len(eachItem) == 2:
+ if eachItem[0]:
+ print >> fh, ' ' * level, '-', eachItem[0]
+ self.__PrintTreeItems(fh, level + 1, eachItem[1])
+ else:
+ if eachItem[0]:
+ print >> fh, ' ' * level, '-', eachItem[0]
+
def GetModules(self):
"""!Create dictionary of modules used to search module by
keywords, description, etc."""
@@ -95,9 +129,16 @@
if __name__ == "__main__":
import sys
- if len(sys.argv) < 2:
- sys.exit(1)
+
+ # i18N
+ import gettext
+ gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
- Data(sys.argv[1]).PrintStrings(sys.stdout)
+ if len(sys.argv) > 1:
+ data = Data(sys.argv[1])
+ else:
+ data = Data()
+ data.PrintTree(sys.stdout)
+
sys.exit(0)
Modified: grass/trunk/gui/wxpython/wxgui.py
===================================================================
--- grass/trunk/gui/wxpython/wxgui.py 2009-09-04 17:30:26 UTC (rev 38972)
+++ grass/trunk/gui/wxpython/wxgui.py 2009-09-04 17:37:06 UTC (rev 38973)
@@ -87,8 +87,9 @@
import gui_modules.colorrules as colorrules
import gui_modules.ogc_services as ogc_services
import gui_modules.prompt as prompt
-from gui_modules.debug import Debug as Debug
-from icons.icon import Icons as Icons
+from gui_modules.debug import Debug
+from gui_modules.help import MenuTreeWindow
+from icons.icon import Icons
UserSettings = preferences.globalSettings
@@ -230,7 +231,7 @@
self.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuHighlight)
return menu
- def __createMenuItem(self, menu, label, help, handler, gcmd, kind=wx.ITEM_NORMAL):
+ def __createMenuItem(self, menu, label, help, handler, gcmd, keywords, kind = wx.ITEM_NORMAL):
"""!Creates menu items"""
if not label:
@@ -475,7 +476,13 @@
lchecked=True,
lopacity=1.0,
lcmd=['d.vect', 'map=%s' % name])
-
+
+ def OnMenuTree(self, event):
+ """!Show dialog with menu tree"""
+ dlg = MenuTreeWindow(self)
+ dlg.CentreOnScreen()
+ dlg.Show()
+
def OnAboutGRASS(self, event):
"""!Display 'About GRASS' dialog"""
info = wx.AboutDialogInfo()
Modified: grass/trunk/gui/wxpython/xml/menudata.xml
===================================================================
--- grass/trunk/gui/wxpython/xml/menudata.xml 2009-09-04 17:30:26 UTC (rev 38972)
+++ grass/trunk/gui/wxpython/xml/menudata.xml 2009-09-04 17:37:06 UTC (rev 38973)
@@ -2697,20 +2697,27 @@
<label>Help</label>
<items>
<menuitem>
- <label>GRASS GIS help</label>
- <help>Display the HTML man pages of GRASS</help>
+ <label>GRASS help</label>
+ <help>Display the manual pages of GRASS</help>
<keywords>general,manual,help</keywords>
<handler>self.RunMenuCmd</handler>
<command>g.manual -i</command>
</menuitem>
<menuitem>
- <label>GRASS GIS GUI help</label>
- <help>Display the HTML man pages of GRASS</help>
+ <label>GUI help</label>
+ <help>Display the manual pages of wxGUI</help>
<keywords>general,manual,help</keywords>
<handler>self.RunMenuCmd</handler>
<command>g.manual wxGUI</command>
</menuitem>
+ <separator />
<menuitem>
+ <label>Show menu tree</label>
+ <help>Show menu tree in new window</help>
+ <handler>self.OnMenuTree</handler>
+ </menuitem>
+ <separator />
+ <menuitem>
<label>About GRASS GIS</label>
<help>About GRASS GIS</help>
<handler>self.OnAboutGRASS</handler>
More information about the grass-commit
mailing list