[GRASS-SVN] r68256 - in grass/trunk/gui: icons/grass wxpython/datacatalog

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Apr 12 20:20:45 PDT 2016


Author: annakrat
Date: 2016-04-12 20:20:44 -0700 (Tue, 12 Apr 2016)
New Revision: 68256

Added:
   grass/trunk/gui/icons/grass/locked.png
   grass/trunk/gui/icons/grass/unlocked.png
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: update data catalog - allow editing outside of current mapset

Added: grass/trunk/gui/icons/grass/locked.png
===================================================================
(Binary files differ)


Property changes on: grass/trunk/gui/icons/grass/locked.png
___________________________________________________________________
Added: svn:mime-type
   + image/png

Added: grass/trunk/gui/icons/grass/unlocked.png
===================================================================
(Binary files differ)


Property changes on: grass/trunk/gui/icons/grass/unlocked.png
___________________________________________________________________
Added: svn:mime-type
   + image/png

Modified: grass/trunk/gui/wxpython/datacatalog/catalog.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/catalog.py	2016-04-12 19:57:43 UTC (rev 68255)
+++ grass/trunk/gui/wxpython/datacatalog/catalog.py	2016-04-13 03:20:44 UTC (rev 68256)
@@ -84,3 +84,7 @@
     def OnReloadCurrentMapset(self, event):
         """Reload current mapset tree only"""
         self.tree.ReloadCurrentMapset()
+
+    def SetRestriction(self, restrict):
+        """Allow editing other mapsets or restrict editing to current mapset"""
+        self.tree.SetRestriction(restrict)

Modified: grass/trunk/gui/wxpython/datacatalog/frame.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/frame.py	2016-04-12 19:57:43 UTC (rev 68255)
+++ grass/trunk/gui/wxpython/datacatalog/frame.py	2016-04-13 03:20:44 UTC (rev 68256)
@@ -26,6 +26,7 @@
 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):
@@ -37,7 +38,7 @@
         self._giface = giface
         self.panel = wx.Panel(self)
 
-        self.toolbar = DataCatalogToolbar(parent = self)
+        self.toolbar = DataCatalogToolbar(parent=self)
         # workaround for http://trac.wxwidgets.org/ticket/13888
         if sys.platform != 'darwin':
             self.SetToolBar(self.toolbar)
@@ -46,7 +47,7 @@
         self.tree = DataCatalogTree(parent=self.panel, giface=self._giface)
         self.tree.InitTreeItems()
         self.tree.ExpandCurrentMapset()
-        
+
         # buttons
         self.btnClose = wx.Button(parent=self.panel, id=wx.ID_CLOSE)
         self.btnClose.SetToolTipString(_("Close GRASS GIS Data Catalog"))
@@ -90,3 +91,7 @@
     def OnReloadCurrentMapset(self, event):
         """Reload current mapset tree only"""
         self.tree.ReloadCurrentMapset()
+
+    def SetRestriction(self, restrict):
+        """Allow editing other mapsets or restrict editing to current mapset"""
+        self.tree.SetRestriction(restrict)

Modified: grass/trunk/gui/wxpython/datacatalog/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/toolbars.py	2016-04-12 19:57:43 UTC (rev 68255)
+++ grass/trunk/gui/wxpython/datacatalog/toolbars.py	2016-04-13 03:20:44 UTC (rev 68256)
@@ -15,15 +15,18 @@
 """
 
 import wx
-from gui_core.toolbars import BaseToolbar, BaseIcons
+from gui_core.toolbars import BaseToolbar
 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"))
+    'reloadMapset': MetaIcon(img='reload', label=_("Reload current GRASS mapset only")),
+    'unlocked': MetaIcon(img='unlocked', label=_("Click to restrict editing to current mapset only")),
+    'locked': MetaIcon(img='locked', label=_("Click to allow editing other mapsets")),
     }
 
+
 class DataCatalogToolbar(BaseToolbar):
     """Main data catalog toolbar
     """
@@ -44,5 +47,17 @@
         return self._getToolbarData((("reloadTree", icons["reloadTree"],
                                       self.parent.OnReloadTree),
                                      ("reloadMapset", icons["reloadMapset"],
-                                      self.parent.OnReloadCurrentMapset)
+                                      self.parent.OnReloadCurrentMapset),
+                                     ("lock", icons['locked'],
+                                      self.OnSetRestriction, wx.ITEM_CHECK)
                                      ))
+
+    def OnSetRestriction(self, event):
+        if self.GetToolState(self.lock):
+            self.SetToolNormalBitmap(self.lock, icons['unlocked'].GetBitmap())
+            self.SetToolShortHelp(self.lock, icons['unlocked'].GetLabel())
+            self.parent.SetRestriction(restrict=False)
+        else:
+            self.SetToolNormalBitmap(self.lock, icons['locked'].GetBitmap())
+            self.SetToolShortHelp(self.lock, icons['locked'].GetLabel())
+            self.parent.SetRestriction(restrict=True)

Modified: grass/trunk/gui/wxpython/datacatalog/tree.py
===================================================================
--- grass/trunk/gui/wxpython/datacatalog/tree.py	2016-04-12 19:57:43 UTC (rev 68255)
+++ grass/trunk/gui/wxpython/datacatalog/tree.py	2016-04-13 03:20:44 UTC (rev 68256)
@@ -32,6 +32,7 @@
 from grass.pydispatch.signal import Signal
 
 import grass.script as gscript
+from grass.script import gisenv
 from grass.exceptions import CalledModuleError
 
 
@@ -50,7 +51,7 @@
     return tmp_gisrc_file, env
 
 
-def getLocationTree(gisdbase, location, queue, mapsets=[]):
+def getLocationTree(gisdbase, location, queue, mapsets=None):
     """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')
@@ -92,6 +93,64 @@
     gscript.try_remove(tmp_gisrc_file)
 
 
+def map_exists(name, element, env, mapset=None):
+    """Check is map is present in the mapset given in the environment
+
+    :param name: name of the map
+    :param element: data type ('raster', 'raster_3d', and 'vector')
+    :param env environment created by function getEnvironment
+    """
+    if not mapset:
+        mapset = gscript.run_command('g.mapset', flags='p', env=env).strip()
+    # change type to element used by find file
+    if element == 'raster':
+        element = 'cell'
+    elif element == 'raster_3d':
+        element = 'grid3'
+    # g.findfile returns non-zero when file was not found
+    # se we ignore return code and just focus on stdout
+    process = gscript.start_command('g.findfile', flags='n',
+                                    element=element, file=name, mapset=mapset,
+                                    stdout=gscript.PIPE, stderr=gscript.PIPE, env=env)
+    output, errors = process.communicate()
+    info = gscript.parse_key_val(output, sep='=')
+    # file is the key questioned in grass.script.core find_file()
+    # return code should be equivalent to checking the output
+    if info['file']:
+        return True
+    else:
+        return False
+
+
+class NameEntryDialog(TextEntryDialog):
+    def __init__(self, element, mapset, env, **kwargs):
+        TextEntryDialog.__init__(self, **kwargs)
+        self._element = element
+        self._mapset = mapset
+        self._env = env
+        id_OK = self.GetAffirmativeId()
+        self.Bind(wx.EVT_BUTTON, self.OnOK, self.FindWindowById(id_OK))
+
+    def OnOK(self, event):
+        new = self.GetValue()
+        if not new:
+            return
+        if map_exists(new, self._element, self._env, self._mapset):
+            dlg = wx.MessageDialog(self, message=_("Map of type {elem} <{name}> already exists in mapset <{mapset}>. "
+                                                   "Do you want to overwrite it?").format(elem=self._element,
+                                   name=new, mapset=self._mapset),
+                                   caption=_("Overwrite?"), style=wx.YES_NO)
+            if dlg.ShowModal() == wx.ID_YES:
+                dlg.Destroy()
+                self._env['GRASS_OVERWRITE'] = '1'
+                self.EndModal(wx.ID_OK)
+            else:
+                dlg.Destroy()
+                return
+        else:
+            self.EndModal(wx.ID_OK)
+
+
 class DataCatalogNode(DictNode):
     """Node representing item in datacatalog."""
     def __init__(self, label, data=None):
@@ -122,15 +181,16 @@
         self.parent = parent
         self.contextMenu.connect(self.OnRightClick)
         self.itemActivated.connect(self.OnDoubleClick)
-        
+
         self._initVariables()
 
     def _initTreeItems(self, locations=None, mapsets=None):
         """Add locations, mapsets and layers to the tree.
         Runs in multiple processes. Saves resulting data and error."""
         # mapsets param currently unused
+        genv = gisenv()
         if not locations:
-            locations = GetListOfLocations(self.gisdbase)
+            locations = GetListOfLocations(genv['GISDBASE'])
 
         loc_count = proc_count = 0
         queue_list = []
@@ -141,13 +201,13 @@
             nprocs = cpu_count()
         except NotImplementedError:
                 nprocs = 4
-                
+
         results = dict()
         errors = []
         location_nodes = []
         nlocations = len(locations)
         grassdata_node = self._model.AppendNode(parent=self._model.root,
-                                                label=_('GRASS locations ({})').format(self.gisdbase),
+                                                label=_('GRASS locations in {}').format(genv['GISDBASE']),
                                                 data=dict(type='grassdata'))
         for location in locations:
             results[location] = dict()
@@ -160,7 +220,7 @@
 
             q = Queue()
             p = Process(target=getLocationTree,
-                        args=(self.gisdbase, location, q))
+                        args=(genv['GISDBASE'], location, q))
             p.start()
 
             queue_list.append(q)
@@ -212,6 +272,7 @@
                 child = None
             return child
 
+        genv = gisenv()
         locationItem, mapsetItem = self.GetCurrentLocationMapsetNode()
         if not locationItem or not mapsetItem:
             return
@@ -224,11 +285,11 @@
 
         q = Queue()
         p = Process(target=getLocationTree,
-                    args=(self.gisdbase, locationItem.data['name'], q, mapsetItem.data['name']))
+                    args=(genv['GISDBASE'], locationItem.data['name'], q, mapsetItem.data['name']))
         p.start()
         maps, error = q.get()
         if error:
-            raise CalledModuleError(e)
+            raise CalledModuleError(error)
 
         self._populateMapsetItem(mapsetItem, maps[mapsetItem.data['name']])
         self.RefreshNode(mapsetItem)
@@ -251,6 +312,10 @@
         """Create popup menu for mapsets"""
         raise NotImplementedError()
 
+    def _popupMenuElement(self):
+        """Create popup menu for elements"""
+        raise NotImplementedError()
+
     def _initVariables(self):
         """Init variables."""
         self.selected_layer = None
@@ -258,11 +323,6 @@
         self.selected_mapset = None
         self.selected_location = None
 
-        gisenv = gscript.gisenv()
-        self.gisdbase = gisenv['GISDBASE']
-        self.glocation = gisenv['LOCATION_NAME']
-        self.gmapset = gisenv['MAPSET']
-
     def GetControl(self):
         """Returns control itself."""
         return self
@@ -279,7 +339,7 @@
             self.selected_layer = item
             type = 'element'
             item = item.parent
-            
+
         if type == 'element':
             self.selected_type = item
             type = 'mapset'
@@ -289,20 +349,22 @@
             self.selected_mapset = item
             type = 'location'
             item = item.parent
-            
+
         if type == 'location':
             self.selected_location = item
-        
+
     def OnSelChanged(self, event):
         self.selected_layer = None
-                
+
     def OnRightClick(self, node):
         """Display popup menu."""
         self.DefineItems(node)
         if self.selected_layer:
-            self._popupMenuLayer(self.selected_mapset.label == self.gmapset)
+            self._popupMenuLayer()
         elif self.selected_mapset and not self.selected_type:
             self._popupMenuMapset()
+        elif self.selected_type:
+            self._popupMenuElement()
 
     def OnDoubleClick(self, node):
         """Expand/Collapse node."""
@@ -310,7 +372,7 @@
             self.CollapseNode(node, recursive=False)
         else:
             self.ExpandNode(node, recursive=False)
-        
+
     def ExpandCurrentLocation(self):
         """Expand current location"""
         location = gscript.gisenv()['LOCATION_NAME']
@@ -323,9 +385,9 @@
 
     def GetCurrentLocationMapsetNode(self):
         """Get current mapset node"""
-        gisenv = gscript.gisenv()
-        location = gisenv['LOCATION_NAME']
-        mapset = gisenv['MAPSET']
+        genv = gisenv()
+        location = genv['LOCATION_NAME']
+        mapset = genv['MAPSET']
         locationItem = self._model.SearchNodes(name=location, type='location')
         if not locationItem:
             return None, None
@@ -335,7 +397,7 @@
             return locationItem[0], None
 
         return locationItem[0], mapsetItem[0]
-            
+
     def ExpandCurrentMapset(self):
         """Expand current mapset"""
         locationItem, mapsetItem = self.GetCurrentLocationMapsetNode()
@@ -343,11 +405,13 @@
             self.Select(mapsetItem, select=True)
             self.ExpandNode(mapsetItem, recursive=True)
 
+
 class DataCatalogTree(LocationMapTree):
     def __init__(self, parent, giface=None):
         """Data Catalog Tree constructor."""
         super(DataCatalogTree, self).__init__(parent)
         self._giface = giface
+        self._restricted = True
 
         self._initVariablesCatalog()
         self.beginDrag = Signal('DataCatalogTree.beginDrag')
@@ -356,18 +420,18 @@
         self.endEdit = Signal('DataCatalogTree.endEdit')
 
         self.Bind(wx.EVT_TREE_BEGIN_DRAG, lambda evt:
-            self._emitSignal(evt.GetItem(), self.beginDrag, event=evt))
+                  self._emitSignal(evt.GetItem(), self.beginDrag, event=evt))
         self.Bind(wx.EVT_TREE_END_DRAG, lambda evt:
-            self._emitSignal(evt.GetItem(), self.endDrag, event=evt))
+                  self._emitSignal(evt.GetItem(), self.endDrag, event=evt))
         self.beginDrag.connect(self.OnBeginDrag)
         self.endDrag.connect(self.OnEndDrag)
 
         self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, lambda evt:
-            self._emitSignal(evt.GetItem(), self.startEdit, event=evt))
+                  self._emitSignal(evt.GetItem(), self.startEdit, event=evt))
         self.Bind(wx.EVT_TREE_END_LABEL_EDIT, lambda evt:
-            self._emitSignal(evt.GetItem(), self.endEdit, event=evt))
-        ###self.startEdit.connect(self.OnStartEditLabel)
-        ###self.endEdit.connect(self.OnEditLabel)
+                  self._emitSignal(evt.GetItem(), self.endEdit, event=evt))
+        self.startEdit.connect(self.OnStartEditLabel)
+        self.endEdit.connect(self.OnEditLabel)
 
     def _initVariablesCatalog(self):
         """Init variables."""
@@ -376,17 +440,20 @@
         self.copy_mapset = None
         self.copy_location = None
 
+    def SetRestriction(self, restrict):
+        self._restricted = restrict
+
     def _runCommand(self, prog, **kwargs):
         cmdString = ' '.join(gscript.make_command(prog, **kwargs))
         ret = RunCommand(prog, parent=self, **kwargs)
 
         return ret, cmdString
-                
+
     def InitTreeItems(self):
         """Add locations, mapsets and layers to the tree."""
         self._initTreeItems()
-        
-    def OnCopy(self, event):
+
+    def OnCopyMap(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
@@ -394,15 +461,17 @@
         self.copy_location = self.selected_location
         label = _("Map <{layer}> marked for copying. "
                   "You can paste it to the current mapset "
-                  "<{mapset}>.".format(layer=self.copy_layer.label, mapset=self.gmapset))
+                  "<{mapset}>.".format(layer=self.copy_layer.label, mapset=gisenv()['MAPSET']))
         self.showNotification.emit(message=label)
 
-    def OnRename(self, event):
-        """Rename levent with dialog"""
-        if self.selected_layer:
-            self.old_name = self.selected_layer.label
-            self.new_name = self._getUserEntry(_('New name'), _('Rename map'), self.old_name)
-            self.Rename()
+    def OnRenameMap(self, event):
+        """Rename layer with dialog"""
+        old_name = self.selected_layer.label
+        gisrc, env = getEnvironment(gisenv()['GISDBASE'], self.selected_location.label, mapset=self.selected_mapset.label)
+        new_name = self._getNewMapName(_('New name'), _('Rename map'),
+                                       old_name, env=env, mapset=self.selected_mapset.label, element=self.selected_type.label)
+        if new_name:
+            self.Rename(old_name, new_name)
 
     def OnStartEditLabel(self, node, event):
         """Start label editing"""
@@ -416,51 +485,44 @@
     def OnEditLabel(self, node, event):
         """End label editing"""
         if self.selected_layer and not event.IsEditCancelled():
-            self.old_name = node.label
-            Debug.msg(1, "End label edit {name}".format(name=self.old_name))
-            self.new_name = event.GetLabel()
-            self.Rename()
+            old_name = node.label
+            Debug.msg(1, "End label edit {name}".format(name=old_name))
+            new_name = event.GetLabel()
+            self.Rename(old_name, new_name)
 
-    def Rename(self):
+    def Rename(self, old, new):
         """Rename layer"""
-        if self.selected_layer and self.new_name:
-            string = self.old_name + ',' + self.new_name
-            gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, self.selected_mapset.label)
-            renamed = 0
-            label = _("Renaming map <{name}>...").format(name=string)
-            self.showNotification.emit(message=label)
-            if self.selected_type.label == 'vector':
-                renamed, cmd = self._runCommand('g.rename', vector=string, env=env)
-            elif self.selected_type.label == 'raster':
-                renamed, cmd = self._runCommand('g.rename', raster=string, env=env)
-            else:
-                renamed, cmd = self._runCommand('g.rename', raster3d=string, env=env)
-            if renamed == 0:
-                self.selected_layer.label = self.new_name
-                self.selected_layer.data['name'] = self.new_name
-                self.RefreshNode(self.selected_layer)
-                self.showNotification.emit(message=_("{cmd} -- completed").format(cmd=cmd))
-                Debug.msg(1, "LAYER RENAMED TO: " + self.new_name)
-            gscript.try_remove(gisrc)
+        string = old + ',' + new
+        gisrc, env = getEnvironment(gisenv()['GISDBASE'], self.selected_location.label, self.selected_mapset.label)
+        label = _("Renaming map <{name}>...").format(name=string)
+        self.showNotification.emit(message=label)
+        if self.selected_type.label == 'vector':
+            renamed, cmd = self._runCommand('g.rename', vector=string, env=env)
+        elif self.selected_type.label == 'raster':
+            renamed, cmd = self._runCommand('g.rename', raster=string, env=env)
+        else:
+            renamed, cmd = self._runCommand('g.rename', raster3d=string, env=env)
+        if renamed == 0:
+            self.selected_layer.label = new
+            self.selected_layer.data['name'] = new
+            self.RefreshNode(self.selected_layer)
+            self.showNotification.emit(message=_("{cmd} -- completed").format(cmd=cmd))
+            Debug.msg(1, "LAYER RENAMED TO: " + new)
+        gscript.try_remove(gisrc)
 
-    def OnPaste(self, event):
-        """Paste layer or mapset"""
+    def OnPasteMap(self, event):
+        """Paste layer"""
         # copying between mapsets of one location
         if not self.copy_layer:
             GMessage(_("No map selected for copying."), parent=self)
             return
-        if self.selected_location == self.copy_location and \
-           self.selected_mapset.data['name'] == gscript.gisenv()['MAPSET']:
-            if self.selected_type:
-                if self.copy_type.label != self.selected_type.label:  # copy raster to vector or vice versa
-                    GError(_("Failed to copy map: invalid map type "
-                             "({} vs. {}).".format(self.copy_type.label, self.selected_type.label)), parent=self)
-                    return
-            self.new_name = self._getUserEntry(_('New name'), _('Copy map'),
-                                               self.copy_layer.label + '_copy')
-            if not self.new_name:
+        if self.selected_location == self.copy_location:
+            gisrc, env = getEnvironment(gisenv()['GISDBASE'], self.selected_location.label, mapset=self.selected_mapset.label)
+            new_name = self._getNewMapName(_('New name'), _('Copy map'),
+                                           self.copy_layer.label, env=env, mapset=self.selected_mapset.label, element=self.copy_type.label)
+            if not new_name:
                 return
-            if self.copy_layer.label == self.new_name:
+            if map_exists(new_name, element=self.copy_type.label, env=env, mapset=self.selected_mapset.label):
                 GMessage(_("Failed to copy map: new map has the same name"), parent=self)
                 return
 
@@ -470,21 +532,21 @@
 
             overwrite = False
             if self.selected_type:
-                found = self._model.SearchNodes(parent=self.selected_type, type=self.copy_type.label, name=self.new_name)
+                found = self._model.SearchNodes(parent=self.selected_type, type=self.copy_type.label, name=new_name)
                 if found and found[0]:
                     dlg = wx.MessageDialog(parent=self,
-                                           message = _("Map <{map}> already exists "
-                                                       "in the current mapset. "
-                                                       "Do you want to overwrite it?").format(map=self.new_name),
-                                           caption = _("Overwrite?"),
-                                           style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
+                                           message=_("Map <{map}> already exists "
+                                                     "in the current mapset. "
+                                                     "Do you want to overwrite it?").format(map=new_name),
+                                           caption=_("Overwrite?"),
+                                           style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
                     ret = dlg.ShowModal()
                     dlg.Destroy()
                     if ret == wx.ID_YES:
                         overwrite = True
 
-            string = self.copy_layer.label + '@' + self.copy_mapset.label + ',' + self.new_name
-            gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, self.selected_mapset.label)
+            string = self.copy_layer.label + '@' + self.copy_mapset.label + ',' + new_name
+
             pasted = 0
             label = _("Copying <{name}>...").format(name=string)
             self.showNotification.emit(message=label)
@@ -498,60 +560,63 @@
                 pasted, cmd = self._runCommand('g.copy', raster_3d=string, overwrite=overwrite, env=env)
                 node = 'raster_3d'
             if pasted == 0:
-                if not self.selected_type:
-                    # add type node if not exists
-                    self.selected_type = self._model.AppendNode(parent=self.selected_mapset, label=node,
-                                                                data=dict(type='element', name=node))
-                if not overwrite:
-                    self._model.AppendNode(parent=self.selected_type, label=self.new_name,
-                                           data=dict(type=node, name=self.new_name))
-                    self._model.SortChildren(self.selected_type)
-                    self.RefreshNode(self.selected_type, recursive=True)
-                Debug.msg(1, "COPIED TO: " + self.new_name)
-                self.showNotification.emit(message= _("{cmd} -- completed").format(cmd=cmd))
+                self.InsertLayer(name=new_name, mapset_node=self.selected_mapset, element_name=node)
+                Debug.msg(1, "COPIED TO: " + new_name)
+                self.showNotification.emit(message=_("g.copy completed").format(cmd=cmd))
             gscript.try_remove(gisrc)
         else:
-            if self.selected_location != self.copy_location:
-                GError(_("Failed to copy map: action is allowed only within the same location."),
-                       parent=self)
-            else:
-                GError(_("Failed to copy map: action is allowed only within the current mapset."),
-                       parent=self)
-        
+            GError(_("Failed to copy map: action is allowed only within the same location."),
+                   parent=self)
+
         # expand selected mapset
         self.ExpandNode(self.selected_mapset, recursive=True)
 
-    def OnDelete(self, event):
+    def InsertLayer(self, name, mapset_node, element_name):
+        """Insert layer into model and refresh tree"""
+        found_element = self._model.SearchNodes(parent=mapset_node, type='element', name=element_name)
+        found_element = found_element[0] if found_element else None
+        if not found_element:
+            # add type node if not exists
+            found_element = self._model.AppendNode(parent=mapset_node, label=element_name,
+                                                   data=dict(type='element', name=element_name))
+        found = self._model.SearchNodes(parent=found_element, name=name)
+        if len(found) == 0:
+            self._model.AppendNode(parent=found_element, label=name,
+                                   data=dict(type=element_name, name=name))
+            self._model.SortChildren(found_element)
+            self.RefreshNode(mapset_node, recursive=True)
+
+    def OnDeleteMap(self, event):
         """Delete layer or mapset"""
-        if self.selected_layer:
-            string = self.selected_layer.label
-            gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, self.selected_mapset.label)
-            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 {name}...").format(name=string)
-                self.showNotification.emit(message=label)
-                if self.selected_type.label == 'vector':
-                    removed, cmd = self._runCommand('g.remove', flags='f', type='vector',
-                                         name=string, env=env)
-                elif self.selected_type.label == 'raster':
-                    removed, cmd = self._runCommand('g.remove', flags='f', type='raster',
-                                         name=string, env=env)
-                else:
-                    removed, cmd = self._runCommand('g.remove', flags='f', type='raster_3d',
-                                         name=string, env=env)
-                if removed == 0:
-                    self._model.RemoveNode(self.selected_layer)
-                    self.RefreshNode(self.selected_type, recursive=True)
-                    Debug.msg(1, "LAYER " + string + " DELETED")
-                    self.showNotification.emit(message= _("{cmd} -- completed").format(cmd=cmd))
-            gscript.try_remove(gisrc)
+        name = self.selected_layer.label
+        gisrc, env = getEnvironment(gisenv()['GISDBASE'], self.selected_location.label, self.selected_mapset.label)
+        if self._confirmDialog(question=_("Do you really want to delete map <{m}> of type <{etype}> from mapset "
+                               "<{mapset}> in location <{loc}>?").format(m=name, mapset=self.selected_mapset.label,
+                                                                         etype=self.selected_type.label,
+                                                                         loc=self.selected_location.label),
+                               title=_('Delete map')) == wx.ID_YES:
+            label = _("Deleting {name}...").format(name=name)
+            self.showNotification.emit(message=label)
+            if self.selected_type.label == 'vector':
+                removed, cmd = self._runCommand('g.remove', flags='f', type='vector',
+                                                name=name, env=env)
+            elif self.selected_type.label == 'raster':
+                removed, cmd = self._runCommand('g.remove', flags='f', type='raster',
+                                                name=name, env=env)
+            else:
+                removed, cmd = self._runCommand('g.remove', flags='f', type='raster_3d',
+                                                name=name, env=env)
+            if removed == 0:
+                self._model.RemoveNode(self.selected_layer)
+                self.RefreshNode(self.selected_type, recursive=True)
+                Debug.msg(1, "LAYER " + name + " DELETED")
+                self.showNotification.emit(message=_("g.remove completed").format(cmd=cmd))
+        gscript.try_remove(gisrc)
 
     def OnDisplayLayer(self, event):
         """Display layer in current graphics view"""
         layerName = []
-        if self.selected_location.label == self.glocation and self.selected_mapset:
+        if self.selected_location.label == gisenv()['LOCATION_NAME'] and self.selected_mapset:
             string = self.selected_layer.label + '@' + self.selected_mapset.label
             layerName.append(string)
             label = _("Displaying {name}...").format(name=string)
@@ -573,35 +638,39 @@
 
     def OnBeginDrag(self, node, event):
         """Just copy necessary data"""
-        if wx.GetMouseState().ControlDown():
-            #cursor = wx.StockCursor(wx.CURSOR_HAND)
-            #self.SetCursor(cursor)
+        self.DefineItems(node)
+        if self.selected_layer and \
+           not (self._restricted and gisenv()['LOCATION_NAME'] != self.selected_location.label):
             event.Allow()
-            self.DefineItems(node)
-            self.OnCopy(event)
+            self.OnCopyMap(event)
             Debug.msg(1, "DRAG")
         else:
             event.Veto()
-            Debug.msg(1, "DRAGGING without ctrl key does nothing")
 
     def OnEndDrag(self, node, event):
         """Copy layer into target"""
-        #cursor = wx.StockCursor(wx.CURSOR_ARROW)
-        #self.SetCursor(cursor)
+
+        if not wx.GetMouseState().ControlDown():
+            GMessage(_("Moving maps not implemented"), parent=self)
+            event.Veto()
+            return
         if node:
             self.DefineItems(node)
+            if self._restricted and gisenv()['MAPSET'] != self.selected_mapset.label:
+                GMessage(_("Maps can be copied only to current mapset"), parent=self)
+                event.Veto()
+                return
             if self.selected_location == self.copy_location and self.selected_mapset:
                 event.Allow()
-                self.OnPaste(event)
-                #cursor = wx.StockCursor(wx.CURSOR_DEFAULT)
-                #self.SetCursor(cursor) # TODO: change cursor while dragging and then back, this is not working
+                self.OnPasteMap(event)
                 Debug.msg(1, "DROP DONE")
             else:
                 event.Veto()
 
-    def _getUserEntry(self, message, title, value):
+    def _getNewMapName(self, message, title, value, element, mapset, env):
         """Dialog for simple text entry"""
-        dlg = TextEntryDialog(self, message, title)
+        dlg = NameEntryDialog(parent=self, message=message, caption=title,
+                              element=element, env=env, mapset=mapset)
         dlg.SetValue(value)
         if dlg.ShowModal() == wx.ID_OK:
             name = dlg.GetValue()
@@ -618,28 +687,43 @@
         dlg.Destroy()
         return res
 
-    def _popupMenuLayer(self, current_mapset):
+    def _popupMenuLayer(self):
         """Create popup menu for layers"""
         menu = wx.Menu()
+        if self._restricted:
+            genv = gisenv()
+            currentMapset = currentLocation = False
+            if self.selected_location.label == genv['LOCATION_NAME']:
+                currentLocation = True
+                if self.selected_mapset.label == genv['MAPSET']:
+                    currentMapset = True
+        else:
+            currentMapset = currentLocation = True
 
         item = wx.MenuItem(menu, wx.NewId(), _("&Copy"))
         menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnCopy, item)
+        self.Bind(wx.EVT_MENU, self.OnCopyMap, item)
+        item.Enable(currentLocation)
 
-        item = wx.MenuItem(menu, wx.NewId(), _("&Delete"))
+        item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
         menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnDelete, item)
-        if not current_mapset:
+        self.Bind(wx.EVT_MENU, self.OnPasteMap, item)
+        if not(currentLocation and self.copy_layer and self.selected_location == self.copy_location):
             item.Enable(False)
 
+        item = wx.MenuItem(menu, wx.NewId(), _("&Delete"))
+        menu.AppendItem(item)
+        self.Bind(wx.EVT_MENU, self.OnDeleteMap, item)
+        item.Enable(currentMapset)
+
         item = wx.MenuItem(menu, wx.NewId(), _("&Rename"))
         menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnRename, item)
-        if not current_mapset:
-            item.Enable(False)
+        self.Bind(wx.EVT_MENU, self.OnRenameMap, item)
+        item.Enable(currentMapset)
 
-        if not isinstance(self._giface, StandaloneGrassInterface):
-            item = wx.MenuItem(menu, wx.NewId(), _("&Display"))
+        if not isinstance(self._giface, StandaloneGrassInterface) and \
+           self.selected_location.label == genv['LOCATION_NAME']:
+            item = wx.MenuItem(menu, wx.NewId(), _("&Display layer"))
             menu.AppendItem(item)
             self.Bind(wx.EVT_MENU, self.OnDisplayLayer, item)
 
@@ -652,7 +736,21 @@
 
         item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
         menu.AppendItem(item)
-        self.Bind(wx.EVT_MENU, self.OnPaste, item)
+        self.Bind(wx.EVT_MENU, self.OnPasteMap, item)
+        if not (self.copy_layer and self.selected_location == self.copy_location):
+            item.Enable(False)
 
         self.PopupMenu(menu)
         menu.Destroy()
+
+    def _popupMenuElement(self):
+        """Create popup menu for elements"""
+        menu = wx.Menu()
+        item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
+        menu.AppendItem(item)
+        self.Bind(wx.EVT_MENU, self.OnPasteMap, item)
+        if not (self.copy_layer and self.selected_location == self.copy_location):
+            item.Enable(False)
+
+        self.PopupMenu(menu)
+        menu.Destroy()



More information about the grass-commit mailing list