[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