[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('<>&')
+    '&lt;>&'
     """
     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