GRASS Programmer's Manual  6.4.2(2012)
menudata.py
Go to the documentation of this file.
00001 """!
00002 @package menudata.py
00003 
00004 @brief Complex list for menu entries for wxGUI.
00005 
00006 Classes:
00007  - MenuData
00008  - ManagerData
00009  - ModelerData
00010  - PsMapData
00011 
00012 Usage:
00013 @code
00014 python menudata.py [action] [manager|modeler]
00015 @endcode
00016 
00017 where <i>action</i>:
00018  - strings (default)
00019  - tree
00020  - commands
00021  - dump
00022 
00023 (C) 2007-2011 by the GRASS Development Team
00024 This program is free software under the GNU General Public License
00025 (>=v2). Read the file COPYING that comes with GRASS for details.
00026 
00027 @author Michael Barton (Arizona State University)
00028 @author Yann Chemin <yann.chemin gmail.com>
00029 @author Martin Landa <landa.martin gmail.com>
00030 @author Glynn Clements
00031 @author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz>
00032 """
00033 
00034 import os
00035 import sys
00036 try:
00037     import xml.etree.ElementTree as etree
00038 except ImportError:
00039     import elementtree.ElementTree as etree # Python <= 2.4
00040 
00041 if not os.getenv("GISBASE"):
00042     sys.exit("GRASS is not running. Exiting...")
00043 
00044 etcwxdir = os.path.join(os.getenv("GISBASE"), "etc", "wxpython")
00045 
00046 class MenuData:
00047     """!Abstract menu data class"""
00048     def __init__(self, filename):
00049         self.tree = etree.parse(filename)
00050 
00051     def _getMenuItem(self, mi):
00052         """!Get menu item
00053 
00054         @param mi menu item instance
00055         """
00056         if mi.tag == 'separator':
00057             return ('', '', '', '', '')
00058         elif mi.tag == 'menuitem':
00059             label    = _(mi.find('label').text)
00060             help     = _(mi.find('help').text)
00061             handler  = mi.find('handler').text
00062             gcmd     = mi.find('command')  # optional
00063             keywords = mi.find('keywords') # optional
00064             shortcut = mi.find('shortcut') # optional
00065             if gcmd != None:
00066                 gcmd = gcmd.text
00067             else:
00068                 gcmd = ""
00069             if keywords != None:
00070                 keywords = keywords.text
00071             else:
00072                 keywords = ""
00073             if shortcut != None:
00074                 shortcut = shortcut.text
00075             else:
00076                 shortcut = ""
00077             return (label, help, handler, gcmd, keywords, shortcut)
00078         elif mi.tag == 'menu':
00079             return self._getMenu(mi)
00080         else:
00081             raise Exception(_("Unknow tag"))
00082 
00083     def _getMenu(self, m):
00084         """!Get menu
00085 
00086         @param m menu
00087 
00088         @return label, menu items
00089         """
00090         label = _(m.find('label').text)
00091         items = m.find('items')
00092         return (label, tuple(map(self._getMenuItem, items)))
00093     
00094     def _getMenuBar(self, mb):
00095         """!Get menu bar
00096 
00097         @param mb menu bar instance
00098         
00099         @return menu items
00100         """
00101         return tuple(map(self._getMenu, mb.findall('menu')))
00102 
00103     def _getMenuData(self, md):
00104         """!Get menu data
00105 
00106         @param md menu data instace
00107         
00108         @return menu data
00109         """
00110         return list(map(self._getMenuBar, md.findall('menubar')))
00111 
00112     def GetMenu(self):
00113         """!Get menu
00114 
00115         @return menu data
00116         """
00117         return self._getMenuData(self.tree.getroot())
00118 
00119     def PrintStrings(self, fh):
00120         """!Print menu strings to file (used for localization)
00121 
00122         @param fh file descriptor"""
00123         className = str(self.__class__).split('.', 1)[1]
00124         fh.write('menustrings_%s = [\n' % className)
00125         for node in self.tree.getiterator():
00126             if node.tag in ['label', 'help']:
00127                 fh.write('     _(%r),\n' % node.text)
00128         fh.write('    \'\']\n')
00129 
00130     def PrintTree(self, fh):
00131         """!Print menu tree to file
00132 
00133         @param fh file descriptor"""
00134         level = 0
00135         for eachMenuData in self.GetMenu():
00136             for label, items in eachMenuData:
00137                 fh.write('- %s\n' % label.replace('&', ''))
00138                 self._PrintTreeItems(fh, level + 1, items)
00139         
00140     def _PrintTreeItems(self, fh, level, menuData):
00141         """!Print menu tree items to file (used by PrintTree)
00142 
00143         @param fh file descriptor
00144         @param level menu level
00145         @param menuData menu data to print out"""
00146         for eachItem in menuData:
00147             if len(eachItem) == 2:
00148                 if eachItem[0]:
00149                     fh.write('%s - %s\n' % (' ' * level, eachItem[0]))
00150                 self._PrintTreeItems(fh, level + 1, eachItem[1])
00151             else:
00152                 if eachItem[0]:
00153                     fh.write('%s - %s\n' % (' ' * level, eachItem[0]))
00154     
00155     def PrintCommands(self, fh, itemSep = ' | ', menuSep = ' > '):
00156         """!Print commands list (command | menu item > menu item)
00157 
00158         @param fh file descriptor
00159         """
00160         level = 0
00161         for eachMenuData in self.GetMenu():
00162             for label, items in eachMenuData:
00163                 menuItems = [label, ]
00164                 self._PrintCommandsItems(fh, level + 1, items,
00165                                          menuItems, itemSep, menuSep)
00166         
00167     def _PrintCommandsItems(self, fh, level, menuData,
00168                              menuItems, itemSep, menuSep):
00169         """!Print commands item (used by PrintCommands)
00170 
00171         @param fh file descriptor
00172         @param menuItems list of menu items
00173         """
00174         for eachItem in menuData:
00175             if len(eachItem) == 2:
00176                 if eachItem[0]:
00177                     try:
00178                         menuItems[level] = eachItem[0]
00179                     except IndexError:
00180                         menuItems.append(eachItem[0])
00181                 self._PrintCommandsItems(fh, level + 1, eachItem[1],
00182                                           menuItems, itemSep, menuSep)
00183             else:
00184                 try:
00185                     del menuItems[level]
00186                 except IndexError:
00187                     pass
00188                 
00189                 if eachItem[3]:
00190                     fh.write('%s%s' % (eachItem[3], itemSep))
00191                     fh.write(menuSep.join(map(lambda x: x.replace('&', ''), menuItems)))
00192                     fh.write('%s%s' % (menuSep, eachItem[0]))
00193                     fh.write('\n')
00194         
00195 class ManagerData(MenuData):
00196     def __init__(self, filename = None):
00197         if not filename:
00198             gisbase = os.getenv('GISBASE')
00199             global etcwxdir
00200             filename = os.path.join(etcwxdir, 'xml', 'menudata.xml')
00201         
00202         MenuData.__init__(self, filename)
00203         
00204     def GetModules(self):
00205         """!Create dictionary of modules used to search module by
00206         keywords, description, etc."""
00207         modules = dict()
00208         
00209         for node in self.tree.getiterator():
00210             if node.tag == 'menuitem':
00211                 module = description = ''
00212                 keywords = []
00213                 for child in node.getchildren():
00214                     if child.tag == 'help':
00215                         description = child.text
00216                     if child.tag == 'command':
00217                         module = child.text
00218                     if child.tag == 'keywords':
00219                         if child.text:
00220                             keywords = child.text.split(',')
00221                     
00222                 if module:
00223                     modules[module] = { 'desc': description,
00224                                         'keywords' : keywords }
00225                     if len(keywords) < 1:
00226                         print >> sys.stderr, "WARNING: Module <%s> has no keywords" % module
00227                 
00228         return modules
00229 
00230 class ModelerData(MenuData):
00231     def __init__(self, filename = None):
00232         if not filename:
00233             gisbase = os.getenv('GISBASE')
00234             global etcwxdir
00235             filename = os.path.join(etcwxdir, 'xml', 'menudata_modeler.xml')
00236         
00237         MenuData.__init__(self, filename)
00238 
00239 class PsMapData(MenuData):
00240     def __init__(self, path = None):
00241         """!Menu for Cartographic Composer (psmap.py)
00242         
00243         @path path to XML to be read (None for menudata_psmap.xml)
00244         """
00245         if not path:
00246             gisbase = os.getenv('GISBASE')
00247             global etcwxdir
00248         path = os.path.join(etcwxdir, 'xml', 'menudata_psmap.xml')
00249         
00250         MenuData.__init__(self, path)
00251 
00252 if __name__ == "__main__":
00253     import sys
00254 
00255     # i18N
00256     import gettext
00257     gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
00258 
00259     action = 'strings'
00260     menu   = 'manager'
00261     
00262     for arg in sys.argv:
00263         if arg in ('strings', 'tree', 'commands', 'dump'):
00264             action =  arg
00265         elif arg in ('manager', 'modeler'):
00266             menu = arg
00267     
00268     if menu == 'manager':
00269         data = ManagerData()
00270     else:
00271         data = ModelerData()
00272 
00273     if action == 'strings':
00274         data.PrintStrings(sys.stdout)
00275     elif action == 'tree':
00276         data.PrintTree(sys.stdout)
00277     elif action == 'commands':
00278         data.PrintCommands(sys.stdout)
00279     
00280     sys.exit(0)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines