GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
menudata.py
Go to the documentation of this file.
1 """!
2 @package menudata.py
3 
4 @brief Complex list for menu entries for wxGUI.
5 
6 Classes:
7  - MenuData
8  - ManagerData
9  - ModelerData
10  - PsMapData
11 
12 Usage:
13 @code
14 python menudata.py [action] [manager|modeler]
15 @endcode
16 
17 where <i>action</i>:
18  - strings (default)
19  - tree
20  - commands
21  - dump
22 
23 (C) 2007-2011 by the GRASS Development Team
24 This program is free software under the GNU General Public License
25 (>=v2). Read the file COPYING that comes with GRASS for details.
26 
27 @author Michael Barton (Arizona State University)
28 @author Yann Chemin <yann.chemin gmail.com>
29 @author Martin Landa <landa.martin gmail.com>
30 @author Glynn Clements
31 @author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz>
32 """
33 
34 import os
35 import sys
36 try:
37  import xml.etree.ElementTree as etree
38 except ImportError:
39  import elementtree.ElementTree as etree # Python <= 2.4
40 
41 if not os.getenv("GISBASE"):
42  sys.exit("GRASS is not running. Exiting...")
43 
44 etcwxdir = os.path.join(os.getenv("GISBASE"), "etc", "wxpython")
45 
46 class MenuData:
47  """!Abstract menu data class"""
48  def __init__(self, filename):
49  self.tree = etree.parse(filename)
50 
51  def _getMenuItem(self, mi):
52  """!Get menu item
53 
54  @param mi menu item instance
55  """
56  if mi.tag == 'separator':
57  return ('', '', '', '', '')
58  elif mi.tag == 'menuitem':
59  label = _(mi.find('label').text)
60  help = _(mi.find('help').text)
61  handler = mi.find('handler').text
62  gcmd = mi.find('command') # optional
63  keywords = mi.find('keywords') # optional
64  shortcut = mi.find('shortcut') # optional
65  if gcmd != None:
66  gcmd = gcmd.text
67  else:
68  gcmd = ""
69  if keywords != None:
70  keywords = keywords.text
71  else:
72  keywords = ""
73  if shortcut != None:
74  shortcut = shortcut.text
75  else:
76  shortcut = ""
77  return (label, help, handler, gcmd, keywords, shortcut)
78  elif mi.tag == 'menu':
79  return self._getMenu(mi)
80  else:
81  raise Exception(_("Unknow tag"))
82 
83  def _getMenu(self, m):
84  """!Get menu
85 
86  @param m menu
87 
88  @return label, menu items
89  """
90  label = _(m.find('label').text)
91  items = m.find('items')
92  return (label, tuple(map(self._getMenuItem, items)))
93 
94  def _getMenuBar(self, mb):
95  """!Get menu bar
96 
97  @param mb menu bar instance
98 
99  @return menu items
100  """
101  return tuple(map(self._getMenu, mb.findall('menu')))
102 
103  def _getMenuData(self, md):
104  """!Get menu data
105 
106  @param md menu data instace
107 
108  @return menu data
109  """
110  return list(map(self._getMenuBar, md.findall('menubar')))
111 
112  def GetMenu(self):
113  """!Get menu
114 
115  @return menu data
116  """
117  return self._getMenuData(self.tree.getroot())
118 
119  def PrintStrings(self, fh):
120  """!Print menu strings to file (used for localization)
121 
122  @param fh file descriptor"""
123  className = str(self.__class__).split('.', 1)[1]
124  fh.write('menustrings_%s = [\n' % className)
125  for node in self.tree.getiterator():
126  if node.tag in ['label', 'help']:
127  fh.write(' _(%r),\n' % node.text)
128  fh.write(' \'\']\n')
129 
130  def PrintTree(self, fh):
131  """!Print menu tree to file
132 
133  @param fh file descriptor"""
134  level = 0
135  for eachMenuData in self.GetMenu():
136  for label, items in eachMenuData:
137  fh.write('- %s\n' % label.replace('&', ''))
138  self._PrintTreeItems(fh, level + 1, items)
139 
140  def _PrintTreeItems(self, fh, level, menuData):
141  """!Print menu tree items to file (used by PrintTree)
142 
143  @param fh file descriptor
144  @param level menu level
145  @param menuData menu data to print out"""
146  for eachItem in menuData:
147  if len(eachItem) == 2:
148  if eachItem[0]:
149  fh.write('%s - %s\n' % (' ' * level, eachItem[0]))
150  self._PrintTreeItems(fh, level + 1, eachItem[1])
151  else:
152  if eachItem[0]:
153  fh.write('%s - %s\n' % (' ' * level, eachItem[0]))
154 
155  def PrintCommands(self, fh, itemSep = ' | ', menuSep = ' > '):
156  """!Print commands list (command | menu item > menu item)
157 
158  @param fh file descriptor
159  """
160  level = 0
161  for eachMenuData in self.GetMenu():
162  for label, items in eachMenuData:
163  menuItems = [label, ]
164  self._PrintCommandsItems(fh, level + 1, items,
165  menuItems, itemSep, menuSep)
166 
167  def _PrintCommandsItems(self, fh, level, menuData,
168  menuItems, itemSep, menuSep):
169  """!Print commands item (used by PrintCommands)
170 
171  @param fh file descriptor
172  @param menuItems list of menu items
173  """
174  for eachItem in menuData:
175  if len(eachItem) == 2:
176  if eachItem[0]:
177  try:
178  menuItems[level] = eachItem[0]
179  except IndexError:
180  menuItems.append(eachItem[0])
181  self._PrintCommandsItems(fh, level + 1, eachItem[1],
182  menuItems, itemSep, menuSep)
183  else:
184  try:
185  del menuItems[level]
186  except IndexError:
187  pass
188 
189  if eachItem[3]:
190  fh.write('%s%s' % (eachItem[3], itemSep))
191  fh.write(menuSep.join(map(lambda x: x.replace('&', ''), menuItems)))
192  fh.write('%s%s' % (menuSep, eachItem[0]))
193  fh.write('\n')
194 
196  def __init__(self, filename = None):
197  if not filename:
198  gisbase = os.getenv('GISBASE')
199  global etcwxdir
200  filename = os.path.join(etcwxdir, 'xml', 'menudata.xml')
201 
202  MenuData.__init__(self, filename)
203 
204  def GetModules(self):
205  """!Create dictionary of modules used to search module by
206  keywords, description, etc."""
207  modules = dict()
208 
209  for node in self.tree.getiterator():
210  if node.tag == 'menuitem':
211  module = description = ''
212  keywords = []
213  for child in node.getchildren():
214  if child.tag == 'help':
215  description = child.text
216  if child.tag == 'command':
217  module = child.text
218  if child.tag == 'keywords':
219  if child.text:
220  keywords = child.text.split(',')
221 
222  if module:
223  modules[module] = { 'desc': description,
224  'keywords' : keywords }
225  if len(keywords) < 1:
226  print >> sys.stderr, "WARNING: Module <%s> has no keywords" % module
227 
228  return modules
229 
231  def __init__(self, filename = None):
232  if not filename:
233  gisbase = os.getenv('GISBASE')
234  global etcwxdir
235  filename = os.path.join(etcwxdir, 'xml', 'menudata_modeler.xml')
236 
237  MenuData.__init__(self, filename)
238 
240  def __init__(self, path = None):
241  """!Menu for Cartographic Composer (psmap.py)
242 
243  @path path to XML to be read (None for menudata_psmap.xml)
244  """
245  if not path:
246  gisbase = os.getenv('GISBASE')
247  global etcwxdir
248  path = os.path.join(etcwxdir, 'xml', 'menudata_psmap.xml')
249 
250  MenuData.__init__(self, path)
251 
252 if __name__ == "__main__":
253  import sys
254 
255  # i18N
256  import gettext
257  gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
258 
259  action = 'strings'
260  menu = 'manager'
261 
262  for arg in sys.argv:
263  if arg in ('strings', 'tree', 'commands', 'dump'):
264  action = arg
265  elif arg in ('manager', 'modeler'):
266  menu = arg
267 
268  if menu == 'manager':
269  data = ManagerData()
270  else:
271  data = ModelerData()
272 
273  if action == 'strings':
274  data.PrintStrings(sys.stdout)
275  elif action == 'tree':
276  data.PrintTree(sys.stdout)
277  elif action == 'commands':
278  data.PrintCommands(sys.stdout)
279 
280  sys.exit(0)