[GRASS-SVN] r56086 - in grass/trunk/gui/wxpython: . core
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu May 2 12:33:25 PDT 2013
Author: wenzeslaus
Date: 2013-05-02 12:33:24 -0700 (Thu, 02 May 2013)
New Revision: 56086
Modified:
grass/trunk/gui/wxpython/core/toolboxes.py
grass/trunk/gui/wxpython/wxguitoolboxes.dox
Log:
wxGUI/toolboxes: doctests, deleting of special element and documentation
Modified: grass/trunk/gui/wxpython/core/toolboxes.py
===================================================================
--- grass/trunk/gui/wxpython/core/toolboxes.py 2013-05-02 16:58:30 UTC (rev 56085)
+++ grass/trunk/gui/wxpython/core/toolboxes.py 2013-05-02 19:33:24 UTC (rev 56086)
@@ -42,6 +42,7 @@
from grass.script.core import ScriptError
+# this could be placed to functions
mainMenuFile = os.path.join(ETCWXDIR, 'xml', 'main_menu.xml')
toolboxesFile = os.path.join(ETCWXDIR, 'xml', 'toolboxes.xml')
wxguiItemsFile = os.path.join(ETCWXDIR, 'xml', 'wxgui_items.xml')
@@ -200,6 +201,55 @@
@param node tree node where to look for subtoolboxes to be expanded
@param toolboxes tree of toolboxes to be used for expansion
+
+ >>> menu = etree.fromstring('''
+ ... <toolbox name="Raster">
+ ... <label>&Raster</label>
+ ... <items>
+ ... <module-item name="r.mask"/>
+ ... <wxgui-item name="RasterMapCalculator"/>
+ ... <subtoolbox name="NeighborhoodAnalysis"/>
+ ... <subtoolbox name="OverlayRasters"/>
+ ... </items>
+ ... </toolbox>''')
+ >>> toolboxes = etree.fromstring('''
+ ... <toolboxes>
+ ... <toolbox name="NeighborhoodAnalysis">
+ ... <label>Neighborhood analysis</label>
+ ... <items>
+ ... <module-item name="r.neighbors"/>
+ ... <module-item name="v.neighbors"/>
+ ... </items>
+ ... </toolbox>
+ ... <toolbox name="OverlayRasters">
+ ... <label>Overlay rasters</label>
+ ... <items>
+ ... <module-item name="r.cross"/>
+ ... </items>
+ ... </toolbox>
+ ... </toolboxes>''')
+ >>> _expandToolboxes(menu, toolboxes)
+ >>> print etree.tostring(menu)
+ <toolbox name="Raster">
+ <label>&Raster</label>
+ <items>
+ <module-item name="r.mask" />
+ <wxgui-item name="RasterMapCalculator" />
+ <toolbox name="NeighborhoodAnalysis">
+ <label>Neighborhood analysis</label>
+ <items>
+ <module-item name="r.neighbors" />
+ <module-item name="v.neighbors" />
+ </items>
+ </toolbox>
+ <toolbox name="OverlayRasters">
+ <label>Overlay rasters</label>
+ <items>
+ <module-item name="r.cross" />
+ </items>
+ </toolbox>
+ </items>
+ </toolbox>
"""
nodes = node.findall('.//toolbox')
if node.tag == 'toolbox': # root
@@ -233,30 +283,50 @@
"""!Expand tag 'user-toolboxes-list'.
Include all user toolboxes.
+
+ >>> tree = etree.fromstring('<toolbox><items><user-toolboxes-list/></items></toolbox>')
+ >>> toolboxes = etree.fromstring('<toolboxes><toolbox name="UserToolbox"><items><module-item name="g.region"/></items></toolbox></toolboxes>')
+ >>> _expandUserToolboxesItem(tree, toolboxes)
+ >>> etree.tostring(tree)
+ '<toolbox><items><toolbox name="GeneratedUserToolboxesList"><label>Toolboxes</label><items><toolbox name="UserToolbox"><items><module-item name="g.region" /></items></toolbox></items></toolbox></items></toolbox>'
"""
tboxes = toolboxes.findall('.//toolbox')
for n in node.findall('./items/user-toolboxes-list'):
items = node.find('./items')
idx = items.getchildren().index(n)
- el = etree.Element('toolbox', attrib={'name': 'dummy'})
+ el = etree.Element('toolbox', attrib={'name': 'GeneratedUserToolboxesList'})
items.insert(idx, el)
label = etree.SubElement(el, tag='label')
label.text = _("Toolboxes")
it = etree.SubElement(el, tag='items')
for toolbox in tboxes:
it.append(copy.deepcopy(toolbox))
+ items.remove(n)
def _removeUserToolboxesItem(root):
- """!Removes tag 'user-toolboxes-list' if there are no user toolboxes."""
+ """!Removes tag 'user-toolboxes-list' if there are no user toolboxes.
+
+ >>> tree = etree.fromstring('<toolbox><items><user-toolboxes-list/></items></toolbox>')
+ >>> _removeUserToolboxesItem(tree)
+ >>> etree.tostring(tree)
+ '<toolbox><items /></toolbox>'
+ """
for n in root.findall('./items/user-toolboxes-list'):
items = root.find('./items')
items.remove(n)
def _expandItems(node, items, itemTag):
- """!Expand items from file"""
+ """!Expand items from file
+
+ >>> tree = etree.fromstring('<items><module-item name="g.region"></module-item></items>')
+ >>> items = etree.fromstring('<module-items><module-item name="g.region"><module>g.region</module><description>GRASS region management</description></module-item></module-items>')
+ >>> _expandItems(tree, items, 'module-item')
+ >>> etree.tostring(tree)
+ '<items><module-item name="g.region"><module>g.region</module><description>GRASS region management</description></module-item></items>'
+ """
for moduleItem in node.findall('.//' + itemTag):
itemName = moduleItem.get('name')
if has_xpath:
@@ -280,7 +350,15 @@
def _expandRuntimeModules(node):
"""!Add information to modules (desc, keywords)
- by running them with --interface-description."""
+ by running them with --interface-description.
+
+ >>> tree = etree.fromstring('<items>'
+ ... '<module-item name="g.region"></module-item>'
+ ... '</items>')
+ >>> _expandRuntimeModules(tree)
+ >>> etree.tostring(tree)
+ '<items><module-item name="g.region"><module>g.region</module><description>Manages the boundary definitions for the geographic region.</description><keywords>general,settings</keywords></module-item></items>'
+ """
modules = node.findall('.//module-item')
for module in modules:
name = module.get('name')
@@ -299,7 +377,11 @@
def _escapeXML(text):
"""!Helper function for correct escaping characters for XML.
- Duplicate function in core/toolboxes.
+ Duplicate function in core/toolboxes and probably also in man compilation
+ and some existing Python package.
+
+ >>> _escapeXML('<>&')
+ '<>&'
"""
return text.replace('<', '<').replace("&", '&').replace(">", '>')
@@ -334,20 +416,40 @@
def _convertTag(node, old, new):
- """!Converts tag name."""
+ """!Converts tag name.
+
+ >>> tree = etree.fromstring('<toolboxes><toolbox><items><module-item/></items></toolbox></toolboxes>')
+ >>> _convertTag(tree, 'toolbox', 'menu')
+ >>> _convertTag(tree, 'module-item', 'menuitem')
+ >>> etree.tostring(tree)
+ '<toolboxes><menu><items><menuitem /></items></menu></toolboxes>'
+ """
for n in node.findall('.//%s' % old):
n.tag = new
def _convertTagAndRemoveAttrib(node, old, new):
- "Converts tag name and removes attributes."
+ """Converts tag name and removes attributes.
+
+ >>> tree = etree.fromstring('<toolboxes><toolbox name="Raster"><items><module-item name="g.region"/></items></toolbox></toolboxes>')
+ >>> _convertTagAndRemoveAttrib(tree, 'toolbox', 'menu')
+ >>> _convertTagAndRemoveAttrib(tree, 'module-item', 'menuitem')
+ >>> etree.tostring(tree)
+ '<toolboxes><menu><items><menuitem /></items></menu></toolboxes>'
+ """
for n in node.findall('.//%s' % old):
n.tag = new
n.attrib = {}
def _convertTree(root):
- """!Converts tree to be the form readable by core/menutree.py."""
+ """!Converts tree to be the form readable by core/menutree.py.
+
+ >>> tree = etree.fromstring('<toolbox name="MainMenu"><label>Main menu</label><items><toolbox><label>Raster</label><items><module-item name="g.region"><module>g.region</module></module-item></items></toolbox></items></toolbox>')
+ >>> _convertTree(tree)
+ >>> etree.tostring(tree)
+ '<menudata><menubar><menu><label>Raster</label><items><menuitem><command>g.region</command></menuitem></items></menu></menubar></menudata>'
+ """
root.attrib = {}
label = root.find('label')
root.remove(label)
@@ -365,8 +467,11 @@
def _getXMLString(root):
- """!Adds comment (about aotogenerated file) to XML.
+ """!Converts XML tree to string
+ Since it is usually requier, this function adds a comment (about
+ autogenerated file) to XML file.
+
@return XML as string
"""
xml = etree.tostring(root, encoding='UTF-8')
@@ -375,7 +480,49 @@
"<!--This is an auto-generated file-->\n")
+def do_doctest_gettext_workaround():
+ """Setups environment for doing a doctest with gettext usage.
+
+ When using gettext with dynamically defined underscore function
+ (`_("For translation")`), doctest does not work properly. One option is to
+ use `import as` instead of dynamically defined underscore function but this
+ would require change all modules which are used by tested module. This
+ should be considered for the future. The second option is to define dummy
+ underscore function and one other function which creates the right
+ environment to satisfy all. This is done by this function.
+ """
+ def new_displayhook(string):
+ """A replacement for default `sys.displayhook`"""
+ if string is not None:
+ sys.stdout.write("%r\n" % (string,))
+
+ def new_translator(string):
+ """A fake gettext underscore function."""
+ return string
+
+ sys.displayhook = new_displayhook
+
+ import __builtin__
+ __builtin__._ = new_translator
+
+
+def test():
+ """Tests the module using doctest
+
+ @return a number of failed tests
+ """
+ import doctest
+
+ do_doctest_gettext_workaround()
+
+ return doctest.testmod().failed
+
+
def main():
+ """Converts the toolboxes files on standard paths to the menudata file
+
+ File is written to the standard output.
+ """
tree = toolboxes2menudata(userDefined=False)
root = tree.getroot()
sys.stdout.write(_getXMLString(root))
@@ -384,4 +531,7 @@
if __name__ == '__main__':
+ if len(sys.argv) > 1:
+ if sys.argv[1] == 'doctest':
+ sys.exit(test())
sys.exit(main())
Modified: grass/trunk/gui/wxpython/wxguitoolboxes.dox
===================================================================
--- grass/trunk/gui/wxpython/wxguitoolboxes.dox 2013-05-02 16:58:30 UTC (rev 56085)
+++ grass/trunk/gui/wxpython/wxguitoolboxes.dox 2013-05-02 19:33:24 UTC (rev 56086)
@@ -23,7 +23,7 @@
content of these objects. Tag emphasizes the markup and the name of the element.
-\section filesOverview Files overview
+\section toolboxesFilesOverview Files overview
\subsection toolboxesFiles Files related to toolboxes
@@ -90,7 +90,7 @@
\enddot
-\subsection otherFiles Other files
+\subsection toolboxesOtherFiles Other files
GRASS source code contains these XML files:
<ul>
@@ -101,6 +101,36 @@
directory.
+\section toolboxesGeneration Generation of files and menu
+
+As noted in the section \ref toolboxesFilesOverview, there are files in the
+GRASS distribution and in the user home directory (particularly in
+\c ".grass7/tooboxes" subdirectory).
+
+When user doesn't have any \c toolboxes.xml or \c main_menu.xml files in the
+home directory, file \c menudata.xml included in the distribution is used to
+build a menu.
+
+When \c toolboxes.xml or \c main_menu.xml file (in user home directory) is newer
+than \c menudata.xml in user home directory or \c menudata.xml does not exists
+in user home directory, the \c menudata.xml is generated when GUI starts.
+
+When \c menudata.xml in user home directory is fresh enough,
+it is used to create a menu.
+
+When \c toolboxes.xml or \c main_menu.xml file is not in user home directory
+but \c menudata.xml is, the file is re-generated (each time the GUI starts).
+So, if you just have your own \c main_menu.xml, it is better to create also
+a \c toolboxes.xml file with no toolboxes (you may want to remove
+\c "<user-toolboxes-list>" tag from your \c main_menu.xml file because it will
+be no longer ignored). Similarly, if you have only the \c toolboxes.xml file it
+is better to copy the \c main_menu.xml file from distribution into your home
+directory.
+
+When reading the main_menu file, user toolboxes are expanded first and then
+toolboxes from distribution are expanded.
+
+
\section toolboxesFile Toolboxes file
This file contains definition of toolboxes. A toolbox contains references
More information about the grass-commit
mailing list