[GRASS-SVN] r41561 - in grass/trunk/gui/wxpython: . gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Mar 26 12:17:39 EDT 2010
Author: martinl
Date: 2010-03-26 12:17:39 -0400 (Fri, 26 Mar 2010)
New Revision: 41561
Added:
grass/trunk/gui/wxpython/gui_modules/layertree.py
Removed:
grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py
Modified:
grass/trunk/gui/wxpython/gui_modules/__init__.py
grass/trunk/gui/wxpython/wxgui.py
Log:
wxgui_utils -> layertree
Modified: grass/trunk/gui/wxpython/gui_modules/__init__.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/__init__.py 2010-03-26 14:36:16 UTC (rev 41560)
+++ grass/trunk/gui/wxpython/gui_modules/__init__.py 2010-03-26 16:17:39 UTC (rev 41561)
@@ -12,6 +12,7 @@
"goutput.py",
"gselect.py",
"histogram.py",
+ "layertree.py",
"location_wizard.py",
"mapdisp_command.py",
"mapdisp_window.py",
@@ -33,5 +34,4 @@
"utils.py",
"vdigit.py",
"workspace.py",
- "wxgui_utils.py",
]
Copied: grass/trunk/gui/wxpython/gui_modules/layertree.py (from rev 41538, grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py)
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/layertree.py (rev 0)
+++ grass/trunk/gui/wxpython/gui_modules/layertree.py 2010-03-26 16:17:39 UTC (rev 41561)
@@ -0,0 +1,1493 @@
+"""!
+ at package layertree.py
+
+ at brief Utility classes for map layer management.
+
+Classes:
+ - AbstractLayer
+ - Layer
+ - LayerTree
+
+(C) 2007-2010 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Michael Barton (Arizona State University)
+ at author Jachym Cepicky (Mendel University of Agriculture)
+ at author Martin Landa <landa.martin gmail.com>
+"""
+
+import os
+import sys
+import string
+
+import wx
+try:
+ import wx.lib.agw.customtreectrl as CT
+except ImportError:
+ import wx.lib.customtreectrl as CT
+import wx.combo
+import wx.lib.newevent
+import wx.lib.buttons as buttons
+
+from grass.script import core as grass
+
+import gdialogs
+import globalvar
+import menuform
+import toolbars
+import mapdisp
+import render
+import histogram
+import utils
+import profile
+from debug import Debug as Debug
+from icon import Icons as Icons
+from preferences import globalSettings as UserSettings
+from vdigit import haveVDigit
+try:
+ import subprocess
+except:
+ from compat import subprocess
+
+try:
+ import treemixin
+except ImportError:
+ from wx.lib.mixins import treemixin
+
+TREE_ITEM_HEIGHT = 25
+
+class LayerTree(treemixin.DragAndDrop, CT.CustomTreeCtrl):
+ """
+ Creates layer tree structure
+ """
+ def __init__(self, parent,
+ id=wx.ID_ANY, pos=wx.DefaultPosition,
+ size=wx.DefaultSize, style=wx.SUNKEN_BORDER,
+ ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
+ CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT |
+ CT.TR_MULTIPLE,**kargs):
+
+ super(LayerTree, self).__init__(parent, id, pos, size, style=style, ctstyle=ctstyle)
+ self.SetName("LayerTree")
+
+ ### SetAutoLayout() causes that no vertical scrollbar is displayed
+ ### when some layers are not visible in layer tree
+ # self.SetAutoLayout(True)
+ self.SetGradientStyle(1)
+ self.EnableSelectionGradient(True)
+ self.SetFirstGradientColour(wx.Colour(100, 100, 100))
+ self.SetSecondGradientColour(wx.Colour(150, 150, 150))
+
+ self.Map = render.Map() # instance of render.Map to be associated with display
+ self.root = None # ID of layer tree root node
+ self.groupnode = 0 # index value for layers
+ self.optpage = {} # dictionary of notebook option pages for each map layer
+ self.layer_selected = None # ID of currently selected layer
+ self.saveitem = {} # dictionary to preserve layer attributes for drag and drop
+ self.first = True # indicates if a layer is just added or not
+ self.flag = '' # flag for drag and drop hittest
+ self.disp_idx = kargs['idx']
+ self.lmgr = kargs['lmgr']
+ self.notebook = kargs['notebook'] # GIS Manager notebook for layer tree
+ self.treepg = parent # notebook page holding layer tree
+ self.auimgr = kargs['auimgr'] # aui manager
+ self.rerender = False # layer change requires a rerendering if auto render
+ self.reorder = False # layer change requires a reordering
+
+ # init associated map display
+ pos = wx.Point((self.disp_idx + 1) * 25, (self.disp_idx + 1) * 25)
+ self.mapdisplay = mapdisp.MapFrame(self,
+ id=wx.ID_ANY, pos=pos,
+ size=globalvar.MAP_WINDOW_SIZE,
+ style=wx.DEFAULT_FRAME_STYLE,
+ tree=self, notebook=self.notebook,
+ lmgr=self.lmgr, page=self.treepg,
+ Map=self.Map, auimgr=self.auimgr)
+
+ # title
+ self.mapdisplay.SetTitle(_("GRASS GIS Map Display: %(id)d - Location: %(loc)s") % \
+ { 'id' : self.disp_idx + 1,
+ 'loc' : grass.gisenv()["LOCATION_NAME"] })
+
+ # show new display
+ if kargs['showMapDisplay'] is True:
+ self.mapdisplay.Show()
+ self.mapdisplay.Refresh()
+ self.mapdisplay.Update()
+
+ self.root = self.AddRoot(_("Map Layers"))
+ self.SetPyData(self.root, (None, None))
+
+ #create image list to use with layer tree
+ il = wx.ImageList(16, 16, mask=False)
+
+ trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, (16, 16))
+ self.folder_open = il.Add(trart)
+ trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))
+ self.folder = il.Add(trart)
+
+ bmpsize = (16, 16)
+ trgif = Icons["addrast"].GetBitmap(bmpsize)
+ self.rast_icon = il.Add(trgif)
+
+ trgif = Icons["addrast3d"].GetBitmap(bmpsize)
+ self.rast3d_icon = il.Add(trgif)
+
+ trgif = Icons["addrgb"].GetBitmap(bmpsize)
+ self.rgb_icon = il.Add(trgif)
+
+ trgif = Icons["addhis"].GetBitmap(bmpsize)
+ self.his_icon = il.Add(trgif)
+
+ trgif = Icons["addshaded"].GetBitmap(bmpsize)
+ self.shaded_icon = il.Add(trgif)
+
+ trgif = Icons["addrarrow"].GetBitmap(bmpsize)
+ self.rarrow_icon = il.Add(trgif)
+
+ trgif = Icons["addrnum"].GetBitmap(bmpsize)
+ self.rnum_icon = il.Add(trgif)
+
+ trgif = Icons["addvect"].GetBitmap(bmpsize)
+ self.vect_icon = il.Add(trgif)
+
+ trgif = Icons["addthematic"].GetBitmap(bmpsize)
+ self.theme_icon = il.Add(trgif)
+
+ trgif = Icons["addchart"].GetBitmap(bmpsize)
+ self.chart_icon = il.Add(trgif)
+
+ trgif = Icons["addgrid"].GetBitmap(bmpsize)
+ self.grid_icon = il.Add(trgif)
+
+ trgif = Icons["addgeodesic"].GetBitmap(bmpsize)
+ self.geodesic_icon = il.Add(trgif)
+
+ trgif = Icons["addrhumb"].GetBitmap(bmpsize)
+ self.rhumb_icon = il.Add(trgif)
+
+ trgif = Icons["addlabels"].GetBitmap(bmpsize)
+ self.labels_icon = il.Add(trgif)
+
+ trgif = Icons["addcmd"].GetBitmap(bmpsize)
+ self.cmd_icon = il.Add(trgif)
+
+ self.AssignImageList(il)
+
+ # use when groups implemented
+ ## self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal)
+ ## self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded)
+
+ self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnExpandNode)
+ self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnCollapseNode)
+ self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivateLayer)
+ self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnChangeSel)
+ self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.OnLayerChecked)
+ self.Bind(wx.EVT_TREE_DELETE_ITEM, self.OnDeleteLayer)
+ self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnLayerContextMenu)
+ #self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnDrag)
+ self.Bind(wx.EVT_TREE_END_DRAG, self.OnEndDrag)
+ #self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnChangeLayerName)
+ self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
+ # self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
+
+ def GetMap(self):
+ """!Get map instace"""
+ return self.Map
+
+ def OnIdle(self, event):
+ """
+ Only re-order and re-render a composite map image from GRASS during
+ idle time instead of multiple times during layer changing.
+ """
+ if self.rerender:
+ if self.mapdisplay.statusbarWin['render'].GetValue():
+ self.mapdisplay.MapWindow.UpdateMap(render=True)
+
+ event.Skip()
+
+ def OnKeyUp(self, event):
+ """!Key pressed"""
+ key = event.GetKeyCode()
+
+ if key == wx.WXK_DELETE and self.lmgr:
+ self.lmgr.OnDeleteLayer(None)
+
+ event.Skip()
+
+ def OnLayerContextMenu (self, event):
+ """!Contextual menu for item/layer"""
+ if not self.layer_selected:
+ event.Skip()
+ return
+
+ ltype = self.GetPyData(self.layer_selected)[0]['type']
+
+ Debug.msg (4, "LayerTree.OnContextMenu: layertype=%s" % \
+ ltype)
+
+ if not hasattr (self, "popupID1"):
+ self.popupID1 = wx.NewId()
+ self.popupID2 = wx.NewId()
+ self.popupID3 = wx.NewId()
+ self.popupID4 = wx.NewId()
+ self.popupID5 = wx.NewId()
+ self.popupID6 = wx.NewId()
+ self.popupID7 = wx.NewId()
+ self.popupID8 = wx.NewId()
+ self.popupID9 = wx.NewId()
+ self.popupID10 = wx.NewId()
+ self.popupID11 = wx.NewId() # nviz
+ self.popupID12 = wx.NewId()
+ self.popupID13 = wx.NewId()
+ self.popupID14 = wx.NewId()
+ self.popupID15 = wx.NewId()
+
+ self.popupMenu = wx.Menu()
+
+ numSelected = len(self.GetSelections())
+
+ # general item
+ self.popupMenu.Append(self.popupID1, text=_("Remove"))
+ self.Bind(wx.EVT_MENU, self.lmgr.OnDeleteLayer, id=self.popupID1)
+
+ if ltype != "command": # rename
+ self.popupMenu.Append(self.popupID2, text=_("Rename"))
+ self.Bind(wx.EVT_MENU, self.RenameLayer, id=self.popupID2)
+ if numSelected > 1:
+ self.popupMenu.Enable(self.popupID2, False)
+
+ # map layer items
+ if ltype != "group" and \
+ ltype != "command":
+ self.popupMenu.AppendSeparator()
+ self.popupMenu.Append(self.popupID8, text=_("Change opacity level"))
+ self.Bind(wx.EVT_MENU, self.OnPopupOpacityLevel, id=self.popupID8)
+ self.popupMenu.Append(self.popupID3, text=_("Properties"))
+ self.Bind(wx.EVT_MENU, self.OnPopupProperties, id=self.popupID3)
+ if ltype in ('raster', 'vector', 'rgb'):
+ self.popupMenu.Append(self.popupID9, text=_("Zoom to selected map(s)"))
+ self.Bind(wx.EVT_MENU, self.mapdisplay.MapWindow.OnZoomToMap, id=self.popupID9)
+ self.popupMenu.Append(self.popupID10, text=_("Set computational region from selected map(s)"))
+ self.Bind(wx.EVT_MENU, self.OnSetCompRegFromMap, id=self.popupID10)
+ if numSelected > 1:
+ self.popupMenu.Enable(self.popupID8, False)
+ self.popupMenu.Enable(self.popupID3, False)
+
+ # specific items
+ try:
+ mltype = self.GetPyData(self.layer_selected)[0]['type']
+ except:
+ mltype = None
+ #
+ # vector layers (specific items)
+ #
+ if mltype and mltype == "vector":
+ self.popupMenu.AppendSeparator()
+ self.popupMenu.Append(self.popupID4, text=_("Show attribute data"))
+ self.Bind (wx.EVT_MENU, self.lmgr.OnShowAttributeTable, id=self.popupID4)
+
+ self.popupMenu.Append(self.popupID5, text=_("Start editing"))
+ self.popupMenu.Append(self.popupID6, text=_("Stop editing"))
+ self.popupMenu.Enable(self.popupID6, False)
+ self.Bind (wx.EVT_MENU, self.OnStartEditing, id=self.popupID5)
+ self.Bind (wx.EVT_MENU, self.OnStopEditing, id=self.popupID6)
+
+ layer = self.GetPyData(self.layer_selected)[0]['maplayer']
+ # enable editing only for vector map layers available in the current mapset
+ digitToolbar = self.mapdisplay.toolbars['vdigit']
+ if digitToolbar:
+ # background vector map
+ self.popupMenu.Append(self.popupID14,
+ text=_("Use as background vector map"),
+ kind=wx.ITEM_CHECK)
+ self.Bind(wx.EVT_MENU, self.OnSetBgMap, id=self.popupID14)
+ if UserSettings.Get(group='vdigit', key='bgmap', subkey='value',
+ internal=True) == layer.GetName():
+ self.popupMenu.Check(self.popupID14, True)
+
+ if layer.GetMapset() != grass.gisenv()['MAPSET']:
+ # only vector map in current mapset can be edited
+ self.popupMenu.Enable (self.popupID5, False)
+ self.popupMenu.Enable (self.popupID6, False)
+ elif digitToolbar and digitToolbar.GetLayer():
+ # vector map already edited
+ vdigitLayer = digitToolbar.GetLayer()
+ if vdigitLayer is layer:
+ # disable 'start editing'
+ self.popupMenu.Enable (self.popupID5, False)
+ # enable 'stop editing'
+ self.popupMenu.Enable(self.popupID6, True)
+ # disable 'remove'
+ self.popupMenu.Enable(self.popupID1, False)
+ # disable 'bgmap'
+ self.popupMenu.Enable(self.popupID14, False)
+ else:
+ # disable 'start editing'
+ self.popupMenu.Enable(self.popupID5, False)
+ # disable 'stop editing'
+ self.popupMenu.Enable(self.popupID6, False)
+ # enable 'bgmap'
+ self.popupMenu.Enable(self.popupID14, True)
+
+ self.popupMenu.Append(self.popupID7, _("Metadata"))
+ self.Bind (wx.EVT_MENU, self.OnMetadata, id=self.popupID7)
+ if numSelected > 1:
+ self.popupMenu.Enable(self.popupID4, False)
+ self.popupMenu.Enable(self.popupID5, False)
+ self.popupMenu.Enable(self.popupID6, False)
+ self.popupMenu.Enable(self.popupID7, False)
+ self.popupMenu.Enable(self.popupID14, False)
+
+ #
+ # raster layers (specific items)
+ #
+ elif mltype and mltype == "raster":
+ self.popupMenu.Append(self.popupID12, text=_("Zoom to selected map(s) (ignore NULLs)"))
+ self.Bind(wx.EVT_MENU, self.mapdisplay.MapWindow.OnZoomToRaster, id=self.popupID12)
+ self.popupMenu.Append(self.popupID13, text=_("Set computational region from selected map(s) (ignore NULLs)"))
+ self.Bind(wx.EVT_MENU, self.OnSetCompRegFromRaster, id=self.popupID13)
+ self.popupMenu.AppendSeparator()
+ self.popupMenu.Append(self.popupID15, _("Set color table"))
+ self.Bind (wx.EVT_MENU, self.OnColorTable, id=self.popupID15)
+ self.popupMenu.Append(self.popupID4, _("Histogram"))
+ self.Bind (wx.EVT_MENU, self.OnHistogram, id=self.popupID4)
+ self.popupMenu.Append(self.popupID5, _("Profile"))
+ self.Bind (wx.EVT_MENU, self.OnProfile, id=self.popupID5)
+ self.popupMenu.Append(self.popupID6, _("Metadata"))
+ self.Bind (wx.EVT_MENU, self.OnMetadata, id=self.popupID6)
+ if self.mapdisplay.toolbars['nviz']:
+ self.popupMenu.Append(self.popupID11, _("Nviz properties"))
+ self.Bind (wx.EVT_MENU, self.OnNvizProperties, id=self.popupID11)
+
+ if numSelected > 1:
+ self.popupMenu.Enable(self.popupID12, False)
+ self.popupMenu.Enable(self.popupID13, False)
+ self.popupMenu.Enable(self.popupID15, False)
+ self.popupMenu.Enable(self.popupID4, False)
+ self.popupMenu.Enable(self.popupID5, False)
+ self.popupMenu.Enable(self.popupID6, False)
+ self.popupMenu.Enable(self.popupID11, False)
+
+ ## self.PopupMenu(self.popupMenu, pos)
+ self.PopupMenu(self.popupMenu)
+ self.popupMenu.Destroy()
+
+ def OnMetadata(self, event):
+ """!Print metadata of raster/vector map layer
+ TODO: Dialog to modify metadata
+ """
+ mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+ mltype = self.GetPyData(self.layer_selected)[0]['type']
+
+ if mltype == 'raster':
+ cmd = ['r.info']
+ elif mltype == 'vector':
+ cmd = ['v.info']
+ cmd.append('map=%s' % mapLayer.name)
+
+ # print output to command log area
+ self.lmgr.goutput.RunCmd(cmd, switchPage=True)
+
+ def OnSetCompRegFromRaster(self, event):
+ """!Set computational region from selected raster map (ignore NULLs)"""
+ mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+
+ cmd = ['g.region',
+ '-p',
+ 'zoom=%s' % mapLayer.name]
+
+ # print output to command log area
+ self.lmgr.goutput.RunCmd(cmd)
+
+ def OnSetCompRegFromMap(self, event):
+ """!Set computational region from selected raster/vector map"""
+ rast = []
+ vect = []
+ rast3d = []
+ for layer in self.GetSelections():
+ mapLayer = self.GetPyData(layer)[0]['maplayer']
+ mltype = self.GetPyData(layer)[0]['type']
+
+ if mltype == 'raster':
+ rast.append(mapLayer.name)
+ elif mltype == 'vector':
+ vect.append(mapLayer.name)
+ elif mltype == '3d-raster':
+ rast3d.append(mapLayer.name)
+
+ cmd = ['g.region']
+ if rast:
+ cmd.append('rast=%s' % ','.join(rast))
+ if vect:
+ cmd.append('vect=%s' % ','.join(vect))
+ if rast3d:
+ cmd.append('rast3d=%s' % ','.join(rast3d))
+
+ # print output to command log area
+ if len(cmd) > 1:
+ cmd.append('-p')
+ self.lmgr.goutput.RunCmd(cmd)
+
+ def OnProfile(self, event):
+ """!Plot profile of given raster map layer"""
+ mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+ if not mapLayer.name:
+ wx.MessageBox(parent=self,
+ message=_("Unable to create profile of "
+ "raster map."),
+ caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+ return False
+
+ if not hasattr (self, "profileFrame"):
+ self.profileFrame = None
+
+ if hasattr (self.mapdisplay, "profile") and self.mapdisplay.profile:
+ self.profileFrame = self.mapdisplay.profile
+
+ if not self.profileFrame:
+ self.profileFrame = profile.ProfileFrame(self.mapdisplay,
+ id=wx.ID_ANY, pos=wx.DefaultPosition, size=(700,300),
+ style=wx.DEFAULT_FRAME_STYLE, rasterList=[mapLayer.name])
+ # show new display
+ self.profileFrame.Show()
+
+ def OnColorTable(self, event):
+ """!Set color table for raster map"""
+ name = self.GetPyData(self.layer_selected)[0]['maplayer'].name
+ menuform.GUI().ParseCommand(['r.colors',
+ 'map=%s' % name],
+ parentframe=self)
+
+ def OnHistogram(self, event):
+ """
+ Plot histogram for given raster map layer
+ """
+ mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+ if not mapLayer.name:
+ wx.MessageBox(parent=self,
+ message=_("Unable to display histogram of "
+ "raster map."),
+ caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+ return False
+
+ if not hasattr (self, "histogramFrame"):
+ self.histogramFrame = None
+
+ if hasattr (self.mapdisplay, "histogram") and self.mapdisplay.histogram:
+ self.histogramFrame = self.mapdisplay.histogram
+
+ if not self.histogramFrame:
+ self.histogramFrame = histogram.HistFrame(self,
+ id=wx.ID_ANY,
+ pos=wx.DefaultPosition, size=globalvar.HIST_WINDOW_SIZE,
+ style=wx.DEFAULT_FRAME_STYLE)
+ # show new display
+ self.histogramFrame.Show()
+
+ self.histogramFrame.SetHistLayer(mapLayer.name)
+ self.histogramFrame.HistWindow.UpdateHist()
+ self.histogramFrame.Refresh()
+ self.histogramFrame.Update()
+
+ return True
+
+ def OnStartEditing(self, event):
+ """
+ Start editing vector map layer requested by the user
+ """
+ if not haveVDigit:
+ from vdigit import errorMsg
+ msg = _("Unable to start vector digitizer.\nThe VDigit python extension "
+ "was not found or loaded properly.\n"
+ "Switching back to 2D display mode.\n\nDetails: %s" % errorMsg)
+
+ self.mapdisplay.toolbars['map'].combo.SetValue (_("2D view"))
+ wx.MessageBox(parent=self.mapdisplay,
+ message=msg,
+ caption=_("Error"),
+ style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+ return
+
+ try:
+ maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+ except:
+ event.Skip()
+ return
+
+ if not self.mapdisplay.toolbars['vdigit']: # enable tool
+ self.mapdisplay.AddToolbar('vdigit')
+ else: # tool already enabled
+ pass
+
+ # mark layer as 'edited'
+ self.mapdisplay.toolbars['vdigit'].StartEditing (maplayer)
+
+ def OnStopEditing(self, event):
+ """
+ Stop editing the current vector map layer
+ """
+ maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+
+ self.mapdisplay.toolbars['vdigit'].OnExit()
+ self.mapdisplay.imgVectorMap = None
+
+ def OnSetBgMap(self, event):
+ """!Set background vector map for editing sesstion"""
+ if event.IsChecked():
+ mapName = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
+ UserSettings.Set(group='vdigit', key='bgmap', subkey='value',
+ value=str(mapName), internal=True)
+ else:
+ UserSettings.Set(group='vdigit', key='bgmap', subkey='value',
+ value='', internal=True)
+
+ def OnPopupProperties (self, event):
+ """!Popup properties dialog"""
+ self.PropertiesDialog(self.layer_selected)
+
+ def OnPopupOpacityLevel(self, event):
+ """!Popup opacity level indicator"""
+ if not self.GetPyData(self.layer_selected)[0]['ctrl']:
+ return
+
+ #win = self.FindWindowById(self.GetPyData(self.layer_selected)[0]['ctrl'])
+ #type = win.GetName()
+ #
+ #self.layer_selected.DeleteWindow()
+
+ maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+ current_opacity = maplayer.GetOpacity()
+
+ dlg = gdialogs.SetOpacityDialog(self, opacity=current_opacity,
+ title=_("Set opacity <%s>") % maplayer.GetName())
+ dlg.CentreOnParent()
+
+ if dlg.ShowModal() == wx.ID_OK:
+ new_opacity = dlg.GetOpacity() # string
+ self.Map.ChangeOpacity(maplayer, new_opacity)
+ maplayer.SetOpacity(new_opacity)
+ opacity_pct = int(new_opacity * 100)
+ layername = self.GetItemText(self.layer_selected)
+ layerbase = layername.split('(')[0].strip()
+ self.SetItemText(self.layer_selected,
+ layerbase + ' (opacity: ' + str(opacity_pct) + '%)')
+
+ # vector layer currently edited
+ if self.mapdisplay.toolbars['vdigit'] and \
+ self.mapdisplay.toolbars['vdigit'].GetLayer() == maplayer:
+ alpha = int(new_opacity * 255)
+ self.mapdisplay.digit.driver.UpdateSettings(alpha)
+
+ # redraw map if auto-rendering is enabled
+ self.rerender = True
+ self.reorder = True
+ #if self.mapdisplay.statusbarWin['render'].GetValue():
+ # print "*** Opacity OnRender *****"
+ # self.mapdisplay.OnRender(None)
+
+ def OnNvizProperties(self, event):
+ """!Nviz-related properties (raster/vector/volume)
+
+ @todo vector/volume
+ """
+ if not self.mapdisplay.nvizToolWin.IsShown():
+ self.mapdisplay.nvizToolWin.Show()
+
+ self.mapdisplay.nvizToolWin.SetPage('surface')
+
+ def RenameLayer (self, event):
+ """!Rename layer"""
+ self.EditLabel(self.layer_selected)
+
+ def AddLayer(self, ltype, lname=None, lchecked=None,
+ lopacity=1.0, lcmd=None, lgroup=None, lvdigit=None, lnviz=None):
+ """!Add new item to the layer tree, create corresponding MapLayer instance.
+ Launch property dialog if needed (raster, vector, etc.)
+
+ @param ltype layer type (raster, vector, 3d-raster, ...)
+ @param lname layer name
+ @param lchecked if True layer is checked
+ @param lopacity layer opacity level
+ @param lcmd command (given as a list)
+ @param lgroup index of group item (-1 for root) or None
+ @param lvdigit vector digitizer settings (eg. geometry attributes)
+ @param lnviz layer Nviz properties
+ """
+ self.first = True
+ params = {} # no initial options parameters
+
+ # deselect active item
+ if self.layer_selected:
+ self.SelectItem(self.layer_selected, select=False)
+
+ Debug.msg (3, "LayerTree().AddLayer(): ltype=%s" % (ltype))
+
+ if ltype == 'command':
+ # generic command item
+ ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
+ pos=wx.DefaultPosition, size=(self.GetSize()[0]-100,25),
+ # style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
+ style=wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
+ ctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
+ # ctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
+ elif ltype == 'group':
+ # group item
+ ctrl = None
+ grouptext = _('Layer group:') + str(self.groupnode)
+ self.groupnode += 1
+ else:
+ btnbmp = Icons["layeropts"].GetBitmap((16,16))
+ ctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp, size=(24,24))
+ ctrl.SetToolTipString(_("Click to edit layer settings"))
+ self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, ctrl)
+ # add layer to the layer tree
+ if self.layer_selected and self.layer_selected != self.GetRootItem():
+ if self.GetPyData(self.layer_selected)[0]['type'] == 'group' \
+ and self.IsExpanded(self.layer_selected):
+ # add to group (first child of self.layer_selected) if group expanded
+ layer = self.PrependItem(parent=self.layer_selected,
+ text='', ct_type=1, wnd=ctrl)
+ else:
+ # prepend to individual layer or non-expanded group
+ if lgroup == -1:
+ # -> last child of root (loading from workspace)
+ layer = self.AppendItem(parentId=self.root,
+ text='', ct_type=1, wnd=ctrl)
+ elif lgroup > -1:
+ # -> last child of group (loading from workspace)
+ parent = self.FindItemByIndex(index = lgroup)
+ if not parent:
+ parent = self.root
+ layer = self.AppendItem(parentId=parent,
+ text='', ct_type=1, wnd=ctrl)
+ elif lgroup is None:
+ # -> previous sibling of selected layer
+ parent = self.GetItemParent(self.layer_selected)
+ layer = self.InsertItem(parentId=parent,
+ input=self.GetPrevSibling(self.layer_selected),
+ text='', ct_type=1, wnd=ctrl)
+ else: # add first layer to the layer tree (first child of root)
+ layer = self.PrependItem(parent=self.root, text='', ct_type=1, wnd=ctrl)
+
+ # layer is initially unchecked as inactive (beside 'command')
+ # use predefined value if given
+ if lchecked is not None:
+ checked = lchecked
+ else:
+ checked = True
+
+ self.CheckItem(layer, checked=checked)
+
+ # select new item
+ self.SelectItem(layer, select=True)
+ self.layer_selected = layer
+
+ # add text and icons for each layer ltype
+ if ltype == 'raster':
+ self.SetItemImage(layer, self.rast_icon)
+ self.SetItemText(layer, '%s %s' % (_('raster'), _('(double click to set properties)')))
+ elif ltype == '3d-raster':
+ self.SetItemImage(layer, self.rast3d_icon)
+ self.SetItemText(layer, '%s %s' % (_('3d raster'), _('(double click to set properties)')))
+ elif ltype == 'rgb':
+ self.SetItemImage(layer, self.rgb_icon)
+ self.SetItemText(layer, '%s %s' % (_('RGB'), _('(double click to set properties)')))
+ elif ltype == 'his':
+ self.SetItemImage(layer, self.his_icon)
+ self.SetItemText(layer, '%s %s' % (_('HIS'), _('(double click to set properties)')))
+ elif ltype == 'shaded':
+ self.SetItemImage(layer, self.shaded_icon)
+ self.SetItemText(layer, '%s %s' % (_('Shaded relief'), _('(double click to set properties)')))
+ elif ltype == 'rastnum':
+ self.SetItemImage(layer, self.rnum_icon)
+ self.SetItemText(layer, '%s %s' % (_('raster cell numbers'), _('(double click to set properties)')))
+ elif ltype == 'rastarrow':
+ self.SetItemImage(layer, self.rarrow_icon)
+ self.SetItemText(layer, '%s %s' % (_('raster flow arrows'), _('(double click to set properties)')))
+ elif ltype == 'vector':
+ self.SetItemImage(layer, self.vect_icon)
+ self.SetItemText(layer, '%s %s' % (_('vector'), _('(double click to set properties)')))
+ elif ltype == 'thememap':
+ self.SetItemImage(layer, self.theme_icon)
+ self.SetItemText(layer, '%s %s' % (_('thematic area (choropleth) map'), _('(double click to set properties)')))
+ elif ltype == 'themechart':
+ self.SetItemImage(layer, self.chart_icon)
+ self.SetItemText(layer, '%s %s' % (_('thematic charts'), _('(double click to set properties)')))
+ elif ltype == 'grid':
+ self.SetItemImage(layer, self.grid_icon)
+ self.SetItemText(layer, '%s %s' % (_('grid'), _('(double click to set properties)')))
+ elif ltype == 'geodesic':
+ self.SetItemImage(layer, self.geodesic_icon)
+ self.SetItemText(layer, '%s %s' % (_('geodesic line'), _('(double click to set properties)')))
+ elif ltype == 'rhumb':
+ self.SetItemImage(layer, self.rhumb_icon)
+ self.SetItemText(layer, '%s %s' % (_('rhumbline'), _('(double click to set properties)')))
+ elif ltype == 'labels':
+ self.SetItemImage(layer, self.labels_icon)
+ self.SetItemText(layer, '%s %s' % (_('vector labels'), _('(double click to set properties)')))
+ elif ltype == 'command':
+ self.SetItemImage(layer, self.cmd_icon)
+ elif ltype == 'group':
+ self.SetItemImage(layer, self.folder)
+ self.SetItemText(layer, grouptext)
+
+ self.first = False
+
+ if ltype != 'group':
+ if lcmd and len(lcmd) > 1:
+ cmd = lcmd
+ render = False
+ name = utils.GetLayerNameFromCmd(lcmd)
+ else:
+ cmd = []
+ if ltype == 'command' and lname:
+ for c in lname.split(';'):
+ cmd.append(c.split(' '))
+
+ render = False
+ name = None
+
+ if ctrl:
+ ctrlId = ctrl.GetId()
+ else:
+ ctrlId = None
+
+ # add a data object to hold the layer's command (does not apply to generic command layers)
+ self.SetPyData(layer, ({'cmd' : cmd,
+ 'type' : ltype,
+ 'ctrl' : ctrlId,
+ 'maplayer' : None,
+ 'vdigit' : lvdigit,
+ 'nviz' : lnviz,
+ 'propwin' : None},
+ None))
+
+ # find previous map layer instance
+ prevItem = self.GetFirstChild(self.root)[0]
+ prevMapLayer = None
+ pos = -1
+ while prevItem and prevItem.IsOk() and prevItem != layer:
+ if self.GetPyData(prevItem)[0]['maplayer']:
+ prevMapLayer = self.GetPyData(prevItem)[0]['maplayer']
+
+ prevItem = self.GetNextSibling(prevItem)
+
+ if prevMapLayer:
+ pos = self.Map.GetLayerIndex(prevMapLayer)
+ else:
+ pos = -1
+
+ maplayer = self.Map.AddLayer(pos=pos,
+ type=ltype, command=self.GetPyData(layer)[0]['cmd'], name=name,
+ l_active=checked, l_hidden=False,
+ l_opacity=lopacity, l_render=render)
+ self.GetPyData(layer)[0]['maplayer'] = maplayer
+
+ # run properties dialog if no properties given
+ if len(cmd) == 0:
+ self.PropertiesDialog(layer, show=True)
+
+ if ltype == '3d-raster' and \
+ not self.mapdisplay.toolbars['nviz']:
+ self.EnableItem(layer, False)
+
+ else: # group
+ self.SetPyData(layer, ({'cmd': None,
+ 'type' : ltype,
+ 'ctrl' : None,
+ 'maplayer' : None,
+ 'propwin' : None},
+ None))
+
+ # use predefined layer name if given
+ if lname:
+ if ltype == 'group':
+ self.SetItemText(layer, lname)
+ elif ltype == 'command':
+ ctrl.SetValue(lname)
+ else:
+ name = lname + ' (opacity: ' + \
+ str(self.GetPyData(layer)[0]['maplayer'].GetOpacity()) + '%)'
+ self.SetItemText(layer, name)
+
+ # updated progress bar range (mapwindow statusbar)
+ if checked is True:
+ self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+
+ # layer.SetHeight(TREE_ITEM_HEIGHT)
+
+ return layer
+
+ def PropertiesDialog (self, layer, show=True):
+ """!Launch the properties dialog"""
+ if self.GetPyData(layer)[0].has_key('propwin') and \
+ self.GetPyData(layer)[0]['propwin'] is not None:
+ # recycle GUI dialogs
+ win = self.GetPyData(layer)[0]['propwin']
+ # update properties (columns, layers)
+ win.notebookpanel.OnUpdateSelection(None)
+ if win.IsShown():
+ win.SetFocus()
+ else:
+ win.Show()
+
+ return
+
+ completed = ''
+ params = self.GetPyData(layer)[1]
+ ltype = self.GetPyData(layer)[0]['type']
+
+ Debug.msg (3, "LayerTree.PropertiesDialog(): ltype=%s" % \
+ ltype)
+
+ if self.GetPyData(layer)[0]['cmd']:
+ module = menuform.GUI()
+ module.ParseCommand(self.GetPyData(layer)[0]['cmd'],
+ completed=(self.GetOptData,layer,params),
+ parentframe=self, show=show)
+
+ self.GetPyData(layer)[0]['cmd'] = module.GetCmd()
+ elif ltype == 'raster':
+ cmd = ['d.rast']
+
+ if UserSettings.Get(group='cmd', key='rasterOpaque', subkey='enabled'):
+ cmd.append('-n')
+ menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == '3d-raster':
+ cmd = ['d.rast3d']
+ menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'rgb':
+ menuform.GUI().ParseCommand(['d.rgb'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'his':
+ menuform.GUI().ParseCommand(['d.his'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'shaded':
+ menuform.GUI().ParseCommand(['d.shadedmap'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'rastarrow':
+ menuform.GUI().ParseCommand(['d.rast.arrow'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'rastnum':
+ menuform.GUI().ParseCommand(['d.rast.num'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'vector':
+ types = ''
+ for type in UserSettings.Get(group='cmd', key='showType').keys():
+ if UserSettings.Get(group='cmd', key='showType', subkey=[type, 'enabled']):
+ types += type + ','
+ types = types.rstrip(',')
+
+ menuform.GUI().ParseCommand(['d.vect', 'type=%s' % types],
+ completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'thememap':
+ # -s flag requested, otherwise only first thematic category is displayed
+ # should be fixed by C-based d.thematic.* modules
+ menuform.GUI().ParseCommand(['d.thematic.area'],
+ completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'themechart':
+ menuform.GUI().ParseCommand(['d.vect.chart'],
+ completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'grid':
+ menuform.GUI().ParseCommand(['d.grid'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'geodesic':
+ menuform.GUI().ParseCommand(['d.geodesic'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'rhumb':
+ menuform.GUI().ParseCommand(['d.rhumbline'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'labels':
+ menuform.GUI().ParseCommand(['d.labels'], completed=(self.GetOptData,layer,params),
+ parentframe=self)
+ elif ltype == 'cmdlayer':
+ pass
+ elif ltype == 'group':
+ pass
+
+ def OnActivateLayer(self, event):
+ """!Double click on the layer item.
+ Launch property dialog, or expand/collapse group of items, etc."""
+
+ layer = event.GetItem()
+ self.layer_selected = layer
+
+ self.PropertiesDialog (layer)
+
+ if self.GetPyData(layer)[0]['type'] == 'group':
+ if self.IsExpanded(layer):
+ self.Collapse(layer)
+ else:
+ self.Expand(layer)
+
+ def OnDeleteLayer(self, event):
+ """!Remove selected layer item from the layer tree"""
+
+ item = event.GetItem()
+
+ try:
+ item.properties.Close(True)
+ except:
+ pass
+
+ if item != self.root:
+ Debug.msg (3, "LayerTree.OnDeleteLayer(): name=%s" % \
+ (self.GetItemText(item)))
+ else:
+ self.root = None
+
+ # unselect item
+ self.Unselect()
+ self.layer_selected = None
+
+ try:
+ if self.GetPyData(item)[0]['type'] != 'group':
+ self.Map.DeleteLayer( self.GetPyData(item)[0]['maplayer'])
+ except:
+ pass
+
+ # redraw map if auto-rendering is enabled
+ self.rerender = True
+ self.reorder = True
+ #if self.mapdisplay.statusbarWin['render'].GetValue():
+ # print "*** Delete OnRender *****"
+ # self.mapdisplay.OnRender(None)
+
+ if self.mapdisplay.toolbars['vdigit']:
+ self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers (updateTool=True)
+
+ # update progress bar range (mapwindow statusbar)
+ self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+
+ event.Skip()
+
+ def OnLayerChecked(self, event):
+ """!Enable/disable data layer"""
+ item = event.GetItem()
+ checked = item.IsChecked()
+
+ digitToolbar = self.mapdisplay.toolbars['vdigit']
+ if self.first == False:
+ # change active parameter for item in layers list in render.Map
+ if self.GetPyData(item)[0]['type'] == 'group':
+ child, cookie = self.GetFirstChild(item)
+ while child:
+ self.CheckItem(child, checked)
+ mapLayer = self.GetPyData(child)[0]['maplayer']
+ if not digitToolbar or \
+ (digitToolbar and digitToolbar.GetLayer() != mapLayer):
+ # ignore when map layer is edited
+ self.Map.ChangeLayerActive(mapLayer, checked)
+ child = self.GetNextSibling(child)
+ else:
+ mapLayer = self.GetPyData(item)[0]['maplayer']
+ if not digitToolbar or \
+ (digitToolbar and digitToolbar.GetLayer() != mapLayer):
+ # ignore when map layer is edited
+ self.Map.ChangeLayerActive(mapLayer, checked)
+
+ #
+ # update progress bar range (mapwindow statusbar)
+ #
+ self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+
+ #
+ # nviz
+ #
+ if self.mapdisplay.toolbars['nviz'] and \
+ self.GetPyData(item) is not None:
+ # nviz - load/unload data layer
+ mapLayer = self.GetPyData(item)[0]['maplayer']
+
+ self.mapdisplay.SetStatusText(_("Please wait, updating data..."), 0)
+
+ if checked: # enable
+ if mapLayer.type == 'raster':
+ self.mapdisplay.MapWindow.LoadRaster(item)
+ elif mapLayer.type == '3d-raster':
+ self.mapdisplay.MapWindow.LoadRaster3d(item)
+ elif mapLayer.type == 'vector':
+ self.mapdisplay.MapWindow.LoadVector(item)
+
+ else: # disable
+ data = self.GetPyData(item)[0]['nviz']
+
+ if mapLayer.type == 'raster':
+ self.mapdisplay.MapWindow.UnloadRaster(item)
+ elif mapLayer.type == '3d-raster':
+ self.mapdisplay.MapWindow.UnloadRaster3d(item)
+ elif mapLayer.type == 'vector':
+ self.mapdisplay.MapWindow.UnloadVector(item)
+
+ if hasattr(self.mapdisplay, "nvizToolWin"):
+ toolWin = self.mapdisplay.nvizToolWin
+ # remove vector page
+ if toolWin.notebook.GetSelection() == toolWin.page['vector']['id']:
+ toolWin.notebook.RemovePage(toolWin.page['vector']['id'])
+ toolWin.page['vector']['id'] = -1
+ toolWin.page['settings']['id'] = 1
+
+ self.mapdisplay.SetStatusText("", 0)
+
+ # redraw map if auto-rendering is enabled
+ self.rerender = True
+ self.reorder = True
+ #if self.mapdisplay.statusbarWin['render'].GetValue():
+ # print "*** Checked OnRender *****"
+ # self.mapdisplay.OnRender(None)
+
+ def OnCmdChanged(self, event):
+ """!Change command string"""
+ ctrl = event.GetEventObject().GetId()
+ cmd = event.GetString()
+
+ layer = self.GetFirstVisibleItem()
+
+ while layer and layer.IsOk():
+ if self.GetPyData(layer)[0]['ctrl'] == ctrl:
+ break
+
+ layer = self.GetNextVisible(layer)
+
+ # change parameters for item in layers list in render.Map
+ self.ChangeLayer(layer)
+
+ event.Skip()
+
+ def OnChangeSel(self, event):
+ """!Selection changed"""
+ oldlayer = event.GetOldItem()
+ layer = event.GetItem()
+ if layer == oldlayer:
+ event.Veto()
+ return
+
+ self.layer_selected = layer
+
+ try:
+ if self.IsSelected(oldlayer):
+ self.SetItemWindowEnabled(oldlayer, True)
+ else:
+ self.SetItemWindowEnabled(oldlayer, False)
+
+ if self.IsSelected(layer):
+ self.SetItemWindowEnabled(layer, True)
+ else:
+ self.SetItemWindowEnabled(layer, False)
+ except:
+ pass
+
+ try:
+ self.RefreshLine(oldlayer)
+ self.RefreshLine(layer)
+ except:
+ pass
+
+ #
+ # update statusbar -> show command string
+ #
+ if self.GetPyData(layer) and self.GetPyData(layer)[0]['maplayer']:
+ cmd = self.GetPyData(layer)[0]['maplayer'].GetCmd(string=True)
+ if len(cmd) > 0:
+ self.lmgr.SetStatusText(cmd)
+
+ # set region if auto-zooming is enabled
+ if self.GetPyData(layer) and self.GetPyData(layer)[0]['cmd'] and \
+ UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
+ mapLayer = self.GetPyData(layer)[0]['maplayer']
+ if mapLayer.GetType() in ('raster', 'vector'):
+ render = self.mapdisplay.statusbarWin['render'].IsChecked()
+ self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
+ render = render)
+
+ #
+ # update nviz tools
+ #
+ if self.mapdisplay.toolbars['nviz'] and \
+ self.GetPyData(self.layer_selected) is not None:
+
+ if self.layer_selected.IsChecked():
+ # update Nviz tool window
+ type = self.GetPyData(self.layer_selected)[0]['maplayer'].type
+
+ if type == 'raster':
+ self.mapdisplay.nvizToolWin.UpdatePage('surface')
+ self.mapdisplay.nvizToolWin.SetPage('surface')
+ elif type == 'vector':
+ self.mapdisplay.nvizToolWin.UpdatePage('vector')
+ self.mapdisplay.nvizToolWin.SetPage('vector')
+ elif type == '3d-raster':
+ self.mapdisplay.nvizToolWin.UpdatePage('volume')
+ self.mapdisplay.nvizToolWin.SetPage('volume')
+ else:
+ for page in ('surface', 'vector', 'volume'):
+ pageId = self.mapdisplay.nvizToolWin.page[page]['id']
+ if pageId > -1:
+ self.mapdisplay.nvizToolWin.notebook.RemovePage(pageId)
+ self.mapdisplay.nvizToolWin.page[page]['id'] = -1
+ self.mapdisplay.nvizToolWin.page['settings']['id'] = 1
+
+ def OnCollapseNode(self, event):
+ """
+ Collapse node
+ """
+ if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
+ self.SetItemImage(self.layer_selected, self.folder)
+
+ def OnExpandNode(self, event):
+ """
+ Expand node
+ """
+ self.layer_selected = event.GetItem()
+ if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
+ self.SetItemImage(self.layer_selected, self.folder_open)
+
+ def OnEndDrag(self, event):
+ self.StopDragging()
+ dropTarget = event.GetItem()
+ self.flag = self.HitTest(event.GetPoint())[1]
+ if self.IsValidDropTarget(dropTarget):
+ self.UnselectAll()
+ if dropTarget != None:
+ self.SelectItem(dropTarget)
+ self.OnDrop(dropTarget, self._dragItem)
+ elif dropTarget == None:
+ self.OnDrop(dropTarget, self._dragItem)
+
+ def OnDrop(self, dropTarget, dragItem):
+ # save everthing associated with item to drag
+ try:
+ old = dragItem # make sure this member exists
+ except:
+ return
+
+ Debug.msg (4, "LayerTree.OnDrop(): layer=%s" % \
+ (self.GetItemText(dragItem)))
+
+ # recreate data layer, insert copy of layer in new position, and delete original at old position
+ newItem = self.RecreateItem (dragItem, dropTarget)
+
+ # if recreated layer is a group, also recreate its children
+ if self.GetPyData(newItem)[0]['type'] == 'group':
+ (child, cookie) = self.GetFirstChild(dragItem)
+ if child:
+ while child:
+ self.RecreateItem(child, dropTarget, parent=newItem)
+ self.Delete(child)
+ child = self.GetNextChild(old, cookie)[0]
+ #self.Expand(newItem)
+
+ # delete layer at original position
+ try:
+ self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
+ except AttributeError:
+ # FIXME being ugly (item.SetWindow(None))
+ pass
+
+ # reorder layers in render.Map to match new order after drag and drop
+ #self.ReorderLayers()
+
+ # redraw map if auto-rendering is enabled
+ self.rerender = True
+ self.reorder = True
+ #if self.mapdisplay.statusbarWin['render'].GetValue():
+ # print "*** Drop OnRender *****"
+ # self.mapdisplay.OnRender(None)
+
+ # select new item
+ self.SelectItem(newItem)
+
+ def RecreateItem (self, dragItem, dropTarget, parent=None):
+ """
+ Recreate item (needed for OnEndDrag())
+ """
+ Debug.msg (4, "LayerTree.RecreateItem(): layer=%s" % \
+ self.GetItemText(dragItem))
+
+ # fetch data (dragItem)
+ checked = self.IsItemChecked(dragItem)
+ image = self.GetItemImage(dragItem, 0)
+ text = self.GetItemText(dragItem)
+ if self.GetPyData(dragItem)[0]['ctrl']:
+ # recreate data layer
+ btnbmp = Icons["layeropts"].GetBitmap((16,16))
+ newctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp, size=(24, 24))
+ newctrl.SetToolTipString(_("Click to edit layer settings"))
+ self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, newctrl)
+ data = self.GetPyData(dragItem)
+
+ elif self.GetPyData(dragItem)[0]['type'] == 'command':
+ # recreate command layer
+ oldctrl = None
+ newctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
+ pos=wx.DefaultPosition, size=(250,25),
+ style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
+ try:
+ newctrl.SetValue(self.GetPyData(dragItem)[0]['maplayer'].GetCmd(string=True))
+ except:
+ pass
+ newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
+ newctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
+ data = self.GetPyData(dragItem)
+
+ elif self.GetPyData(dragItem)[0]['type'] == 'group':
+ # recreate group
+ newctrl = None
+ data = None
+
+ # decide where to put recreated item
+ if dropTarget != None and dropTarget != self.GetRootItem():
+ if parent:
+ # new item is a group
+ afteritem = parent
+ else:
+ # new item is a single layer
+ afteritem = dropTarget
+
+ # dragItem dropped on group
+ if self.GetPyData(afteritem)[0]['type'] == 'group':
+ newItem = self.PrependItem(afteritem, text=text, \
+ ct_type=1, wnd=newctrl, image=image, \
+ data=data)
+ self.Expand(afteritem)
+ else:
+ #dragItem dropped on single layer
+ newparent = self.GetItemParent(afteritem)
+ newItem = self.InsertItem(newparent, self.GetPrevSibling(afteritem), \
+ text=text, ct_type=1, wnd=newctrl, \
+ image=image, data=data)
+ else:
+ # if dragItem not dropped on a layer or group, append or prepend it to the layer tree
+ if self.flag & wx.TREE_HITTEST_ABOVE:
+ newItem = self.PrependItem(self.root, text=text, \
+ ct_type=1, wnd=newctrl, image=image, \
+ data=data)
+ elif (self.flag & wx.TREE_HITTEST_BELOW) or (self.flag & wx.TREE_HITTEST_NOWHERE) \
+ or (self.flag & wx.TREE_HITTEST_TOLEFT) or (self.flag & wx.TREE_HITTEST_TORIGHT):
+ newItem = self.AppendItem(self.root, text=text, \
+ ct_type=1, wnd=newctrl, image=image, \
+ data=data)
+
+ #update new layer
+ self.SetPyData(newItem, self.GetPyData(dragItem))
+ if newctrl:
+ self.GetPyData(newItem)[0]['ctrl'] = newctrl.GetId()
+ else:
+ self.GetPyData(newItem)[0]['ctrl'] = None
+
+ self.CheckItem(newItem, checked=checked) # causes a new render
+
+ # newItem.SetHeight(TREE_ITEM_HEIGHT)
+
+ return newItem
+
+ def GetOptData(self, dcmd, layer, params, propwin):
+ """!Process layer data"""
+ # set layer text to map name
+ if dcmd:
+ mapLayer = self.GetPyData(layer)[0]['maplayer']
+ opacity = int(mapLayer.GetOpacity(float=True) * 100)
+ mapname = utils.GetLayerNameFromCmd(dcmd, layerType=mapLayer.type,
+ fullyQualified=True)
+ if not mapname:
+ wx.MessageBox(parent=self,
+ message=_("Map <%s> not found.") % utils.GetLayerNameFromCmd(dcmd),
+ caption=_("Error"),
+ style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+
+ return
+
+ self.SetItemText(layer, mapname + ' (opacity: ' + str(opacity) + '%)')
+
+ # update layer data
+ if params:
+ self.SetPyData(layer, (self.GetPyData(layer)[0], params))
+ if dcmd:
+ self.GetPyData(layer)[0]['cmd'] = dcmd
+ self.GetPyData(layer)[0]['propwin'] = propwin
+
+ # change parameters for item in layers list in render.Map
+ self.ChangeLayer(layer)
+
+ # set region if auto-zooming is enabled
+ if dcmd and UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
+ mapLayer = self.GetPyData(layer)[0]['maplayer']
+ if mapLayer.GetType() in ('raster', 'vector'):
+ render = UserSettings.Get(group = 'display', key = 'autoRendering', subkey = 'enabled')
+ self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
+ render = render)
+
+ if self.mapdisplay.toolbars['nviz'] and dcmd:
+ # update nviz session
+ mapLayer = self.GetPyData(layer)[0]['maplayer']
+ mapWin = self.mapdisplay.MapWindow
+ if len(mapLayer.GetCmd()) > 0:
+ id = -1
+ if mapLayer.type == 'raster':
+ if mapWin.IsLoaded(layer):
+ mapWin.UnloadRaster(layer)
+
+ mapWin.LoadRaster(layer)
+
+ elif mapLayer.type == '3d-raster':
+ if mapWin.IsLoaded(layer):
+ mapWin.UnloadRaster3d(layer)
+
+ mapWin.LoadRaster3d(layer)
+
+ elif mapLayer.type == 'vector':
+ if mapWin.IsLoaded(layer):
+ mapWin.UnloadVector(layer)
+
+ mapWin.LoadVector(layer)
+
+ # reset view when first layer loaded
+ nlayers = len(mapWin.Map.GetListOfLayers(l_type=('raster', 'vector'),
+ l_active=True))
+ if nlayers < 2:
+ mapWin.ResetView()
+
+ def ReorderLayers(self):
+ """!Add commands from data associated with
+ any valid layers (checked or not) to layer list in order to
+ match layers in layer tree."""
+
+ # make a list of visible layers
+ treelayers = []
+
+ vislayer = self.GetFirstVisibleItem()
+
+ if not vislayer or self.GetPyData(vislayer) is None:
+ return
+
+ itemList = ""
+
+ for item in range(self.GetCount()):
+ itemList += self.GetItemText(vislayer) + ','
+ if self.GetPyData(vislayer)[0]['type'] != 'group':
+ treelayers.append(self.GetPyData(vislayer)[0]['maplayer'])
+
+ if not self.GetNextVisible(vislayer):
+ break
+ else:
+ vislayer = self.GetNextVisible(vislayer)
+
+ Debug.msg (4, "LayerTree.ReorderLayers(): items=%s" % \
+ (itemList))
+
+ # reorder map layers
+ treelayers.reverse()
+ self.Map.ReorderLayers(treelayers)
+ self.reorder = False
+
+ def ChangeLayer(self, item):
+ """!Change layer"""
+ type = self.GetPyData(item)[0]['type']
+ layerName = None
+
+ if type == 'command':
+ win = self.FindWindowById(self.GetPyData(item)[0]['ctrl'])
+ if win.GetValue() != None:
+ cmd = win.GetValue().split(';')
+ cmdlist = []
+ for c in cmd:
+ cmdlist.append(c.split(' '))
+ opac = 1.0
+ chk = self.IsItemChecked(item)
+ hidden = not self.IsVisible(item)
+ elif type != 'group':
+ if self.GetPyData(item)[0] is not None:
+ cmdlist = self.GetPyData(item)[0]['cmd']
+ opac = self.GetPyData(item)[0]['maplayer'].GetOpacity(float=True)
+ chk = self.IsItemChecked(item)
+ hidden = not self.IsVisible(item)
+ # determine layer name
+ layerName = utils.GetLayerNameFromCmd(cmdlist, fullyQualified=True)
+ if not layerName:
+ layerName = self.GetItemText(item)
+
+ maplayer = self.Map.ChangeLayer(layer=self.GetPyData(item)[0]['maplayer'], type=type,
+ command=cmdlist, name=layerName,
+ l_active=chk, l_hidden=hidden, l_opacity=opac, l_render=False)
+
+ self.GetPyData(item)[0]['maplayer'] = maplayer
+
+ # if digitization tool enabled -> update list of available vector map layers
+ if self.mapdisplay.toolbars['vdigit']:
+ self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers(updateTool=True)
+
+ # redraw map if auto-rendering is enabled
+ self.rerender = True
+ self.reorder = True
+ #if self.mapdisplay.statusbarWin['render'].GetValue():
+ # print "*** Change OnRender *****"
+ # self.mapdisplay.OnRender(None)
+
+ def OnCloseWindow(self, event):
+ pass
+ # self.Map.Clean()
+
+ def FindItemByData(self, key, value):
+ """!Find item based on key and value (see PyData[0])
+
+ @return item instance
+ @return None not found
+ """
+ item = self.GetFirstChild(self.root)[0]
+ return self.__FindSubItemByData(item, key, value)
+
+ def FindItemByIndex(self, index):
+ """!Find item by index (starting at 0)
+
+ @return item instance
+ @return None not found
+ """
+ item = self.GetFirstChild(self.root)[0]
+ i = 0
+ while item and item.IsOk():
+ if i == index:
+ return item
+
+ item = self.GetNextVisible(item)
+ i += 1
+
+ return None
+
+ def EnableItemType(self, type, enable=True):
+ """!Enable/disable items in layer tree"""
+ item = self.GetFirstChild(self.root)[0]
+ while item and item.IsOk():
+ mapLayer = self.GetPyData(item)[0]['maplayer']
+ if mapLayer and type == mapLayer.type:
+ self.EnableItem(item, enable)
+
+ item = self.GetNextSibling(item)
+
+ def __FindSubItemByData(self, item, key, value):
+ """!Support method for FindItemByValue"""
+ while item and item.IsOk():
+ try:
+ itemValue = self.GetPyData(item)[0][key]
+ except KeyError:
+ return None
+
+ if value == itemValue:
+ return item
+ if self.GetPyData(item)[0]['type'] == 'group':
+ subItem = self.GetFirstChild(item)[0]
+ found = self.__FindSubItemByData(subItem, key, value)
+ if found:
+ return found
+ item = self.GetNextSibling(item)
+
+ return None
+
Deleted: grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py 2010-03-26 14:36:16 UTC (rev 41560)
+++ grass/trunk/gui/wxpython/gui_modules/wxgui_utils.py 2010-03-26 16:17:39 UTC (rev 41561)
@@ -1,1493 +0,0 @@
-"""!
- at package wxgui_utils.py
-
- at brief Utility classes for map layer management.
-
-Classes:
- - AbstractLayer
- - Layer
- - LayerTree
-
-(C) 2007-2010 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Michael Barton (Arizona State University)
- at author Jachym Cepicky (Mendel University of Agriculture)
- at author Martin Landa <landa.martin gmail.com>
-"""
-
-import os
-import sys
-import string
-
-import wx
-try:
- import wx.lib.agw.customtreectrl as CT
-except ImportError:
- import wx.lib.customtreectrl as CT
-import wx.combo
-import wx.lib.newevent
-import wx.lib.buttons as buttons
-
-from grass.script import core as grass
-
-import gdialogs
-import globalvar
-import menuform
-import toolbars
-import mapdisp
-import render
-import histogram
-import utils
-import profile
-from debug import Debug as Debug
-from icon import Icons as Icons
-from preferences import globalSettings as UserSettings
-from vdigit import haveVDigit
-try:
- import subprocess
-except:
- from compat import subprocess
-
-try:
- import treemixin
-except ImportError:
- from wx.lib.mixins import treemixin
-
-TREE_ITEM_HEIGHT = 25
-
-class LayerTree(treemixin.DragAndDrop, CT.CustomTreeCtrl):
- """
- Creates layer tree structure
- """
- def __init__(self, parent,
- id=wx.ID_ANY, pos=wx.DefaultPosition,
- size=wx.DefaultSize, style=wx.SUNKEN_BORDER,
- ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
- CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT |
- CT.TR_MULTIPLE,**kargs):
-
- super(LayerTree, self).__init__(parent, id, pos, size, style=style, ctstyle=ctstyle)
- self.SetName("LayerTree")
-
- ### SetAutoLayout() causes that no vertical scrollbar is displayed
- ### when some layers are not visible in layer tree
- # self.SetAutoLayout(True)
- self.SetGradientStyle(1)
- self.EnableSelectionGradient(True)
- self.SetFirstGradientColour(wx.Colour(100, 100, 100))
- self.SetSecondGradientColour(wx.Colour(150, 150, 150))
-
- self.Map = render.Map() # instance of render.Map to be associated with display
- self.root = None # ID of layer tree root node
- self.groupnode = 0 # index value for layers
- self.optpage = {} # dictionary of notebook option pages for each map layer
- self.layer_selected = None # ID of currently selected layer
- self.saveitem = {} # dictionary to preserve layer attributes for drag and drop
- self.first = True # indicates if a layer is just added or not
- self.flag = '' # flag for drag and drop hittest
- self.disp_idx = kargs['idx']
- self.lmgr = kargs['lmgr']
- self.notebook = kargs['notebook'] # GIS Manager notebook for layer tree
- self.treepg = parent # notebook page holding layer tree
- self.auimgr = kargs['auimgr'] # aui manager
- self.rerender = False # layer change requires a rerendering if auto render
- self.reorder = False # layer change requires a reordering
-
- # init associated map display
- pos = wx.Point((self.disp_idx + 1) * 25, (self.disp_idx + 1) * 25)
- self.mapdisplay = mapdisp.MapFrame(self,
- id=wx.ID_ANY, pos=pos,
- size=globalvar.MAP_WINDOW_SIZE,
- style=wx.DEFAULT_FRAME_STYLE,
- tree=self, notebook=self.notebook,
- lmgr=self.lmgr, page=self.treepg,
- Map=self.Map, auimgr=self.auimgr)
-
- # title
- self.mapdisplay.SetTitle(_("GRASS GIS Map Display: %(id)d - Location: %(loc)s") % \
- { 'id' : self.disp_idx + 1,
- 'loc' : grass.gisenv()["LOCATION_NAME"] })
-
- # show new display
- if kargs['showMapDisplay'] is True:
- self.mapdisplay.Show()
- self.mapdisplay.Refresh()
- self.mapdisplay.Update()
-
- self.root = self.AddRoot(_("Map Layers"))
- self.SetPyData(self.root, (None, None))
-
- #create image list to use with layer tree
- il = wx.ImageList(16, 16, mask=False)
-
- trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, (16, 16))
- self.folder_open = il.Add(trart)
- trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))
- self.folder = il.Add(trart)
-
- bmpsize = (16, 16)
- trgif = Icons["addrast"].GetBitmap(bmpsize)
- self.rast_icon = il.Add(trgif)
-
- trgif = Icons["addrast3d"].GetBitmap(bmpsize)
- self.rast3d_icon = il.Add(trgif)
-
- trgif = Icons["addrgb"].GetBitmap(bmpsize)
- self.rgb_icon = il.Add(trgif)
-
- trgif = Icons["addhis"].GetBitmap(bmpsize)
- self.his_icon = il.Add(trgif)
-
- trgif = Icons["addshaded"].GetBitmap(bmpsize)
- self.shaded_icon = il.Add(trgif)
-
- trgif = Icons["addrarrow"].GetBitmap(bmpsize)
- self.rarrow_icon = il.Add(trgif)
-
- trgif = Icons["addrnum"].GetBitmap(bmpsize)
- self.rnum_icon = il.Add(trgif)
-
- trgif = Icons["addvect"].GetBitmap(bmpsize)
- self.vect_icon = il.Add(trgif)
-
- trgif = Icons["addthematic"].GetBitmap(bmpsize)
- self.theme_icon = il.Add(trgif)
-
- trgif = Icons["addchart"].GetBitmap(bmpsize)
- self.chart_icon = il.Add(trgif)
-
- trgif = Icons["addgrid"].GetBitmap(bmpsize)
- self.grid_icon = il.Add(trgif)
-
- trgif = Icons["addgeodesic"].GetBitmap(bmpsize)
- self.geodesic_icon = il.Add(trgif)
-
- trgif = Icons["addrhumb"].GetBitmap(bmpsize)
- self.rhumb_icon = il.Add(trgif)
-
- trgif = Icons["addlabels"].GetBitmap(bmpsize)
- self.labels_icon = il.Add(trgif)
-
- trgif = Icons["addcmd"].GetBitmap(bmpsize)
- self.cmd_icon = il.Add(trgif)
-
- self.AssignImageList(il)
-
- # use when groups implemented
- ## self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal)
- ## self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded)
-
- self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnExpandNode)
- self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnCollapseNode)
- self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivateLayer)
- self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnChangeSel)
- self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.OnLayerChecked)
- self.Bind(wx.EVT_TREE_DELETE_ITEM, self.OnDeleteLayer)
- self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnLayerContextMenu)
- #self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnDrag)
- self.Bind(wx.EVT_TREE_END_DRAG, self.OnEndDrag)
- #self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnChangeLayerName)
- self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
- # self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
- self.Bind(wx.EVT_IDLE, self.OnIdle)
-
- def GetMap(self):
- """!Get map instace"""
- return self.Map
-
- def OnIdle(self, event):
- """
- Only re-order and re-render a composite map image from GRASS during
- idle time instead of multiple times during layer changing.
- """
- if self.rerender:
- if self.mapdisplay.statusbarWin['render'].GetValue():
- self.mapdisplay.MapWindow.UpdateMap(render=True)
-
- event.Skip()
-
- def OnKeyUp(self, event):
- """!Key pressed"""
- key = event.GetKeyCode()
-
- if key == wx.WXK_DELETE and self.lmgr:
- self.lmgr.OnDeleteLayer(None)
-
- event.Skip()
-
- def OnLayerContextMenu (self, event):
- """!Contextual menu for item/layer"""
- if not self.layer_selected:
- event.Skip()
- return
-
- ltype = self.GetPyData(self.layer_selected)[0]['type']
-
- Debug.msg (4, "LayerTree.OnContextMenu: layertype=%s" % \
- ltype)
-
- if not hasattr (self, "popupID1"):
- self.popupID1 = wx.NewId()
- self.popupID2 = wx.NewId()
- self.popupID3 = wx.NewId()
- self.popupID4 = wx.NewId()
- self.popupID5 = wx.NewId()
- self.popupID6 = wx.NewId()
- self.popupID7 = wx.NewId()
- self.popupID8 = wx.NewId()
- self.popupID9 = wx.NewId()
- self.popupID10 = wx.NewId()
- self.popupID11 = wx.NewId() # nviz
- self.popupID12 = wx.NewId()
- self.popupID13 = wx.NewId()
- self.popupID14 = wx.NewId()
- self.popupID15 = wx.NewId()
-
- self.popupMenu = wx.Menu()
-
- numSelected = len(self.GetSelections())
-
- # general item
- self.popupMenu.Append(self.popupID1, text=_("Remove"))
- self.Bind(wx.EVT_MENU, self.lmgr.OnDeleteLayer, id=self.popupID1)
-
- if ltype != "command": # rename
- self.popupMenu.Append(self.popupID2, text=_("Rename"))
- self.Bind(wx.EVT_MENU, self.RenameLayer, id=self.popupID2)
- if numSelected > 1:
- self.popupMenu.Enable(self.popupID2, False)
-
- # map layer items
- if ltype != "group" and \
- ltype != "command":
- self.popupMenu.AppendSeparator()
- self.popupMenu.Append(self.popupID8, text=_("Change opacity level"))
- self.Bind(wx.EVT_MENU, self.OnPopupOpacityLevel, id=self.popupID8)
- self.popupMenu.Append(self.popupID3, text=_("Properties"))
- self.Bind(wx.EVT_MENU, self.OnPopupProperties, id=self.popupID3)
- if ltype in ('raster', 'vector', 'rgb'):
- self.popupMenu.Append(self.popupID9, text=_("Zoom to selected map(s)"))
- self.Bind(wx.EVT_MENU, self.mapdisplay.MapWindow.OnZoomToMap, id=self.popupID9)
- self.popupMenu.Append(self.popupID10, text=_("Set computational region from selected map(s)"))
- self.Bind(wx.EVT_MENU, self.OnSetCompRegFromMap, id=self.popupID10)
- if numSelected > 1:
- self.popupMenu.Enable(self.popupID8, False)
- self.popupMenu.Enable(self.popupID3, False)
-
- # specific items
- try:
- mltype = self.GetPyData(self.layer_selected)[0]['type']
- except:
- mltype = None
- #
- # vector layers (specific items)
- #
- if mltype and mltype == "vector":
- self.popupMenu.AppendSeparator()
- self.popupMenu.Append(self.popupID4, text=_("Show attribute data"))
- self.Bind (wx.EVT_MENU, self.lmgr.OnShowAttributeTable, id=self.popupID4)
-
- self.popupMenu.Append(self.popupID5, text=_("Start editing"))
- self.popupMenu.Append(self.popupID6, text=_("Stop editing"))
- self.popupMenu.Enable(self.popupID6, False)
- self.Bind (wx.EVT_MENU, self.OnStartEditing, id=self.popupID5)
- self.Bind (wx.EVT_MENU, self.OnStopEditing, id=self.popupID6)
-
- layer = self.GetPyData(self.layer_selected)[0]['maplayer']
- # enable editing only for vector map layers available in the current mapset
- digitToolbar = self.mapdisplay.toolbars['vdigit']
- if digitToolbar:
- # background vector map
- self.popupMenu.Append(self.popupID14,
- text=_("Use as background vector map"),
- kind=wx.ITEM_CHECK)
- self.Bind(wx.EVT_MENU, self.OnSetBgMap, id=self.popupID14)
- if UserSettings.Get(group='vdigit', key='bgmap', subkey='value',
- internal=True) == layer.GetName():
- self.popupMenu.Check(self.popupID14, True)
-
- if layer.GetMapset() != grass.gisenv()['MAPSET']:
- # only vector map in current mapset can be edited
- self.popupMenu.Enable (self.popupID5, False)
- self.popupMenu.Enable (self.popupID6, False)
- elif digitToolbar and digitToolbar.GetLayer():
- # vector map already edited
- vdigitLayer = digitToolbar.GetLayer()
- if vdigitLayer is layer:
- # disable 'start editing'
- self.popupMenu.Enable (self.popupID5, False)
- # enable 'stop editing'
- self.popupMenu.Enable(self.popupID6, True)
- # disable 'remove'
- self.popupMenu.Enable(self.popupID1, False)
- # disable 'bgmap'
- self.popupMenu.Enable(self.popupID14, False)
- else:
- # disable 'start editing'
- self.popupMenu.Enable(self.popupID5, False)
- # disable 'stop editing'
- self.popupMenu.Enable(self.popupID6, False)
- # enable 'bgmap'
- self.popupMenu.Enable(self.popupID14, True)
-
- self.popupMenu.Append(self.popupID7, _("Metadata"))
- self.Bind (wx.EVT_MENU, self.OnMetadata, id=self.popupID7)
- if numSelected > 1:
- self.popupMenu.Enable(self.popupID4, False)
- self.popupMenu.Enable(self.popupID5, False)
- self.popupMenu.Enable(self.popupID6, False)
- self.popupMenu.Enable(self.popupID7, False)
- self.popupMenu.Enable(self.popupID14, False)
-
- #
- # raster layers (specific items)
- #
- elif mltype and mltype == "raster":
- self.popupMenu.Append(self.popupID12, text=_("Zoom to selected map(s) (ignore NULLs)"))
- self.Bind(wx.EVT_MENU, self.mapdisplay.MapWindow.OnZoomToRaster, id=self.popupID12)
- self.popupMenu.Append(self.popupID13, text=_("Set computational region from selected map(s) (ignore NULLs)"))
- self.Bind(wx.EVT_MENU, self.OnSetCompRegFromRaster, id=self.popupID13)
- self.popupMenu.AppendSeparator()
- self.popupMenu.Append(self.popupID15, _("Set color table"))
- self.Bind (wx.EVT_MENU, self.OnColorTable, id=self.popupID15)
- self.popupMenu.Append(self.popupID4, _("Histogram"))
- self.Bind (wx.EVT_MENU, self.OnHistogram, id=self.popupID4)
- self.popupMenu.Append(self.popupID5, _("Profile"))
- self.Bind (wx.EVT_MENU, self.OnProfile, id=self.popupID5)
- self.popupMenu.Append(self.popupID6, _("Metadata"))
- self.Bind (wx.EVT_MENU, self.OnMetadata, id=self.popupID6)
- if self.mapdisplay.toolbars['nviz']:
- self.popupMenu.Append(self.popupID11, _("Nviz properties"))
- self.Bind (wx.EVT_MENU, self.OnNvizProperties, id=self.popupID11)
-
- if numSelected > 1:
- self.popupMenu.Enable(self.popupID12, False)
- self.popupMenu.Enable(self.popupID13, False)
- self.popupMenu.Enable(self.popupID15, False)
- self.popupMenu.Enable(self.popupID4, False)
- self.popupMenu.Enable(self.popupID5, False)
- self.popupMenu.Enable(self.popupID6, False)
- self.popupMenu.Enable(self.popupID11, False)
-
- ## self.PopupMenu(self.popupMenu, pos)
- self.PopupMenu(self.popupMenu)
- self.popupMenu.Destroy()
-
- def OnMetadata(self, event):
- """!Print metadata of raster/vector map layer
- TODO: Dialog to modify metadata
- """
- mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
- mltype = self.GetPyData(self.layer_selected)[0]['type']
-
- if mltype == 'raster':
- cmd = ['r.info']
- elif mltype == 'vector':
- cmd = ['v.info']
- cmd.append('map=%s' % mapLayer.name)
-
- # print output to command log area
- self.lmgr.goutput.RunCmd(cmd, switchPage=True)
-
- def OnSetCompRegFromRaster(self, event):
- """!Set computational region from selected raster map (ignore NULLs)"""
- mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
-
- cmd = ['g.region',
- '-p',
- 'zoom=%s' % mapLayer.name]
-
- # print output to command log area
- self.lmgr.goutput.RunCmd(cmd)
-
- def OnSetCompRegFromMap(self, event):
- """!Set computational region from selected raster/vector map"""
- rast = []
- vect = []
- rast3d = []
- for layer in self.GetSelections():
- mapLayer = self.GetPyData(layer)[0]['maplayer']
- mltype = self.GetPyData(layer)[0]['type']
-
- if mltype == 'raster':
- rast.append(mapLayer.name)
- elif mltype == 'vector':
- vect.append(mapLayer.name)
- elif mltype == '3d-raster':
- rast3d.append(mapLayer.name)
-
- cmd = ['g.region']
- if rast:
- cmd.append('rast=%s' % ','.join(rast))
- if vect:
- cmd.append('vect=%s' % ','.join(vect))
- if rast3d:
- cmd.append('rast3d=%s' % ','.join(rast3d))
-
- # print output to command log area
- if len(cmd) > 1:
- cmd.append('-p')
- self.lmgr.goutput.RunCmd(cmd)
-
- def OnProfile(self, event):
- """!Plot profile of given raster map layer"""
- mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
- if not mapLayer.name:
- wx.MessageBox(parent=self,
- message=_("Unable to create profile of "
- "raster map."),
- caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
- return False
-
- if not hasattr (self, "profileFrame"):
- self.profileFrame = None
-
- if hasattr (self.mapdisplay, "profile") and self.mapdisplay.profile:
- self.profileFrame = self.mapdisplay.profile
-
- if not self.profileFrame:
- self.profileFrame = profile.ProfileFrame(self.mapdisplay,
- id=wx.ID_ANY, pos=wx.DefaultPosition, size=(700,300),
- style=wx.DEFAULT_FRAME_STYLE, rasterList=[mapLayer.name])
- # show new display
- self.profileFrame.Show()
-
- def OnColorTable(self, event):
- """!Set color table for raster map"""
- name = self.GetPyData(self.layer_selected)[0]['maplayer'].name
- menuform.GUI().ParseCommand(['r.colors',
- 'map=%s' % name],
- parentframe=self)
-
- def OnHistogram(self, event):
- """
- Plot histogram for given raster map layer
- """
- mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
- if not mapLayer.name:
- wx.MessageBox(parent=self,
- message=_("Unable to display histogram of "
- "raster map."),
- caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
- return False
-
- if not hasattr (self, "histogramFrame"):
- self.histogramFrame = None
-
- if hasattr (self.mapdisplay, "histogram") and self.mapdisplay.histogram:
- self.histogramFrame = self.mapdisplay.histogram
-
- if not self.histogramFrame:
- self.histogramFrame = histogram.HistFrame(self,
- id=wx.ID_ANY,
- pos=wx.DefaultPosition, size=globalvar.HIST_WINDOW_SIZE,
- style=wx.DEFAULT_FRAME_STYLE)
- # show new display
- self.histogramFrame.Show()
-
- self.histogramFrame.SetHistLayer(mapLayer.name)
- self.histogramFrame.HistWindow.UpdateHist()
- self.histogramFrame.Refresh()
- self.histogramFrame.Update()
-
- return True
-
- def OnStartEditing(self, event):
- """
- Start editing vector map layer requested by the user
- """
- if not haveVDigit:
- from vdigit import errorMsg
- msg = _("Unable to start vector digitizer.\nThe VDigit python extension "
- "was not found or loaded properly.\n"
- "Switching back to 2D display mode.\n\nDetails: %s" % errorMsg)
-
- self.mapdisplay.toolbars['map'].combo.SetValue (_("2D view"))
- wx.MessageBox(parent=self.mapdisplay,
- message=msg,
- caption=_("Error"),
- style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
- return
-
- try:
- maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
- except:
- event.Skip()
- return
-
- if not self.mapdisplay.toolbars['vdigit']: # enable tool
- self.mapdisplay.AddToolbar('vdigit')
- else: # tool already enabled
- pass
-
- # mark layer as 'edited'
- self.mapdisplay.toolbars['vdigit'].StartEditing (maplayer)
-
- def OnStopEditing(self, event):
- """
- Stop editing the current vector map layer
- """
- maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
-
- self.mapdisplay.toolbars['vdigit'].OnExit()
- self.mapdisplay.imgVectorMap = None
-
- def OnSetBgMap(self, event):
- """!Set background vector map for editing sesstion"""
- if event.IsChecked():
- mapName = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
- UserSettings.Set(group='vdigit', key='bgmap', subkey='value',
- value=str(mapName), internal=True)
- else:
- UserSettings.Set(group='vdigit', key='bgmap', subkey='value',
- value='', internal=True)
-
- def OnPopupProperties (self, event):
- """!Popup properties dialog"""
- self.PropertiesDialog(self.layer_selected)
-
- def OnPopupOpacityLevel(self, event):
- """!Popup opacity level indicator"""
- if not self.GetPyData(self.layer_selected)[0]['ctrl']:
- return
-
- #win = self.FindWindowById(self.GetPyData(self.layer_selected)[0]['ctrl'])
- #type = win.GetName()
- #
- #self.layer_selected.DeleteWindow()
-
- maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
- current_opacity = maplayer.GetOpacity()
-
- dlg = gdialogs.SetOpacityDialog(self, opacity=current_opacity,
- title=_("Set opacity <%s>") % maplayer.GetName())
- dlg.CentreOnParent()
-
- if dlg.ShowModal() == wx.ID_OK:
- new_opacity = dlg.GetOpacity() # string
- self.Map.ChangeOpacity(maplayer, new_opacity)
- maplayer.SetOpacity(new_opacity)
- opacity_pct = int(new_opacity * 100)
- layername = self.GetItemText(self.layer_selected)
- layerbase = layername.split('(')[0].strip()
- self.SetItemText(self.layer_selected,
- layerbase + ' (opacity: ' + str(opacity_pct) + '%)')
-
- # vector layer currently edited
- if self.mapdisplay.toolbars['vdigit'] and \
- self.mapdisplay.toolbars['vdigit'].GetLayer() == maplayer:
- alpha = int(new_opacity * 255)
- self.mapdisplay.digit.driver.UpdateSettings(alpha)
-
- # redraw map if auto-rendering is enabled
- self.rerender = True
- self.reorder = True
- #if self.mapdisplay.statusbarWin['render'].GetValue():
- # print "*** Opacity OnRender *****"
- # self.mapdisplay.OnRender(None)
-
- def OnNvizProperties(self, event):
- """!Nviz-related properties (raster/vector/volume)
-
- @todo vector/volume
- """
- if not self.mapdisplay.nvizToolWin.IsShown():
- self.mapdisplay.nvizToolWin.Show()
-
- self.mapdisplay.nvizToolWin.SetPage('surface')
-
- def RenameLayer (self, event):
- """!Rename layer"""
- self.EditLabel(self.layer_selected)
-
- def AddLayer(self, ltype, lname=None, lchecked=None,
- lopacity=1.0, lcmd=None, lgroup=None, lvdigit=None, lnviz=None):
- """!Add new item to the layer tree, create corresponding MapLayer instance.
- Launch property dialog if needed (raster, vector, etc.)
-
- @param ltype layer type (raster, vector, 3d-raster, ...)
- @param lname layer name
- @param lchecked if True layer is checked
- @param lopacity layer opacity level
- @param lcmd command (given as a list)
- @param lgroup index of group item (-1 for root) or None
- @param lvdigit vector digitizer settings (eg. geometry attributes)
- @param lnviz layer Nviz properties
- """
- self.first = True
- params = {} # no initial options parameters
-
- # deselect active item
- if self.layer_selected:
- self.SelectItem(self.layer_selected, select=False)
-
- Debug.msg (3, "LayerTree().AddLayer(): ltype=%s" % (ltype))
-
- if ltype == 'command':
- # generic command item
- ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
- pos=wx.DefaultPosition, size=(self.GetSize()[0]-100,25),
- # style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
- style=wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
- ctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
- # ctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
- elif ltype == 'group':
- # group item
- ctrl = None
- grouptext = _('Layer group:') + str(self.groupnode)
- self.groupnode += 1
- else:
- btnbmp = Icons["layeropts"].GetBitmap((16,16))
- ctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp, size=(24,24))
- ctrl.SetToolTipString(_("Click to edit layer settings"))
- self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, ctrl)
- # add layer to the layer tree
- if self.layer_selected and self.layer_selected != self.GetRootItem():
- if self.GetPyData(self.layer_selected)[0]['type'] == 'group' \
- and self.IsExpanded(self.layer_selected):
- # add to group (first child of self.layer_selected) if group expanded
- layer = self.PrependItem(parent=self.layer_selected,
- text='', ct_type=1, wnd=ctrl)
- else:
- # prepend to individual layer or non-expanded group
- if lgroup == -1:
- # -> last child of root (loading from workspace)
- layer = self.AppendItem(parentId=self.root,
- text='', ct_type=1, wnd=ctrl)
- elif lgroup > -1:
- # -> last child of group (loading from workspace)
- parent = self.FindItemByIndex(index = lgroup)
- if not parent:
- parent = self.root
- layer = self.AppendItem(parentId=parent,
- text='', ct_type=1, wnd=ctrl)
- elif lgroup is None:
- # -> previous sibling of selected layer
- parent = self.GetItemParent(self.layer_selected)
- layer = self.InsertItem(parentId=parent,
- input=self.GetPrevSibling(self.layer_selected),
- text='', ct_type=1, wnd=ctrl)
- else: # add first layer to the layer tree (first child of root)
- layer = self.PrependItem(parent=self.root, text='', ct_type=1, wnd=ctrl)
-
- # layer is initially unchecked as inactive (beside 'command')
- # use predefined value if given
- if lchecked is not None:
- checked = lchecked
- else:
- checked = True
-
- self.CheckItem(layer, checked=checked)
-
- # select new item
- self.SelectItem(layer, select=True)
- self.layer_selected = layer
-
- # add text and icons for each layer ltype
- if ltype == 'raster':
- self.SetItemImage(layer, self.rast_icon)
- self.SetItemText(layer, '%s %s' % (_('raster'), _('(double click to set properties)')))
- elif ltype == '3d-raster':
- self.SetItemImage(layer, self.rast3d_icon)
- self.SetItemText(layer, '%s %s' % (_('3d raster'), _('(double click to set properties)')))
- elif ltype == 'rgb':
- self.SetItemImage(layer, self.rgb_icon)
- self.SetItemText(layer, '%s %s' % (_('RGB'), _('(double click to set properties)')))
- elif ltype == 'his':
- self.SetItemImage(layer, self.his_icon)
- self.SetItemText(layer, '%s %s' % (_('HIS'), _('(double click to set properties)')))
- elif ltype == 'shaded':
- self.SetItemImage(layer, self.shaded_icon)
- self.SetItemText(layer, '%s %s' % (_('Shaded relief'), _('(double click to set properties)')))
- elif ltype == 'rastnum':
- self.SetItemImage(layer, self.rnum_icon)
- self.SetItemText(layer, '%s %s' % (_('raster cell numbers'), _('(double click to set properties)')))
- elif ltype == 'rastarrow':
- self.SetItemImage(layer, self.rarrow_icon)
- self.SetItemText(layer, '%s %s' % (_('raster flow arrows'), _('(double click to set properties)')))
- elif ltype == 'vector':
- self.SetItemImage(layer, self.vect_icon)
- self.SetItemText(layer, '%s %s' % (_('vector'), _('(double click to set properties)')))
- elif ltype == 'thememap':
- self.SetItemImage(layer, self.theme_icon)
- self.SetItemText(layer, '%s %s' % (_('thematic area (choropleth) map'), _('(double click to set properties)')))
- elif ltype == 'themechart':
- self.SetItemImage(layer, self.chart_icon)
- self.SetItemText(layer, '%s %s' % (_('thematic charts'), _('(double click to set properties)')))
- elif ltype == 'grid':
- self.SetItemImage(layer, self.grid_icon)
- self.SetItemText(layer, '%s %s' % (_('grid'), _('(double click to set properties)')))
- elif ltype == 'geodesic':
- self.SetItemImage(layer, self.geodesic_icon)
- self.SetItemText(layer, '%s %s' % (_('geodesic line'), _('(double click to set properties)')))
- elif ltype == 'rhumb':
- self.SetItemImage(layer, self.rhumb_icon)
- self.SetItemText(layer, '%s %s' % (_('rhumbline'), _('(double click to set properties)')))
- elif ltype == 'labels':
- self.SetItemImage(layer, self.labels_icon)
- self.SetItemText(layer, '%s %s' % (_('vector labels'), _('(double click to set properties)')))
- elif ltype == 'command':
- self.SetItemImage(layer, self.cmd_icon)
- elif ltype == 'group':
- self.SetItemImage(layer, self.folder)
- self.SetItemText(layer, grouptext)
-
- self.first = False
-
- if ltype != 'group':
- if lcmd and len(lcmd) > 1:
- cmd = lcmd
- render = False
- name = utils.GetLayerNameFromCmd(lcmd)
- else:
- cmd = []
- if ltype == 'command' and lname:
- for c in lname.split(';'):
- cmd.append(c.split(' '))
-
- render = False
- name = None
-
- if ctrl:
- ctrlId = ctrl.GetId()
- else:
- ctrlId = None
-
- # add a data object to hold the layer's command (does not apply to generic command layers)
- self.SetPyData(layer, ({'cmd' : cmd,
- 'type' : ltype,
- 'ctrl' : ctrlId,
- 'maplayer' : None,
- 'vdigit' : lvdigit,
- 'nviz' : lnviz,
- 'propwin' : None},
- None))
-
- # find previous map layer instance
- prevItem = self.GetFirstChild(self.root)[0]
- prevMapLayer = None
- pos = -1
- while prevItem and prevItem.IsOk() and prevItem != layer:
- if self.GetPyData(prevItem)[0]['maplayer']:
- prevMapLayer = self.GetPyData(prevItem)[0]['maplayer']
-
- prevItem = self.GetNextSibling(prevItem)
-
- if prevMapLayer:
- pos = self.Map.GetLayerIndex(prevMapLayer)
- else:
- pos = -1
-
- maplayer = self.Map.AddLayer(pos=pos,
- type=ltype, command=self.GetPyData(layer)[0]['cmd'], name=name,
- l_active=checked, l_hidden=False,
- l_opacity=lopacity, l_render=render)
- self.GetPyData(layer)[0]['maplayer'] = maplayer
-
- # run properties dialog if no properties given
- if len(cmd) == 0:
- self.PropertiesDialog(layer, show=True)
-
- if ltype == '3d-raster' and \
- not self.mapdisplay.toolbars['nviz']:
- self.EnableItem(layer, False)
-
- else: # group
- self.SetPyData(layer, ({'cmd': None,
- 'type' : ltype,
- 'ctrl' : None,
- 'maplayer' : None,
- 'propwin' : None},
- None))
-
- # use predefined layer name if given
- if lname:
- if ltype == 'group':
- self.SetItemText(layer, lname)
- elif ltype == 'command':
- ctrl.SetValue(lname)
- else:
- name = lname + ' (opacity: ' + \
- str(self.GetPyData(layer)[0]['maplayer'].GetOpacity()) + '%)'
- self.SetItemText(layer, name)
-
- # updated progress bar range (mapwindow statusbar)
- if checked is True:
- self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
-
- # layer.SetHeight(TREE_ITEM_HEIGHT)
-
- return layer
-
- def PropertiesDialog (self, layer, show=True):
- """!Launch the properties dialog"""
- if self.GetPyData(layer)[0].has_key('propwin') and \
- self.GetPyData(layer)[0]['propwin'] is not None:
- # recycle GUI dialogs
- win = self.GetPyData(layer)[0]['propwin']
- # update properties (columns, layers)
- win.notebookpanel.OnUpdateSelection(None)
- if win.IsShown():
- win.SetFocus()
- else:
- win.Show()
-
- return
-
- completed = ''
- params = self.GetPyData(layer)[1]
- ltype = self.GetPyData(layer)[0]['type']
-
- Debug.msg (3, "LayerTree.PropertiesDialog(): ltype=%s" % \
- ltype)
-
- if self.GetPyData(layer)[0]['cmd']:
- module = menuform.GUI()
- module.ParseCommand(self.GetPyData(layer)[0]['cmd'],
- completed=(self.GetOptData,layer,params),
- parentframe=self, show=show)
-
- self.GetPyData(layer)[0]['cmd'] = module.GetCmd()
- elif ltype == 'raster':
- cmd = ['d.rast']
-
- if UserSettings.Get(group='cmd', key='rasterOpaque', subkey='enabled'):
- cmd.append('-n')
- menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == '3d-raster':
- cmd = ['d.rast3d']
- menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'rgb':
- menuform.GUI().ParseCommand(['d.rgb'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'his':
- menuform.GUI().ParseCommand(['d.his'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'shaded':
- menuform.GUI().ParseCommand(['d.shadedmap'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'rastarrow':
- menuform.GUI().ParseCommand(['d.rast.arrow'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'rastnum':
- menuform.GUI().ParseCommand(['d.rast.num'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'vector':
- types = ''
- for type in UserSettings.Get(group='cmd', key='showType').keys():
- if UserSettings.Get(group='cmd', key='showType', subkey=[type, 'enabled']):
- types += type + ','
- types = types.rstrip(',')
-
- menuform.GUI().ParseCommand(['d.vect', 'type=%s' % types],
- completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'thememap':
- # -s flag requested, otherwise only first thematic category is displayed
- # should be fixed by C-based d.thematic.* modules
- menuform.GUI().ParseCommand(['d.thematic.area'],
- completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'themechart':
- menuform.GUI().ParseCommand(['d.vect.chart'],
- completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'grid':
- menuform.GUI().ParseCommand(['d.grid'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'geodesic':
- menuform.GUI().ParseCommand(['d.geodesic'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'rhumb':
- menuform.GUI().ParseCommand(['d.rhumbline'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'labels':
- menuform.GUI().ParseCommand(['d.labels'], completed=(self.GetOptData,layer,params),
- parentframe=self)
- elif ltype == 'cmdlayer':
- pass
- elif ltype == 'group':
- pass
-
- def OnActivateLayer(self, event):
- """!Double click on the layer item.
- Launch property dialog, or expand/collapse group of items, etc."""
-
- layer = event.GetItem()
- self.layer_selected = layer
-
- self.PropertiesDialog (layer)
-
- if self.GetPyData(layer)[0]['type'] == 'group':
- if self.IsExpanded(layer):
- self.Collapse(layer)
- else:
- self.Expand(layer)
-
- def OnDeleteLayer(self, event):
- """!Remove selected layer item from the layer tree"""
-
- item = event.GetItem()
-
- try:
- item.properties.Close(True)
- except:
- pass
-
- if item != self.root:
- Debug.msg (3, "LayerTree.OnDeleteLayer(): name=%s" % \
- (self.GetItemText(item)))
- else:
- self.root = None
-
- # unselect item
- self.Unselect()
- self.layer_selected = None
-
- try:
- if self.GetPyData(item)[0]['type'] != 'group':
- self.Map.DeleteLayer( self.GetPyData(item)[0]['maplayer'])
- except:
- pass
-
- # redraw map if auto-rendering is enabled
- self.rerender = True
- self.reorder = True
- #if self.mapdisplay.statusbarWin['render'].GetValue():
- # print "*** Delete OnRender *****"
- # self.mapdisplay.OnRender(None)
-
- if self.mapdisplay.toolbars['vdigit']:
- self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers (updateTool=True)
-
- # update progress bar range (mapwindow statusbar)
- self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
-
- event.Skip()
-
- def OnLayerChecked(self, event):
- """!Enable/disable data layer"""
- item = event.GetItem()
- checked = item.IsChecked()
-
- digitToolbar = self.mapdisplay.toolbars['vdigit']
- if self.first == False:
- # change active parameter for item in layers list in render.Map
- if self.GetPyData(item)[0]['type'] == 'group':
- child, cookie = self.GetFirstChild(item)
- while child:
- self.CheckItem(child, checked)
- mapLayer = self.GetPyData(child)[0]['maplayer']
- if not digitToolbar or \
- (digitToolbar and digitToolbar.GetLayer() != mapLayer):
- # ignore when map layer is edited
- self.Map.ChangeLayerActive(mapLayer, checked)
- child = self.GetNextSibling(child)
- else:
- mapLayer = self.GetPyData(item)[0]['maplayer']
- if not digitToolbar or \
- (digitToolbar and digitToolbar.GetLayer() != mapLayer):
- # ignore when map layer is edited
- self.Map.ChangeLayerActive(mapLayer, checked)
-
- #
- # update progress bar range (mapwindow statusbar)
- #
- self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
-
- #
- # nviz
- #
- if self.mapdisplay.toolbars['nviz'] and \
- self.GetPyData(item) is not None:
- # nviz - load/unload data layer
- mapLayer = self.GetPyData(item)[0]['maplayer']
-
- self.mapdisplay.SetStatusText(_("Please wait, updating data..."), 0)
-
- if checked: # enable
- if mapLayer.type == 'raster':
- self.mapdisplay.MapWindow.LoadRaster(item)
- elif mapLayer.type == '3d-raster':
- self.mapdisplay.MapWindow.LoadRaster3d(item)
- elif mapLayer.type == 'vector':
- self.mapdisplay.MapWindow.LoadVector(item)
-
- else: # disable
- data = self.GetPyData(item)[0]['nviz']
-
- if mapLayer.type == 'raster':
- self.mapdisplay.MapWindow.UnloadRaster(item)
- elif mapLayer.type == '3d-raster':
- self.mapdisplay.MapWindow.UnloadRaster3d(item)
- elif mapLayer.type == 'vector':
- self.mapdisplay.MapWindow.UnloadVector(item)
-
- if hasattr(self.mapdisplay, "nvizToolWin"):
- toolWin = self.mapdisplay.nvizToolWin
- # remove vector page
- if toolWin.notebook.GetSelection() == toolWin.page['vector']['id']:
- toolWin.notebook.RemovePage(toolWin.page['vector']['id'])
- toolWin.page['vector']['id'] = -1
- toolWin.page['settings']['id'] = 1
-
- self.mapdisplay.SetStatusText("", 0)
-
- # redraw map if auto-rendering is enabled
- self.rerender = True
- self.reorder = True
- #if self.mapdisplay.statusbarWin['render'].GetValue():
- # print "*** Checked OnRender *****"
- # self.mapdisplay.OnRender(None)
-
- def OnCmdChanged(self, event):
- """!Change command string"""
- ctrl = event.GetEventObject().GetId()
- cmd = event.GetString()
-
- layer = self.GetFirstVisibleItem()
-
- while layer and layer.IsOk():
- if self.GetPyData(layer)[0]['ctrl'] == ctrl:
- break
-
- layer = self.GetNextVisible(layer)
-
- # change parameters for item in layers list in render.Map
- self.ChangeLayer(layer)
-
- event.Skip()
-
- def OnChangeSel(self, event):
- """!Selection changed"""
- oldlayer = event.GetOldItem()
- layer = event.GetItem()
- if layer == oldlayer:
- event.Veto()
- return
-
- self.layer_selected = layer
-
- try:
- if self.IsSelected(oldlayer):
- self.SetItemWindowEnabled(oldlayer, True)
- else:
- self.SetItemWindowEnabled(oldlayer, False)
-
- if self.IsSelected(layer):
- self.SetItemWindowEnabled(layer, True)
- else:
- self.SetItemWindowEnabled(layer, False)
- except:
- pass
-
- try:
- self.RefreshLine(oldlayer)
- self.RefreshLine(layer)
- except:
- pass
-
- #
- # update statusbar -> show command string
- #
- if self.GetPyData(layer) and self.GetPyData(layer)[0]['maplayer']:
- cmd = self.GetPyData(layer)[0]['maplayer'].GetCmd(string=True)
- if len(cmd) > 0:
- self.lmgr.SetStatusText(cmd)
-
- # set region if auto-zooming is enabled
- if self.GetPyData(layer) and self.GetPyData(layer)[0]['cmd'] and \
- UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
- mapLayer = self.GetPyData(layer)[0]['maplayer']
- if mapLayer.GetType() in ('raster', 'vector'):
- render = self.mapdisplay.statusbarWin['render'].IsChecked()
- self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
- render = render)
-
- #
- # update nviz tools
- #
- if self.mapdisplay.toolbars['nviz'] and \
- self.GetPyData(self.layer_selected) is not None:
-
- if self.layer_selected.IsChecked():
- # update Nviz tool window
- type = self.GetPyData(self.layer_selected)[0]['maplayer'].type
-
- if type == 'raster':
- self.mapdisplay.nvizToolWin.UpdatePage('surface')
- self.mapdisplay.nvizToolWin.SetPage('surface')
- elif type == 'vector':
- self.mapdisplay.nvizToolWin.UpdatePage('vector')
- self.mapdisplay.nvizToolWin.SetPage('vector')
- elif type == '3d-raster':
- self.mapdisplay.nvizToolWin.UpdatePage('volume')
- self.mapdisplay.nvizToolWin.SetPage('volume')
- else:
- for page in ('surface', 'vector', 'volume'):
- pageId = self.mapdisplay.nvizToolWin.page[page]['id']
- if pageId > -1:
- self.mapdisplay.nvizToolWin.notebook.RemovePage(pageId)
- self.mapdisplay.nvizToolWin.page[page]['id'] = -1
- self.mapdisplay.nvizToolWin.page['settings']['id'] = 1
-
- def OnCollapseNode(self, event):
- """
- Collapse node
- """
- if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
- self.SetItemImage(self.layer_selected, self.folder)
-
- def OnExpandNode(self, event):
- """
- Expand node
- """
- self.layer_selected = event.GetItem()
- if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
- self.SetItemImage(self.layer_selected, self.folder_open)
-
- def OnEndDrag(self, event):
- self.StopDragging()
- dropTarget = event.GetItem()
- self.flag = self.HitTest(event.GetPoint())[1]
- if self.IsValidDropTarget(dropTarget):
- self.UnselectAll()
- if dropTarget != None:
- self.SelectItem(dropTarget)
- self.OnDrop(dropTarget, self._dragItem)
- elif dropTarget == None:
- self.OnDrop(dropTarget, self._dragItem)
-
- def OnDrop(self, dropTarget, dragItem):
- # save everthing associated with item to drag
- try:
- old = dragItem # make sure this member exists
- except:
- return
-
- Debug.msg (4, "LayerTree.OnDrop(): layer=%s" % \
- (self.GetItemText(dragItem)))
-
- # recreate data layer, insert copy of layer in new position, and delete original at old position
- newItem = self.RecreateItem (dragItem, dropTarget)
-
- # if recreated layer is a group, also recreate its children
- if self.GetPyData(newItem)[0]['type'] == 'group':
- (child, cookie) = self.GetFirstChild(dragItem)
- if child:
- while child:
- self.RecreateItem(child, dropTarget, parent=newItem)
- self.Delete(child)
- child = self.GetNextChild(old, cookie)[0]
- #self.Expand(newItem)
-
- # delete layer at original position
- try:
- self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
- except AttributeError:
- # FIXME being ugly (item.SetWindow(None))
- pass
-
- # reorder layers in render.Map to match new order after drag and drop
- #self.ReorderLayers()
-
- # redraw map if auto-rendering is enabled
- self.rerender = True
- self.reorder = True
- #if self.mapdisplay.statusbarWin['render'].GetValue():
- # print "*** Drop OnRender *****"
- # self.mapdisplay.OnRender(None)
-
- # select new item
- self.SelectItem(newItem)
-
- def RecreateItem (self, dragItem, dropTarget, parent=None):
- """
- Recreate item (needed for OnEndDrag())
- """
- Debug.msg (4, "LayerTree.RecreateItem(): layer=%s" % \
- self.GetItemText(dragItem))
-
- # fetch data (dragItem)
- checked = self.IsItemChecked(dragItem)
- image = self.GetItemImage(dragItem, 0)
- text = self.GetItemText(dragItem)
- if self.GetPyData(dragItem)[0]['ctrl']:
- # recreate data layer
- btnbmp = Icons["layeropts"].GetBitmap((16,16))
- newctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp, size=(24, 24))
- newctrl.SetToolTipString(_("Click to edit layer settings"))
- self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, newctrl)
- data = self.GetPyData(dragItem)
-
- elif self.GetPyData(dragItem)[0]['type'] == 'command':
- # recreate command layer
- oldctrl = None
- newctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
- pos=wx.DefaultPosition, size=(250,25),
- style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
- try:
- newctrl.SetValue(self.GetPyData(dragItem)[0]['maplayer'].GetCmd(string=True))
- except:
- pass
- newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
- newctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
- data = self.GetPyData(dragItem)
-
- elif self.GetPyData(dragItem)[0]['type'] == 'group':
- # recreate group
- newctrl = None
- data = None
-
- # decide where to put recreated item
- if dropTarget != None and dropTarget != self.GetRootItem():
- if parent:
- # new item is a group
- afteritem = parent
- else:
- # new item is a single layer
- afteritem = dropTarget
-
- # dragItem dropped on group
- if self.GetPyData(afteritem)[0]['type'] == 'group':
- newItem = self.PrependItem(afteritem, text=text, \
- ct_type=1, wnd=newctrl, image=image, \
- data=data)
- self.Expand(afteritem)
- else:
- #dragItem dropped on single layer
- newparent = self.GetItemParent(afteritem)
- newItem = self.InsertItem(newparent, self.GetPrevSibling(afteritem), \
- text=text, ct_type=1, wnd=newctrl, \
- image=image, data=data)
- else:
- # if dragItem not dropped on a layer or group, append or prepend it to the layer tree
- if self.flag & wx.TREE_HITTEST_ABOVE:
- newItem = self.PrependItem(self.root, text=text, \
- ct_type=1, wnd=newctrl, image=image, \
- data=data)
- elif (self.flag & wx.TREE_HITTEST_BELOW) or (self.flag & wx.TREE_HITTEST_NOWHERE) \
- or (self.flag & wx.TREE_HITTEST_TOLEFT) or (self.flag & wx.TREE_HITTEST_TORIGHT):
- newItem = self.AppendItem(self.root, text=text, \
- ct_type=1, wnd=newctrl, image=image, \
- data=data)
-
- #update new layer
- self.SetPyData(newItem, self.GetPyData(dragItem))
- if newctrl:
- self.GetPyData(newItem)[0]['ctrl'] = newctrl.GetId()
- else:
- self.GetPyData(newItem)[0]['ctrl'] = None
-
- self.CheckItem(newItem, checked=checked) # causes a new render
-
- # newItem.SetHeight(TREE_ITEM_HEIGHT)
-
- return newItem
-
- def GetOptData(self, dcmd, layer, params, propwin):
- """!Process layer data"""
- # set layer text to map name
- if dcmd:
- mapLayer = self.GetPyData(layer)[0]['maplayer']
- opacity = int(mapLayer.GetOpacity(float=True) * 100)
- mapname = utils.GetLayerNameFromCmd(dcmd, layerType=mapLayer.type,
- fullyQualified=True)
- if not mapname:
- wx.MessageBox(parent=self,
- message=_("Map <%s> not found.") % utils.GetLayerNameFromCmd(dcmd),
- caption=_("Error"),
- style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
-
- return
-
- self.SetItemText(layer, mapname + ' (opacity: ' + str(opacity) + '%)')
-
- # update layer data
- if params:
- self.SetPyData(layer, (self.GetPyData(layer)[0], params))
- if dcmd:
- self.GetPyData(layer)[0]['cmd'] = dcmd
- self.GetPyData(layer)[0]['propwin'] = propwin
-
- # change parameters for item in layers list in render.Map
- self.ChangeLayer(layer)
-
- # set region if auto-zooming is enabled
- if dcmd and UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
- mapLayer = self.GetPyData(layer)[0]['maplayer']
- if mapLayer.GetType() in ('raster', 'vector'):
- render = UserSettings.Get(group = 'display', key = 'autoRendering', subkey = 'enabled')
- self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
- render = render)
-
- if self.mapdisplay.toolbars['nviz'] and dcmd:
- # update nviz session
- mapLayer = self.GetPyData(layer)[0]['maplayer']
- mapWin = self.mapdisplay.MapWindow
- if len(mapLayer.GetCmd()) > 0:
- id = -1
- if mapLayer.type == 'raster':
- if mapWin.IsLoaded(layer):
- mapWin.UnloadRaster(layer)
-
- mapWin.LoadRaster(layer)
-
- elif mapLayer.type == '3d-raster':
- if mapWin.IsLoaded(layer):
- mapWin.UnloadRaster3d(layer)
-
- mapWin.LoadRaster3d(layer)
-
- elif mapLayer.type == 'vector':
- if mapWin.IsLoaded(layer):
- mapWin.UnloadVector(layer)
-
- mapWin.LoadVector(layer)
-
- # reset view when first layer loaded
- nlayers = len(mapWin.Map.GetListOfLayers(l_type=('raster', 'vector'),
- l_active=True))
- if nlayers < 2:
- mapWin.ResetView()
-
- def ReorderLayers(self):
- """!Add commands from data associated with
- any valid layers (checked or not) to layer list in order to
- match layers in layer tree."""
-
- # make a list of visible layers
- treelayers = []
-
- vislayer = self.GetFirstVisibleItem()
-
- if not vislayer or self.GetPyData(vislayer) is None:
- return
-
- itemList = ""
-
- for item in range(self.GetCount()):
- itemList += self.GetItemText(vislayer) + ','
- if self.GetPyData(vislayer)[0]['type'] != 'group':
- treelayers.append(self.GetPyData(vislayer)[0]['maplayer'])
-
- if not self.GetNextVisible(vislayer):
- break
- else:
- vislayer = self.GetNextVisible(vislayer)
-
- Debug.msg (4, "LayerTree.ReorderLayers(): items=%s" % \
- (itemList))
-
- # reorder map layers
- treelayers.reverse()
- self.Map.ReorderLayers(treelayers)
- self.reorder = False
-
- def ChangeLayer(self, item):
- """!Change layer"""
- type = self.GetPyData(item)[0]['type']
- layerName = None
-
- if type == 'command':
- win = self.FindWindowById(self.GetPyData(item)[0]['ctrl'])
- if win.GetValue() != None:
- cmd = win.GetValue().split(';')
- cmdlist = []
- for c in cmd:
- cmdlist.append(c.split(' '))
- opac = 1.0
- chk = self.IsItemChecked(item)
- hidden = not self.IsVisible(item)
- elif type != 'group':
- if self.GetPyData(item)[0] is not None:
- cmdlist = self.GetPyData(item)[0]['cmd']
- opac = self.GetPyData(item)[0]['maplayer'].GetOpacity(float=True)
- chk = self.IsItemChecked(item)
- hidden = not self.IsVisible(item)
- # determine layer name
- layerName = utils.GetLayerNameFromCmd(cmdlist, fullyQualified=True)
- if not layerName:
- layerName = self.GetItemText(item)
-
- maplayer = self.Map.ChangeLayer(layer=self.GetPyData(item)[0]['maplayer'], type=type,
- command=cmdlist, name=layerName,
- l_active=chk, l_hidden=hidden, l_opacity=opac, l_render=False)
-
- self.GetPyData(item)[0]['maplayer'] = maplayer
-
- # if digitization tool enabled -> update list of available vector map layers
- if self.mapdisplay.toolbars['vdigit']:
- self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers(updateTool=True)
-
- # redraw map if auto-rendering is enabled
- self.rerender = True
- self.reorder = True
- #if self.mapdisplay.statusbarWin['render'].GetValue():
- # print "*** Change OnRender *****"
- # self.mapdisplay.OnRender(None)
-
- def OnCloseWindow(self, event):
- pass
- # self.Map.Clean()
-
- def FindItemByData(self, key, value):
- """!Find item based on key and value (see PyData[0])
-
- @return item instance
- @return None not found
- """
- item = self.GetFirstChild(self.root)[0]
- return self.__FindSubItemByData(item, key, value)
-
- def FindItemByIndex(self, index):
- """!Find item by index (starting at 0)
-
- @return item instance
- @return None not found
- """
- item = self.GetFirstChild(self.root)[0]
- i = 0
- while item and item.IsOk():
- if i == index:
- return item
-
- item = self.GetNextVisible(item)
- i += 1
-
- return None
-
- def EnableItemType(self, type, enable=True):
- """!Enable/disable items in layer tree"""
- item = self.GetFirstChild(self.root)[0]
- while item and item.IsOk():
- mapLayer = self.GetPyData(item)[0]['maplayer']
- if mapLayer and type == mapLayer.type:
- self.EnableItem(item, enable)
-
- item = self.GetNextSibling(item)
-
- def __FindSubItemByData(self, item, key, value):
- """!Support method for FindItemByValue"""
- while item and item.IsOk():
- try:
- itemValue = self.GetPyData(item)[0][key]
- except KeyError:
- return None
-
- if value == itemValue:
- return item
- if self.GetPyData(item)[0]['type'] == 'group':
- subItem = self.GetFirstChild(item)[0]
- found = self.__FindSubItemByData(subItem, key, value)
- if found:
- return found
- item = self.GetNextSibling(item)
-
- return None
-
Modified: grass/trunk/gui/wxpython/wxgui.py
===================================================================
--- grass/trunk/gui/wxpython/wxgui.py 2010-03-26 14:36:16 UTC (rev 41560)
+++ grass/trunk/gui/wxpython/wxgui.py 2010-03-26 16:17:39 UTC (rev 41561)
@@ -72,7 +72,7 @@
import gui_modules.utils as utils
import gui_modules.preferences as preferences
-import gui_modules.wxgui_utils as wxgui_utils
+import gui_modules.layertree as layertree
import gui_modules.mapdisp as mapdisp
import gui_modules.menudata as menudata
import gui_modules.menuform as menuform
@@ -1159,12 +1159,12 @@
self.curr_page = self.gm_cb.GetCurrentPage()
# create layer tree (tree control for managing GIS layers) and put on new notebook page
- self.curr_page.maptree = wxgui_utils.LayerTree(self.curr_page, id=wx.ID_ANY, pos=wx.DefaultPosition,
- size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS
- |wx.TR_LINES_AT_ROOT|wx.TR_HIDE_ROOT
- |wx.TR_DEFAULT_STYLE|wx.NO_BORDER|wx.FULL_REPAINT_ON_RESIZE,
- idx=self.disp_idx, lmgr=self, notebook=self.gm_cb,
- auimgr=self._auimgr, showMapDisplay=show)
+ self.curr_page.maptree = layertree.LayerTree(self.curr_page, id=wx.ID_ANY, pos=wx.DefaultPosition,
+ size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS |
+ wx.TR_LINES_AT_ROOT| wx.TR_HIDE_ROOT |
+ wx.TR_DEFAULT_STYLE| wx.NO_BORDER | wx.FULL_REPAINT_ON_RESIZE,
+ idx=self.disp_idx, lmgr=self, notebook=self.gm_cb,
+ auimgr=self._auimgr, showMapDisplay=show)
# layout for controls
cb_boxsizer = wx.BoxSizer(wx.VERTICAL)
More information about the grass-commit
mailing list