Browse Source

wxGUI: data catalog now also available as standalone tool (g.gui.datacatalog)
note: the tool needs a lot of improvements, please free to contribute!


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@66128 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 9 years ago
parent
commit
e9c41c0bc7

+ 3 - 3
gui/wxpython/Makefile

@@ -1,6 +1,6 @@
 MODULE_TOPDIR = ../..
 
-SUBDIRS = docs animation mapswipe gmodeler rlisetup psmap dbmgr vdigit iclass gcp timeline tplot
+SUBDIRS = docs animation datacatalog mapswipe gmodeler rlisetup psmap dbmgr vdigit iclass gcp timeline tplot
 EXTRA_CLEAN_FILES = menustrings.py build_ext.pyc xml/menudata.xml xml/module_tree_menudata.xml */*.pyc
 
 include $(MODULE_TOPDIR)/include/Make/Dir.make
@@ -9,7 +9,7 @@ include $(MODULE_TOPDIR)/include/Make/Python.make
 DSTDIR = $(GUIDIR)/wxpython
 
 SRCFILES := $(wildcard icons/*.py scripts/*.py xml/*) \
-	$(wildcard animation/* core/*.py dbmgr/* gcp/*.py gmodeler/* \
+	$(wildcard animation/* core/*.py datacatalog/* dbmgr/* gcp/*.py gmodeler/* \
 	gui_core/*.py iclass/* lmgr/*.py location_wizard/*.py mapwin/*.py mapdisp/*.py \
 	mapswipe/* modules/*.py nviz/*.py psmap/* rdigit/* rlisetup/* timeline/* vdigit/* \
 	vnet/*.py web_services/*.py wxplot/*.py iscatt/*.py tplot/*) \
@@ -18,7 +18,7 @@ SRCFILES := $(wildcard icons/*.py scripts/*.py xml/*) \
 DSTFILES := $(patsubst %,$(DSTDIR)/%,$(SRCFILES)) \
 	$(patsubst %.py,$(DSTDIR)/%.pyc,$(filter %.py,$(SRCFILES)))
 
-PYDSTDIRS := $(patsubst %,$(DSTDIR)/%,animation core dbmgr gcp gmodeler \
+PYDSTDIRS := $(patsubst %,$(DSTDIR)/%,animation core datacatalog dbmgr gcp gmodeler \
 	gui_core iclass lmgr location_wizard mapwin mapdisp modules nviz psmap \
 	mapswipe vdigit wxplot web_services rdigit rlisetup vnet timeline iscatt tplot)
 

+ 5 - 0
gui/wxpython/datacatalog/Makefile

@@ -0,0 +1,5 @@
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/GuiScript.make
+
+default: guiscript

+ 5 - 0
gui/wxpython/datacatalog/__init__.py

@@ -0,0 +1,5 @@
+all = [
+    'catalog',
+    'frame',
+    'tree',
+]

+ 69 - 0
gui/wxpython/datacatalog/catalog.py

@@ -0,0 +1,69 @@
+"""
+@package datacatalog::catalog
+
+@brief Data catalog
+
+Classes:
+ - datacatalog::DataCatalog
+
+(C) 2014 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.
+
+@author Tereza Fiedlerova
+"""
+
+import wx
+
+from core.gthread import gThread
+from core.debug import Debug
+from datacatalog.tree import DataCatalogTree
+
+from grass.pydispatch.signal import Signal
+
+class DataCatalog(wx.Panel):
+    """Data catalog panel"""
+    def __init__(self, parent, giface=None, id = wx.ID_ANY, title=_("Data catalog"),
+                 name='catalog', **kwargs):
+        """Panel constructor  """
+        self.showNotification = Signal('DataCatalog.showNotification')
+        self.parent = parent
+        self.baseTitle = title
+        wx.Panel.__init__(self, parent = parent, id = id, **kwargs)
+        self.SetName("DataCatalog")
+        
+        Debug.msg(1, "DataCatalog.__init__()")
+        
+        # tree with layers
+        self.tree = DataCatalogTree(self, giface=giface)
+        self.thread = gThread()
+        self._loaded = False
+        self.tree.showNotification.connect(self.showNotification)
+
+        # some layout
+        self._layout()
+        
+    def _layout(self):
+        """Do layout"""
+        sizer = wx.BoxSizer(wx.VERTICAL)
+
+        sizer.Add(item = self.tree.GetControl(), proportion = 1,
+                  flag = wx.EXPAND)          
+        
+        self.SetAutoLayout(True)
+        self.SetSizer(sizer)
+        
+        self.Layout()
+
+    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.ExpandCurrentLocation()

+ 72 - 0
gui/wxpython/datacatalog/frame.py

@@ -0,0 +1,72 @@
+"""
+@package datacatalog::frame
+
+@brief Data catalog frame class
+
+Classes:
+ - datacatalog::DataCatalogTree
+ - datacatalog::DataCatalogFrame
+
+(C) 2014-2015 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.
+
+@author Tereza Fiedlerova
+"""
+
+import wx
+
+from grass.script import core as gcore
+
+from core.utils import _
+from datacatalog.tree import DataCatalogTree
+
+class DataCatalogFrame(wx.Frame):
+    """Frame for testing purposes only."""
+    def __init__(self, parent, giface=None):
+        wx.Frame.__init__(self, parent=parent,
+                          title=_('GRASS GIS Data Catalog (experimetal)'))
+
+        self._giface = giface
+        self.panel = wx.Panel(self)
+
+        # tree
+        self.tree = DataCatalogTree(parent=self.panel, giface=self._giface)
+        self.tree.InitTreeItems()
+        
+        # buttons
+        self.btnClose = wx.Button(parent=self.panel, id=wx.ID_CLOSE)
+        self.btnClose.SetToolTipString(_("Close GRASS GIS Data Catalog"))
+        self.btnClose.SetDefault()
+
+        # events
+        
+        self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        
+        self._layout()
+        
+    def _layout(self):
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(self.tree, proportion=1, flag=wx.EXPAND)
+        
+        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+        btnSizer.Add(self.btnClose)
+        
+        sizer.Add(item = btnSizer, proportion = 0,
+                  flag = wx.ALL | wx.ALIGN_RIGHT,
+                  border = 5)
+        
+        self.panel.SetSizerAndFit(sizer)
+        sizer.SetSizeHints(self.panel)
+        
+        self.SetMinSize((400, 500))
+
+    def OnCloseWindow(self, event):
+        """Cancel button pressed"""
+        if not isinstance(event, wx.CloseEvent):
+            self.Destroy()
+        
+        event.Skip()

+ 58 - 0
gui/wxpython/datacatalog/g.gui.datacatalog.html

@@ -0,0 +1,58 @@
+<!-- meta page description: wxGUI Data Catalog -->
+<!-- meta page index: topic_gui|GUI -->
+<h2>DESCRIPTION</h2>
+
+The <b>Data Catalog</b> is a <em><a href="wxGUI.html">wxGUI</a></em> component
+for browsing, modifying and managing GRASS maps.
+
+<p>
+Data Catalog allows you to:
+
+<ul>
+  <li>browse GRASS locations and mapsets in the current GIS directory</li>
+  <li>browse GRASS 2D/3D raster and vector maps</li>
+  <li>rename GRASS maps in the current mapset</li>
+  <li>copy GRASS maps from different mapsets into current mapsets (within the same location)</li>
+  <li>delete GRASS maps located in the current mapset</li>
+</ul>
+
+<h2>NOTES</h2>
+
+<h3>WARNING</h3>
+
+Data Catalog is <b>experimental and requires significant
+developement!</b>, see
+the <a href="http://trac.osgeo.org/grass/wiki/wxGUIDevelopment/wxDataCatalog">trac
+wiki page</a>.
+
+<h3>TODO</h3>
+
+<ul>
+  <li>Extend this manual, add screenshot</li>
+  <li>Improve this tool,
+see <a href="http://trac.osgeo.org/grass/wiki/wxGUIDevelopment/wxDataCatalog">trac
+wiki page</a></li>
+</ul>
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="wxGUI.html">wxGUI</a><br>
+  <a href="wxGUI.components.html">wxGUI components</a>
+</em>
+
+<p>
+<em>
+  <a href="g.copy.html">g.copy</a>,
+  <a href="g.copy.html">g.rename</a>,
+  <a href="g.copy.html">g.remove</a>,
+  <a href="g.list.html">g.list</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+Tereza Fiedlerova, OSGeoREL, Czech Technical University in Prague,
+Czech Republic
+
+<p>
+<i>$Date$</i>

+ 48 - 0
gui/wxpython/datacatalog/g.gui.datacatalog.py

@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+############################################################################
+#
+# MODULE:    Data catalog
+# AUTHOR(S): Tereza Fiedlerova
+# PURPOSE:   GRASS data catalog for browsing, modifying and managing GRASS maps
+# COPYRIGHT: (C) 2014-2015 by Tereza Fiedlerova, and the GRASS Development Team
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+############################################################################
+
+#%module
+#% description: Tool for browsing, modifying and managing GRASS maps.
+#% keyword: general
+#% keyword: GUI
+#% keyword: map management
+#%end
+
+import grass.script as gscript
+
+def main():
+    options, flags = gscript.parser()
+
+    # import wx only after running parser
+    # to avoid issues when only interface is needed
+    import wx
+
+    from core.giface import StandaloneGrassInterface
+    from datacatalog.frame import DataCatalogFrame
+
+    app = wx.App()
+
+    frame = DataCatalogFrame(parent=None, giface=StandaloneGrassInterface())
+    frame.CentreOnScreen()
+    frame.Show()
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main()

+ 15 - 113
gui/wxpython/lmgr/datacatalog.py

@@ -1,17 +1,16 @@
 """
-@package lmgr::datacatalog
+@package datacatalog::tree
 
-@brief Data catalog
+@brief Data catalog tree classes
 
 Classes:
- - datacatalog::DataCatalog
  - datacatalog::LocationMapTree
  - datacatalog::DataCatalogTree
 
 @todo:
  - use gui_core/treeview.py
 
-(C) 2014 by Tereza Fiedlerova, and the GRASS Development Team
+(C) 2014-2015 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
@@ -20,70 +19,21 @@ for details.
 @author Tereza Fiedlerova
 """
 
-import os
-import sys
-
 import wx
-import wx.gizmos as gizmos
 
 from core.gcmd import RunCommand, GError, GMessage
 from core.utils import GetListOfLocations, ListOfMapsets
-from core.gthread import gThread
 from core.debug import Debug
 from gui_core.dialogs import TextEntryDialog
+from core.giface import StandaloneGrassInterface
 
 from grass.pydispatch.signal import Signal
 
 import grass.script as grass
 
-class DataCatalog(wx.Panel):
-    """Data catalog panel"""
-    def __init__(self, parent, giface=None, id = wx.ID_ANY, title=_("Data catalog"),
-                 name='catalog', **kwargs):
-        """Panel constructor  """
-        self.showNotification = Signal('DataCatalog.showNotification')
-        self.parent = parent
-        self.baseTitle = title
-        wx.Panel.__init__(self, parent = parent, id = id, **kwargs)
-        self.SetName("DataCatalog")
-        
-        Debug.msg(1, "DataCatalog.__init__()")
-        
-        # tree with layers
-        self.tree = DataCatalogTree(self)
-        self.thread = gThread()
-        self._loaded = False
-        self.tree.showNotification.connect(self.showNotification)
-
-        # some layout
-        self._layout()
-        
-    def _layout(self):
-        """Do layout"""
-        sizer = wx.BoxSizer(wx.VERTICAL)
-
-        sizer.Add(item = self.tree.GetControl(), proportion = 1,
-                  flag = wx.EXPAND)          
-        
-        self.SetAutoLayout(True)
-        self.SetSizer(sizer)
-        
-        self.Layout()
-
-    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.ExpandCurrentLocation()
-
 class LocationMapTree(wx.TreeCtrl):
     def __init__(self, parent, style=wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS | 
-                 wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_COLUMN_LINES | wx.TR_SINGLE):
+                 wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_SINGLE):
         """Location Map Tree constructor."""
         super(LocationMapTree, self).__init__(parent, id=wx.ID_ANY, style=style)
         self.showNotification = Signal('Tree.showNotification')
@@ -287,9 +237,10 @@ class LocationMapTree(wx.TreeCtrl):
             Debug.msg(1, "Location <%s> not found" % location)
 
 class DataCatalogTree(LocationMapTree):
-    def __init__(self, parent):
+    def __init__(self, parent, giface=None):
         """Data Catalog Tree constructor."""
         super(DataCatalogTree, self).__init__(parent)
+        self._giface = giface
         
         self._initVariablesCatalog()
 
@@ -460,11 +411,11 @@ class DataCatalogTree(LocationMapTree):
             self.showNotification.emit(message=label)
             label = "d."+self.GetItemText(self.selected_type)+" --q map="+string+"    -- completed. Go to Map layers for further operations."
             if (self.GetItemText(self.selected_type)=='vector'):
-                self.parent.parent.AddMaps(layerName, 'vector', True)
+                self._giface.lmgr.AddMaps(layerName, 'vector', True)
             elif (self.GetItemText(self.selected_type)=='raster'):
-                self.parent.parent.AddMaps(layerName, 'raster', True)     
+                self._giface.lmgr.AddMaps(layerName, 'raster', True)     
             else:
-                self.parent.parent.AddMaps(layerName, 'raster_3d', True)
+                self._giface.lmgr.AddMaps(layerName, 'raster_3d', True)
                 label = "d.rast --q map="+string+"    -- completed. Go to 'Map layers' for further operations." # generate this message (command) automatically?
             self.showNotification.emit(message=label)
             Debug.msg(1,"LAYER "+self.GetItemText(self.selected_layer)+" DISPLAYED")
@@ -539,10 +490,11 @@ class DataCatalogTree(LocationMapTree):
         item = wx.MenuItem(menu, wx.NewId(), _("&Rename"))
         menu.AppendItem(item)
         self.Bind(wx.EVT_MENU, self.OnRename, item)
-        
-        item = wx.MenuItem(menu, wx.NewId(), _("&Display layer"))
-        menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnDisplayLayer, item)
+
+        if not isinstance(self._giface, StandaloneGrassInterface):
+            item = wx.MenuItem(menu, wx.NewId(), _("&Display layer"))
+            menu.AppendItem(item)
+            self.Bind(wx.EVT_MENU, self.OnDisplayLayer, item)
         
         self.PopupMenu(menu)
         menu.Destroy()
@@ -557,53 +509,3 @@ class DataCatalogTree(LocationMapTree):
         
         self.PopupMenu(menu)
         menu.Destroy()
-
-# testing...
-if __name__ == "__main__":
-    class TestTree(LocationMapTree):
-        def __init__(self, parent):
-            """Test Tree constructor."""
-            super(TestTree, self).__init__(parent, style=wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS | 
-                                           wx.TR_HAS_BUTTONS | wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_COLUMN_LINES |
-                                           wx.TR_MULTIPLE)
-            
-        def InitTreeItems(self):
-            """Add locations, mapsets and layers to the tree."""
-            gisenv = grass.gisenv()
-            location = gisenv['LOCATION_NAME']
-            mapset = gisenv['MAPSET']
-            self._initTreeItems(locations=[location],
-                                mapsets=[mapset])
-            
-            self.ExpandAll()
-        
-        def _popupMenuLayer(self):
-            """Create popup menu for layers"""
-            pass
-
-        def _popupMenuMapset(self):
-            """Create popup menu for mapsets"""
-            pass
-
-    class TestFrame(wx.Frame):
-        """Frame for testing purposes only."""
-        def __init__(self, model=None):
-            wx.Frame.__init__(self, None, title='Test tree')
-
-            panel = wx.Panel(self)
-            self.tree = TestTree(parent=self)
-            self.tree.SetMinSize((300, 500))
-            self.tree.InitTreeItems()
-
-            szr = wx.BoxSizer(wx.VERTICAL)
-            szr.Add(self.tree, 1, wx.ALIGN_CENTER)
-            panel.SetSizerAndFit(szr)
-            szr.SetSizeHints(self)
-
-    def main():
-        app = wx.App()
-        frame = TestFrame()
-        frame.Show()
-        app.MainLoop()
-    
-    main()

+ 2 - 0
gui/wxpython/docs/wxGUI.components.html

@@ -11,6 +11,8 @@ List of available <em><a href="wxGUI.html">wxGUI</a></em> components:
     available also as a command line tool <em><a href="g.gui.dbmgr.html">g.gui.dbmgr</a></em></li>
   <li><a href="wxGUI.psmap.html">Cartographic Composer</a>,
     available also as a command line tool <em><a href="g.gui.psmap.html">g.gui.psmap</a></em></li>
+  <li><a href="wxGUI.datacatalog.html">Data Catalog</a>,
+    available also as a command line tool <em><a href="g.gui.datacatalog.html">g.gui.datacatalog</a></em></li>
   <li><a href="wxGUI.gmodeler.html">Graphical Modeler</a>,
     available also as a command line tool <em><a href="g.gui.gmodeler.html">g.gui.gmodeler</a></em></li>
   <li><a href="wxGUI.gcp.html">Ground Control Points Manager</a>,

+ 1 - 1
gui/wxpython/lmgr/frame.py

@@ -70,7 +70,7 @@ from lmgr.toolbars         import LMWorkspaceToolbar, LMDataToolbar, LMToolsTool
 from lmgr.toolbars         import LMMiscToolbar, LMVectorToolbar, LMNvizToolbar
 from lmgr.pyshell          import PyShellWindow
 from lmgr.giface           import LayerManagerGrassInterface
-from lmgr.datacatalog      import DataCatalog
+from datacatalog.catalog   import DataCatalog
 from gui_core.forms        import GUI
 from gcp.manager           import GCPWizard
 from nviz.main             import haveNviz