[GRASS-SVN] r66128 - in grass/trunk/gui/wxpython: . datacatalog docs lmgr

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Sep 6 08:12:27 PDT 2015


Author: martinl
Date: 2015-09-06 08:12:27 -0700 (Sun, 06 Sep 2015)
New Revision: 66128

Added:
   grass/trunk/gui/wxpython/datacatalog/
   grass/trunk/gui/wxpython/datacatalog/Makefile
   grass/trunk/gui/wxpython/datacatalog/__init__.py
   grass/trunk/gui/wxpython/datacatalog/catalog.py
   grass/trunk/gui/wxpython/datacatalog/frame.py
   grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.html
   grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.py
   grass/trunk/gui/wxpython/datacatalog/tree.py
Removed:
   grass/trunk/gui/wxpython/lmgr/datacatalog.py
Modified:
   grass/trunk/gui/wxpython/Makefile
   grass/trunk/gui/wxpython/docs/wxGUI.components.html
   grass/trunk/gui/wxpython/lmgr/frame.py
Log:
wxGUI: data catalog now also available as standalone tool (g.gui.datacatalog)
       note: the tool needs a lot of improvements, please free to contribute!


Modified: grass/trunk/gui/wxpython/Makefile
===================================================================
--- grass/trunk/gui/wxpython/Makefile	2015-09-06 13:06:27 UTC (rev 66127)
+++ grass/trunk/gui/wxpython/Makefile	2015-09-06 15:12:27 UTC (rev 66128)
@@ -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 @@
 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 @@
 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)
 

Added: grass/trunk/gui/wxpython/datacatalog/Makefile
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/Makefile	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/Makefile	2015-09-06 15:12:27 UTC (rev 66128)
@@ -0,0 +1,5 @@
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/GuiScript.make
+
+default: guiscript


Property changes on: grass/trunk/gui/wxpython/datacatalog/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass/trunk/gui/wxpython/datacatalog/__init__.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/__init__.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/__init__.py	2015-09-06 15:12:27 UTC (rev 66128)
@@ -0,0 +1,5 @@
+all = [
+    'catalog',
+    'frame',
+    'tree',
+]


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

Copied: grass/trunk/gui/wxpython/datacatalog/catalog.py (from rev 66127, grass/trunk/gui/wxpython/lmgr/datacatalog.py)
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/catalog.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/catalog.py	2015-09-06 15:12:27 UTC (rev 66128)
@@ -0,0 +1,69 @@
+"""
+ at package datacatalog::catalog
+
+ at 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.
+
+ at 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()

Added: grass/trunk/gui/wxpython/datacatalog/frame.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/frame.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/frame.py	2015-09-06 15:12:27 UTC (rev 66128)
@@ -0,0 +1,72 @@
+"""
+ at package datacatalog::frame
+
+ at 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.
+
+ at 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()


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

Added: grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.html
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.html	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.html	2015-09-06 15:12:27 UTC (rev 66128)
@@ -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>


Property changes on: grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/g.gui.datacatalog.py	2015-09-06 15:12:27 UTC (rev 66128)
@@ -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()


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

Added: grass/trunk/gui/wxpython/datacatalog/tree.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/tree.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/datacatalog/tree.py	2015-09-06 15:12:27 UTC (rev 66128)
@@ -0,0 +1,511 @@
+"""
+ at package datacatalog::tree
+
+ at brief Data catalog tree classes
+
+Classes:
+ - datacatalog::LocationMapTree
+ - datacatalog::DataCatalogTree
+
+ at todo:
+ - use gui_core/treeview.py
+
+(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.
+
+ at author Tereza Fiedlerova
+"""
+
+import wx
+
+from core.gcmd import RunCommand, GError, GMessage
+from core.utils import GetListOfLocations, ListOfMapsets
+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 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_SINGLE):
+        """Location Map Tree constructor."""
+        super(LocationMapTree, self).__init__(parent, id=wx.ID_ANY, style=style)
+        self.showNotification = Signal('Tree.showNotification')
+        self.parent = parent
+        self.root = self.AddRoot('Catalog') # will not be displayed when we use TR_HIDE_ROOT flag
+        
+        self._initVariables()
+        self.MakeBackup()
+
+        wx.EVT_TREE_ITEM_RIGHT_CLICK(self, wx.ID_ANY, self.OnRightClick)
+        
+        self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
+
+    def _initTreeItems(self, locations = [], mapsets = []):
+        """Add locations, mapsets and layers to the tree."""
+        if not locations:
+            locations = GetListOfLocations(self.gisdbase)
+        if not mapsets:
+            mapsets = ['*']
+        
+        first = True
+        for loc in locations:
+            location = loc
+            if first:
+                self.ChangeEnvironment(location, 'PERMANENT')
+                first = False
+            else:
+                self.ChangeEnvironment(location)
+            
+            varloc = self.AppendItem(self.root, loc)
+            # add all mapsets
+            mapsets = ListOfMapsets()
+            if mapsets:
+                for mapset in mapsets:
+                    self.AppendItem(varloc, mapset)
+            else:
+                self.AppendItem(varloc, _("No mapsets readable"))
+                continue
+
+            # get list of all maps in location
+            maplist = RunCommand('g.list', flags='mt', type='raster,raster_3d,vector', mapset=','.join(mapsets),
+                                 quiet=True, read=True)
+            maplist = maplist.splitlines()
+            for ml in maplist:
+                # parse
+                parts1 = ml.split('/')
+                parts2 = parts1[1].split('@')
+                mapset = parts2[1]
+                mlayer = parts2[0]
+                ltype = parts1[0]
+
+                # add mapset
+                if self.itemExists(mapset, varloc) == False:
+                    varmapset = self.AppendItem(varloc, mapset)
+                else:
+                    varmapset = self.getItemByName(mapset, varloc)
+
+                # add type node if not exists
+                if self.itemExists(ltype, varmapset) == False:
+                    vartype = self.AppendItem(varmapset, ltype)
+                
+                self.AppendItem(vartype, mlayer)
+            
+        self.RestoreBackup()          
+        Debug.msg(1, "Tree filled")    
+
+    def InitTreeItems(self):
+        """Create popup menu for layers"""
+        raise NotImplementedError()
+
+    def _popupMenuLayer(self):
+        """Create popup menu for layers"""
+        raise NotImplementedError()
+
+    def _popupMenuMapset(self):
+        """Create popup menu for mapsets"""
+        raise NotImplementedError()
+
+    def _initVariables(self):
+        """Init variables."""
+        self.selected_layer = None
+        self.selected_type = None
+        self.selected_mapset = None
+        self.selected_location = None
+        
+        self.gisdbase =  grass.gisenv()['GISDBASE']
+        self.ctrldown = False
+
+    def GetControl(self):
+        """Returns control itself."""
+        return self
+    
+    def DefineItems(self, item0):
+        """Set selected items."""
+        self.selected_layer = None
+        self.selected_type = None
+        self.selected_mapset = None
+        self.selected_location = None
+        items = []
+        item = item0
+        while (self.GetItemParent(item)):
+            items.insert(0,item)
+            item = self.GetItemParent(item)
+        
+        self.selected_location = items[0]
+        length = len(items)
+        if (length > 1):
+            self.selected_mapset = items[1]
+            if (length > 2):
+                self.selected_type = items[2]
+                if (length > 3):
+                    self.selected_layer = items[3]
+        
+    def getItemByName(self, match, root):
+        """Return match item from the root."""
+        item, cookie = self.GetFirstChild(root)
+        while item.IsOk():
+            if self.GetItemText(item) == match:
+                return item
+            item, cookie = self.GetNextChild(root, cookie)
+        return None
+    
+    def itemExists(self, match, root):
+        """Return true if match item exists in the root item."""
+        item, cookie = self.GetFirstChild(root)
+        while item.IsOk():
+            if self.GetItemText(item) == match:
+                return True
+            item, cookie = self.GetNextChild(root, cookie)
+        return False       
+    
+    def UpdateTree(self):
+        """Update whole tree."""
+        self.DeleteAllItems()
+        self.root = self.AddRoot('Tree')
+        self.AddTreeItems()
+        label = "Tree updated."
+        self.showNotification.emit(message=label)
+        
+    def OnSelChanged(self, event):
+        self.selected_layer = None
+        
+    def OnRightClick(self, event):
+        """Display popup menu."""
+        self.DefineItems(event.GetItem())
+        if(self.selected_layer):
+            self._popupMenuLayer()
+        elif(self.selected_mapset and self.selected_type==None):
+            self._popupMenuMapset() 
+    
+    def OnDoubleClick(self, event):
+        """Double click"""
+        Debug.msg(1, "Double CLICK")
+            
+    def OnKeyDown(self, event):
+        """Set key event and check if control key is down"""
+        keycode = event.GetKeyCode()
+        if keycode == wx.WXK_CONTROL:
+            self.ctrldown = True
+            Debug.msg(1,"CONTROL ON")
+
+    def OnKeyUp(self, event):
+        """Check if control key is up"""
+        keycode = event.GetKeyCode()
+        if keycode == wx.WXK_CONTROL:
+            self.ctrldown = False
+            Debug.msg(1,"CONTROL OFF")
+
+    def MakeBackup(self):
+        """Make backup for case of change"""
+        gisenv = grass.gisenv()
+        self.glocation = gisenv['LOCATION_NAME']
+        self.gmapset = gisenv['MAPSET']
+
+    def RestoreBackup(self):
+        """Restore backup"""
+        stringl = 'LOCATION_NAME='+self.glocation
+        RunCommand('g.gisenv', set=stringl)
+        stringm = 'MAPSET='+self.gmapset
+        RunCommand('g.gisenv', set=stringm)
+        
+    def ChangeEnvironment(self, location, mapset=None):
+        """Change gisenv variables -> location, mapset"""
+        stringl = 'LOCATION_NAME='+location
+        RunCommand('g.gisenv', set=stringl)
+        if mapset:
+            stringm = 'MAPSET='+mapset
+            RunCommand('g.gisenv', set=stringm)
+
+    def ExpandCurrentLocation(self):
+        """Expand current location"""
+        location = grass.gisenv()['LOCATION_NAME']
+        item = self.getItemByName(location, self.root)
+        if item is not None:
+            self.SelectItem(item)
+            self.ExpandAllChildren(item)
+            self.EnsureVisible(item)
+        else:
+            Debug.msg(1, "Location <%s> not found" % location)
+
+class DataCatalogTree(LocationMapTree):
+    def __init__(self, parent, giface=None):
+        """Data Catalog Tree constructor."""
+        super(DataCatalogTree, self).__init__(parent)
+        self._giface = giface
+        
+        self._initVariablesCatalog()
+
+        wx.EVT_TREE_BEGIN_DRAG(self, wx.ID_ANY, self.OnBeginDrag)
+        wx.EVT_TREE_END_DRAG(self, wx.ID_ANY, self.OnEndDrag)
+        
+        wx.EVT_TREE_END_LABEL_EDIT(self, wx.ID_ANY, self.OnEditLabel)
+        wx.EVT_TREE_BEGIN_LABEL_EDIT(self, wx.ID_ANY, self.OnStartEditLabel)
+    
+    def _initVariablesCatalog(self):
+        """Init variables."""
+        self.copy_layer = None
+        self.copy_type = None
+        self.copy_mapset = None
+        self.copy_location = None
+
+    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
+        self.copy_type = self.selected_type
+        self.copy_mapset = self.selected_mapset
+        self.copy_location = self.selected_location 
+        label = "Layer "+self.GetItemText(self.copy_layer)+" copied to clipboard. You can paste it to selected mapset."
+        self.showNotification.emit(message=label)
+        
+    def OnRename(self, event): 
+        """Rename levent with dialog"""
+        if (self.selected_layer):
+            self.old_name = self.GetItemText(self.selected_layer)
+            self.new_name = self._getUserEntry(_('New name'), _('Rename map'), self.old_name)
+            self.rename() 
+    
+    def OnStartEditLabel(self, event):
+        """Start label editing"""
+        item = event.GetItem()
+        self.DefineItems(item)
+        Debug.msg(1, "Start label edit "+self.GetItemText(item))
+        label = _("Editing") + " " + self.GetItemText(item)
+        self.showNotification.emit(message=label)
+        if (self.selected_layer == None):
+            event.Veto()
+    
+    def OnEditLabel(self, event):
+        """End label editing"""
+        if (self.selected_layer):
+            item = event.GetItem()
+            self.old_name = self.GetItemText(item)
+            Debug.msg(1, "End label edit "+self.old_name)
+            wx.CallAfter(self.afterEdit, self, item)
+            
+    def afterEdit(pro, self, item):
+        self.new_name = self.GetItemText(item)
+        self.rename()
+    
+    def rename(self):
+        """Rename layer"""
+        if self.selected_layer and self.new_name:
+            string = self.old_name+','+self.new_name
+            self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))
+            renamed = 0
+            label = _("Renaming") + " " + string + " ..."
+            self.showNotification.emit(message=label)
+            if (self.GetItemText(self.selected_type)=='vector'):
+                renamed = RunCommand('g.rename', vector=string)
+            elif (self.GetItemText(self.selected_type)=='raster'):
+                renamed = RunCommand('g.rename', raster=string)
+            else:
+                renamed = RunCommand('g.rename', raster3d=string)
+            if (renamed==0):
+                self.SetItemText(self.selected_layer,self.new_name)
+                label = "g.rename "+self.GetItemText(self.selected_type)+"="+string+"   -- completed"
+                self.showNotification.emit(message=label)
+                Debug.msg(1,"LAYER RENAMED TO: "+self.new_name)
+            self.RestoreBackup()    
+        
+    def OnPaste(self, event):
+        """Paste layer or mapset""" 
+        # copying between mapsets of one location
+        if (self.copy_layer == None):
+                return
+        if (self.selected_location == self.copy_location and self.selected_mapset):
+            if (self.selected_type != None):
+                if (self.GetItemText(self.copy_type) != self.GetItemText(self.selected_type)): # copy raster to vector or vice versa
+                    GError(_("Failed to copy layer: invalid type."), parent = self)
+                    return
+            self.new_name = self._getUserEntry(_('New name'), _('Copy map'),
+                                               self.GetItemText(self.copy_layer) + '_copy')
+            if not self.new_name:
+                return
+            if (self.GetItemText(self.copy_layer) == self.new_name):
+                GMessage(_("Layer was not copied: new layer has the same name"), parent=self) 
+                return
+            string = self.GetItemText(self.copy_layer)+'@'+self.GetItemText(self.copy_mapset)+','+self.new_name
+            self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))
+            pasted = 0
+            type = None
+            label = _("Copying") + " " + string + " ..."
+            self.showNotification.emit(message=label)
+            if (self.GetItemText(self.copy_type)=='vector'):
+                pasted = RunCommand('g.copy', vector=string)
+                node = 'vector'     
+            elif (self.GetItemText(self.copy_type)=='raster'):
+                pasted = RunCommand('g.copy', raster=string)
+                node = 'raster'
+            else:
+                pasted = RunCommand('g.copy', raster_3d=string)
+                node = 'raster_3d'
+            if pasted == 0:
+                if self.selected_type == None:
+                    self.selected_type = self.getItemByName(node, self.selected_mapset)
+                    if self.selected_type == None:
+                        # add type node if not exists
+                        self.selected_type = self.AppendItem(self.selected_mapset, node)
+                self.AppendItem(self.selected_type,self.new_name) 
+                self.SortChildren(self.selected_type)
+                Debug.msg(1,"COPIED TO: "+self.new_name)
+                label = "g.copy "+self.GetItemText(self.copy_type)+"="+string+"    -- completed" # generate this message (command) automatically?
+                self.showNotification.emit(message=label)
+        else:
+            GError(_("Failed to copy layer: action is allowed only within the same location."),
+                   parent=self)
+        
+        # expand selected mapset
+        self.ExpandAllChildren(self.selected_mapset)
+        self.EnsureVisible(self.selected_mapset)
+        
+        self.RestoreBackup()
+        
+        
+    def OnDelete(self, event):
+        """Delete layer or mapset"""
+        if (self.selected_layer):
+            string = self.GetItemText(self.selected_layer)
+            self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))
+            removed = 0
+            # TODO: rewrite this that it will tell map type in the dialog
+            if (self._confirmDialog(question=_('Do you really want to delete map <{m}>?').format(m=string),
+                                    title=_('Delete map')) == wx.ID_YES):
+                label = _("Deleting") + " " + string + " ..."
+                self.showNotification.emit(message=label)
+                if (self.GetItemText(self.selected_type)=='vector'):
+                    removed = RunCommand('g.remove', flags='f', type='vector',
+                                         name=string)
+                elif (self.GetItemText(self.selected_type)=='raster'):
+                    removed = RunCommand('g.remove', flags='f', type='raster',
+                                         name=string)
+                else:
+                    removed = RunCommand('g.remove', flags='f', type='raster_3d',
+                                         name=string)
+                if (removed==0):
+                    self.Delete(self.selected_layer)
+                    Debug.msg(1,"LAYER "+string+" DELETED")
+                    label = "g.remove -f type="+self.GetItemText(self.selected_type)+" name="+string+"    -- completed" # generate this message (command) automatically?
+                    self.showNotification.emit(message=label)
+            self.RestoreBackup()
+            
+    def OnDisplayLayer(self, event):
+        """Display layer in current graphics view"""
+        layerName = []
+        if (self.GetItemText(self.selected_location) == self.glocation and self.selected_mapset):
+            string = self.GetItemText(self.selected_layer)+'@'+self.GetItemText(self.selected_mapset)
+            layerName.append(string)
+            label = _("Displaying") + " " + string + " ..."
+            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._giface.lmgr.AddMaps(layerName, 'vector', True)
+            elif (self.GetItemText(self.selected_type)=='raster'):
+                self._giface.lmgr.AddMaps(layerName, 'raster', True)     
+            else:
+                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")
+        else:
+            GError(_("Failed to display layer: not in current mapset or invalid layer"),
+                   parent = self)
+
+    def OnBeginDrag(self, event):
+        """Just copy necessary data"""
+        if (self.ctrldown):
+            #cursor = wx.StockCursor(wx.CURSOR_HAND)
+            #self.SetCursor(cursor)
+            event.Allow()
+            self.DefineItems(event.GetItem())
+            self.OnCopy(event)
+            Debug.msg(1,"DRAG")
+        else:
+            event.Veto()
+            Debug.msg(1,"DRAGGING without ctrl key does nothing") 
+        
+    def OnEndDrag(self, event):
+        """Copy layer into target"""
+        #cursor = wx.StockCursor(wx.CURSOR_ARROW)
+        #self.SetCursor(cursor)
+        if (event.GetItem()): 
+            self.DefineItems(event.GetItem())
+            if (self.selected_location == self.copy_location and self.selected_mapset):
+                event.Allow()
+                self.OnPaste(event)
+                self.ctrldown = False
+                #cursor = wx.StockCursor(wx.CURSOR_DEFAULT)
+                #self.SetCursor(cursor) # TODO: change cursor while dragging and then back, this is not working
+                Debug.msg(1,"DROP DONE") 
+            else:
+                event.Veto()
+
+    def _getUserEntry(self, message, title, value):
+        """Dialog for simple text entry"""
+        dlg = TextEntryDialog(self, message, title)
+        dlg.SetValue(value)
+        if dlg.ShowModal() == wx.ID_OK:
+            name = dlg.GetValue()
+        else:
+            name = None
+        dlg.Destroy()
+
+        return name
+
+    def _confirmDialog(self, question, title):
+        """Confirm dialog"""
+        dlg = wx.MessageDialog(self, question, title, wx.YES_NO)
+        res = dlg.ShowModal()
+        dlg.Destroy()
+        return res
+
+    def _popupMenuLayer(self):
+        """Create popup menu for layers"""
+        menu = wx.Menu()
+        
+        item = wx.MenuItem(menu, wx.NewId(), _("&Copy"))
+        menu.AppendItem(item)
+        self.Bind(wx.EVT_MENU, self.OnCopy, item)
+
+        item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
+        menu.AppendItem(item)
+        self.Bind(wx.EVT_MENU, self.OnPaste, item)
+ 
+        item = wx.MenuItem(menu, wx.NewId(), _("&Delete"))
+        menu.AppendItem(item)
+        self.Bind(wx.EVT_MENU, self.OnDelete, item)
+        
+        item = wx.MenuItem(menu, wx.NewId(), _("&Rename"))
+        menu.AppendItem(item)
+        self.Bind(wx.EVT_MENU, self.OnRename, 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()
+        
+    def _popupMenuMapset(self):
+        """Create popup menu for mapsets"""
+        menu = wx.Menu()
+
+        item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
+        menu.AppendItem(item)
+        self.Bind(wx.EVT_MENU, self.OnPaste, item)
+        
+        self.PopupMenu(menu)
+        menu.Destroy()


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

Modified: grass/trunk/gui/wxpython/docs/wxGUI.components.html
===================================================================
--- grass/trunk/gui/wxpython/docs/wxGUI.components.html	2015-09-06 13:06:27 UTC (rev 66127)
+++ grass/trunk/gui/wxpython/docs/wxGUI.components.html	2015-09-06 15:12:27 UTC (rev 66128)
@@ -11,6 +11,8 @@
     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>,

Deleted: grass/trunk/gui/wxpython/lmgr/datacatalog.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/datacatalog.py	2015-09-06 13:06:27 UTC (rev 66127)
+++ grass/trunk/gui/wxpython/lmgr/datacatalog.py	2015-09-06 15:12:27 UTC (rev 66128)
@@ -1,609 +0,0 @@
-"""
- at package lmgr::datacatalog
-
- at brief Data catalog
-
-Classes:
- - datacatalog::DataCatalog
- - datacatalog::LocationMapTree
- - datacatalog::DataCatalogTree
-
- at todo:
- - use gui_core/treeview.py
-
-(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.
-
- at 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 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):
-        """Location Map Tree constructor."""
-        super(LocationMapTree, self).__init__(parent, id=wx.ID_ANY, style=style)
-        self.showNotification = Signal('Tree.showNotification')
-        self.parent = parent
-        self.root = self.AddRoot('Catalog') # will not be displayed when we use TR_HIDE_ROOT flag
-        
-        self._initVariables()
-        self.MakeBackup()
-
-        wx.EVT_TREE_ITEM_RIGHT_CLICK(self, wx.ID_ANY, self.OnRightClick)
-        
-        self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
-        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
-        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
-
-    def _initTreeItems(self, locations = [], mapsets = []):
-        """Add locations, mapsets and layers to the tree."""
-        if not locations:
-            locations = GetListOfLocations(self.gisdbase)
-        if not mapsets:
-            mapsets = ['*']
-        
-        first = True
-        for loc in locations:
-            location = loc
-            if first:
-                self.ChangeEnvironment(location, 'PERMANENT')
-                first = False
-            else:
-                self.ChangeEnvironment(location)
-            
-            varloc = self.AppendItem(self.root, loc)
-            # add all mapsets
-            mapsets = ListOfMapsets()
-            if mapsets:
-                for mapset in mapsets:
-                    self.AppendItem(varloc, mapset)
-            else:
-                self.AppendItem(varloc, _("No mapsets readable"))
-                continue
-
-            # get list of all maps in location
-            maplist = RunCommand('g.list', flags='mt', type='raster,raster_3d,vector', mapset=','.join(mapsets),
-                                 quiet=True, read=True)
-            maplist = maplist.splitlines()
-            for ml in maplist:
-                # parse
-                parts1 = ml.split('/')
-                parts2 = parts1[1].split('@')
-                mapset = parts2[1]
-                mlayer = parts2[0]
-                ltype = parts1[0]
-
-                # add mapset
-                if self.itemExists(mapset, varloc) == False:
-                    varmapset = self.AppendItem(varloc, mapset)
-                else:
-                    varmapset = self.getItemByName(mapset, varloc)
-
-                # add type node if not exists
-                if self.itemExists(ltype, varmapset) == False:
-                    vartype = self.AppendItem(varmapset, ltype)
-                
-                self.AppendItem(vartype, mlayer)
-            
-        self.RestoreBackup()          
-        Debug.msg(1, "Tree filled")    
-
-    def InitTreeItems(self):
-        """Create popup menu for layers"""
-        raise NotImplementedError()
-
-    def _popupMenuLayer(self):
-        """Create popup menu for layers"""
-        raise NotImplementedError()
-
-    def _popupMenuMapset(self):
-        """Create popup menu for mapsets"""
-        raise NotImplementedError()
-
-    def _initVariables(self):
-        """Init variables."""
-        self.selected_layer = None
-        self.selected_type = None
-        self.selected_mapset = None
-        self.selected_location = None
-        
-        self.gisdbase =  grass.gisenv()['GISDBASE']
-        self.ctrldown = False
-
-    def GetControl(self):
-        """Returns control itself."""
-        return self
-    
-    def DefineItems(self, item0):
-        """Set selected items."""
-        self.selected_layer = None
-        self.selected_type = None
-        self.selected_mapset = None
-        self.selected_location = None
-        items = []
-        item = item0
-        while (self.GetItemParent(item)):
-            items.insert(0,item)
-            item = self.GetItemParent(item)
-        
-        self.selected_location = items[0]
-        length = len(items)
-        if (length > 1):
-            self.selected_mapset = items[1]
-            if (length > 2):
-                self.selected_type = items[2]
-                if (length > 3):
-                    self.selected_layer = items[3]
-        
-    def getItemByName(self, match, root):
-        """Return match item from the root."""
-        item, cookie = self.GetFirstChild(root)
-        while item.IsOk():
-            if self.GetItemText(item) == match:
-                return item
-            item, cookie = self.GetNextChild(root, cookie)
-        return None
-    
-    def itemExists(self, match, root):
-        """Return true if match item exists in the root item."""
-        item, cookie = self.GetFirstChild(root)
-        while item.IsOk():
-            if self.GetItemText(item) == match:
-                return True
-            item, cookie = self.GetNextChild(root, cookie)
-        return False       
-    
-    def UpdateTree(self):
-        """Update whole tree."""
-        self.DeleteAllItems()
-        self.root = self.AddRoot('Tree')
-        self.AddTreeItems()
-        label = "Tree updated."
-        self.showNotification.emit(message=label)
-        
-    def OnSelChanged(self, event):
-        self.selected_layer = None
-        
-    def OnRightClick(self, event):
-        """Display popup menu."""
-        self.DefineItems(event.GetItem())
-        if(self.selected_layer):
-            self._popupMenuLayer()
-        elif(self.selected_mapset and self.selected_type==None):
-            self._popupMenuMapset() 
-    
-    def OnDoubleClick(self, event):
-        """Double click"""
-        Debug.msg(1, "Double CLICK")
-            
-    def OnKeyDown(self, event):
-        """Set key event and check if control key is down"""
-        keycode = event.GetKeyCode()
-        if keycode == wx.WXK_CONTROL:
-            self.ctrldown = True
-            Debug.msg(1,"CONTROL ON")
-
-    def OnKeyUp(self, event):
-        """Check if control key is up"""
-        keycode = event.GetKeyCode()
-        if keycode == wx.WXK_CONTROL:
-            self.ctrldown = False
-            Debug.msg(1,"CONTROL OFF")
-
-    def MakeBackup(self):
-        """Make backup for case of change"""
-        gisenv = grass.gisenv()
-        self.glocation = gisenv['LOCATION_NAME']
-        self.gmapset = gisenv['MAPSET']
-
-    def RestoreBackup(self):
-        """Restore backup"""
-        stringl = 'LOCATION_NAME='+self.glocation
-        RunCommand('g.gisenv', set=stringl)
-        stringm = 'MAPSET='+self.gmapset
-        RunCommand('g.gisenv', set=stringm)
-        
-    def ChangeEnvironment(self, location, mapset=None):
-        """Change gisenv variables -> location, mapset"""
-        stringl = 'LOCATION_NAME='+location
-        RunCommand('g.gisenv', set=stringl)
-        if mapset:
-            stringm = 'MAPSET='+mapset
-            RunCommand('g.gisenv', set=stringm)
-
-    def ExpandCurrentLocation(self):
-        """Expand current location"""
-        location = grass.gisenv()['LOCATION_NAME']
-        item = self.getItemByName(location, self.root)
-        if item is not None:
-            self.SelectItem(item)
-            self.ExpandAllChildren(item)
-            self.EnsureVisible(item)
-        else:
-            Debug.msg(1, "Location <%s> not found" % location)
-
-class DataCatalogTree(LocationMapTree):
-    def __init__(self, parent):
-        """Data Catalog Tree constructor."""
-        super(DataCatalogTree, self).__init__(parent)
-        
-        self._initVariablesCatalog()
-
-        wx.EVT_TREE_BEGIN_DRAG(self, wx.ID_ANY, self.OnBeginDrag)
-        wx.EVT_TREE_END_DRAG(self, wx.ID_ANY, self.OnEndDrag)
-        
-        wx.EVT_TREE_END_LABEL_EDIT(self, wx.ID_ANY, self.OnEditLabel)
-        wx.EVT_TREE_BEGIN_LABEL_EDIT(self, wx.ID_ANY, self.OnStartEditLabel)
-    
-    def _initVariablesCatalog(self):
-        """Init variables."""
-        self.copy_layer = None
-        self.copy_type = None
-        self.copy_mapset = None
-        self.copy_location = None
-
-    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
-        self.copy_type = self.selected_type
-        self.copy_mapset = self.selected_mapset
-        self.copy_location = self.selected_location 
-        label = "Layer "+self.GetItemText(self.copy_layer)+" copied to clipboard. You can paste it to selected mapset."
-        self.showNotification.emit(message=label)
-        
-    def OnRename(self, event): 
-        """Rename levent with dialog"""
-        if (self.selected_layer):
-            self.old_name = self.GetItemText(self.selected_layer)
-            self.new_name = self._getUserEntry(_('New name'), _('Rename map'), self.old_name)
-            self.rename() 
-    
-    def OnStartEditLabel(self, event):
-        """Start label editing"""
-        item = event.GetItem()
-        self.DefineItems(item)
-        Debug.msg(1, "Start label edit "+self.GetItemText(item))
-        label = _("Editing") + " " + self.GetItemText(item)
-        self.showNotification.emit(message=label)
-        if (self.selected_layer == None):
-            event.Veto()
-    
-    def OnEditLabel(self, event):
-        """End label editing"""
-        if (self.selected_layer):
-            item = event.GetItem()
-            self.old_name = self.GetItemText(item)
-            Debug.msg(1, "End label edit "+self.old_name)
-            wx.CallAfter(self.afterEdit, self, item)
-            
-    def afterEdit(pro, self, item):
-        self.new_name = self.GetItemText(item)
-        self.rename()
-    
-    def rename(self):
-        """Rename layer"""
-        if self.selected_layer and self.new_name:
-            string = self.old_name+','+self.new_name
-            self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))
-            renamed = 0
-            label = _("Renaming") + " " + string + " ..."
-            self.showNotification.emit(message=label)
-            if (self.GetItemText(self.selected_type)=='vector'):
-                renamed = RunCommand('g.rename', vector=string)
-            elif (self.GetItemText(self.selected_type)=='raster'):
-                renamed = RunCommand('g.rename', raster=string)
-            else:
-                renamed = RunCommand('g.rename', raster3d=string)
-            if (renamed==0):
-                self.SetItemText(self.selected_layer,self.new_name)
-                label = "g.rename "+self.GetItemText(self.selected_type)+"="+string+"   -- completed"
-                self.showNotification.emit(message=label)
-                Debug.msg(1,"LAYER RENAMED TO: "+self.new_name)
-            self.RestoreBackup()    
-        
-    def OnPaste(self, event):
-        """Paste layer or mapset""" 
-        # copying between mapsets of one location
-        if (self.copy_layer == None):
-                return
-        if (self.selected_location == self.copy_location and self.selected_mapset):
-            if (self.selected_type != None):
-                if (self.GetItemText(self.copy_type) != self.GetItemText(self.selected_type)): # copy raster to vector or vice versa
-                    GError(_("Failed to copy layer: invalid type."), parent = self)
-                    return
-            self.new_name = self._getUserEntry(_('New name'), _('Copy map'),
-                                               self.GetItemText(self.copy_layer) + '_copy')
-            if not self.new_name:
-                return
-            if (self.GetItemText(self.copy_layer) == self.new_name):
-                GMessage(_("Layer was not copied: new layer has the same name"), parent=self) 
-                return
-            string = self.GetItemText(self.copy_layer)+'@'+self.GetItemText(self.copy_mapset)+','+self.new_name
-            self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))
-            pasted = 0
-            type = None
-            label = _("Copying") + " " + string + " ..."
-            self.showNotification.emit(message=label)
-            if (self.GetItemText(self.copy_type)=='vector'):
-                pasted = RunCommand('g.copy', vector=string)
-                node = 'vector'     
-            elif (self.GetItemText(self.copy_type)=='raster'):
-                pasted = RunCommand('g.copy', raster=string)
-                node = 'raster'
-            else:
-                pasted = RunCommand('g.copy', raster_3d=string)
-                node = 'raster_3d'
-            if pasted == 0:
-                if self.selected_type == None:
-                    self.selected_type = self.getItemByName(node, self.selected_mapset)
-                    if self.selected_type == None:
-                        # add type node if not exists
-                        self.selected_type = self.AppendItem(self.selected_mapset, node)
-                self.AppendItem(self.selected_type,self.new_name) 
-                self.SortChildren(self.selected_type)
-                Debug.msg(1,"COPIED TO: "+self.new_name)
-                label = "g.copy "+self.GetItemText(self.copy_type)+"="+string+"    -- completed" # generate this message (command) automatically?
-                self.showNotification.emit(message=label)
-        else:
-            GError(_("Failed to copy layer: action is allowed only within the same location."),
-                   parent=self)
-        
-        # expand selected mapset
-        self.ExpandAllChildren(self.selected_mapset)
-        self.EnsureVisible(self.selected_mapset)
-        
-        self.RestoreBackup()
-        
-        
-    def OnDelete(self, event):
-        """Delete layer or mapset"""
-        if (self.selected_layer):
-            string = self.GetItemText(self.selected_layer)
-            self.ChangeEnvironment(self.GetItemText(self.selected_location), self.GetItemText(self.selected_mapset))
-            removed = 0
-            # TODO: rewrite this that it will tell map type in the dialog
-            if (self._confirmDialog(question=_('Do you really want to delete map <{m}>?').format(m=string),
-                                    title=_('Delete map')) == wx.ID_YES):
-                label = _("Deleting") + " " + string + " ..."
-                self.showNotification.emit(message=label)
-                if (self.GetItemText(self.selected_type)=='vector'):
-                    removed = RunCommand('g.remove', flags='f', type='vector',
-                                         name=string)
-                elif (self.GetItemText(self.selected_type)=='raster'):
-                    removed = RunCommand('g.remove', flags='f', type='raster',
-                                         name=string)
-                else:
-                    removed = RunCommand('g.remove', flags='f', type='raster_3d',
-                                         name=string)
-                if (removed==0):
-                    self.Delete(self.selected_layer)
-                    Debug.msg(1,"LAYER "+string+" DELETED")
-                    label = "g.remove -f type="+self.GetItemText(self.selected_type)+" name="+string+"    -- completed" # generate this message (command) automatically?
-                    self.showNotification.emit(message=label)
-            self.RestoreBackup()
-            
-    def OnDisplayLayer(self, event):
-        """Display layer in current graphics view"""
-        layerName = []
-        if (self.GetItemText(self.selected_location) == self.glocation and self.selected_mapset):
-            string = self.GetItemText(self.selected_layer)+'@'+self.GetItemText(self.selected_mapset)
-            layerName.append(string)
-            label = _("Displaying") + " " + string + " ..."
-            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)
-            elif (self.GetItemText(self.selected_type)=='raster'):
-                self.parent.parent.AddMaps(layerName, 'raster', True)     
-            else:
-                self.parent.parent.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")
-        else:
-            GError(_("Failed to display layer: not in current mapset or invalid layer"),
-                   parent = self)
-
-    def OnBeginDrag(self, event):
-        """Just copy necessary data"""
-        if (self.ctrldown):
-            #cursor = wx.StockCursor(wx.CURSOR_HAND)
-            #self.SetCursor(cursor)
-            event.Allow()
-            self.DefineItems(event.GetItem())
-            self.OnCopy(event)
-            Debug.msg(1,"DRAG")
-        else:
-            event.Veto()
-            Debug.msg(1,"DRAGGING without ctrl key does nothing") 
-        
-    def OnEndDrag(self, event):
-        """Copy layer into target"""
-        #cursor = wx.StockCursor(wx.CURSOR_ARROW)
-        #self.SetCursor(cursor)
-        if (event.GetItem()): 
-            self.DefineItems(event.GetItem())
-            if (self.selected_location == self.copy_location and self.selected_mapset):
-                event.Allow()
-                self.OnPaste(event)
-                self.ctrldown = False
-                #cursor = wx.StockCursor(wx.CURSOR_DEFAULT)
-                #self.SetCursor(cursor) # TODO: change cursor while dragging and then back, this is not working
-                Debug.msg(1,"DROP DONE") 
-            else:
-                event.Veto()
-
-    def _getUserEntry(self, message, title, value):
-        """Dialog for simple text entry"""
-        dlg = TextEntryDialog(self, message, title)
-        dlg.SetValue(value)
-        if dlg.ShowModal() == wx.ID_OK:
-            name = dlg.GetValue()
-        else:
-            name = None
-        dlg.Destroy()
-
-        return name
-
-    def _confirmDialog(self, question, title):
-        """Confirm dialog"""
-        dlg = wx.MessageDialog(self, question, title, wx.YES_NO)
-        res = dlg.ShowModal()
-        dlg.Destroy()
-        return res
-
-    def _popupMenuLayer(self):
-        """Create popup menu for layers"""
-        menu = wx.Menu()
-        
-        item = wx.MenuItem(menu, wx.NewId(), _("&Copy"))
-        menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnCopy, item)
-
-        item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
-        menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnPaste, item)
- 
-        item = wx.MenuItem(menu, wx.NewId(), _("&Delete"))
-        menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnDelete, item)
-        
-        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)
-        
-        self.PopupMenu(menu)
-        menu.Destroy()
-        
-    def _popupMenuMapset(self):
-        """Create popup menu for mapsets"""
-        menu = wx.Menu()
-
-        item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
-        menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnPaste, item)
-        
-        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()

Modified: grass/trunk/gui/wxpython/lmgr/frame.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/frame.py	2015-09-06 13:06:27 UTC (rev 66127)
+++ grass/trunk/gui/wxpython/lmgr/frame.py	2015-09-06 15:12:27 UTC (rev 66128)
@@ -70,7 +70,7 @@
 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



More information about the grass-commit mailing list