[GRASS-SVN] r68405 - grass/trunk/gui/wxpython/datacatalog

svn_grass at osgeo.org svn_grass at osgeo.org
Sat May 7 20:01:53 PDT 2016


Author: annakrat
Date: 2016-05-07 20:01:53 -0700 (Sat, 07 May 2016)
New Revision: 68405

Modified:
   grass/trunk/gui/wxpython/datacatalog/catalog.py
   grass/trunk/gui/wxpython/datacatalog/frame.py
   grass/trunk/gui/wxpython/datacatalog/toolbars.py
   grass/trunk/gui/wxpython/datacatalog/tree.py
Log:
wxGUI/catalog: add search

Modified: grass/trunk/gui/wxpython/datacatalog/catalog.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/catalog.py	2016-05-08 02:56:35 UTC (rev 68404)
+++ grass/trunk/gui/wxpython/datacatalog/catalog.py	2016-05-08 03:01:53 UTC (rev 68405)
@@ -94,3 +94,6 @@
     def SetRestriction(self, restrict):
         """Allow editing other mapsets or restrict editing to current mapset"""
         self.tree.SetRestriction(restrict)
+
+    def Filter(self, text):
+        self.tree.Filter(text=text)

Modified: grass/trunk/gui/wxpython/datacatalog/frame.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/frame.py	2016-05-08 02:56:35 UTC (rev 68404)
+++ grass/trunk/gui/wxpython/datacatalog/frame.py	2016-05-08 03:01:53 UTC (rev 68405)
@@ -125,3 +125,6 @@
                           mapset=mapset) == 0:
                 GMessage(parent=self,
                          message=_("Current mapset is <%s>.") % mapset)
+
+    def Filter(self, text):
+        self.tree.Filter(text=text)

Modified: grass/trunk/gui/wxpython/datacatalog/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/toolbars.py	2016-05-08 02:56:35 UTC (rev 68404)
+++ grass/trunk/gui/wxpython/datacatalog/toolbars.py	2016-05-08 03:01:53 UTC (rev 68405)
@@ -45,7 +45,19 @@
         BaseToolbar.__init__(self, parent)
 
         self.InitToolbar(self._toolbarData())
-
+        self.filterId = wx.NewId()
+        self.filter = wx.TextCtrl(parent=self, id=self.filterId)
+        self.filter.SetSize((120, self.filter.GetBestSize()[1]))
+        self.filter.Bind(wx.EVT_TEXT,
+                         lambda event: self.parent.Filter(
+                         self.filter.GetValue()))
+        self.AddControl(wx.StaticText(self, label=_("Search:")))
+        self.AddControl(self.filter)
+        help = _("Type to search database by map type or name. "
+                 "Use prefix 'r:', 'v:' and 'r3:'"
+                 "to show only raster, vector or 3D raster data, respectively. "
+                 "Use Python regular expressions to refine your search.")
+        self.SetToolShortHelp(self.filterId, help)
         # realize the toolbar
         self.Realize()
 

Modified: grass/trunk/gui/wxpython/datacatalog/tree.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/tree.py	2016-05-08 02:56:35 UTC (rev 68404)
+++ grass/trunk/gui/wxpython/datacatalog/tree.py	2016-05-08 03:01:53 UTC (rev 68405)
@@ -17,6 +17,8 @@
 @author Anna Petrasova (kratochanna gmail com)
 """
 import os
+import re
+import copy
 from multiprocessing import Process, Queue, cpu_count
 
 import wx
@@ -36,6 +38,65 @@
 from grass.exceptions import CalledModuleError
 
 
+def filterModel(model, element=None, name=None):
+    """Filter tree model based on type or name of map using regular expressions.
+    Copies tree and remove nodes which don't match."""
+    fmodel = copy.deepcopy(model)
+    nodesToRemove = []
+    if name:
+        try:
+            regex = re.compile(name)
+        except:
+            return fmodel
+    for gisdbase in fmodel.root.children:
+        for location in gisdbase.children:
+            for mapset in location.children:
+                for elem in mapset.children:
+                    if element and elem.label != element:
+                        nodesToRemove.append(elem)
+                        continue
+                    for node in elem.children:
+                        if name and regex.search(node.label) is None:
+                            nodesToRemove.append(node)
+
+    for node in reversed(nodesToRemove):
+        fmodel.RemoveNode(node)
+
+    cleanUpTree(fmodel)
+    return fmodel
+
+
+def cleanUpTree(model):
+    """Removes empty element/mapsets/locations nodes.
+    It first removes empty elements, then mapsets, then locations"""
+    # removes empty elements
+    nodesToRemove = []
+    for gisdbase in model.root.children:
+        for location in gisdbase.children:
+            for mapset in location.children:
+                for element in mapset.children:
+                    if not element.children:
+                        nodesToRemove.append(element)
+    for node in reversed(nodesToRemove):
+        model.RemoveNode(node)
+    # removes empty mapsets
+    nodesToRemove = []
+    for gisdbase in model.root.children:
+        for location in gisdbase.children:
+            for mapset in location.children:
+                if not mapset.children:
+                    nodesToRemove.append(mapset)
+    for node in reversed(nodesToRemove):
+        model.RemoveNode(node)
+    # removes empty locations
+    nodesToRemove = []
+    for gisdbase in model.root.children:
+        for location in gisdbase.children:
+            if not location.children:
+                nodesToRemove.append(location)
+    for node in reversed(nodesToRemove):
+        model.RemoveNode(node)
+
 def getEnvironment(gisdbase, location, mapset):
     """Creates environment to be passed in run_command for example.
     Returns tuple with temporary file path and the environment. The user
@@ -210,6 +271,7 @@
             wx.TR_SINGLE):
         """Location Map Tree constructor."""
         self._model = TreeModel(DataCatalogNode)
+        self._orig_model = self._model
         super(
             LocationMapTree,
             self).__init__(
@@ -298,6 +360,7 @@
         if errors:
             wx.CallAfter(GWarning, '\n'.join(errors))
         Debug.msg(1, "Tree filled")
+        self.RefreshNode(self._model.root)
         self.RefreshItems()
 
     def InitTreeItems(self):
@@ -306,6 +369,7 @@
 
     def ReloadTreeItems(self):
         """Reload locations, mapsets and layers in the tree."""
+        self._orig_model = self._model
         self._model.RemoveNode(self._model.root)
         self.RefreshNode(self._model.root)
         self.InitTreeItems()
@@ -344,6 +408,7 @@
             raise CalledModuleError(error)
 
         self._populateMapsetItem(mapsetItem, maps[mapsetItem.data['name']])
+        self._orig_model = copy.deepcopy(self._model)
         self.RefreshNode(mapsetItem)
         self.RefreshItems()
 
@@ -786,6 +851,29 @@
             self.changeLocation.emit(mapset=self.selected_mapset.label, location=self.selected_location.label)
         self.ExpandCurrentMapset()
 
+    def Filter(self, text):
+        """Filter tree based on name and type."""
+        text = text.strip()
+        if len(text.split(':')) > 1:
+            name = text.split(':')[1].strip()
+            elem = text.split(':')[0].strip()
+            if 'r' == elem:
+                element = 'raster'
+            elif 'r3' == elem:
+                element = 'raster_3d'
+            elif 'v' == elem:
+                element = 'vector'
+            else:
+                element = None
+        else:
+            element = None
+            name = text.strip()
+
+        self._model = filterModel(self._orig_model, name=name, element=element)
+        self.RefreshNode(self._model.root)
+        self.RefreshItems()
+        self.ExpandCurrentMapset()
+
     def _getNewMapName(self, message, title, value, element, mapset, env):
         """Dialog for simple text entry"""
         dlg = NameEntryDialog(parent=self, message=message, caption=title,



More information about the grass-commit mailing list