[GRASS-SVN] r42204 - grass/trunk/gui/wxpython/gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon May 10 05:01:04 EDT 2010
Author: martinl
Date: 2010-05-10 05:01:04 -0400 (Mon, 10 May 2010)
New Revision: 42204
Added:
grass/trunk/gui/wxpython/gui_modules/ghelp.py
Removed:
grass/trunk/gui/wxpython/gui_modules/help.py
Modified:
grass/trunk/gui/wxpython/gui_modules/__init__.py
grass/trunk/gui/wxpython/gui_modules/gmodeler.py
grass/trunk/gui/wxpython/gui_modules/goutput.py
Log:
wxGUI: improve SearchModuleWindow
Modified: grass/trunk/gui/wxpython/gui_modules/__init__.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/__init__.py 2010-05-09 21:06:48 UTC (rev 42203)
+++ grass/trunk/gui/wxpython/gui_modules/__init__.py 2010-05-10 09:01:04 UTC (rev 42204)
@@ -8,6 +8,7 @@
"gcmd.py",
"gdialogs.py",
"georect.py",
+ "ghelp.py"
"globalvar.py",
"goutput.py",
"gselect.py",
Copied: grass/trunk/gui/wxpython/gui_modules/ghelp.py (from rev 42181, grass/trunk/gui/wxpython/gui_modules/help.py)
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/ghelp.py (rev 0)
+++ grass/trunk/gui/wxpython/gui_modules/ghelp.py 2010-05-10 09:01:04 UTC (rev 42204)
@@ -0,0 +1,994 @@
+"""!
+ at package help.py
+
+ at brief Help window
+
+Classes:
+ - HelpWindow
+ - SearchModuleWindow
+ - ItemTree
+ - MenuTreeWindow
+ - MenuTree
+ - AboutWindow
+ - InstallExtensionWindow
+ - ExtensionTree
+
+(C) 2008-2010 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.
+
+ at author Martin Landa <landa.martin gmail.com>
+"""
+
+import os
+
+import wx
+try:
+ import wx.lib.agw.customtreectrl as CT
+# import wx.lib.agw.hyperlink as hl
+except ImportError:
+ import wx.lib.customtreectrl as CT
+# import wx.lib.hyperlink as hl
+import wx.lib.flatnotebook as FN
+import wx.lib.scrolledpanel as scrolled
+
+import menudata
+import gcmd
+import globalvar
+import menuform
+
+class HelpWindow(wx.Frame):
+ """!GRASS Quickstart help window"""
+ def __init__(self, parent, id, title, size, file):
+
+ wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ # text
+ helpFrame = wx.html.HtmlWindow(parent=self, id=wx.ID_ANY)
+ helpFrame.SetStandardFonts (size = 10)
+ helpFrame.SetBorders(10)
+ wx.InitAllImageHandlers()
+
+ helpFrame.LoadFile(file)
+ self.Ok = True
+
+ sizer.Add(item=helpFrame, proportion=1, flag=wx.EXPAND)
+
+ self.SetAutoLayout(True)
+ self.SetSizer(sizer)
+ # sizer.Fit(self)
+ # sizer.SetSizeHints(self)
+ self.Layout()
+
+class SearchModuleWindow(wx.Panel):
+ """!Search module window (used in MenuTreeWindow)"""
+ def __init__(self, parent, id = wx.ID_ANY, cmdPrompt = None, showChoice = True, **kwargs):
+ self.showChoice = showChoice
+ self.cmdPrompt = cmdPrompt
+
+ wx.Panel.__init__(self, parent = parent, id = id, **kwargs)
+
+ self._searchDict = { _('description') : 'description',
+ _('command') : 'command',
+ _('keywords') : 'keywords' }
+
+ self.box = wx.StaticBox(parent = self, id = wx.ID_ANY,
+ label=" %s " % _("Find module(s)"))
+
+ self.searchBy = wx.Choice(parent = self, id = wx.ID_ANY,
+ choices = [_('description'),
+ _('keywords'),
+ _('command')])
+ self.searchBy.SetSelection(0)
+
+ self.search = wx.TextCtrl(parent = self, id = wx.ID_ANY,
+ value = "", size = (-1, 25),
+ style = wx.TE_PROCESS_ENTER)
+ self.search.Bind(wx.EVT_TEXT, self.OnSearchModule)
+
+ if self.showChoice:
+ self.searchTip = menuform.StaticWrapText(parent = self, id = wx.ID_ANY,
+ size = (-1, 35))
+
+ self.searchChoice = wx.Choice(parent = self, id = wx.ID_ANY)
+ self.searchChoice.Bind(wx.EVT_CHOICE, self.OnSelectModule)
+
+ self._layout()
+
+ def _layout(self):
+ """!Do layout"""
+ sizer = wx.StaticBoxSizer(self.box, wx.HORIZONTAL)
+ gridSizer = wx.GridBagSizer(hgap = 3, vgap = 3)
+ gridSizer.AddGrowableCol(1)
+
+ gridSizer.Add(item = self.searchBy,
+ flag=wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
+ gridSizer.Add(item = self.search,
+ flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, pos = (0, 1))
+ if self.showChoice:
+ gridSizer.Add(item = self.searchTip,
+ flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, pos = (1, 0), span = (1, 2))
+ gridSizer.Add(item = self.searchChoice,
+ flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, pos = (2, 0), span = (1, 2))
+
+ sizer.Add(item = gridSizer, proportion = 1)
+
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+
+ def GetSelection(self):
+ """!Get selected element"""
+ selection = self.searchBy.GetStringSelection()
+
+ return self._searchDict[selection]
+
+ def SetSelection(self, i):
+ """!Set selection element"""
+ self.searchBy.SetSelection(i)
+
+ def OnSearchModule(self, event):
+ """!Search module by keywords or description"""
+ if not self.cmdPrompt:
+ event.Skip()
+ return
+
+ text = event.GetString()
+ if not text:
+ self.cmdPrompt.SetFilter(None)
+ return
+
+ modules = dict()
+ iFound = 0
+ for module, data in self.cmdPrompt.moduleDesc.iteritems():
+ found = False
+ if self.searchBy.GetSelection() == 0: # -> description
+ if text in data['desc']:
+ found = True
+ else: # -> keywords
+ if self.cmdPrompt.CheckKey(text, data['keywords']):
+ found = True
+
+ if found:
+ iFound += 1
+ try:
+ group, name = module.split('.')
+ except ValueError:
+ continue # TODO
+
+ if not modules.has_key(group):
+ modules[group] = list()
+ modules[group].append(name)
+
+ self.cmdPrompt.SetFilter(modules)
+ self.searchTip.SetLabel(_("%d modules found") % iFound)
+ self.searchChoice.SetItems(self.cmdPrompt.GetCommandItems())
+
+ def OnSelectModule(self, event):
+ """!Module selected from choice, update command prompt"""
+ cmd = event.GetString().split(' ', 1)[0]
+ text = cmd + ' '
+ pos = len(text)
+
+ if self.cmdPrompt:
+ self.cmdPrompt.SetText(text)
+ self.cmdPrompt.SetSelectionStart(pos)
+ self.cmdPrompt.SetCurrentPos(pos)
+ self.cmdPrompt.SetFocus()
+
+ desc = self.cmdPrompt.GetCommandDesc(cmd)
+ self.searchTip.SetLabel(desc)
+
+class MenuTreeWindow(wx.Panel):
+ """!Show menu tree"""
+ def __init__(self, parent, id = wx.ID_ANY, **kwargs):
+ self.parent = parent # LayerManager
+
+ wx.Panel.__init__(self, parent = parent, id = id, **kwargs)
+
+ self.dataBox = wx.StaticBox(parent = self, id = wx.ID_ANY,
+ label=" %s " % _("Menu tree (double-click to run command)"))
+ # tree
+ self.tree = MenuTree(parent = self, data = menudata.ManagerData())
+ self.tree.Load()
+
+ # search widget
+ self.search = SearchModuleWindow(parent = self, showChoice = False)
+
+ # buttons
+ self.btnRun = wx.Button(self, id = wx.ID_OK, label = _("Run"))
+ self.btnRun.SetToolTipString(_("Run selected command"))
+ self.btnRun.Enable(False)
+
+ # bindings
+ self.btnRun.Bind(wx.EVT_BUTTON, self.OnRun)
+ self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
+ self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnItemSelected)
+ self.search.Bind(wx.EVT_TEXT_ENTER, self.OnShowItem)
+ self.search.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
+
+ self._layout()
+
+ self.search.SetFocus()
+
+ def _layout(self):
+ """!Do dialog layout"""
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ # body
+ dataSizer = wx.StaticBoxSizer(self.dataBox, wx.HORIZONTAL)
+ dataSizer.Add(item = self.tree, proportion =1,
+ flag = wx.EXPAND)
+
+ # buttons
+ btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(item = self.btnRun, 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 = self.search, 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.Fit(self)
+ sizer.SetSizeHints(self)
+
+ self.SetSizer(sizer)
+
+ self.Fit()
+ self.SetAutoLayout(True)
+ self.Layout()
+
+ 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:
+ return
+
+ handler = 'self.parent.' + data['handler'].lstrip('self.')
+ if data['handler'] == 'self.OnXTerm':
+ wx.MessageBox(parent = self,
+ message = _('You must run this command from the menu or command line',
+ 'This command require an XTerm'),
+ caption = _('Message'), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+ elif data['command']:
+ eval(handler)(event = None, cmd = data['command'].split())
+ else:
+ eval(handler)(None)
+
+ def OnShowItem(self, event):
+ """!Show selected item"""
+ self.tree.OnShowItem(event)
+ if self.tree.GetSelected():
+ self.btnRun.Enable()
+ else:
+ self.btnRun.Enable(False)
+
+ 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
+
+ if data['command']:
+ label = data['command'] + ' -- ' + data['description']
+ else:
+ label = data['description']
+
+ self.parent.SetStatusText(label, 0)
+
+ def OnUpdateStatusBar(self, event):
+ """!Update statusbar text"""
+ element = self.search.GetSelection()
+ self.tree.SearchItems(element = element,
+ value = event.GetString())
+
+ nItems = len(self.tree.itemsMarked)
+ if event.GetString():
+ self.parent.SetStatusText(_("%d items match") % nItems, 0)
+ else:
+ self.parent.SetStatusText("", 0)
+
+ event.Skip()
+
+class ItemTree(CT.CustomTreeCtrl):
+ def __init__(self, parent, 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):
+ super(ItemTree, self).__init__(parent, id, ctstyle = ctstyle, **kwargs)
+
+ self.root = self.AddRoot(_("Menu tree"))
+ self.itemsMarked = [] # list of marked items
+ self.itemSelected = None
+
+ 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.GetFirstChild(self.root)[0]
+ self._processItem(item, element, value, items)
+
+ self.itemsMarked = items
+ self.itemSelected = None
+
+ 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.GetFirstChild(item)[0]
+ if subItem:
+ self._processItem(subItem, element, value, listOfItems)
+ data = self.GetPyData(item)
+
+ if data and data.has_key(element) and \
+ value.lower() in data[element].lower():
+ listOfItems.append(item)
+
+ item = self.GetNextSibling(item)
+
+ def GetSelected(self):
+ """!Get selected item"""
+ return self.itemSelected
+
+ def OnShowItem(self, event):
+ """!Highlight first found item in menu tree"""
+ if len(self.itemsMarked) > 0:
+ if self.GetSelected():
+ self.ToggleItemSelection(self.GetSelected())
+ idx = self.itemsMarked.index(self.GetSelected()) + 1
+ else:
+ idx = 0
+ try:
+ self.ToggleItemSelection(self.itemsMarked[idx])
+ self.itemSelected = self.itemsMarked[idx]
+ self.EnsureVisible(self.itemsMarked[idx])
+ except IndexError:
+ self.ToggleItemSelection(self.itemsMarked[0]) # reselect first item
+ self.EnsureVisible(self.itemsMarked[0])
+ self.itemSelected = self.itemsMarked[0]
+ else:
+ for item in self.root.GetChildren():
+ self.Collapse(item)
+ itemSelected = self.GetSelection()
+ if itemSelected:
+ self.ToggleItemSelection(itemSelected)
+ self.itemSelected = None
+
+class MenuTree(ItemTree):
+ """!Menu tree class"""
+ def __init__(self, parent, data, **kwargs):
+ self.parent = parent
+ self.menudata = data
+
+ super(MenuTree, self).__init__(parent, **kwargs)
+
+ 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.replace('&', ''))
+ 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 = { 'item' : eachItem[0],
+ 'description' : eachItem[1],
+ 'handler' : eachItem[2],
+ 'command' : eachItem[3],
+ 'keywords' : eachItem[4] }
+
+ self.SetPyData(itemNew, data)
+
+class AboutWindow(wx.Frame):
+ def __init__(self, parent):
+ """!Create custom About Window
+
+ @todo improve styling
+ """
+ wx.Frame.__init__(self, parent=parent, id=wx.ID_ANY, size=(550,400),
+ title=_('About GRASS GIS'))
+
+ panel = wx.Panel(parent = self, id = wx.ID_ANY)
+
+ # icon
+ self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
+
+ # get version and web site
+ version, svn_gis_h_rev, svn_gis_h_date = gcmd.RunCommand('g.version',
+ flags = 'r',
+ read = True).splitlines()
+
+ infoTxt = wx.Panel(parent = panel, id = wx.ID_ANY)
+ infoSizer = wx.BoxSizer(wx.VERTICAL)
+ infoGridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+ infoGridSizer.AddGrowableCol(0)
+ infoGridSizer.AddGrowableCol(1)
+ logo = os.path.join(globalvar.ETCDIR, "gui", "icons", "grass.ico")
+ logoBitmap = wx.StaticBitmap(parent = infoTxt, id = wx.ID_ANY,
+ bitmap = wx.Bitmap(name = logo,
+ type = wx.BITMAP_TYPE_ICO))
+ infoSizer.Add(item = logoBitmap, proportion = 0,
+ flag = wx.ALL | wx.ALIGN_CENTER, border = 25)
+
+ info = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
+ label = version.replace('GRASS', 'GRASS GIS').strip() + '\n\n')
+ info.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
+ infoSizer.Add(item = info, proportion = 0,
+ flag = wx.BOTTOM | wx.ALIGN_CENTER, border = 15)
+
+ infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
+ label = _('Official GRASS site:')),
+ pos = (0, 0),
+ flag = wx.ALIGN_RIGHT)
+
+ infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
+ label = 'http://grass.osgeo.org'),
+ pos = (0, 1),
+ flag = wx.ALIGN_LEFT)
+
+ # infoGridSizer.Add(item = hl.HyperLinkCtrl(parent = self, id = wx.ID_ANY,
+ # label = 'http://grass.osgeo.org',
+ # URL = 'http://grass.osgeo.org'),
+ # pos = (0, 1),
+ # flag = wx.LEFT)
+
+ infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
+ label = _('GIS Library Revision:')),
+ pos = (2, 0),
+ flag = wx.ALIGN_RIGHT)
+
+ infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
+ label = svn_gis_h_rev.split(' ')[1] + ' (' +
+ svn_gis_h_date.split(' ')[1] + ')'),
+ pos = (2, 1),
+ flag = wx.ALIGN_LEFT)
+
+ infoSizer.Add(item = infoGridSizer,
+ proportion = 1,
+ flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL,
+ border = 25)
+
+ #
+ # create pages
+ #
+ copyrightwin = self.PageCopyright()
+ licensewin = self.PageLicense()
+ authorwin = self.PageCredit()
+ contribwin = self.PageContributors()
+ transwin = self.PageTranslators()
+
+ # create a flat notebook for displaying information about GRASS
+ nbstyle = FN.FNB_VC8 | \
+ FN.FNB_BACKGROUND_GRADIENT | \
+ FN.FNB_TABS_BORDER_SIMPLE | \
+ FN.FNB_NO_X_BUTTON
+
+ aboutNotebook = FN.FlatNotebook(panel, id=wx.ID_ANY, style=nbstyle)
+ aboutNotebook.SetTabAreaColour(globalvar.FNPageColor)
+
+ # make pages for About GRASS notebook
+ pg1 = aboutNotebook.AddPage(infoTxt, text=_("Info"))
+ pg2 = aboutNotebook.AddPage(copyrightwin, text=_("Copyright"))
+ pg3 = aboutNotebook.AddPage(licensewin, text=_("License"))
+ pg4 = aboutNotebook.AddPage(authorwin, text=_("Authors"))
+ pg5 = aboutNotebook.AddPage(contribwin, text=_("Contributors"))
+ pg5 = aboutNotebook.AddPage(transwin, text=_("Translators"))
+
+ wx.CallAfter(aboutNotebook.SetSelection, 0)
+
+ # buttons
+ btnClose = wx.Button(parent = panel, id = wx.ID_CLOSE)
+ btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(item = btnClose, proportion = 0,
+ flag = wx.ALL | wx.ALIGN_RIGHT,
+ border = 5)
+ # bindings
+ # self.aboutNotebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnAGPageChanged)
+ btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
+
+ infoTxt.SetSizer(infoSizer)
+ infoSizer.Fit(infoTxt)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(item=aboutNotebook, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=1)
+ sizer.Add(item=btnSizer, proportion=0,
+ flag=wx.ALL | wx.ALIGN_RIGHT, border=1)
+ panel.SetSizer(sizer)
+ self.Layout()
+
+ def PageCopyright(self):
+ """Copyright information"""
+ copyfile = os.path.join(os.getenv("GISBASE"), "COPYING")
+ if os.path.exists(copyfile):
+ copyrightFile = open(copyfile, 'r')
+ copytext = copyrightFile.read()
+ copyrightFile.close()
+ else:
+ copytext = _('%s file missing') % 'COPYING'
+
+ # put text into a scrolling panel
+ copyrightwin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
+ size=wx.DefaultSize,
+ style = wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER)
+ copyrighttxt = wx.StaticText(copyrightwin, id=wx.ID_ANY, label=copytext)
+ copyrightwin.SetAutoLayout(True)
+ copyrightwin.sizer = wx.BoxSizer(wx.VERTICAL)
+ copyrightwin.sizer.Add(item=copyrighttxt, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=3)
+ copyrightwin.SetSizer(copyrightwin.sizer)
+ copyrightwin.Layout()
+ copyrightwin.SetupScrolling()
+
+ return copyrightwin
+
+ def PageLicense(self):
+ """Licence about"""
+ licfile = os.path.join(os.getenv("GISBASE"), "GPL.TXT")
+ if os.path.exists(licfile):
+ licenceFile = open(licfile, 'r')
+ license = ''.join(licenceFile.readlines())
+ licenceFile.close()
+ else:
+ license = _('%s file missing') % 'GPL.TXT'
+ # put text into a scrolling panel
+ licensewin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
+ style = wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER)
+ licensetxt = wx.StaticText(licensewin, id=wx.ID_ANY, label=license)
+ licensewin.SetAutoLayout(True)
+ licensewin.sizer = wx.BoxSizer(wx.VERTICAL)
+ licensewin.sizer.Add(item=licensetxt, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=3)
+ licensewin.SetSizer(licensewin.sizer)
+ licensewin.Layout()
+ licensewin.SetupScrolling()
+
+ return licensewin
+
+ def PageCredit(self):
+ """Credit about"""
+ # credits
+ authfile = os.path.join(os.getenv("GISBASE"), "AUTHORS")
+ if os.path.exists(authfile):
+ authorsFile = open(authfile, 'r')
+ authors = unicode(''.join(authorsFile.readlines()), "utf-8")
+ authorsFile.close()
+ else:
+ authors = _('%s file missing') % 'AUTHORS'
+ authorwin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
+ style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
+ authortxt = wx.StaticText(authorwin, id=wx.ID_ANY, label=authors)
+ authorwin.SetAutoLayout(1)
+ authorwin.SetupScrolling()
+ authorwin.sizer = wx.BoxSizer(wx.VERTICAL)
+ authorwin.sizer.Add(item=authortxt, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=3)
+ authorwin.SetSizer(authorwin.sizer)
+ authorwin.Layout()
+
+ return authorwin
+
+ def PageContributors(self):
+ """Contributors info"""
+ contribfile = os.path.join(os.getenv("GISBASE"), "contributors.csv")
+ if os.path.exists(contribfile):
+ contribFile = open(contribfile, 'r')
+ contribs = list()
+ for line in contribFile.readlines():
+ cvs_id, name, email, country, osgeo_id, rfc2_agreed = line.split(',')
+ contribs.append((name, email, country, osgeo_id))
+ contribs[0] = (_('Name'), _('E-mail'), _('Country'), _('OSGeo_ID'))
+ contribFile.close()
+ else:
+ contribs = None
+
+ contribwin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
+ style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
+ contribwin.SetAutoLayout(1)
+ contribwin.SetupScrolling()
+ contribwin.sizer = wx.BoxSizer(wx.VERTICAL)
+
+ if not contribs:
+ contribtxt = wx.StaticText(contribwin, id=wx.ID_ANY,
+ label=_('%s file missing') % 'contibutors.csv')
+ contribwin.sizer.Add(item=contribtxt, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=3)
+ else:
+ contribBox = wx.FlexGridSizer(cols=4, vgap=5, hgap=5)
+ for developer in contribs:
+ for item in developer:
+ contribBox.Add(item = wx.StaticText(parent = contribwin, id = wx.ID_ANY,
+ label = item))
+ contribwin.sizer.Add(item=contribBox, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=3)
+
+ contribwin.SetSizer(contribwin.sizer)
+ contribwin.Layout()
+
+ return contribwin
+
+ def PageTranslators(self):
+ """Translators info"""
+ translatorsfile = os.path.join(os.getenv("GISBASE"), "translators.csv")
+ if os.path.exists(translatorsfile):
+ translatorsFile = open(translatorsfile, 'r')
+ translators = dict()
+ for line in translatorsFile.readlines()[1:]:
+ name, email, languages = line.rstrip('\n').split(',')
+ for language in languages.split(' '):
+ if not translators.has_key(language):
+ translators[language] = list()
+ translators[language].append((name, email))
+ translatorsFile.close()
+ else:
+ translators = None
+
+ translatorswin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
+ style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
+ translatorswin.SetAutoLayout(1)
+ translatorswin.SetupScrolling()
+ translatorswin.sizer = wx.BoxSizer(wx.VERTICAL)
+
+ if not translators:
+ translatorstxt = wx.StaticText(translatorswin, id=wx.ID_ANY,
+ label=_('%s file missing') % 'translators.csv')
+ translatorswin.sizer.Add(item=translatorstxt, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=3)
+ else:
+ translatorsBox = wx.FlexGridSizer(cols=3, vgap=5, hgap=5)
+ languages = translators.keys()
+ languages.sort()
+ translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
+ label = _('Name')))
+ translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
+ label = _('E-mail')))
+ translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
+ label = _('Language')))
+ for lang in languages:
+ for translator in translators[lang]:
+ name, email = translator
+ translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
+ label = unicode(name, "utf-8")))
+ translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
+ label = email))
+ translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
+ label = lang))
+
+ translatorswin.sizer.Add(item=translatorsBox, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=3)
+
+ translatorswin.SetSizer(translatorswin.sizer)
+ translatorswin.Layout()
+
+ return translatorswin
+
+ def OnCloseWindow(self, event):
+ """!Close window"""
+ self.Close()
+
+class InstallExtensionWindow(wx.Frame):
+ def __init__(self, parent, id = wx.ID_ANY,
+ title = _("Fetch & install new extension from GRASS Addons"), **kwargs):
+ self.parent = parent
+
+ wx.Frame.__init__(self, parent = parent, id = id, title = title, **kwargs)
+
+ self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
+
+ self.repoBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+ label=" %s " % _("Repository"))
+ self.findBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+ label=" %s " % _("Find extension by"))
+ self.treeBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+ label=" %s " % _("List of extensions"))
+
+ self.repo = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
+ value = 'https://svn.osgeo.org/grass/grass-addons')
+ self.fullDesc = wx.CheckBox(parent = self.panel, id=wx.ID_ANY,
+ label = _("Fetch full info including description and keywords (takes time)"))
+ self.fullDesc.SetValue(False)
+
+ self.search = SearchModuleWindow(parent = self.panel, showLabel = False)
+ self.search.SetSelection(2)
+
+ self.tree = ExtensionTree(parent = self.panel, log = parent.GetLogWindow())
+
+ self.statusbar = self.CreateStatusBar(0)
+
+ self.btnFetch = wx.Button(parent = self.panel, id = wx.ID_ANY,
+ label = _("&Fetch"))
+ self.btnFetch.SetToolTipString(_("Fetch list of available modules from GRASS Addons SVN repository"))
+ self.btnClose = wx.Button(parent = self.panel, id = wx.ID_CLOSE)
+ self.btnInstall = wx.Button(parent = self.panel, id = wx.ID_ANY,
+ label = _("&Install"))
+ self.btnInstall.SetToolTipString(_("Install selected add-ons GRASS module"))
+ self.btnInstall.Enable(False)
+
+ self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
+ self.btnFetch.Bind(wx.EVT_BUTTON, self.OnFetch)
+ self.btnInstall.Bind(wx.EVT_BUTTON, self.OnInstall)
+ self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
+ self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnItemSelected)
+ self.search.Bind(wx.EVT_TEXT_ENTER, self.OnShowItem)
+ self.search.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
+
+ self._layout()
+
+ def _layout(self):
+ """!Do layout"""
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ repoSizer = wx.StaticBoxSizer(self.repoBox, wx.VERTICAL)
+ repo1Sizer = wx.BoxSizer(wx.HORIZONTAL)
+ repo1Sizer.Add(item = self.repo, proportion = 1,
+ flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL, border = 1)
+ repo1Sizer.Add(item = self.btnFetch, proportion = 0,
+ flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL, border = 1)
+ repoSizer.Add(item = repo1Sizer,
+ flag = wx.EXPAND)
+ repoSizer.Add(item = self.fullDesc)
+
+ findSizer = wx.StaticBoxSizer(self.findBox, wx.HORIZONTAL)
+ findSizer.Add(item = self.search, proportion = 1)
+
+ treeSizer = wx.StaticBoxSizer(self.treeBox, wx.HORIZONTAL)
+ treeSizer.Add(item = self.tree, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 1)
+
+ btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(item = self.btnClose, proportion = 0,
+ flag = wx.LEFT | wx.RIGHT, border = 5)
+ btnSizer.Add(item = self.btnInstall, proportion = 0,
+ flag = wx.LEFT | wx.RIGHT, border = 5)
+
+ sizer.Add(item = repoSizer, proportion = 0,
+ flag = wx.ALL | wx.EXPAND, border = 3)
+ sizer.Add(item = findSizer, proportion = 0,
+ flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
+ sizer.Add(item = treeSizer, proportion = 1,
+ flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
+ sizer.Add(item = btnSizer, proportion=0,
+ flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
+
+ self.panel.SetSizer(sizer)
+ sizer.Fit(self.panel)
+
+ self.Layout()
+
+ def _install(self, name):
+ if not name:
+ return
+ log = self.parent.GetLogWindow()
+ log.RunCmd(['g.extension', 'extension=' + name,
+ 'svnurl=' + self.repo.GetValue().strip()])
+ self.OnCloseWindow(None)
+
+ def OnUpdateStatusBar(self, event):
+ """!Update statusbar text"""
+ element = self.search.GetSelection()
+ if not self.tree.IsLoaded():
+ self.SetStatusText(_("Fetch list of available extensions by clicking on 'Fetch' button"), 0)
+ return
+
+ self.tree.SearchItems(element = element,
+ value = event.GetString())
+
+ nItems = len(self.tree.itemsMarked)
+ if event.GetString():
+ self.SetStatusText(_("%d items match") % nItems, 0)
+ else:
+ self.SetStatusText("", 0)
+
+ event.Skip()
+
+ def OnCloseWindow(self, event):
+ """!Close window"""
+ self.Destroy()
+
+ def OnFetch(self, event):
+ """!Fetch list of available extensions"""
+ self.SetStatusText(_("Fetching list of modules from GRASS-Addons SVN (be patient)..."), 0)
+ self.tree.Load(url = self.repo.GetValue().strip(), full = self.fullDesc.IsChecked())
+ self.SetStatusText("", 0)
+
+ def OnItemActivated(self, event):
+ item = event.GetItem()
+ data = self.tree.GetPyData(item)
+ if data and data.has_key('command'):
+ self._install(data['command'])
+
+ def OnInstall(self, event):
+ """!Install selected extension"""
+ item = self.tree.GetSelected()
+ if not item.IsOk():
+ return
+ self._install(self.tree.GetItemText(item))
+
+ def OnItemSelected(self, event):
+ """!Item selected"""
+ item = event.GetItem()
+ self.tree.itemSelected = item
+ data = self.tree.GetPyData(item)
+ if not data:
+ self.SetStatusText('', 0)
+ self.btnInstall.Enable(False)
+ else:
+ self.SetStatusText(data.get('description', ''), 0)
+ self.btnInstall.Enable(True)
+
+ def OnShowItem(self, event):
+ """!Show selected item"""
+ self.tree.OnShowItem(event)
+ if self.tree.GetSelected():
+ self.btnInstall.Enable()
+ else:
+ self.btnInstall.Enable(False)
+
+class ExtensionTree(ItemTree):
+ """!List of available extensions"""
+ def __init__(self, parent, log, 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 # GMFrame
+ self.log = log
+
+ super(ExtensionTree, self).__init__(parent, id, ctstyle = ctstyle, **kwargs)
+
+ self._initTree()
+
+ def _initTree(self):
+ for prefix in ('display', 'database',
+ 'general', 'imagery',
+ 'misc', 'postscript', 'paint',
+ 'raster', 'raster3D', 'sites', 'vector'):
+ self.AppendItem(parentId = self.root,
+ text = prefix)
+ self._loaded = False
+
+ def _expandPrefix(self, c):
+ name = { 'd' : 'display',
+ 'db' : 'database',
+ 'g' : 'general',
+ 'i' : 'imagery',
+ 'm' : 'misc',
+ 'ps' : 'postscript',
+ 'p' : 'paint',
+ 'r' : 'raster',
+ 'r3' : 'raster3D',
+ 's' : 'sites',
+ 'v' : 'vector' }
+
+ if name.has_key(c):
+ return name[c]
+
+ return c
+
+ def _findItem(self, text):
+ """!Find item"""
+ item = self.GetFirstChild(self.root)[0]
+ while item and item.IsOk():
+ if text == self.GetItemText(item):
+ return item
+
+ item = self.GetNextSibling(item)
+
+ return None
+
+ def Load(self, url, full = False):
+ """!Load list of extensions"""
+ self.DeleteAllItems()
+ self.root = self.AddRoot(_("Menu tree"))
+ self._initTree()
+
+ if full:
+ flags = 'g'
+ else:
+ flags = 'l'
+ ret = gcmd.RunCommand('g.extension', read = True,
+ svnurl = url,
+ flags = flags, quiet = True)
+ if not ret:
+ return
+
+ mdict = dict()
+ for line in ret.splitlines():
+ if full:
+ key, value = line.split('=', 1)
+ if key == 'name':
+ prefix, name = value.split('.', 1)
+ if not mdict.has_key(prefix):
+ mdict[prefix] = dict()
+ mdict[prefix][name] = dict()
+ else:
+ mdict[prefix][name][key] = value
+ else:
+ prefix, name = line.strip().split('.', 1)
+ if not mdict.has_key(prefix):
+ mdict[prefix] = dict()
+
+ mdict[prefix][name] = { 'command' : prefix + '.' + name }
+
+ for prefix in mdict.keys():
+ prefixName = self._expandPrefix(prefix)
+ item = self._findItem(prefixName)
+ names = mdict[prefix].keys()
+ names.sort()
+ for name in names:
+ new = self.AppendItem(parentId = item,
+ text = prefix + '.' + name)
+ data = dict()
+ for key in mdict[prefix][name].keys():
+ data[key] = mdict[prefix][name][key]
+
+ self.SetPyData(new, data)
+
+ self._loaded = True
+
+ def IsLoaded(self):
+ """Check if items are loaded"""
+ return self._loaded
Modified: grass/trunk/gui/wxpython/gui_modules/gmodeler.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gmodeler.py 2010-05-09 21:06:48 UTC (rev 42203)
+++ grass/trunk/gui/wxpython/gui_modules/gmodeler.py 2010-05-10 09:01:04 UTC (rev 42204)
@@ -58,6 +58,8 @@
from gcmd import GMessage, GError
from gdialogs import ElementDialog, GetImageHandlers
from preferences import PreferencesBaseDialog, globalSettings as UserSettings
+from ghelp import SearchModuleWindow
+
from grass.script import core as grass
class Model(object):
@@ -477,6 +479,7 @@
Debug.msg(4, "ModelFrame.OnModelSave(): filename=%s" % self.modelFile)
self.WriteModelFile(self.modelFile)
self.SetStatusText(_('File <%s> saved') % self.modelFile, 0)
+ self.SetTitle(self.baseTitle + " - " + os.path.basename(self.modelFile))
elif not self.modelFile:
self.OnModelSaveAs(None)
@@ -1530,37 +1533,20 @@
self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
-
- self.findBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
- label=" %s " % _("Find module(s) by"))
+
self.cmdBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
label=" %s " % _("Command"))
- self.searchBy = wx.Choice(parent = self.panel, id = wx.ID_ANY,
- choices = [_("description"),
- _("keywords")])
- self.searchBy.SetSelection(0)
- self.search = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
- value = "", size = (-1, 25))
- self.searchTip = menuform.StaticWrapText(parent = self.panel, id = wx.ID_ANY,
- size = (-1, 35))
-
- self.searchChoice = wx.Choice(parent = self.panel, id = wx.ID_ANY)
-
self.cmd_prompt = prompt.GPromptSTC(parent = self)
-
+ self.search = SearchModuleWindow(parent = self.panel, cmdPrompt = self.cmd_prompt)
+
# get commands
items = self.cmd_prompt.GetCommandItems()
- self.searchTip.SetLabel(_("%d modules found") % len(items))
- self.searchChoice.SetItems(items)
self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
self.btnOk = wx.Button(self.panel, wx.ID_OK)
self.btnOk.SetDefault()
- self.search.Bind(wx.EVT_TEXT, self.OnSearchModule)
- self.searchChoice.Bind(wx.EVT_CHOICE, self.OnSelectModule)
-
self._layout()
self.SetSize((500, 275))
@@ -1570,31 +1556,12 @@
btnSizer.AddButton(self.btnCancel)
btnSizer.AddButton(self.btnOk)
btnSizer.Realize()
-
- findSizer = wx.StaticBoxSizer(self.findBox, wx.HORIZONTAL)
- gridSizer = wx.GridBagSizer(hgap = 3, vgap = 3)
- gridSizer.AddGrowableCol(1)
-
- cmdSizer = wx.StaticBoxSizer(self.cmdBox, wx.VERTICAL)
- gridSizer.Add(item = self.searchBy,
- flag=wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
- gridSizer.Add(item = self.search,
- flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, pos = (0, 1))
- gridSizer.Add(item = self.searchTip,
- flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, pos = (1, 0), span = (1, 2))
- gridSizer.Add(item = self.searchChoice,
- flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, pos = (2, 0), span = (1, 2))
- findSizer.Add(item = gridSizer, proportion = 1)
-
- cmdSizer.Add(item=self.cmd_prompt, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=1)
-
mainSizer = wx.BoxSizer(wx.VERTICAL)
- mainSizer.Add(item=findSizer, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=5)
- mainSizer.Add(item=cmdSizer, proportion=1,
- flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
+ mainSizer.Add(item=self.search, proportion=0,
+ flag=wx.EXPAND | wx.ALL, border=3)
+ mainSizer.Add(item=self.cmd_prompt, proportion=1,
+ flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
mainSizer.Add(item=btnSizer, proportion=0,
flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
@@ -1619,53 +1586,7 @@
cmd = shlex.split(utils.EncodeString((line)))
return cmd
-
- def OnSearchModule(self, event):
- """!Search module by keywords or description"""
- text = event.GetString()
- if not text:
- self.cmd_prompt.SetFilter(None)
- return
-
- modules = dict()
- iFound = 0
- for module, data in self.cmd_prompt.moduleDesc.iteritems():
- found = False
- if self.searchBy.GetSelection() == 0: # -> description
- if text in data['desc']:
- found = True
- else: # -> keywords
- if self.cmd_prompt.CheckKey(text, data['keywords']):
- found = True
-
- if found:
- iFound += 1
- try:
- group, name = module.split('.')
- except ValueError:
- continue # TODO
-
- if not modules.has_key(group):
- modules[group] = list()
- modules[group].append(name)
-
- self.cmd_prompt.SetFilter(modules)
- self.searchTip.SetLabel(_("%d modules found") % iFound)
- self.searchChoice.SetItems(self.cmd_prompt.GetCommandItems())
-
- def OnSelectModule(self, event):
- """!Module selected from choice, update command prompt"""
- cmd = event.GetString().split(' ', 1)[0]
- text = cmd + ' '
- pos = len(text)
- self.cmd_prompt.SetText(text)
- self.cmd_prompt.SetSelectionStart(pos)
- self.cmd_prompt.SetCurrentPos(pos)
- self.cmd_prompt.SetFocus()
-
- desc = self.cmd_prompt.GetCommandDesc(cmd)
- self.searchTip.SetLabel(desc)
-
+
def OnOk(self, event):
self.btnOk.SetFocus()
Modified: grass/trunk/gui/wxpython/gui_modules/goutput.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/goutput.py 2010-05-09 21:06:48 UTC (rev 42203)
+++ grass/trunk/gui/wxpython/gui_modules/goutput.py 2010-05-10 09:01:04 UTC (rev 42204)
@@ -40,7 +40,7 @@
from debug import Debug
from preferences import globalSettings as UserSettings
-from help import SearchModuleWindow
+from ghelp import SearchModuleWindow
wxCmdOutput, EVT_CMD_OUTPUT = NewEvent()
wxCmdProgress, EVT_CMD_PROGRESS = NewEvent()
@@ -186,9 +186,10 @@
self.Bind(EVT_CMD_DONE, self.OnCmdDone)
# search & command prompt
- self.search = SearchModuleWindow(parent = self.panelPrompt)
-
self.cmd_prompt = prompt.GPromptSTC(parent = self)
+
+ self.search = SearchModuleWindow(parent = self.panelPrompt, cmdPrompt = self.cmd_prompt)
+
if self.parent.GetName() != 'LayerManager':
self.search.Hide()
self.cmd_prompt.Hide()
@@ -227,8 +228,6 @@
self.btn_abort.Bind(wx.EVT_BUTTON, self.OnCmdAbort)
self.btn_abort.Bind(EVT_CMD_ABORT, self.OnCmdAbort)
- self.search.Bind(wx.EVT_TEXT, self.OnSearchModule)
-
self.__layout()
def __layout(self):
@@ -244,7 +243,7 @@
if self.search.IsShown():
PromptSizer.Add(item=self.search, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=1)
+ flag=wx.EXPAND | wx.ALL, border=3)
PromptSizer.Add(item=self.cmd_prompt, proportion=1,
flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
@@ -542,39 +541,7 @@
def GetCmd(self):
"""!Get running command or None"""
return self.requestQ.get()
-
- def OnSearchModule(self, event):
- """!Search module by keywords or description"""
- text = event.GetString()
- if not text:
- self.cmd_prompt.SetFilter(None)
- return
-
- modules = dict()
- iFound = 0
- for module, data in self.cmd_prompt.moduleDesc.iteritems():
- found = False
- if self.search.GetSelection() == 'description': # -> description
- if text in data['desc']:
- found = True
- else: # -> keywords
- if self.cmd_prompt.CheckKey(text, data['keywords']):
- found = True
-
- if found:
- iFound += 1
- try:
- group, name = module.split('.')
- except ValueError:
- continue # TODO
-
- if not modules.has_key(group):
- modules[group] = list()
- modules[group].append(name)
-
- self.parent.statusbar.SetStatusText(_("%d modules found") % iFound)
- self.cmd_prompt.SetFilter(modules)
-
+
def OnCmdOutput(self, event):
"""!Print command output"""
message = event.text
Deleted: grass/trunk/gui/wxpython/gui_modules/help.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/help.py 2010-05-09 21:06:48 UTC (rev 42203)
+++ grass/trunk/gui/wxpython/gui_modules/help.py 2010-05-10 09:01:04 UTC (rev 42204)
@@ -1,928 +0,0 @@
-"""!
- at package help.py
-
- at brief Help window
-
-Classes:
- - HelpWindow
- - SearchModuleWindow
- - ItemTree
- - MenuTreeWindow
- - MenuTree
- - AboutWindow
- - InstallExtensionWindow
- - ExtensionTree
-
-(C) 2008-2010 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.
-
- at author Martin Landa <landa.martin gmail.com>
-"""
-
-import os
-
-import wx
-try:
- import wx.lib.agw.customtreectrl as CT
-# import wx.lib.agw.hyperlink as hl
-except ImportError:
- import wx.lib.customtreectrl as CT
-# import wx.lib.hyperlink as hl
-import wx.lib.flatnotebook as FN
-import wx.lib.scrolledpanel as scrolled
-
-import menudata
-import gcmd
-import globalvar
-
-class HelpWindow(wx.Frame):
- """!GRASS Quickstart help window"""
- def __init__(self, parent, id, title, size, file):
-
- wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
-
- sizer = wx.BoxSizer(wx.VERTICAL)
-
- # text
- helpFrame = wx.html.HtmlWindow(parent=self, id=wx.ID_ANY)
- helpFrame.SetStandardFonts (size = 10)
- helpFrame.SetBorders(10)
- wx.InitAllImageHandlers()
-
- helpFrame.LoadFile(file)
- self.Ok = True
-
- sizer.Add(item=helpFrame, proportion=1, flag=wx.EXPAND)
-
- self.SetAutoLayout(True)
- self.SetSizer(sizer)
- # sizer.Fit(self)
- # sizer.SetSizeHints(self)
- self.Layout()
-
-class SearchModuleWindow(wx.Panel):
- """!Search module window (used in MenuTreeWindow)"""
- def __init__(self, parent, id = wx.ID_ANY, showLabel = True, **kwargs):
- self.showLabel = showLabel
-
- wx.Panel.__init__(self, parent = parent, id = id, **kwargs)
-
- self._searchDict = { _('description') : 'description',
- _('command') : 'command',
- _('keywords') : 'keywords' }
-
- self.searchBy = wx.Choice(parent = self, id = wx.ID_ANY,
- choices = [_('description'),
- _('keywords'),
- _('command')])
- self.searchBy.SetSelection(0)
-
- self.search = wx.TextCtrl(parent = self, id = wx.ID_ANY,
- value = "", size = (-1, 25),
- style = wx.TE_PROCESS_ENTER)
-
- self._layout()
-
- def _layout(self):
- """!Do layout"""
- # search
- sizer = wx.BoxSizer(wx.HORIZONTAL)
- if self.showLabel:
- sizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
- label = _("Find module by:")),
- proportion = 0,
- flag = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border = 3)
- sizer.Add(item = self.searchBy, proportion = 0,
- flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT | wx.RIGHT,
- border = 5)
- sizer.Add(item = self.search, proportion = 1,
- flag = wx.EXPAND | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
- border = 5)
-
- self.SetSizer(sizer)
- sizer.Fit(self)
-
- def GetSelection(self):
- """!Get selected element"""
- selection = self.searchBy.GetStringSelection()
-
- return self._searchDict[selection]
-
- def SetSelection(self, i):
- """!Set selection element"""
- self.searchBy.SetSelection(i)
-
-class MenuTreeWindow(wx.Panel):
- """!Show menu tree"""
- def __init__(self, parent, id = wx.ID_ANY, **kwargs):
- self.parent = parent # LayerManager
-
- wx.Panel.__init__(self, parent = parent, id = id, **kwargs)
-
- self.dataBox = wx.StaticBox(parent = self, id = wx.ID_ANY,
- label=" %s " % _("Menu tree (double-click to run command)"))
- # tree
- self.tree = MenuTree(parent = self, data = menudata.ManagerData())
- self.tree.Load()
-
- # search widget
- self.search = SearchModuleWindow(parent = self)
-
- # buttons
- self.btnRun = wx.Button(self, id = wx.ID_OK, label = _("Run"))
- self.btnRun.SetToolTipString(_("Run selected command"))
- self.btnRun.Enable(False)
-
- # bindings
- self.btnRun.Bind(wx.EVT_BUTTON, self.OnRun)
- self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
- self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnItemSelected)
- self.search.Bind(wx.EVT_TEXT_ENTER, self.OnShowItem)
- self.search.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
-
- self._layout()
-
- self.search.SetFocus()
-
- def _layout(self):
- """!Do dialog layout"""
- sizer = wx.BoxSizer(wx.VERTICAL)
-
- # body
- dataSizer = wx.StaticBoxSizer(self.dataBox, wx.HORIZONTAL)
- dataSizer.Add(item = self.tree, proportion =1,
- flag = wx.EXPAND)
-
- # buttons
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
- btnSizer.Add(item = self.btnRun, 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 = self.search, 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.Fit(self)
- sizer.SetSizeHints(self)
-
- self.SetSizer(sizer)
-
- self.Fit()
- self.SetAutoLayout(True)
- self.Layout()
-
- 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:
- return
-
- handler = 'self.parent.' + data['handler'].lstrip('self.')
- if data['handler'] == 'self.OnXTerm':
- wx.MessageBox(parent = self,
- message = _('You must run this command from the menu or command line',
- 'This command require an XTerm'),
- caption = _('Message'), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
- elif data['command']:
- eval(handler)(event = None, cmd = data['command'].split())
- else:
- eval(handler)(None)
-
- def OnShowItem(self, event):
- """!Show selected item"""
- self.tree.OnShowItem(event)
- if self.tree.GetSelected():
- self.btnRun.Enable()
- else:
- self.btnRun.Enable(False)
-
- 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
-
- if data['command']:
- label = data['command'] + ' -- ' + data['description']
- else:
- label = data['description']
-
- self.parent.SetStatusText(label, 0)
-
- def OnUpdateStatusBar(self, event):
- """!Update statusbar text"""
- element = self.search.GetSelection()
- self.tree.SearchItems(element = element,
- value = event.GetString())
-
- nItems = len(self.tree.itemsMarked)
- if event.GetString():
- self.parent.SetStatusText(_("%d items match") % nItems, 0)
- else:
- self.parent.SetStatusText("", 0)
-
- event.Skip()
-
-class ItemTree(CT.CustomTreeCtrl):
- def __init__(self, parent, 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):
- super(ItemTree, self).__init__(parent, id, ctstyle = ctstyle, **kwargs)
-
- self.root = self.AddRoot(_("Menu tree"))
- self.itemsMarked = [] # list of marked items
- self.itemSelected = None
-
- 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.GetFirstChild(self.root)[0]
- self._processItem(item, element, value, items)
-
- self.itemsMarked = items
- self.itemSelected = None
-
- 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.GetFirstChild(item)[0]
- if subItem:
- self._processItem(subItem, element, value, listOfItems)
- data = self.GetPyData(item)
-
- if data and data.has_key(element) and \
- value.lower() in data[element].lower():
- listOfItems.append(item)
-
- item = self.GetNextSibling(item)
-
- def GetSelected(self):
- """!Get selected item"""
- return self.itemSelected
-
- def OnShowItem(self, event):
- """!Highlight first found item in menu tree"""
- if len(self.itemsMarked) > 0:
- if self.GetSelected():
- self.ToggleItemSelection(self.GetSelected())
- idx = self.itemsMarked.index(self.GetSelected()) + 1
- else:
- idx = 0
- try:
- self.ToggleItemSelection(self.itemsMarked[idx])
- self.itemSelected = self.itemsMarked[idx]
- self.EnsureVisible(self.itemsMarked[idx])
- except IndexError:
- self.ToggleItemSelection(self.itemsMarked[0]) # reselect first item
- self.EnsureVisible(self.itemsMarked[0])
- self.itemSelected = self.itemsMarked[0]
- else:
- for item in self.root.GetChildren():
- self.Collapse(item)
- itemSelected = self.GetSelection()
- if itemSelected:
- self.ToggleItemSelection(itemSelected)
- self.itemSelected = None
-
-class MenuTree(ItemTree):
- """!Menu tree class"""
- def __init__(self, parent, data, **kwargs):
- self.parent = parent
- self.menudata = data
-
- super(MenuTree, self).__init__(parent, **kwargs)
-
- 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.replace('&', ''))
- 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 = { 'item' : eachItem[0],
- 'description' : eachItem[1],
- 'handler' : eachItem[2],
- 'command' : eachItem[3],
- 'keywords' : eachItem[4] }
-
- self.SetPyData(itemNew, data)
-
-class AboutWindow(wx.Frame):
- def __init__(self, parent):
- """!Create custom About Window
-
- @todo improve styling
- """
- wx.Frame.__init__(self, parent=parent, id=wx.ID_ANY, size=(550,400),
- title=_('About GRASS GIS'))
-
- panel = wx.Panel(parent = self, id = wx.ID_ANY)
-
- # icon
- self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
-
- # get version and web site
- version, svn_gis_h_rev, svn_gis_h_date = gcmd.RunCommand('g.version',
- flags = 'r',
- read = True).splitlines()
-
- infoTxt = wx.Panel(parent = panel, id = wx.ID_ANY)
- infoSizer = wx.BoxSizer(wx.VERTICAL)
- infoGridSizer = wx.GridBagSizer(vgap=5, hgap=5)
- infoGridSizer.AddGrowableCol(0)
- infoGridSizer.AddGrowableCol(1)
- logo = os.path.join(globalvar.ETCDIR, "gui", "icons", "grass.ico")
- logoBitmap = wx.StaticBitmap(parent = infoTxt, id = wx.ID_ANY,
- bitmap = wx.Bitmap(name = logo,
- type = wx.BITMAP_TYPE_ICO))
- infoSizer.Add(item = logoBitmap, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER, border = 25)
-
- info = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
- label = version.replace('GRASS', 'GRASS GIS').strip() + '\n\n')
- info.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
- infoSizer.Add(item = info, proportion = 0,
- flag = wx.BOTTOM | wx.ALIGN_CENTER, border = 15)
-
- infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
- label = _('Official GRASS site:')),
- pos = (0, 0),
- flag = wx.ALIGN_RIGHT)
-
- infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
- label = 'http://grass.osgeo.org'),
- pos = (0, 1),
- flag = wx.ALIGN_LEFT)
-
- # infoGridSizer.Add(item = hl.HyperLinkCtrl(parent = self, id = wx.ID_ANY,
- # label = 'http://grass.osgeo.org',
- # URL = 'http://grass.osgeo.org'),
- # pos = (0, 1),
- # flag = wx.LEFT)
-
- infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
- label = _('GIS Library Revision:')),
- pos = (2, 0),
- flag = wx.ALIGN_RIGHT)
-
- infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY,
- label = svn_gis_h_rev.split(' ')[1] + ' (' +
- svn_gis_h_date.split(' ')[1] + ')'),
- pos = (2, 1),
- flag = wx.ALIGN_LEFT)
-
- infoSizer.Add(item = infoGridSizer,
- proportion = 1,
- flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL,
- border = 25)
-
- #
- # create pages
- #
- copyrightwin = self.PageCopyright()
- licensewin = self.PageLicense()
- authorwin = self.PageCredit()
- contribwin = self.PageContributors()
- transwin = self.PageTranslators()
-
- # create a flat notebook for displaying information about GRASS
- nbstyle = FN.FNB_VC8 | \
- FN.FNB_BACKGROUND_GRADIENT | \
- FN.FNB_TABS_BORDER_SIMPLE | \
- FN.FNB_NO_X_BUTTON
-
- aboutNotebook = FN.FlatNotebook(panel, id=wx.ID_ANY, style=nbstyle)
- aboutNotebook.SetTabAreaColour(globalvar.FNPageColor)
-
- # make pages for About GRASS notebook
- pg1 = aboutNotebook.AddPage(infoTxt, text=_("Info"))
- pg2 = aboutNotebook.AddPage(copyrightwin, text=_("Copyright"))
- pg3 = aboutNotebook.AddPage(licensewin, text=_("License"))
- pg4 = aboutNotebook.AddPage(authorwin, text=_("Authors"))
- pg5 = aboutNotebook.AddPage(contribwin, text=_("Contributors"))
- pg5 = aboutNotebook.AddPage(transwin, text=_("Translators"))
-
- wx.CallAfter(aboutNotebook.SetSelection, 0)
-
- # buttons
- btnClose = wx.Button(parent = panel, id = wx.ID_CLOSE)
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
- btnSizer.Add(item = btnClose, proportion = 0,
- flag = wx.ALL | wx.ALIGN_RIGHT,
- border = 5)
- # bindings
- # self.aboutNotebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnAGPageChanged)
- btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
-
- infoTxt.SetSizer(infoSizer)
- infoSizer.Fit(infoTxt)
-
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(item=aboutNotebook, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=1)
- sizer.Add(item=btnSizer, proportion=0,
- flag=wx.ALL | wx.ALIGN_RIGHT, border=1)
- panel.SetSizer(sizer)
- self.Layout()
-
- def PageCopyright(self):
- """Copyright information"""
- copyfile = os.path.join(os.getenv("GISBASE"), "COPYING")
- if os.path.exists(copyfile):
- copyrightFile = open(copyfile, 'r')
- copytext = copyrightFile.read()
- copyrightFile.close()
- else:
- copytext = _('%s file missing') % 'COPYING'
-
- # put text into a scrolling panel
- copyrightwin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
- size=wx.DefaultSize,
- style = wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER)
- copyrighttxt = wx.StaticText(copyrightwin, id=wx.ID_ANY, label=copytext)
- copyrightwin.SetAutoLayout(True)
- copyrightwin.sizer = wx.BoxSizer(wx.VERTICAL)
- copyrightwin.sizer.Add(item=copyrighttxt, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=3)
- copyrightwin.SetSizer(copyrightwin.sizer)
- copyrightwin.Layout()
- copyrightwin.SetupScrolling()
-
- return copyrightwin
-
- def PageLicense(self):
- """Licence about"""
- licfile = os.path.join(os.getenv("GISBASE"), "GPL.TXT")
- if os.path.exists(licfile):
- licenceFile = open(licfile, 'r')
- license = ''.join(licenceFile.readlines())
- licenceFile.close()
- else:
- license = _('%s file missing') % 'GPL.TXT'
- # put text into a scrolling panel
- licensewin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
- style = wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER)
- licensetxt = wx.StaticText(licensewin, id=wx.ID_ANY, label=license)
- licensewin.SetAutoLayout(True)
- licensewin.sizer = wx.BoxSizer(wx.VERTICAL)
- licensewin.sizer.Add(item=licensetxt, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=3)
- licensewin.SetSizer(licensewin.sizer)
- licensewin.Layout()
- licensewin.SetupScrolling()
-
- return licensewin
-
- def PageCredit(self):
- """Credit about"""
- # credits
- authfile = os.path.join(os.getenv("GISBASE"), "AUTHORS")
- if os.path.exists(authfile):
- authorsFile = open(authfile, 'r')
- authors = unicode(''.join(authorsFile.readlines()), "utf-8")
- authorsFile.close()
- else:
- authors = _('%s file missing') % 'AUTHORS'
- authorwin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
- style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
- authortxt = wx.StaticText(authorwin, id=wx.ID_ANY, label=authors)
- authorwin.SetAutoLayout(1)
- authorwin.SetupScrolling()
- authorwin.sizer = wx.BoxSizer(wx.VERTICAL)
- authorwin.sizer.Add(item=authortxt, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=3)
- authorwin.SetSizer(authorwin.sizer)
- authorwin.Layout()
-
- return authorwin
-
- def PageContributors(self):
- """Contributors info"""
- contribfile = os.path.join(os.getenv("GISBASE"), "contributors.csv")
- if os.path.exists(contribfile):
- contribFile = open(contribfile, 'r')
- contribs = list()
- for line in contribFile.readlines():
- cvs_id, name, email, country, osgeo_id, rfc2_agreed = line.split(',')
- contribs.append((name, email, country, osgeo_id))
- contribs[0] = (_('Name'), _('E-mail'), _('Country'), _('OSGeo_ID'))
- contribFile.close()
- else:
- contribs = None
-
- contribwin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
- style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
- contribwin.SetAutoLayout(1)
- contribwin.SetupScrolling()
- contribwin.sizer = wx.BoxSizer(wx.VERTICAL)
-
- if not contribs:
- contribtxt = wx.StaticText(contribwin, id=wx.ID_ANY,
- label=_('%s file missing') % 'contibutors.csv')
- contribwin.sizer.Add(item=contribtxt, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=3)
- else:
- contribBox = wx.FlexGridSizer(cols=4, vgap=5, hgap=5)
- for developer in contribs:
- for item in developer:
- contribBox.Add(item = wx.StaticText(parent = contribwin, id = wx.ID_ANY,
- label = item))
- contribwin.sizer.Add(item=contribBox, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=3)
-
- contribwin.SetSizer(contribwin.sizer)
- contribwin.Layout()
-
- return contribwin
-
- def PageTranslators(self):
- """Translators info"""
- translatorsfile = os.path.join(os.getenv("GISBASE"), "translators.csv")
- if os.path.exists(translatorsfile):
- translatorsFile = open(translatorsfile, 'r')
- translators = dict()
- for line in translatorsFile.readlines()[1:]:
- name, email, languages = line.rstrip('\n').split(',')
- for language in languages.split(' '):
- if not translators.has_key(language):
- translators[language] = list()
- translators[language].append((name, email))
- translatorsFile.close()
- else:
- translators = None
-
- translatorswin = scrolled.ScrolledPanel(self, id=wx.ID_ANY,
- style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
- translatorswin.SetAutoLayout(1)
- translatorswin.SetupScrolling()
- translatorswin.sizer = wx.BoxSizer(wx.VERTICAL)
-
- if not translators:
- translatorstxt = wx.StaticText(translatorswin, id=wx.ID_ANY,
- label=_('%s file missing') % 'translators.csv')
- translatorswin.sizer.Add(item=translatorstxt, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=3)
- else:
- translatorsBox = wx.FlexGridSizer(cols=3, vgap=5, hgap=5)
- languages = translators.keys()
- languages.sort()
- translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
- label = _('Name')))
- translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
- label = _('E-mail')))
- translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
- label = _('Language')))
- for lang in languages:
- for translator in translators[lang]:
- name, email = translator
- translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
- label = unicode(name, "utf-8")))
- translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
- label = email))
- translatorsBox.Add(item = wx.StaticText(parent = translatorswin, id = wx.ID_ANY,
- label = lang))
-
- translatorswin.sizer.Add(item=translatorsBox, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=3)
-
- translatorswin.SetSizer(translatorswin.sizer)
- translatorswin.Layout()
-
- return translatorswin
-
- def OnCloseWindow(self, event):
- """!Close window"""
- self.Close()
-
-class InstallExtensionWindow(wx.Frame):
- def __init__(self, parent, id = wx.ID_ANY,
- title = _("Fetch & install new extension from GRASS Addons"), **kwargs):
- self.parent = parent
-
- wx.Frame.__init__(self, parent = parent, id = id, title = title, **kwargs)
-
- self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
-
- self.repoBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
- label=" %s " % _("Repository"))
- self.findBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
- label=" %s " % _("Find extension by"))
- self.treeBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
- label=" %s " % _("List of extensions"))
-
- self.repo = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
- value = 'https://svn.osgeo.org/grass/grass-addons')
- self.fullDesc = wx.CheckBox(parent = self.panel, id=wx.ID_ANY,
- label = _("Fetch full info including description and keywords (takes time)"))
- self.fullDesc.SetValue(False)
-
- self.search = SearchModuleWindow(parent = self.panel, showLabel = False)
- self.search.SetSelection(2)
-
- self.tree = ExtensionTree(parent = self.panel, log = parent.GetLogWindow())
-
- self.statusbar = self.CreateStatusBar(0)
-
- self.btnFetch = wx.Button(parent = self.panel, id = wx.ID_ANY,
- label = _("&Fetch"))
- self.btnFetch.SetToolTipString(_("Fetch list of available modules from GRASS Addons SVN repository"))
- self.btnClose = wx.Button(parent = self.panel, id = wx.ID_CLOSE)
- self.btnInstall = wx.Button(parent = self.panel, id = wx.ID_ANY,
- label = _("&Install"))
- self.btnInstall.SetToolTipString(_("Install selected add-ons GRASS module"))
- self.btnInstall.Enable(False)
-
- self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
- self.btnFetch.Bind(wx.EVT_BUTTON, self.OnFetch)
- self.btnInstall.Bind(wx.EVT_BUTTON, self.OnInstall)
- self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
- self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnItemSelected)
- self.search.Bind(wx.EVT_TEXT_ENTER, self.OnShowItem)
- self.search.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
-
- self._layout()
-
- def _layout(self):
- """!Do layout"""
- sizer = wx.BoxSizer(wx.VERTICAL)
- repoSizer = wx.StaticBoxSizer(self.repoBox, wx.VERTICAL)
- repo1Sizer = wx.BoxSizer(wx.HORIZONTAL)
- repo1Sizer.Add(item = self.repo, proportion = 1,
- flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL, border = 1)
- repo1Sizer.Add(item = self.btnFetch, proportion = 0,
- flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL, border = 1)
- repoSizer.Add(item = repo1Sizer,
- flag = wx.EXPAND)
- repoSizer.Add(item = self.fullDesc)
-
- findSizer = wx.StaticBoxSizer(self.findBox, wx.HORIZONTAL)
- findSizer.Add(item = self.search, proportion = 1)
-
- treeSizer = wx.StaticBoxSizer(self.treeBox, wx.HORIZONTAL)
- treeSizer.Add(item = self.tree, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 1)
-
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
- btnSizer.Add(item = self.btnClose, proportion = 0,
- flag = wx.LEFT | wx.RIGHT, border = 5)
- btnSizer.Add(item = self.btnInstall, proportion = 0,
- flag = wx.LEFT | wx.RIGHT, border = 5)
-
- sizer.Add(item = repoSizer, proportion = 0,
- flag = wx.ALL | wx.EXPAND, border = 3)
- sizer.Add(item = findSizer, proportion = 0,
- flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
- sizer.Add(item = treeSizer, proportion = 1,
- flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
- sizer.Add(item = btnSizer, proportion=0,
- flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
-
- self.panel.SetSizer(sizer)
- sizer.Fit(self.panel)
-
- self.Layout()
-
- def _install(self, name):
- if not name:
- return
- log = self.parent.GetLogWindow()
- log.RunCmd(['g.extension', 'extension=' + name,
- 'svnurl=' + self.repo.GetValue().strip()])
- self.OnCloseWindow(None)
-
- def OnUpdateStatusBar(self, event):
- """!Update statusbar text"""
- element = self.search.GetSelection()
- if not self.tree.IsLoaded():
- self.SetStatusText(_("Fetch list of available extensions by clicking on 'Fetch' button"), 0)
- return
-
- self.tree.SearchItems(element = element,
- value = event.GetString())
-
- nItems = len(self.tree.itemsMarked)
- if event.GetString():
- self.SetStatusText(_("%d items match") % nItems, 0)
- else:
- self.SetStatusText("", 0)
-
- event.Skip()
-
- def OnCloseWindow(self, event):
- """!Close window"""
- self.Destroy()
-
- def OnFetch(self, event):
- """!Fetch list of available extensions"""
- self.SetStatusText(_("Fetching list of modules from GRASS-Addons SVN (be patient)..."), 0)
- self.tree.Load(url = self.repo.GetValue().strip(), full = self.fullDesc.IsChecked())
- self.SetStatusText("", 0)
-
- def OnItemActivated(self, event):
- item = event.GetItem()
- data = self.tree.GetPyData(item)
- if data and data.has_key('command'):
- self._install(data['command'])
-
- def OnInstall(self, event):
- """!Install selected extension"""
- item = self.tree.GetSelected()
- if not item.IsOk():
- return
- self._install(self.tree.GetItemText(item))
-
- def OnItemSelected(self, event):
- """!Item selected"""
- item = event.GetItem()
- self.tree.itemSelected = item
- data = self.tree.GetPyData(item)
- if not data:
- self.SetStatusText('', 0)
- self.btnInstall.Enable(False)
- else:
- self.SetStatusText(data.get('description', ''), 0)
- self.btnInstall.Enable(True)
-
- def OnShowItem(self, event):
- """!Show selected item"""
- self.tree.OnShowItem(event)
- if self.tree.GetSelected():
- self.btnInstall.Enable()
- else:
- self.btnInstall.Enable(False)
-
-class ExtensionTree(ItemTree):
- """!List of available extensions"""
- def __init__(self, parent, log, 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 # GMFrame
- self.log = log
-
- super(ExtensionTree, self).__init__(parent, id, ctstyle = ctstyle, **kwargs)
-
- self._initTree()
-
- def _initTree(self):
- for prefix in ('display', 'database',
- 'general', 'imagery',
- 'misc', 'postscript', 'paint',
- 'raster', 'raster3D', 'sites', 'vector'):
- self.AppendItem(parentId = self.root,
- text = prefix)
- self._loaded = False
-
- def _expandPrefix(self, c):
- name = { 'd' : 'display',
- 'db' : 'database',
- 'g' : 'general',
- 'i' : 'imagery',
- 'm' : 'misc',
- 'ps' : 'postscript',
- 'p' : 'paint',
- 'r' : 'raster',
- 'r3' : 'raster3D',
- 's' : 'sites',
- 'v' : 'vector' }
-
- if name.has_key(c):
- return name[c]
-
- return c
-
- def _findItem(self, text):
- """!Find item"""
- item = self.GetFirstChild(self.root)[0]
- while item and item.IsOk():
- if text == self.GetItemText(item):
- return item
-
- item = self.GetNextSibling(item)
-
- return None
-
- def Load(self, url, full = False):
- """!Load list of extensions"""
- self.DeleteAllItems()
- self.root = self.AddRoot(_("Menu tree"))
- self._initTree()
-
- if full:
- flags = 'g'
- else:
- flags = 'l'
- ret = gcmd.RunCommand('g.extension', read = True,
- svnurl = url,
- flags = flags, quiet = True)
- if not ret:
- return
-
- mdict = dict()
- for line in ret.splitlines():
- if full:
- key, value = line.split('=', 1)
- if key == 'name':
- prefix, name = value.split('.', 1)
- if not mdict.has_key(prefix):
- mdict[prefix] = dict()
- mdict[prefix][name] = dict()
- else:
- mdict[prefix][name][key] = value
- else:
- prefix, name = line.strip().split('.', 1)
- if not mdict.has_key(prefix):
- mdict[prefix] = dict()
-
- mdict[prefix][name] = { 'command' : prefix + '.' + name }
-
- for prefix in mdict.keys():
- prefixName = self._expandPrefix(prefix)
- item = self._findItem(prefixName)
- names = mdict[prefix].keys()
- names.sort()
- for name in names:
- new = self.AppendItem(parentId = item,
- text = prefix + '.' + name)
- data = dict()
- for key in mdict[prefix][name].keys():
- data[key] = mdict[prefix][name][key]
-
- self.SetPyData(new, data)
-
- self._loaded = True
-
- def IsLoaded(self):
- """Check if items are loaded"""
- return self._loaded
More information about the grass-commit
mailing list