Hi,
nice work, can I do some changes (mostly style) or you don’t want me to mess it now to avoid conflicts?
Anna
···
On Sat, Jun 28, 2014 at 12:46 PM, <svn_grass@osgeo.org> wrote:
Author: martinl
Date: 2014-06-28 09:46:15 -0700 (Sat, 28 Jun 2014)
New Revision: 61032Added:
grass/trunk/gui/wxpython/lmgr/datacatalog.py
Modified:
grass/trunk/gui/wxpython/lmgr/init.py
grass/trunk/gui/wxpython/lmgr/frame.py
Log:
wxGUI: first experimental prototype of Data Catalog in Layer Manager (author: Tereza Fiedlerova)Modified: grass/trunk/gui/wxpython/lmgr/init.py
— grass/trunk/gui/wxpython/lmgr/init.py 2014-06-28 16:26:15 UTC (rev 61031)
+++ grass/trunk/gui/wxpython/lmgr/init.py 2014-06-28 16:46:15 UTC (rev 61032)
@@ -5,4 +5,5 @@
‘pyshell’,
‘frame’,
‘giface’,
- ‘datacatalog’
]Added: grass/trunk/gui/wxpython/lmgr/datacatalog.py
— grass/trunk/gui/wxpython/lmgr/datacatalog.py (rev 0)
+++ grass/trunk/gui/wxpython/lmgr/datacatalog.py 2014-06-28 16:46:15 UTC (rev 61032)
@@ -0,0 +1,477 @@
+“”"
+@package lmgr::datacatalog
+
+@brief Data catalog
+
+Classes:
- datacatalog::DataCatalog
- datacatalog::DataCatalogTree
+(C) 2014 by Tereza Fiedlerova, and the GRASS Development Team
+
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+@author Tereza Fiedlerova
+“”"
+
+import os
+import sys
+
+import wx
+
+from core.gcmd import RunCommand, GError, GMessage
+from core.utils import GetListOfLocations
+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
+class DataCatalogTree(wx.TreeCtrl):
- def init(self, parent):
- “”“Tree constructor.”“”
- super(DataCatalogTree, self).init(parent, id=wx.ID_ANY, 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)
- 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)
- wx.EVT_TREE_BEGIN_DRAG(self, wx.ID_ANY, self.OnBeginDrag)
- wx.EVT_TREE_END_DRAG(self, wx.ID_ANY, self.OnEndDrag)
- self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
- self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
- self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
- 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 _initVariables(self):
- “”“Init variables.”“”
- self.selected_layer = None
- self.selected_type = None
- self.selected_mapset = None
- self.selected_location = None
- self.copy_layer = None
- self.copy_type = None
- self.copy_mapset = None
- self.copy_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 InitTreeItems(self):
- “”“Add locations, mapsets and layers to the tree.”“”
- locations = GetListOfLocations(self.gisdbase)
- 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)
- #get list of all maps in location
- maplist = RunCommand(‘g.mlist’, flags=‘mt’, type=‘rast,rast3d,vect’, mapset=‘*’, 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]
- if self.itemExists(mapset, varloc) == False:
- varmapset = self.AppendItem(varloc, mapset)
- if (self.GetItemText(varmapset) == mapset):
- if (self.itemExists(ltype, varmapset) == False):
- vartype = self.AppendItem(varmapset, ltype)
- else:
- varmapset = self.getItemByName(mapset, varloc)
- if (self.itemExists(ltype, varmapset) == False):
- vartype = self.AppendItem(varmapset, ltype)
- self.AppendItem(vartype, mlayer)
- self.RestoreBackup()
- Debug.msg(1, “Tree filled”)
- 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):
- “”“Rename layer”“”
- Debug.msg(1, “Double CLICK”)
- 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.textDialog((‘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):
- 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)==‘vect’):
- renamed = RunCommand(‘g.rename’, vect=string)
- elif (self.GetItemText(self.selected_type)==‘rast’):
- renamed = RunCommand(‘g.rename’, rast=string)
- else:
- renamed = RunCommand(‘g.rename’, rast3d=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.textDialog((‘New name’), _(‘Copy map’), self.GetItemText(self.copy_layer)+‘_copy’)
- 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)==‘vect’):
- pasted = RunCommand(‘g.copy’, vect=string)
- node = ‘vect’
- elif (self.GetItemText(self.copy_type)==‘rast’):
- pasted = RunCommand(‘g.copy’, rast=string)
- node = ‘rast’
- else:
- pasted = RunCommand(‘g.copy’, rast3d=string)
- node = ‘rast3d’
- if (pasted==0):
- if (self.selected_type == None):
- self.selected_type = self.getItemByName(node, self.selected_mapset)
- 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)
- 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
- if (self.confirmDialog((‘Do you really want to delete layer’) +string+‘?’, _(‘Delete map’)) == wx.ID_YES):
- label = _(“Deleting”) + " " + string + " …"
- self.showNotification.emit(message=label)
- if (self.GetItemText(self.selected_type)==‘vect’):
- removed = RunCommand(‘g.remove’, vect=string)
- elif (self.GetItemText(self.selected_type)==‘rast’):
- removed = RunCommand(‘g.remove’, rast=string)
- else:
- removed = RunCommand(‘g.remove’, rast3d=string)
- if (removed==0):
- self.Delete(self.selected_layer)
- Debug.msg(1,“LAYER “+string+” DELETED”)
- label = “g.remove “+self.GetItemText(self.selected_type)+”=”+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)==‘vect’):
- self.parent.parent.AddMaps(layerName, ‘vect’, True)
- elif (self.GetItemText(self.selected_type)==‘rast’):
- self.parent.parent.AddMaps(layerName, ‘rast’, True)
- else:
- self.parent.parent.AddMaps(layerName, ‘rast3d’, 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 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 _textDialog(self, message, title, value):
- “”“Dialog for simple text entry”“”
- dlg = TextEntryDialog(self, message, title)
- dlg.SetValue(value)
- res = dlg.ShowModal()
- self.new_name = dlg.GetValue()
- dlg.Destroy()
- 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()
- def MakeBackup(self):
- “”“Make backup for case of change”“”
- self.glocation = grass.gisenv()[‘LOCATION_NAME’]
- self.gmapset = grass.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)
Property changes on: grass/trunk/gui/wxpython/lmgr/datacatalog.py
Added: svn:mime-type
- text/x-python
Added: svn:eol-style- native
Modified: grass/trunk/gui/wxpython/lmgr/frame.py
— grass/trunk/gui/wxpython/lmgr/frame.py 2014-06-28 16:26:15 UTC (rev 61031)
+++ grass/trunk/gui/wxpython/lmgr/frame.py 2014-06-28 16:46:15 UTC (rev 61032)
@@ -70,6 +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 gui_core.forms import GUI
from gcp.manager import GCPWizard
from nviz.main import haveNviz
@@ -317,6 +318,11 @@
else:
self.search = None
create ‘data catalog’ notebook page
- self.datacatalog = DataCatalog(parent = self, giface = self._giface)
- self.datacatalog.showNotification.connect(lambda message: self.SetStatusText(message))
- self.notebook.AddPage(page = self.datacatalog, text = _(“Data catalog”), name = ‘catalog’)
create ‘python shell’ notebook page
if not UserSettings.Get(group = ‘manager’, key = ‘hideTabs’, subkey = ‘pyshell’):
self.pyshell = PyShellWindow(parent = self)
@@ -544,6 +550,8 @@
page = event.GetSelection()
if page == self.notebook.GetPageIndexByName(‘output’):
wx.CallAfter(self.goutput.ResetFocus)
- elif page == self.notebook.GetPageIndexByName(‘catalog’):
- wx.CallAfter(self.datacatalog.LoadItems)
self.SetStatusText(‘’, 0)event.Skip()
grass-commit mailing list
grass-commit@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-commit