[GRASS-SVN] r68224 - in grass/trunk/gui/wxpython: core datacatalog

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Apr 8 07:25:18 PDT 2016


Author: martinl
Date: 2016-04-08 07:25:18 -0700 (Fri, 08 Apr 2016)
New Revision: 68224

Added:
   grass/trunk/gui/wxpython/datacatalog/toolbars.py
Modified:
   grass/trunk/gui/wxpython/core/treemodel.py
   grass/trunk/gui/wxpython/datacatalog/catalog.py
   grass/trunk/gui/wxpython/datacatalog/frame.py
   grass/trunk/gui/wxpython/datacatalog/tree.py
Log:
wxGUI/datacatalog: add toolbar and implement two functions - reload whole tree or current mapset only (new feature)

Modified: grass/trunk/gui/wxpython/core/treemodel.py
===================================================================
--- grass/trunk/gui/wxpython/core/treemodel.py	2016-04-07 08:15:06 UTC (rev 68223)
+++ grass/trunk/gui/wxpython/core/treemodel.py	2016-04-08 14:25:18 UTC (rev 68224)
@@ -132,6 +132,10 @@
         """Removes node."""
         if node.parent:
             node.parent.children.remove(node)
+        else:
+            # node is root
+            for n in node.children:
+                node.children.remove(n)
 
     def SortChildren(self, node):
         """Sorts children alphabetically based on label."""

Modified: grass/trunk/gui/wxpython/datacatalog/catalog.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/catalog.py	2016-04-07 08:15:06 UTC (rev 68223)
+++ grass/trunk/gui/wxpython/datacatalog/catalog.py	2016-04-08 14:25:18 UTC (rev 68224)
@@ -21,6 +21,7 @@
 from core.debug import Debug
 from datacatalog.tree import DataCatalogTree
 from core.utils import _
+from datacatalog.toolbars import DataCatalogToolbar
 
 from grass.pydispatch.signal import Signal
 
@@ -36,7 +37,10 @@
         self.SetName("DataCatalog")
         
         Debug.msg(1, "DataCatalog.__init__()")
-        
+
+        # toolbar
+        self.toolbar = DataCatalogToolbar(parent = self)
+
         # tree with layers
         self.tree = DataCatalogTree(self, giface=giface)
         self.thread = gThread()
@@ -50,6 +54,9 @@
         """Do layout"""
         sizer = wx.BoxSizer(wx.VERTICAL)
 
+        sizer.Add(item = self.toolbar, proportion = 0,
+                  flag = wx.EXPAND)          
+
         sizer.Add(item = self.tree.GetControl(), proportion = 1,
                   flag = wx.EXPAND)          
         
@@ -61,10 +68,19 @@
     def LoadItems(self):
         if self._loaded:
             return
-        
+
         self.thread.Run(callable=self.tree.InitTreeItems,
                         ondone=lambda event: self.LoadItemsDone())
 
     def LoadItemsDone(self):
         self._loaded = True
         self.tree.ExpandCurrentMapset()
+
+    def OnReloadTree(self, event):
+        """Reload whole tree"""
+        self.tree.ReloadTreeItems()
+        self.tree.ExpandCurrentMapset()
+
+    def OnReloadCurrentMapset(self, event):
+        """Reload current mapset tree only"""
+        self.tree.ReloadCurrentMapset()

Modified: grass/trunk/gui/wxpython/datacatalog/frame.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/frame.py	2016-04-07 08:15:06 UTC (rev 68223)
+++ grass/trunk/gui/wxpython/datacatalog/frame.py	2016-04-08 14:25:18 UTC (rev 68224)
@@ -6,24 +6,26 @@
 Classes:
  - datacatalog::DataCatalogFrame
 
-(C) 2014-2015 by Tereza Fiedlerova, and the GRASS Development Team
+(C) 2014-2016 by Tereza Fiedlerova, and the GRASS Development Team
 
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 
- at author Tereza Fiedlerova
+ at author Tereza Fiedlerova (original author)
+ at author Martin Landa <landa.martin gmail.com> (various improvements)
 """
 
 import os
+import sys
 
 import wx
 
 from core.utils import _
 from core.globalvar import ICONDIR
 from datacatalog.tree import DataCatalogTree
+from datacatalog.toolbars import DataCatalogToolbar
 
-
 class DataCatalogFrame(wx.Frame):
     """Frame for testing purposes only."""
     def __init__(self, parent, giface=None):
@@ -35,6 +37,11 @@
         self._giface = giface
         self.panel = wx.Panel(self)
 
+        self.toolbar = DataCatalogToolbar(parent = self)
+        # workaround for http://trac.wxwidgets.org/ticket/13888
+        if sys.platform != 'darwin':
+            self.SetToolBar(self.toolbar)
+
         # tree
         self.tree = DataCatalogTree(parent=self.panel, giface=self._giface)
         self.tree.InitTreeItems()
@@ -74,3 +81,12 @@
             self.Destroy()
 
         event.Skip()
+
+    def OnReloadTree(self, event):
+        """Reload whole tree"""
+        self.tree.ReloadTreeItems()
+        self.tree.ExpandCurrentMapset()
+
+    def OnReloadCurrentMapset(self, event):
+        """Reload current mapset tree only"""
+        self.tree.ReloadCurrentMapset()

Added: grass/trunk/gui/wxpython/datacatalog/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/toolbars.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/toolbars.py	2016-04-08 14:25:18 UTC (rev 68224)
@@ -0,0 +1,48 @@
+"""
+ at package datacatalog.toolbars
+
+ at brief Data Catalog toolbars
+
+Classes:
+ - toolbars::DataCatalogToolbar(BaseToolbar)
+
+(C) 2016 by the GRASS Development Team
+
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Martin Landa <landa.martin gmail.com>
+"""
+
+import wx
+from gui_core.toolbars import BaseToolbar, BaseIcons
+from icons.icon import MetaIcon
+from core.utils import _
+
+icons = {
+    'reloadTree': MetaIcon(img='redraw', label=_("Reload GRASS locations")),
+    'reloadMapset': MetaIcon(img='reload', label=_("Reload current GRASS mapset only"))
+    }
+
+class DataCatalogToolbar(BaseToolbar):
+    """Main data catalog toolbar
+    """
+    def __init__(self, parent):
+        """Main toolbar constructor
+        """
+        BaseToolbar.__init__(self, parent)
+
+        self.InitToolbar(self._toolbarData())
+
+        # realize the toolbar
+        self.Realize()
+
+    def _toolbarData(self):
+        """Returns toolbar data (name, icon, handler)"""
+        # BaseIcons are a set of often used icons. It is possible
+        # to reuse icons in ./trunk/gui/icons/grass or add new ones there.
+        return self._getToolbarData((("reloadTree", icons["reloadTree"],
+                                      self.parent.OnReloadTree),
+                                     ("reloadMapset", icons["reloadMapset"],
+                                      self.parent.OnReloadCurrentMapset)
+                                     ))


Property changes on: grass/trunk/gui/wxpython/datacatalog/toolbars.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Modified: grass/trunk/gui/wxpython/datacatalog/tree.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/tree.py	2016-04-07 08:15:06 UTC (rev 68223)
+++ grass/trunk/gui/wxpython/datacatalog/tree.py	2016-04-08 14:25:18 UTC (rev 68224)
@@ -50,7 +50,7 @@
     return tmp_gisrc_file, env
 
 
-def getLocationTree(gisdbase, location, queue):
+def getLocationTree(gisdbase, location, queue, mapsets=[]):
     """Creates dictionary with mapsets, elements, layers for given location.
     Returns tuple with the dictionary and error (or None)"""
     tmp_gisrc_file, env = getEnvironment(gisdbase, location, 'PERMANENT')
@@ -59,7 +59,8 @@
     maps_dict = {}
     elements = ['raster', 'raster_3d', 'vector']
     try:
-        mapsets = gscript.read_command('g.mapsets', flags='l', quiet=True, env=env).strip()
+        if not mapsets:
+            mapsets = gscript.read_command('g.mapsets', flags='l', quiet=True, env=env).strip()
     except CalledModuleError:
         queue.put((maps_dict, _("Failed to read mapsets from location <{l}>.").format(l=location)))
         gscript.try_remove(tmp_gisrc_file)
@@ -175,16 +176,11 @@
                     proc_list[i].join()
                     if error:
                         errors.append(error)
+
                     for key in sorted(maps.keys()):
                         mapset_node = self._model.AppendNode(parent=location_nodes[i], label=key,
                                                              data=dict(type='mapset', name=key))
-                        for elem in maps[key]:
-                            if maps[key][elem]:
-                                element_node = self._model.AppendNode(parent=mapset_node, label=elem,
-                                                                      data=dict(type='element', name=elem))
-                                for layer in maps[key][elem]:
-                                    self._model.AppendNode(parent=element_node, label=layer,
-                                                           data=dict(type=elem, name=layer))
+                        self._populateMapsetItem(mapset_node, maps[key])
 
                 proc_count = 0
                 proc_list = []
@@ -198,9 +194,55 @@
         self.RefreshItems()
 
     def InitTreeItems(self):
-        """Create popup menu for layers"""
+        """Load locations, mapsets and layers in the tree."""
         raise NotImplementedError()
 
+    def ReloadTreeItems(self):
+        """Reload locations, mapsets and layers in the tree."""
+        self._model.RemoveNode(self._model.root)
+        self.RefreshNode(self._model.root)
+        self.InitTreeItems()
+
+    def ReloadCurrentMapset(self):
+        """Reload current mapset tree only."""
+        def get_first_child(node):
+            try:
+                child = mapsetItem.children[0]
+            except IndexError:
+                child = None
+            return child
+
+        locationItem, mapsetItem = self.GetCurrentLocationMapsetNode()
+        if not locationItem or not mapsetItem:
+            return
+
+        if mapsetItem.children:
+            node = get_first_child(mapsetItem)
+            while node:
+                self._model.RemoveNode(node)
+                node = get_first_child(mapsetItem)
+
+        q = Queue()
+        p = Process(target=getLocationTree,
+                    args=(self.gisdbase, locationItem.data['name'], q, mapsetItem.data['name']))
+        p.start()
+        maps, error = q.get()
+        if error:
+            raise CalledModuleError(e)
+
+        self._populateMapsetItem(mapsetItem, maps[mapsetItem.data['name']])
+        self.RefreshNode(mapsetItem)
+        self.RefreshItems()
+
+    def _populateMapsetItem(self, mapset_node, data):
+        for elem in data:
+            if data[elem]:
+                element_node = self._model.AppendNode(parent=mapset_node, label=elem,
+                                                      data=dict(type='element', name=elem))
+                for layer in data[elem]:
+                    self._model.AppendNode(parent=element_node, label=layer,
+                                           data=dict(type=elem, name=layer))
+
     def _popupMenuLayer(self):
         """Create popup menu for layers"""
         raise NotImplementedError()
@@ -279,20 +321,27 @@
         else:
             Debug.msg(1, "Location <%s> not found" % location)
 
-    def ExpandCurrentMapset(self):
-        """Expand current mapset"""
+    def GetCurrentLocationMapsetNode(self):
+        """Get current mapset node"""
         gisenv = gscript.gisenv()
         location = gisenv['LOCATION_NAME']
         mapset = gisenv['MAPSET']
         locationItem = self._model.SearchNodes(name=location, type='location')
-        mapsetItem = None
-        if locationItem:
-            mapsetItem = self._model.SearchNodes(parent=locationItem[0], name=mapset, type='mapset')
+        if not locationItem:
+            return None, None
+
+        mapsetItem = self._model.SearchNodes(parent=locationItem[0], name=mapset, type='mapset')
+        if not mapsetItem:
+            return locationItem[0], None
+
+        return locationItem[0], mapsetItem[0]
+            
+    def ExpandCurrentMapset(self):
+        """Expand current mapset"""
+        locationItem, mapsetItem = self.GetCurrentLocationMapsetNode()
         if mapsetItem:
-            self.Select(mapsetItem[0], select=True)
-            self.ExpandNode(mapsetItem[0], recursive=True)
-        else:
-            Debug.msg(1, "Mapset <%s> not found" % mapset)
+            self.Select(mapsetItem, select=True)
+            self.ExpandNode(mapsetItem, recursive=True)
 
 class DataCatalogTree(LocationMapTree):
     def __init__(self, parent, giface=None):
@@ -336,7 +385,7 @@
     def InitTreeItems(self):
         """Add locations, mapsets and layers to the tree."""
         self._initTreeItems()
-
+        
     def OnCopy(self, event):
         """Copy layer or mapset (just save it temporarily, copying is done by paste)"""
         self.copy_layer = self.selected_layer



More information about the grass-commit mailing list