[GRASS-SVN] r42586 - grass-addons/gui/wxpython/data_catalog

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Jun 18 23:33:21 EDT 2010


Author: rashadkm
Date: 2010-06-19 03:33:21 +0000 (Sat, 19 Jun 2010)
New Revision: 42586

Removed:
   grass-addons/gui/wxpython/data_catalog/toolbars.py
Modified:
   grass-addons/gui/wxpython/data_catalog/LayerTree.py
   grass-addons/gui/wxpython/data_catalog/catalog.py
   grass-addons/gui/wxpython/data_catalog/mapdisplay.py
Log:
updated according to latest svn

Modified: grass-addons/gui/wxpython/data_catalog/LayerTree.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/LayerTree.py	2010-06-17 20:18:34 UTC (rev 42585)
+++ grass-addons/gui/wxpython/data_catalog/LayerTree.py	2010-06-19 03:33:21 UTC (rev 42586)
@@ -4,13 +4,27 @@
 import glob
 import render
 from threading import Thread
+from debug import Debug as Debug
+from icon import Icons as Icons
+import gui_modules.menuform as menuform
+import gdialogs
+from preferences import globalSettings as UserSettings
+from vdigit import haveVDigit
+from gcmd import GMessage
+import histogram
+import gui_modules.profile as profile
 
+
 import wx.lib.customtreectrl as CT
 try:
     import treemixin 
 except ImportError:
     from wx.lib.mixins import treemixin
 
+import wx.combo
+import wx.lib.newevent
+import wx.lib.buttons  as  buttons
+
 #To run DataCatalog from any directory set this pathname for access to gui_modules 
 gbase = os.getenv("GISBASE") 
 pypath = os.path.join(gbase,'etc','wxpython','gui_modules')
@@ -22,9 +36,10 @@
     globalvar.CheckForWx()
 import gcmd
 
+import utils
+from grass.script import core as grass
 
 
-
 class LayerTree(treemixin.DragAndDrop, CT.CustomTreeCtrl):
 
 
@@ -35,514 +50,1657 @@
                  ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
                  CT.TR_HIDE_ROOT | CT.TR_FULL_ROW_HIGHLIGHT |
                  CT.TR_MULTIPLE,mapdisplay=None,frame=None,panel=None,Map=None,lmgr=None,gisdbase=None):
-        self.items = []
-        self.itemCounter = 0
-        
-        super(LayerTree, self).__init__(parent, id, pos, size, style=style, ctstyle=ctstyle)
-        self.SetName("LayerTree")
+		self.items = []
+		self.itemCounter = 0
 
+		super(LayerTree, self).__init__(parent, id, pos, size, style=style, ctstyle=ctstyle)
+		self.SetName("LayerTree")
+		self.lmgr = lmgr
 
-        self.itemFont = wx.Font(pointSize=9,weight=0, family=wx.FONTFAMILY_DEFAULT ,style=wx.FONTSTYLE_ITALIC)
+		self.frame =  frame
 
-        self.gisdbase = gisdbase
 
+		self.itemFont = wx.Font(pointSize=9,weight=0, family=wx.FONTFAMILY_DEFAULT ,style=wx.FONTSTYLE_ITALIC)
 
-        self.Map = None
+		self.gisdbase = gisdbase
+
+		self.layer_selected = None 
+
+		self.l_selected = None
+
+		self.rerender = False                # layer change requires a rerendering if auto render
+		self.reorder = False 
+
+		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) 
+
+
+		self.Map = Map
         #if self.Map is not None:
         #    print self.Map.width
 
-        self.ID_REN= wx.NewId()
-        self.ID_COPY = wx.NewId()
-        self.ID_DEL = wx.NewId()
-        self.ID_OSSIM = wx.NewId()
-        self.ID_OSSIM2 = wx.NewId()
-        self.ID_INFO = wx.NewId()
-        self.ID_REPORT = wx.NewId()
-        self.ID_AREA = 200
-        self.ID_LENGTH = 201
-        self.ID_COOR = 202
+		
+		self.mapname = None
+		self.layertype=None
 
-        acel = wx.AcceleratorTable([ 
-		        (wx.ACCEL_CTRL,  ord('R'), self.ID_REN ) ,
-		        (wx.ACCEL_CTRL,  ord('C'), self.ID_COPY) ,
-		        (wx.ACCEL_NORMAL, wx.WXK_DELETE, self.ID_DEL) ])
+		self.ID_COPY = wx.NewId()
+		self.ID_OSSIM = wx.NewId()
+		self.ID_OSSIM2 = wx.NewId()
+		self.ID_INFO = wx.NewId()
+		self.ID_REPORT = wx.NewId()
+		self.ID_AREA = 200
+		self.ID_LENGTH = 201
+		self.ID_COOR = 202
+		self.ID_REN = wx.NewId()
+		self.ID_DEL = wx.NewId()
 
+		self.root = self.AddRoot("Map Layers")
+		self.SetPyData(self.root, (None,None))
 
-        self.SetAcceleratorTable(acel)
 
-        self.dict = {}
+		self.dict = {}
 
-        self.colour = '0:0:0'  #default colour for vector lines
-        self.colour_selected = False
+		self.colour = '0:0:0'  #default colour for vector lines
+		self.colour_selected = False
 
-        self.layer = []
-        self.maplayer = None
+		self.layer = []
 
-        d = self.GetParent()
-        notebook = d.GetParent()
+		d = self.GetParent()
+		notebook = d.GetParent()
 
 
-        child=notebook.GetChildren()
-        for panel in child:
-              if panel.GetName() == "pg_panel":
-                self.mapdisplay = panel
+		child=notebook.GetChildren()
+		for panel in child:
+			  if panel.GetName() == "MapWindow":
+				self.mapdisplay = panel
 
-        self.MapWindow = self.mapdisplay.MapWindow2D
-        self.Bind(CT.EVT_TREE_ITEM_CHECKED,     self.OnLayerChecked)
-        self.Bind(CT.EVT_TREE_ITEM_ACTIVATED,     self.ChooseColour)
 
-        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK,self.OnTreePopUp)
-        self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndRename)
-        self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnBeginRename)
+		self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.OnLayerChecked)
+		# self.Bind(CT.EVT_TREE_ITEM_ACTIVATED,     self.ChooseColour)
 
-	    #Event bindings for tree menu
-        self.Bind(wx.EVT_MENU,self.OnCopy,id=self.ID_COPY)
-        self.Bind(wx.EVT_MENU,self.OnRename,id=self.ID_REN)
-        self.Bind(wx.EVT_MENU,self.OnDelete,id=self.ID_DEL)
-        self.Bind(wx.EVT_MENU,self.OnOssim,id=self.ID_OSSIM)
-        self.Bind(wx.EVT_MENU,self.OnOssim2,id=self.ID_OSSIM2)
-        self.Bind(wx.EVT_MENU,self.OnInfo,id=self.ID_INFO)
-        self.Bind(wx.EVT_MENU,self.OnReport,id=self.ID_REPORT)
-        self.Bind(wx.EVT_MENU,self.OnvReport,id=self.ID_AREA)
-        self.Bind(wx.EVT_MENU,self.OnvReport,id=self.ID_LENGTH)
-        self.Bind(wx.EVT_MENU,self.OnvReport,id=self.ID_COOR)
+		#self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK,self.OnTreePopUp)
+		self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndRename)
+		self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnBeginRename)
 
+		#Event bindings for tree menu
+		self.Bind(wx.EVT_MENU,self.OnCopy,id=self.ID_COPY)
+		self.Bind(wx.EVT_MENU,self.OnRenameMap,id=self.ID_REN)
+		self.Bind(wx.EVT_MENU,self.OnDeleteMap,id=self.ID_DEL)
+		self.Bind(wx.EVT_MENU,self.OnOssim,id=self.ID_OSSIM)
+		self.Bind(wx.EVT_MENU,self.OnOssim2,id=self.ID_OSSIM2)
 
-    def ChooseColour(self,event):
 
-        colourdialog = wx.ColourDialog(self)
-        colourdialog.ShowModal()
-        rgb = colourdialog.GetColourData().GetColour()
-        rgb = str(rgb)
-        self.colour = rgb.replace(',',':')
-        self.colour = self.colour.strip('(')
-        self.colour = self.colour.strip(')')
 
-        item = event.GetItem()
-        col = colourdialog.GetColourData().GetColour()
+		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(wx.EVT_TREE_DELETE_ITEM,      self.OnDeleteMap)
+		self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnLayerContextMenu)
+		self.Bind(wx.EVT_TREE_END_DRAG,         self.OnEndDrag)
+		self.Bind(wx.EVT_KEY_UP,                self.OnKeyUp)
+		self.Bind(wx.EVT_IDLE,                  self.OnIdle)
 
-        self.SetHilightFocusColour(col)
-        self.SetItemTextColour(item,col)
+    def GetMap(self):
+        """!Get map instace"""
+        return self.Map
+    
+    def GetMapDisplay(self):
+        """!Get associated MapFrame"""
+        return self.mapdisplay
+    
+    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 Minimal(self,item):
+        mnuCopy = self.popupMenu.Append(self.ID_COPY,'&Copy Map\tCtrl+C')
+        mnuRename = self.popupMenu.Append(self.ID_REN,'&Rename Map\tCtrl-R')
+        mnuDel = self.popupMenu.Append(self.ID_DEL,'&Delete Map\tDEL')
+        self.popupMenu.AppendSeparator()
+        mnuOssim = self.popupMenu.Append(self.ID_OSSIM,'&Send to OssimPlanet')
+        mnuOssim = self.popupMenu.Append(self.ID_OSSIM2,'&Remove from OssimPlanet')
+
+
+        
+    def OnLayerContextMenu (self, event):
+        """!Contextual menu for item/layer"""
+        if not self.layer_selected:
+            event.Skip()
+            return
+		
+        self.popupMenu = wx.Menu()
         item =  event.GetItem()
-        parent = self.GetItemParent(item)
-        if self.IsItemChecked(parent):
-            self.colour_selected = True
-            self.CheckItem(parent)
+        if self.IsItemChecked(item) == False:
+            self.Minimal(item)
         else:
-            self.CheckItem(parent)
+            self.Minimal(item)
+            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()
+
+            numSelected = len(self.GetSelections()) 
+
+			# general item
+            self.popupMenu.Append(self.popupID1, text=_("Remove from MapTree"))
+            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', 'raster3d') and self.mapdisplay.toolbars['nviz']:
+                    self.popupMenu.Append(self.popupID11, _("3D view properties"))
+                    self.Bind (wx.EVT_MENU, self.OnNvizProperties, id=self.popupID11)
+
+                if ltype in ('raster', 'vector', 'rgb'):
+                    self.popupMenu.Append(self.popupID9, text=_("Zoom to selected map(s)"))
+                    self.Bind(wx.EVT_MENU, self.mapdisplay.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.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 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
 
-    def OnInfo(self,event):
+        if hasattr (self.mapdisplay, "profile") and self.mapdisplay.profile:
+            self.profileFrame = self.mapdisplay.profile
 
-        item =  self.GetSelection()
-        parent = self.GetItemParent(item)
-        pText = self.GetItemText(parent)
+        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
 
-        leftpanel=self.GetParent()
-        notebook = leftpanel.GetParent()
-        frame = notebook.GetParent()
+        if not hasattr (self, "histogramFrame"):
+            self.histogramFrame = None
 
-        if not self.ItemHasChildren(item):
-            self.mapname =  self.GetItemText(item) + "@" + frame.cmbMapset.GetValue()
+        if hasattr (self.mapdisplay, "histogram") and self.mapdisplay.histogram:
+            self.histogramFrame = self.mapdisplay.histogram
 
-            if pText == "Raster Map" :
-                command = ["r.info", 'map=' +  self.mapname]
-                frame.goutput.RunCmd(command)
-            if pText == "Vector Map" :
-                command = ["v.info", 'map=' +  self.mapname]
-                frame.goutput.RunCmd(command)
+        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()
 
-    def OnReport(self,event):
+        self.histogramFrame.SetHistLayer(mapLayer.name)
+        self.histogramFrame.HistWindow.UpdateHist()
+        self.histogramFrame.Refresh()
+        self.histogramFrame.Update()
 
-        item =  self.GetSelection()
-        parent = self.GetItemParent(item)
-        pText = self.GetItemText(parent)
+        return True
 
-        leftpanel=self.GetParent()
-        notebook = leftpanel.GetParent()
-        frame = notebook.GetParent()
+    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']
         
-        if not self.ItemHasChildren(item):
-            self.mapname =  self.GetItemText(item) + "@" + frame.cmbMapset.GetValue()
+        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) + '%)')
             
-            if pText == "Raster Map" :
-                command = ["r.report", 'map=' +  self.mapname]
-                frame.goutput.RunCmd(command)
-#            if pText == "Vector Map" :
-#                command = ["v.report", 'map=' +  self.mapname]
-#                frame.goutput.RunCmd(command)
+            # 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
+        """
+        self.lmgr.notebook.SetSelection(3)
+        ltype = self.GetPyData(self.layer_selected)[0]['type']
+        if ltype == 'raster':
+            self.lmgr.nviz.SetPage('surface')
+        elif ltype == 'vector':
+            self.lmgr.nviz.SetPage('vector')
+        elif ltype == 'raster3d':
+            self.lmgr.nviz.SetPage('volume')
         
-    def OnvReport(self,event):
+    def RenameLayer (self, event):
+        """!Rename layer"""
+        self.EditLabel(self.layer_selected)
 
-        item =  self.GetSelection()
-        Id = event.GetId()
-        if Id == 200:
-            option = 'area'
-        elif Id == 201:
-            option = 'length'
-        elif Id == 202:
-            option = 'coor'
-        parent = self.GetItemParent(item)
-        pText = self.GetItemText(parent)
+    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.)
 
-        leftpanel=self.GetParent()
-        notebook = leftpanel.GetParent()
-        frame = notebook.GetParent()
+        @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 not self.ItemHasChildren(item):
-        self.mapname =  self.GetItemText(item) + "@" + frame.cmbMapset.GetValue()
-        command = ["v.report", 'map=' +  self.mapname,'option=' + str(option)]
-        frame.goutput.RunCmd(command)
+        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 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='rasterOverlay', subkey='enabled'):
+                cmd.append('-o')
+            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.vect.thematic', '-s'], 
+                                        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.
+        """
+        self.lmgr.WorkspaceChanged()
+        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"""
+        self.lmgr.WorkspaceChanged()
+        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()
+        checked = self.IsItemChecked(item)
+        self.SelectItem(item)
 
 
-        pText = self.GetItemText(self.GetItemParent(item)) 
 
+    def OnCmdChanged(self, event):
+        """!Change command string"""
+        ctrl = event.GetEventObject().GetId()
+        cmd = event.GetString()
+        
+        layer = self.GetFirstVisibleItem()
 
-        leftpanel=self.GetParent()
-        notebook = leftpanel.GetParent()
-        frame = notebook.GetParent()
+        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
 
-        self.mapname =  self.GetItemText(item) + "@" + frame.cmbMapset.GetValue()
-        #for f in frames:
-        #    print f.GetName()     
-        #maptree = mapframe.maptree
+        #
+        # 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)
 
-        if pText == "Raster Map" :
-            if checked == True:
-                self.cmd= ['d.rast', str("map=" + self.mapname)]
-                maplayer = self.MapWindow.Map.AddLayer(type='raster', name=self.mapname, command=self.cmd)
-                self.layer_selected = maplayer
-                self.type = 'raster'
+        # 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.lmgr.nviz.UpdatePage('surface')
+                    self.lmgr.nviz.SetPage('surface')
+                elif type == 'vector':
+                    self.lmgr.nviz.UpdatePage('vector')
+                    self.lmgr.nviz.SetPage('vector')
+                elif type == '3d-raster':
+                    self.lmgr.nviz.UpdatePage('volume')
+                    self.lmgr.nviz.SetPage('volume')
             else:
-                layers =  self.MapWindow.Map.GetListOfLayers( l_type='raster', l_name=self.mapname)
-                for layer in layers:
-                    self.MapWindow.Map.DeleteLayer(layer)
-                    self.MapWindow.EraseMap()
+                for page in ('surface', 'vector', 'volume'):
+                    pageId = self.lmgr.nviz.page[page]['id']
+                    if pageId > -1:
+                        self.lmgr.nviz.notebook.RemovePage(pageId)
+                        self.lmgr.nviz.page[page]['id'] = -1
+                        self.lmgr.nviz.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)
 
-        if pText == "Vector Map" :
-            if checked == True:
-                self.cmd= ['d.vect', str("map=" + self.mapname),str('color=' +  self.colour)]
-                if self.colour_selected == False:
-                    maplayer = self.MapWindow.Map.AddLayer(type='vector', name=self.mapname, command=self.cmd)
-                else:
-                    self.colour_selected = False
-                    layers =  self.MapWindow.Map.GetListOfLayers( l_type='vector', l_name=self.mapname)
-                    for layer in layers:
-                        maplayer=layer.__init__(type='vector', name=self.mapname, cmd=self.cmd)
-                self.layer_selected = maplayer
-                self.type = 'vector'
+        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:
-                layers =  self.MapWindow.Map.GetListOfLayers( l_type='vector', l_name=self.mapname)
-                for layer in layers:
-                    self.MapWindow.Map.DeleteLayer(layer)
-                    self.MapWindow.EraseMap()
+                # 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:
+                GMessage(parent=self,
+                         message=_("Map <%s> not found.") % utils.GetLayerNameFromCmd(dcmd))
+                return
+            
+            self.SetItemText(layer, mapname + ' (opacity: ' + str(opacity) + '%)')
         
-        self.MapWindow.Map.region = self.MapWindow.Map.GetRegion()
-        self.MapWindow.flag = True
-        self.MapWindow.UpdateMap(render=True)
-        self.MapWindow.flag = False
+        # 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 = ""
 
-    def AddTreeNodes(self,location,mapset):
+        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
         """
-        Adds tree nodes. raster,vector and dbf files are identified using 
-        their directory structure.
+        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
         """
-        self.DeleteAllItems()
-        root = self.AddRoot("Map Layers")
-        self.SetPyData(root, (None,None))
-        node_raster = self.AppendItem(root, "Raster Map")
-        node_vector = self.AppendItem(root, "Vector Map")
-        node_dbf = self.AppendItem(root, "DBF")
-        treeNodes = [node_raster,node_vector,node_dbf]
+        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)
 
-        glocs = glob.glob(os.path.join(self.gisdbase,location, mapset,"*"))
-        for gloc in glocs:
-            if not os.path.isfile(gloc) and os.path.isdir(gloc):
-                if(os.path.basename(gloc)=='cellhd'):
-                    for rast in glob.glob(os.path.join(self.gisdbase,location, mapset,gloc, "*")):
-	                    self.PrependItem(node_raster, os.path.basename(rast),ct_type=1)
-                elif(os.path.basename(gloc)=='vector'):
-                    for vect in glob.glob(os.path.join(self.gisdbase,location, mapset,gloc, "*")):
-                        vectormap = self.PrependItem(node_vector, os.path.basename(vect),ct_type=1)
-                        self.PrependItem(vectormap, "colour")
-                elif(os.path.basename(gloc)=='dbf'):
-                    for dfile in glob.glob(os.path.join(self.gisdbase,location, mapset,gloc, "*")):
-	                    self.PrependItem(node_dbf, os.path.basename(dfile),ct_type=1)
+        return None
 
-        #Nodes with no children are given an italic type font
-        for node in treeNodes: 
-            if not self.ItemHasChildren(node):
-	            if self.GetItemText(node) == 'Raster Map':
-		            tmp_item = self.AppendItem(node, "No raster maps found.")
-	            elif self.GetItemText(node) == 'Vector Map':
-		            tmp_item = self.AppendItem(node, "No vector maps found.")
-	            elif self.GetItemText(node) == 'DBF':
-		            tmp_item = self.AppendItem(node, "No DBF files found.")
-	            self.SetItemFont(tmp_item,self.itemFont)
 
+	def ChooseColour(self,event):
 
-        self.SortChildren(node_raster)
-        self.SortChildren(node_vector)
-        self.SortChildren(node_dbf)
+		colourdialog = wx.ColourDialog(self)
+		colourdialog.ShowModal()
+		rgb = colourdialog.GetColourData().GetColour()
+		rgb = str(rgb)
+		self.colour = rgb.replace(',',':')
+		self.colour = self.colour.strip('(')
+		self.colour = self.colour.strip(')')
 
+		item = event.GetItem()
+		col = colourdialog.GetColourData().GetColour()
 
-    def OnBeginRename(self,event):
+		self.SetHilightFocusColour(col)
+		self.SetItemTextColour(item,col)
+		item =  event.GetItem()
+		parent = self.GetItemParent(item)
+		if self.IsItemChecked(parent):
+			self.colour_selected = True
+			self.CheckItem(parent)
+		else:
+			self.CheckItem(parent)
 
-        item = self.GetItemText(event.GetItem())
-        if type(item) == str and item in ("Raster Map", "Vector Map" , "DBF"):
-            event.Veto()             #disable editing of parent items
 
-    def OnEndRename(self,event):
-	    """
-	    Rename mapset using grass commands
-	    """
-	    item = event.GetItem()
-	    oldName = self.GetItemText(item) 
-	    try:
-		    newName =  self.GetEditControl().GetValue()
-	    except:
-		    return
-	    parent =self.GetItemParent(item)
-	    if self.GetItemText(parent) == "Raster Map" :
-		    cmdflag = 'rast=' +  oldName + ',' + newName
-	    elif self.GetItemText(parent) == "Vector Map" :
-		    cmdflag = 'vect=' +  oldName + ',' + newName
+	def OnInfo(self,event):
 
-	    if cmdflag:
-		    command = ["g.rename", cmdflag]
-		    gcmd.CommandThread(command,stdout=None,stderr=None).run()
+		item =  self.GetSelection()
+		parent = self.GetItemParent(item)
+		pText = self.GetItemText(parent)
 
+		leftpanel=self.GetParent()
+		notebook = leftpanel.GetParent()
+		frame = notebook.GetParent()
 
+		if not self.ItemHasChildren(item):
+			self.mapname =  self.GetItemText(item) + "@" + frame.cmbMapset.GetValue()
 
-    def OnTreePopUp(self,event):
-        """
-        Display a popupMenu for copy,rename & delete operations
-        """
-        item =  event.GetItem()
-        parent = self.GetItemParent(item)
-        pText = self.GetItemText(parent)
-      #  if not self.ItemHasChildren(item) and \
-      #         self.GetItemFont(item) != self.itemFont:
-        if self.GetItemText(item)!='Raster Map' and \
-                self.GetItemText(item)!='Vector Map' and \
-                self.GetItemText(item)!='DBF' and \
-                self.GetItemText(item)!='colour' and \
-                self.GetItemFont(item) != self.itemFont:
-            self.popupmenu = wx.Menu()
-            mnuCopy = self.popupmenu.Append(self.ID_COPY,'&Copy\tCtrl+C')
-            mnuRename = self.popupmenu.Append(self.ID_REN,'&Rename\tCtrl-R')
-            mnuDel = self.popupmenu.Append(self.ID_DEL,'&Delete\tDEL')
-            #self.popupmenu.AppendSeperator()
-            mnuOssim = self.popupmenu.Append(self.ID_OSSIM,'&Send to OssimPlanet')
-            mnuOssim = self.popupmenu.Append(self.ID_OSSIM2,'&Remove from OssimPlanet')
-            #self.popupmenu.AppendSeperator()
-            mnuInfo = self.popupmenu.Append(self.ID_INFO,'&Info')
+		if pText == "Raster Map" :
+			command = ["r.info", 'map=' +  self.mapname]
+			frame.goutput.RunCmd(command)
+		if pText == "Vector Map" :
+			command = ["v.info", 'map=' +  self.mapname]
+			frame.goutput.RunCmd(command)
 
-            if pText == 'Vector Map':
-                mnuReport = wx.Menu()
-                mnuReport.Append(self.ID_AREA, 'Area')
-                mnuReport.Append(self.ID_LENGTH, 'Length')
-                mnuReport.Append(self.ID_COOR, 'Coordinate')
-                self.popupmenu.AppendMenu(wx.ID_ANY, 'Report', mnuReport)
-            else:
-                mnuReport =self.popupmenu.Append(self.ID_REPORT,'&Report')
 
-            self.PopupMenu(self.popupmenu)
+    def OnReport(self,event):
 
+        item =  self.GetSelection()
+        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 OnBeginRename(self,event):
+
+		item = self.GetItemText(event.GetItem())
+
+    def OnEndRename(self,event):
+		"""
+		Rename mapset using grass commands
+		"""
+		item = event.GetItem()
+		oldName = self.GetItemText(item) 
+		try:
+			newName =  self.GetEditControl().GetValue()
+		except:
+			return
+	
+
+
     def OnCopy( self,event ):
-        #print "copy"
-	    item =  self.GetSelection()
-	    parent = self.GetItemParent(item)
-	    pText = self.GetItemText(parent)
-	    name = self.GetCopyName(item)
-	    if pText == "Raster Map" :
-		    cmdflag = 'rast=' + self.GetItemText(item) + ',' + name
-		    self.PrependItem(parent=parent,text=name,ct_type=1)
-	    elif pText  == "Vector Map" :
-		    cmdflag = 'vect=' + self.GetItemText(item) + ',' + name
-		    self.PrependItem(parent=parent,text=name,ct_type=1)
+		#print "copy"
+		item =  self.GetSelection()
+		parent = self.GetItemParent(item)
+		pText = self.GetItemText(parent)
+		name = self.GetCopyName(item)
+		if pText == "Raster Map" :
+			cmdflag = 'rast=' + self.GetItemText(item) + ',' + name
+			self.PrependItem(parent=parent,text=name,ct_type=1)
+		elif pText  == "Vector Map" :
+			cmdflag = 'vect=' + self.GetItemText(item) + ',' + name
+			self.PrependItem(parent=parent,text=name,ct_type=1)
 
-	    if cmdflag:
-		    command = ["g.copy", cmdflag]
-		    gcmd.CommandThread(command,stdout=None,stderr=None).run()
+		if cmdflag:
+			command = ["g.copy", cmdflag]
+			gcmd.CommandThread(command,stdout=None,stderr=None).run()
 
 
     def GetCopyName(self, item):
-	    """
-	    Returns unique name depending on the mapname to be copied.
-	    """
+        """
+        Returns unique name depending on the mapname to be copied.
+        """
 
-	    def GetPrefix(prefix):
-		    """
-		    This returns a prefix to the given map name 
-		    prefix applied here is _copy_x.
-		    """
+        def GetPrefix(prefix):
+			"""
+			This returns a prefix to the given map name 
+			prefix applied here is _copy_x.
+			"""
 
-		    prefix = "_copy_" + str(self.count)
-		    self.count = self.count + 1
-		    return prefix
-        
-            #end of GetPrefix
+			prefix = "_copy_" + str(self.count)
+			self.count = self.count + 1
+			return prefix
 
-	    def CheckName(parent,prefix,name):
-		    """
-		    Checks all silbings of the parent wheather the name 
-		    already exists.
-		    """
-		    ncount = self.GetChildrenCount(parent, False)
-		    ck = 1
-		    current , ck = self.GetFirstChild(parent)
-		    for i in range(ncount):
-			    if str(self.GetItemText(current)) == str(name + prefix):
-				    return False
-			    else:
-				    current,ck = self.GetNextChild(parent,ck)
-		    return True
-            
-            #End of CheckName
+			#end of GetPrefix
 
-        #GetCopyName function starts here
-	    ext = None	
-	    self.count  = 1
-	    ext = GetPrefix(ext)
-	    name = str(self.GetItemText(item))
-	    parent = self.GetItemParent(item)
-	    while  CheckName(parent,ext,name) == False:
-		    ext = GetPrefix(ext)
-		    CheckName(parent,ext,name)
+        def CheckName(parent,prefix,name):
+			"""
+			Checks all silbings of the parent wheather the name 
+			already exists.
+			"""
+			ncount = self.GetChildrenCount(parent, False)
+			ck = 1
+			current , ck = self.GetFirstChild(parent)
+			for i in range(ncount):
+				if str(self.GetItemText(current)) == str(name + prefix):
+					return False
+				else:
+					current,ck = self.GetNextChild(parent,ck)
+			return True
+		
+			#End of CheckName
 
-	    name = str(name + ext)
-	    return name
+		#GetCopyName function starts here
+        ext = None	
+        self.count  = 1
+        ext = GetPrefix(ext)
+        name = str(self.GetItemText(item))
+        parent = self.GetItemParent(item)
+        while  CheckName(parent,ext,name) == False:
+	        ext = GetPrefix(ext)
+	        CheckName(parent,ext,name)
 
+        name = str(name + ext)
+        return name
 
-    def OnRename( self,event ):
 
+    def OnRenameMap( self,event ):
         item = self.GetSelection()
         self.EditLabel( self.GetSelection())
+        mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+        mltype = self.GetPyData(self.layer_selected)[0]['type']
+        try:
+            newName =  self.GetEditControl().GetValue()
+        except:
+            newName = mapLayer.name
 
 
-    def OnDelete( self,event ):
-        """
-        Performs grass command for deleting a map
-        """
-        item =  self.GetSelection()
-        dlg = wx.MessageDialog(self, message=_(    "Do you want to delete selected map ?"),
-                            caption=_("Delete Map"),
-                            style=wx.YES_NO | wx.YES_DEFAULT | \
-                                wx.CANCEL | wx.ICON_QUESTION)
-        ret = dlg.ShowModal()
-        if ret == wx.ID_YES:
-            dlg.Destroy()
-            parent  =self.GetItemParent(item) 
-            if self.GetItemText(parent) == "Raster Map" :
-                cmdflag = 'rast=' + str(self.GetItemText(item))
-            elif self.GetItemText(parent) == "Vector Map" :
-                cmdflag = 'vect=' + str(self.GetItemText(item))
 
-            if cmdflag:
-                command = ["g.remove", cmdflag]
-                gcmd.CommandThread(command,stdout=None,stderr=None).run()
-                select = self.GetPrevSibling(item)
-                self.Delete(item)
-                #self.SelectItem(select)
+        if mltype == 'raster':
+            cmd = ['g.rename rast=']
+        elif mltype == 'vector':
+            cmd = ['g.rename vect=']
+        cmd.append('%s,%s' % mapLayer.name,newName)
 
-        elif ret == wx.ID_CANCEL:
-         dlg.Destroy()
-         return
+        # print output to command log area
+        self.lmgr.goutput.RunCmd(cmd, switchPage=True)
 
+
+    def OnDeleteMap( self,event ):
+		"""
+		Performs grass command for deleting a map
+		"""
+		item =  self.GetSelection()
+		if item is not None:
+			dlg = wx.MessageDialog(self, message=_(    "Do you want to delete selected map ?"),
+						        caption=_("Delete Map"),
+						        style=wx.YES_NO | wx.YES_DEFAULT | \
+						            wx.CANCEL | wx.ICON_QUESTION)
+			ret = dlg.ShowModal()
+			if ret == wx.ID_YES:
+				dlg.Destroy()
+				parent  =self.GetItemParent(item) 
+				if self.GetItemText(parent) == "Raster Map" :
+					cmdflag = 'rast=' + str(self.GetItemText(item))
+				elif self.GetItemText(parent) == "Vector Map" :
+					cmdflag = 'vect=' + str(self.GetItemText(item))
+
+				if cmdflag:
+					command = ["g.remove", cmdflag]
+					gcmd.CommandThread(command,stdout=None,stderr=None).run()
+					select = self.GetPrevSibling(item)
+					self.Delete(item)
+					#self.SelectItem(select)
+
+			elif ret == wx.ID_CANCEL:
+			 dlg.Destroy()
+			 return
+
+
     def OnOssim( self,event ):
-        """
-        Performs grass command for adding a map
-        """
-        item =  self.GetSelection()
-        cmdflag = None
-        parent  =self.GetItemParent(item) 
-        if self.GetItemText(parent) == "Raster Map" :
-            cmdflag = 'r.planet.py -a map=' + str(self.GetItemText(item))
-        else:
-            if self.GetItemText(item) == 'colour':
-                col=self.GetItemTextColour(item)
-                mapname = self.GetItemParent(item)
-            else:
-                child,cookie = self.GetFirstChild(item)
-                mapname = item
-                col = self.GetItemTextColour(child)
-            if col.IsOk() is True:
-                col=str(col)
-                col = col.replace('(','')
-                col = col.replace(')','')
-                col = col.split(',')
 
-                cmdflag = 'v.planet.py -a map=' + str(self.GetItemText(mapname)) + \
-                            ' brush=' + str(col[0].strip()+','+col[1].strip()+','+col[2].strip()) + \
-                            ' pen=' + str(col[0].strip()+','+col[1].strip()+','+col[2].strip()) + \
-                            ' size=' +str('1,1')
-                #print cmdflag
+		"""
+		Performs grass command for adding a map
+		"""
+		item =  self.GetSelection()
+		cmdflag = None
+		parent  =self.GetItemParent(item) 
+		if self.GetItemText(parent) == "Raster Map" :
+			cmdflag = 'r.planet.py -a map=' + str(self.GetItemText(item))
+		else:
+			if self.GetItemText(item) == 'colour':
+				col=self.GetItemTextColour(item)
+				mapname = self.GetItemParent(item)
+			else:
+				child,cookie = self.GetFirstChild(item)
+				mapname = item
+				col = self.GetItemTextColour(child)
+			if col.IsOk() is True:
+				col=str(col)
+				col = col.replace('(','')
+				col = col.replace(')','')
+				col = col.split(',')
 
-        if cmdflag is not None:        
-            current = OssimPlanet(cmdflag)
-            current.start()
+				cmdflag = 'v.planet.py -a map=' + str(self.GetItemText(mapname)) + \
+				            ' brush=' + str(col[0].strip()+','+col[1].strip()+','+col[2].strip()) + \
+				            ' pen=' + str(col[0].strip()+','+col[1].strip()+','+col[2].strip()) + \
+				            ' size=' +str('1,1')
+				#print cmdflag
 
+		if cmdflag is not None:        
+			current = OssimPlanet(cmdflag)
+			current.start()
 
 
+
     def OnOssim2( self,event ):
-        """
-        Performs grass command for deleting a map
-        """
-        item =  self.GetSelection()
-        cmdflag = None
-        parent  =self.GetItemParent(item) 
-        if self.GetItemText(parent) == "Raster Map" :
-            cmdflag = 'r.planet.py -r map=' + str(self.GetItemText(item))
-        else:
-            if self.GetItemText(item) == 'colour':
-                previtem = self.GetItemParent(item)
-                cmdflag = 'v.planet.py -r map=' + str(self.GetItemText(previtem))
-            else:
-                cmdflag = 'v.planet.py -r map=' + str(self.GetItemText(item))
+		"""
+		Performs grass command for deleting a map
+		"""
+		item =  self.GetSelection()
+		cmdflag = None
+		parent  =self.GetItemParent(item) 
+		if self.GetItemText(parent) == "Raster Map" :
+			cmdflag = 'r.planet.py -r map=' + str(self.GetItemText(item))
+		else:
+			if self.GetItemText(item) == 'colour':
+				previtem = self.GetItemParent(item)
+				cmdflag = 'v.planet.py -r map=' + str(self.GetItemText(previtem))
+			else:
+				cmdflag = 'v.planet.py -r map=' + str(self.GetItemText(item))
 
-        if cmdflag is not None:
-            current = OssimPlanet(cmdflag)
-            current.start()
+		if cmdflag is not None:
+			current = OssimPlanet(cmdflag)
+			current.start()
         
 
-    def OnDisplay(self, event):
 
-        item =  event.GetItem()
-        pText = self.GetItemText(self.GetItemParent(item)) 
-        
 
-
 class OssimPlanet(Thread):
    def __init__ (self,cmd):
       Thread.__init__(self)

Modified: grass-addons/gui/wxpython/data_catalog/catalog.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/catalog.py	2010-06-17 20:18:34 UTC (rev 42585)
+++ grass-addons/gui/wxpython/data_catalog/catalog.py	2010-06-19 03:33:21 UTC (rev 42586)
@@ -94,6 +94,8 @@
 import gui_modules.dbm as dbm
 import gui_modules.workspace as workspace
 import gui_modules.colorrules as colorrules
+import gui_modules.vclean as vclean
+import gui_modules.nviz_tools as nviz_tools
 
 if grassversion != "6.4.0svn":
     import gui_modules.menu as menu
@@ -107,12 +109,15 @@
 
 #from gmconsole import GLog
 from mapdisplay import MapFrame
-from LayerTree import LayerTree
 import wx.lib.flatnotebook as FN
 from   icons.icon import Icons
 from preferences import globalSettings as UserSettings
 import render
 import gc
+from   gui_modules.ghelp import MenuTreeWindow
+from   gui_modules.ghelp import AboutWindow
+from   gui_modules.toolbars import LayerManagerToolbar
+from   gui_modules.ghelp import InstallExtensionWindow
 
 class DataCatalog(wx.Frame):
 
@@ -126,13 +131,10 @@
         self.parent = parent
 
         wx.Frame.__init__(self, parent, id, title, pos=pos, size=size)
+        self.SetName("LayerManager")
+        
+        self._auimgr=wx.aui.AuiManager(self)
  
-
-        #self.Maximize()
-
-        self.dict = {}
-
-
         self.gisbase  = os.getenv("GISBASE")
         self.gisrc  = self.read_gisrc()
         self.viewInfo = True        #to display v/r.info on mapdisplay
@@ -141,19 +143,29 @@
         #backup location and mapset from gisrc which may be modified  by datacatalog
         self.iLocation = self.gisrc['LOCATION_NAME']
         self.iMapset = self.gisrc['MAPSET']
-        
 
-        #self.Map = render.Map()
 
-        self.curr_pagenum  = -1           # currently selected page number for layer tree notebook
-        self.encoding      = 'ISO-8859-1' # default encoding for display fonts
+
+        # initialize variables
+        self.disp_idx      = 0            # index value for map displays and layer trees
+        self.curr_page     = ''           # currently selected page for layer tree notebook
+        self.curr_pagenum  = ''           # currently selected page number for layer tree notebook
         self.workspaceFile = workspace    # workspace file
-        self.menucmd       = dict()       # menuId / cmd
+        self.workspaceChanged = False     # track changes in workspace
         self.georectifying = None         # reference to GCP class or None
-
+        # list of open dialogs
         self.dialogs        = dict()
         self.dialogs['preferences'] = None
         self.dialogs['atm'] = list()
+        
+        # creating widgets
+        self.menubar = menu.Menu(parent = self, data = menudata.ManagerData())
+        self.SetMenuBar(self.menubar)
+        self.menucmd = self.menubar.GetCmd()
+        self.statusbar = self.CreateStatusBar(number=1)
+        self.notebook  = self.__createNoteBook()
+        self.toolbar = LayerManagerToolbar(parent = self)
+        self.SetToolBar(self.toolbar)
 
 
 
@@ -186,15 +198,18 @@
             self.menubar = menu.Menu(parent = self, data = menudata.ManagerData())
         else:
             self.menubar, self.menudata = self.__createMenuBar()
-        #self.statusbar = self.CreateStatusBar(number=1)
-        #self.cmdprompt, self.cmdinput = self.__createCommandPrompt()
-        self.toolbar   = self.__createToolBar()
+        self.SetMenuBar(self.menubar)
+        self.menucmd = self.menubar.GetCmd()
+        self.statusbar = self.CreateStatusBar(number=1)
+        self.notebook  = self.__createNoteBook()
+        self.toolbar = LayerManagerToolbar(parent = self)
+        self.SetToolBar(self.toolbar)
 
         #setting splitter window
 
         self.cmbPanel = wx.Panel(self,name="cmbpanel")
-
 
+
         self.maptree = None
         self.pg_panel = None
         self.cb_loclist = []
@@ -210,292 +225,31 @@
         self.options = ['on', 'off']
         self.radiobox = wx.RadioBox(self.cmbPanel, wx.ID_ANY,  choices=self.options, style=wx.HORIZONTAL)
         self.radiobox.SetSelection(1)
-        #self.chkInfo = wx.CheckBox(self.cmbPanel, wx.ID_ANY,"display Info", wx.DefaultPosition, wx.DefaultSize)
         self.treeExpand = wx.CheckBox(self.cmbPanel, wx.ID_ANY,"Expand All", wx.DefaultPosition, wx.DefaultSize)
         self.cmbLocation = wx.ComboBox(self.cmbPanel, value = "Select Location",size=wx.DefaultSize, choices=self.loclist)
         self.cmbMapset = wx.ComboBox(self.cmbPanel, value = "Select Mapset", size=wx.DefaultSize)	
-        #self.tree = wx.TreeCtrl(self.pLeft, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TR_HIDE_ROOT|wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS)
 
 
-
         self.itemFont = wx.Font(pointSize=9,weight=0, family=wx.FONTFAMILY_DEFAULT ,style=wx.FONTSTYLE_ITALIC)
 
-        
         self.notebook  = self.__createNoteBook()
-        self.cmdprompt = self.__createCommandPrompt()
-
-       # self._mgr = self.pg_panel._layerManager
-
-#        self._mgr.AddPane(self.cmdprompt, wx.aui.AuiPaneInfo().CentrePane().Dockable(False).BestSize((-1,-1)).CloseButton(False).DestroyOnClose(True). Layer(0))
-
-        self.current = self.notebook.GetCurrentPage()    
+        self.curr_page = self.notebook.GetCurrentPage()    
  
 
         #self.goutput.Redirect()
 
-    
-       # self.ltree = LayerTree(self.pLeft,wx.ID_ANY,gisdbase=self.gisdbase,frame=self.pg_panel)
 
         self.doBindings()
         self.doLayout()
 
-        self.cmbSizer.Add(self.cmdprompt)
-
-        self.Map =    self.GetMapDisplay()
-
+    def OnInstallExtension(self, event):
+        """!Install extension from GRASS Addons SVN repository"""
+        win = InstallExtensionWindow(self, size = (550, 400))
+        win.CentreOnScreen()
+        win.Show()
         
 
 
-
-
-    def GetMapDisplay(self):
-        self.panel = self.notebook.GetCurrentPage()
-        return self.panel.Map
-                            
-
-    def __createMenuBar(self):
-        """!Creates menubar"""
-
-        self.menubar = wx.MenuBar()
-        if grassversion == "6.5.svn":
-            self.menudata = menudata.ManagerData()
-        else:
-            self.menudata = menudata.Data()        
-        for eachMenuData in self.menudata.GetMenu():
-            for eachHeading in eachMenuData:
-                menuLabel = eachHeading[0]
-                menuItems = eachHeading[1]
-                self.menubar.Append(self.__createMenu(menuItems), menuLabel)
-
-        self.SetMenuBar(self.menubar)
-
-        return (self.menubar, self.menudata)
-
-    def __createCommandPrompt(self):
-        """!Creates command-line input area"""
-        self.cmdprompt = wx.Panel(self)
-
-        button = wx.Button(parent=self.cmdprompt, id=wx.ID_ANY, label="Cmd >",
-                            size=(70,23))
-        button.SetToolTipString(_("Click for erasing command prompt"))
-	# label.SetFont(wx.Font(pointSize=11, family=wx.FONTFAMILY_DEFAULT,
-        #                      style=wx.NORMAL, weight=wx.BOLD))
-        self.cinput = wx.TextCtrl(parent=self.cmdprompt, id=wx.ID_ANY,
-                            value="",
-                            style= wx.TE_PROCESS_ENTER,
-                            size=(250,20))
-
-        #cinput.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
-
-        wx.CallAfter(self.cinput.SetInsertionPoint, 0)
-
-        self.Bind(wx.EVT_TEXT_ENTER, self.OnRunCmd,   self.cinput)
-        self.Bind(wx.EVT_BUTTON,     self.OnCmdClear,      button)
-        #self.Bind(wx.EVT_TEXT,       self.OnUpdateStatusBar, input)
-
-        # layout
-        sizer = wx.BoxSizer(wx.HORIZONTAL)
-        sizer.Add(item=button, proportion=0,
-                  flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER,
-                  border=4)
-        sizer.Add(item=self.cinput, proportion=1,
-                  flag=wx.EXPAND | wx.ALL,
-                  border=1)
-
-        self.cmdprompt.SetSizer(sizer)
-        #sizer.Fit(self.cmdprompt)
-        self.cmdprompt.Layout()
-
-        return self.cmdprompt
-
-
-    def OnCmdClear(self,event):
-        self.cinput.SetValue('')
-        self.cinput.SetFocus()
-
-    def __createMenu(self, menuData):
-        """!Creates menu"""
-
-        menu = wx.Menu()
-        for eachItem in menuData:
-            if len(eachItem) == 2:
-                label = eachItem[0]
-                subMenu = self.__createMenu(eachItem[1])
-                menu.AppendMenu(wx.ID_ANY, label, subMenu)
-            else:
-                if grassversion == "6.4.0svn":
-                    self.__createMenuItem(menu, *eachItem)
-                else:
-                    self.__createMenuItem7(menu, *eachItem)
-        self.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuHighlight)
-        return menu
-
-#    def __createMenuItem(self, menu, label, help, handler, gcmd, keywords, shortcut = '', kind = wx.ITEM_NORMAL):
-    def __createMenuItem(self, menu, label, help, handler, gcmd, kind=wx.ITEM_NORMAL):
-        """Creates menu items"""
-
-        if not label:
-            menu.AppendSeparator()
-            return
-
-        if len(gcmd) > 0:
-            helpString = gcmd + ' -- ' + help
-        else:
-            helpString = help
-
-        menuItem = menu.Append(wx.ID_ANY, label, helpString, kind)
-        
-        self.menucmd[menuItem.GetId()] = gcmd
-
-        if len(gcmd) > 0 and \
-                gcmd.split()[0] not in globalvar.grassCmd['all']:
-            menuItem.Enable (False)
-
-        rhandler = eval(handler)
-
-        self.Bind(wx.EVT_MENU, rhandler, menuItem)
-
-    def __createMenuItem7(self, menu, label, help, handler, gcmd, keywords, shortcut = '', kind = wx.ITEM_NORMAL):
-        """!Creates menu items"""
-
-        if not label:
-            menu.AppendSeparator()
-            return
-
-        if len(gcmd) > 0:
-            helpString = gcmd + ' -- ' + help
-        else:
-            helpString = help
-        
-        if shortcut:
-            label += '\t' + shortcut
-        
-        menuItem = menu.Append(wx.ID_ANY, label, helpString, kind)
-
-        self.menucmd[menuItem.GetId()] = gcmd
-
-        if len(gcmd) > 0 and \
-                gcmd.split()[0] not in globalvar.grassCmd['all']:
-            menuItem.Enable (False)
-
-        rhandler = eval(handler)
-
-        self.Bind(wx.EVT_MENU, rhandler, menuItem)
-
-
-
-
-
-    def OnXTermNoXMon(self, event):
-        """!
-        Run commands that need xterm
-        """
-        self.OnXTerm(event, need_xmon = False)
-        
-    def OnXTerm(self, event, need_xmon = True):
-        """!
-        Run commands that need interactive xmon
-
-        @param need_xmon True to start X monitor
-        """
-        # unset display mode
-        del os.environ['GRASS_RENDER_IMMEDIATE']
-        
-        if need_xmon:
-            # open next available xmon
-            xmonlist = []
-            
-            # make list of xmons that are not running
-            ret = gcmd.RunCommand('d.mon',
-                                  flags = 'L',
-                                  read = True)
-            
-            for line in ret.split('\n'):               
-                line = line.strip()
-                if line.startswith('x') and 'not running' in line:
-                    xmonlist.append(line[0:2])
-            
-            # find available xmon
-            xmon = xmonlist[0]
-            
-            # bring up the xmon
-            cmdlist = ['d.mon', xmon]
-            p = gcmd.Command(cmdlist, wait=False)
-        
-        # run the command        
-        command = self.GetMenuCmd(event)
-        command = ' '.join(command)
-        
-        gisbase = os.environ['GISBASE']
-        
-        if sys.platform == "win32":
-            runbat = os.path.join(gisbase,'etc','grass-run.bat')
-            cmdlist = ["start", runbat, runbat, command]
-        else:
-            if sys.platform == "darwin":
-                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-mac')
-            else:
-                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-wrapper')
-            
-            grassrun = os.path.join(gisbase,'etc','grass-run.sh')
-            cmdlist = [xtermwrapper, '-e', grassrun, command]
-        
-        p = gcmd.Command(cmdlist, wait=False)
-        
-        # reset display mode
-        os.environ['GRASS_RENDER_IMMEDIATE'] = 'TRUE'
-
-    def OnRunCmd(self, event):
-        """Run command"""
-        cmdString = event.GetString()
-
-        if cmdString[:2] == 'd.' and not self.current:
-            self.NewDisplay(show=True)
-        
-        cmd = shlex.split(str(cmdString))
-        if len(cmd) > 1:
-            self.goutput.RunCmd(cmd, switchPage=True)
-        else:
-            self.goutput.RunCmd(cmd, switchPage=False)
-        
-        self.OnUpdateStatusBar(None)
-
-
-    def OnUpdateStatusBar(self, event):
-        #if event is None:
-         #   self.statusbar.SetStatusText("")
-        #else:
-         #   self.statusbar.SetStatusText(_("Type GRASS command and run by pressing ENTER"))
-        print "asdf4"
-
-
-    def __createToolBar(self):
-        """!Creates toolbar"""
-
-        self.toolbar = self.CreateToolBar()
-        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
-
-        for each in self.ToolbarData():
-            self.AddToolbarButton(self.toolbar, *each)
-        self.toolbar.Realize()
-
-        return self.toolbar
-
-    def OnMenuHighlight(self, event):
-        """
-        Default menu help handler
-        """
-         # Show how to get menu item info from this event handler
-        id = event.GetMenuId()
-        item = self.GetMenuBar().FindItemById(id)
-        if item:
-            text = item.GetText()
-            help = item.GetHelp()
-
-        # but in this case just call Skip so the default is done
-        event.Skip()
-
-        
     def __createNoteBook(self):
         """!Creates notebook widgets"""
 
@@ -516,7 +270,7 @@
         self.notebook.SetTabAreaColour(globalvar.FNPageColor)
 
        # self._lmgr=wx.aui.AuiManager(self)
-        self.pg_panel = MapFrame(parent=self.notebook, id=wx.ID_ANY, Map=render.Map(),  size=globalvar.MAP_WINDOW_SIZE,flag=True,frame=self,gismgr=self)
+        self.pg_panel = MapFrame(parent=self.notebook, id=wx.ID_ANY, Map=render.Map(), size=globalvar.MAP_WINDOW_SIZE,flag=False,frame=self)
         
         self.disp_idx = self.disp_idx + 1
         self.notebook.AddPage(self.pg_panel, text="Display "+ str(self.disp_idx), select = True)
@@ -524,7 +278,7 @@
         self.goutput = goutput.GMConsole(self, pageid=1)
         self.outpage = self.notebook.AddPage(self.goutput, text=_("Command console"))
 
-        self.notebook.SetSelection(0)
+        #self.notebook.SetSelection(0)
 
 
        # self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
@@ -537,139 +291,48 @@
 
         return self.notebook
 
-    def OnPageChanged(self, event):
-        """!Page in notebook changed"""
-        pageno = event.GetSelection()
-        self.page = self.notebook.GetPage(pageno)
-        if page == self.goutput.pageid:
-            # remove '(...)'
-            self.notebook.SetPageText(page, _("Command output"))
         
-        event.Skip()
-
-    def OnCBPageClosed(self, event):
-        """
-        Page of notebook closed
-        Also close associated map display
-        """
-        self.curr_page = self.notebook.GetCurrentPage()
-        if UserSettings.Get(group='manager', key='askOnQuit', subkey='enabled'):
-            maptree = self.curr_page.maptree
-            
-            if self.workspaceFile:
-                message = _("Do you want to save changes in the workspace?")
-            else:
-                message = _("Do you want to store current settings "
-                            "to workspace file?")
-            
-            # ask user to save current settings
-            if maptree.GetCount() > 0:
-                dlg = wx.MessageDialog(self,
-                                       message=message,
-                                       caption=_("Close Map Display %d") % (self.curr_pagenum + 1),
-                                       style=wx.YES_NO | wx.YES_DEFAULT |
-                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
-                ret = dlg.ShowModal()
-                if ret == wx.ID_YES:
-                    if not self.workspaceFile:
-                        self.OnWorkspaceSaveAs()
-                    else:
-                        self.SaveToWorkspaceFile(self.workspaceFile)
-                elif ret == wx.ID_CANCEL:
-                    event.Veto()
-                    dlg.Destroy()
-                    return
-                dlg.Destroy()
+    def AddNviz(self):
+        """!Add nviz notebook page"""
+        self.nviz = nviz_tools.NvizToolWindow(parent = self,
+                                              display = self.curr_page.maptree.GetMapDisplay()) 
+        self.notebook.AddPage(self.nviz, text = _("3D view"))
+        self.notebook.SetSelection(self.notebook.GetPageCount() - 1)
         
-        self.notebook.GetPage(event.GetSelection()).maptree.Map.Clean()
-        self.notebook.GetPage(event.GetSelection()).maptree.Close(True)
-        self.disp_idx = self.disp_idx - 1
+    def RemoveNviz(self):
+        """!Remove nviz notebook page"""
+        # print self.notebook.GetPage(1)
+        self.notebook.RemovePage(3)
+        del self.nviz
+        self.notebook.SetSelection(0)
         
-        self.curr_page = None
+    def WorkspaceChanged(self):
+        """!Update window title"""
+        if not self.workspaceChanged:
+            self.workspaceChanged = True
         
-        event.Skip()
-
-    def OnCBPageChanged(self, event):
-        """!Page in notebook (display) changed"""
-
-
-        old_pgnum = event.GetOldSelection()
-        new_pgnum = event.GetSelection()
-
-        self.oldpage = self.notebook.GetPage(old_pgnum)
-
-       
-        self.curr_page   = self.notebook.GetCurrentPage()
-        self.curr_pagenum = self.notebook.GetSelection()
-
-
-
-  #      self.cmbMapset.SetValue(self.cb_loclist[self.disp_idx])
- #       self.cmbLocation.SetValue(self.cb_loclist[self.disp_idx])
-#        self.disp_idx
-
-
-        index  = self.notebook.GetSelection()
-        self.page = self.notebook.GetPage(index)
+        if self.workspaceFile:
+            self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile) + '*')
         
-    
-
-    
-
-        
-
- #       print index
-#        print self.cb_mapfile
-        #import pdb
-       # pdb.set_trace()
-
-        try:
-            a_loc = str(self.cb_loclist[index])
-            a_map =  str(self.cb_maplist[index])
-          
-           # a_mapfile = self.cb_mapfile[index]
-
-        except IndexError:
-            a_loc = "Select Location"
-            a_map = "Select Mapset"
-
-        self.cmbLocation.SetValue(a_loc)
-        self.cmbMapset.SetValue(a_map)
-
-
-
-        try:
-            self.gisrc['LOCATION_NAME'] = self.cb_loclist[index]
-            self.gisrc['MAPSET'] = self.cb_maplist[index]
-
-
-        except:
-            pass
-        #self.page.Map.Region = self.page.Map.GetRegion()
-
-        self.update_grassrc(self.gisrc)
-        
-    
-        
-        event.Skip()
-
-
-
     def OnGeorectify(self, event):
+        """!Launch georectifier module
         """
-        Launch georectifier module
-        """
         georect.GeorectWizard(self)
 
-
     def OnGModeler(self, event):
         """!Launch Graphical Modeler"""
         win = gmodeler.ModelFrame(parent = self)
         win.CentreOnScreen()
         
         win.Show()
-
-
+        
+    def OnDone(self, returncode):
+        """Command execution finised"""
+        if hasattr(self, "model"):
+            self.model.DeleteIntermediateData(log = self.goutput)
+            del self.model
+        self.SetStatusText('')
+        
     def OnRunModel(self, event):
         """!Run model"""
         filename = ''
@@ -700,8 +363,6 @@
         self.SetStatusText(_('Running model...'), 0)
         self.model.Run(log = self.goutput,
                        onDone = self.OnDone)
-
-
         
     def OnMapsets(self, event):
         """
@@ -724,62 +385,75 @@
         """
         pass
 
-    def OnPageChanged(self,event):
-        self.current = self.notebook.GetPage(event.GetSelection())
-        #self.current = self.notebook.GetCurrentPage()
-        #self.current.Map = self.GetMapDisplay()
+    def OnCBPageChanged(self, event):
+        """!Page in notebook (display) changed"""
+        old_pgnum = event.GetOldSelection()
+        new_pgnum = event.GetSelection()
+        
+        self.curr_page   = self.notebook.GetCurrentPage()
+        self.curr_pagenum = self.notebook.GetSelection()
+        
+        try:
+            self.curr_page.maptree.mapdisplay.SetFocus()
+            self.curr_page.maptree.mapdisplay.Raise()
+        except:
+            pass
+        
         event.Skip()
 
+    def OnPageChanged(self, event):
+        """!Page in notebook changed"""
+        page = event.GetSelection()
+        if page == self.goutput.pageid:
+            # remove '(...)'
+            self.notebook.SetPageText(page, _("Command console"))
+            self.goutput.cmd_prompt.SetSTCFocus(True)
+        self.SetStatusText('', 0)
+        
+        event.Skip()
 
-
-    def OnPageClosed(self, event):
-        """
-        Page of notebook closed
+    def OnCBPageClosed(self, event):
+        """!Page of notebook closed
         Also close associated map display
         """
+        if UserSettings.Get(group='manager', key='askOnQuit', subkey='enabled'):
+            maptree = self.curr_page.maptree
+            
+            if self.workspaceFile:
+                message = _("Do you want to save changes in the workspace?")
+            else:
+                message = _("Do you want to store current settings "
+                            "to workspace file?")
+            
+            # ask user to save current settings
+            if maptree.GetCount() > 0:
+                dlg = wx.MessageDialog(self,
+                                       message=message,
+                                       caption=_("Close Map Display %d") % (self.curr_pagenum + 1),
+                                       style=wx.YES_NO | wx.YES_DEFAULT |
+                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
+                ret = dlg.ShowModal()
+                if ret == wx.ID_YES:
+                    if not self.workspaceFile:
+                        self.OnWorkspaceSaveAs()
+                    else:
+                        self.SaveToWorkspaceFile(self.workspaceFile)
+                elif ret == wx.ID_CANCEL:
+                    event.Veto()
+                    dlg.Destroy()
+                    return
+                dlg.Destroy()
 
+        self.gm_cb.GetPage(event.GetSelection()).maptree.Map.Clean()
+        self.gm_cb.GetPage(event.GetSelection()).maptree.Close(True)
 
-#        if UserSettings.Get(group='manager', key='askOnQuit', subkey='enabled'):
-#            maptree = self.current.maptree
-#           
-#            if self.workspaceFile:
-#                message = _("Do you want to save changes in the workspace?")
-#            else:
-#                message = _("Do you want to store current settings "
-#                            "to workspace file?")
-#            
-#            # ask user to save current settings
-#            if maptree.GetCount() > 0:
-#                dlg = wx.MessageDialog(self,
-#                                       message=message,
-#                                       caption=_("Close Map Display %d") % (self.disp_idx),
-#                                       style=wx.YES_NO | wx.YES_DEFAULT |
-#                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
-#                ret = dlg.ShowModal()
-#                if ret == wx.ID_YES:
-#                    if not self.workspaceFile:
-#                        self.OnWorkspaceSaveAs()
-#                    else:
-#                        self.SaveToWorkspaceFile(self.workspaceFile)
-#                elif ret == wx.ID_CANCEL:
-#
-#                    event.Veto()
-#                    dlg.Destroy()
-#                    return
-#                dlg.Destroy()
+        self.curr_page = None
 
-
-        self.notebook.GetPage(event.GetSelection()).maptree.Map.Clean()
-        self.disp_idx = self.disp_idx - 1
-        self.notebook.DeletePage(self.notebook.GetCurrentPage())
-        self.current = self.notebook.GetCurrentPage()
-        #self.current.Map.Clean()
         event.Skip()
 
-        
     def GetLogWindow(self):
         """!Get widget for command output"""
-        return self.gmconsole.goutput
+        return self.goutput
     
     def GetMenuCmd(self, event):
         """!Get GRASS command from menu item
@@ -801,9 +475,9 @@
             return cmdlist
 
         try:
-            layer = self.current.maptree.layer_selected
-            name = self.current.maptree.GetPyData(layer)[0]['maplayer'].name
-            type = self.current.maptree.GetPyData(layer)[0]['type']
+            layer = self.curr_page.maptree.layer_selected
+            name = self.curr_page.maptree.GetPyData(layer)[0]['maplayer'].name
+            type = self.curr_page.maptree.GetPyData(layer)[0]['type']
         except:
             layer = None
         if layer and len(cmdlist) == 1: # only if no paramaters given
@@ -815,11 +489,11 @@
 
         return cmdlist
 
-    def RunMenuCmd(self, event):
+    def RunMenuCmd(self, event, cmd = ''):
         """!Run command selected from menu"""
-        print "asdf"
-        #cmd = self.GetMenuCmd(event)
-        #goutput.GMConsole(self, pageid=1).RunCmd(cmd, switchPage=True)
+        if event:
+            cmd = self.GetMenuCmd(event)
+        self.goutput.RunCmd(cmd, switchPage=False)
 
     def OnMenuCmd(self, event, cmd = ''):
         """!Parse command selected from menu"""
@@ -827,36 +501,88 @@
             cmd = self.GetMenuCmd(event)
         menuform.GUI().ParseCommand(cmd, parentframe=self)
 
+    def OnRunScript(self, event):
+        """!Run script"""
+        # open dialog and choose script file
+        dlg = wx.FileDialog(parent = self, message = _("Choose script file"),
+                            defaultDir = os.getcwd(), wildcard = _("Bash script (*.sh)|*.sh|Python script (*.py)|*.py"))
+        
+        filename = None
+        if dlg.ShowModal() == wx.ID_OK:
+            filename = dlg.GetPath()
+        
+        if not filename:
+            return False
+
+        if not os.path.exists(filename):
+            wx.MessageBox(parent = self,
+                          message = _("Script file '%s' doesn't exist. Operation cancelled.") % filename,
+                          caption = _("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+            return
+        
+        self.goutput.WriteCmdLog(_("Launching script '%s'...") % filename)
+        self.goutput.RunCmd(filename, switchPage = True)
+        
     def OnChangeLocation(self, event):
         """Change current location"""
-        pass
+        dlg = gdialogs.LocationDialog(parent = self)
+        if dlg.ShowModal() == wx.ID_OK:
+            location, mapset = dlg.GetValues()
+            if location and mapset:
+                ret = gcmd.RunCommand("g.gisenv",
+                                      set = "LOCATION_NAME=%s" % location)
+                ret += gcmd.RunCommand("g.gisenv",
+                                       set = "MAPSET=%s" % mapset)
+                if ret > 0:
+                    wx.MessageBox(parent = self,
+                                  message = _("Unable to switch to location <%(loc)s> mapset <%(mapset)s>.") % \
+                                      { 'loc' : location, 'mapset' : mapset },
+                                  caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
+                else:
+                    # close workspace
+                    self.OnWorkspaceClose()
+                    self.OnWorkspaceNew()
+                    wx.MessageBox(parent = self,
+                                  message = _("Current location is <%(loc)s>.\n"
+                                              "Current mapset is <%(mapset)s>.") % \
+                                      { 'loc' : location, 'mapset' : mapset },
+                                  caption = _("Info"), style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
                     
     def OnChangeMapset(self, event):
         """Change current mapset"""
-        pass
+        dlg = gdialogs.MapsetDialog(parent = self)
+        if dlg.ShowModal() == wx.ID_OK:
+            mapset = dlg.GetMapset()
+            if mapset:
+                if gcmd.RunCommand("g.gisenv",
+                                   set = "MAPSET=%s" % mapset) != 0:
+                    wx.MessageBox(parent = self,
+                                  message = _("Unable to switch to mapset <%s>.") % mapset,
+                                  caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
+                else:
+                    wx.MessageBox(parent = self,
+                                  message = _("Current mapset is <%s>.") % mapset,
+                                  caption = _("Info"), style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
         
     def OnNewVector(self, event):
         """!Create new vector map layer"""
-        name, add = gdialogs.CreateNewVector(self, cmd = (('v.edit',  { 'tool' : 'create' }, 'map')))
+        name, add = gdialogs.CreateNewVector(self, log = self.goutput,
+                                             cmd = (('v.edit',
+                                                     { 'tool' : 'create' },
+                                                     'map')))
         
         if name and add:
             # add layer to map layer tree
-            self.current.maptree.AddLayer(ltype='vector',
+            self.curr_page.maptree.AddLayer(ltype='vector',
                                             lname=name,
                                             lchecked=True,
                                             lopacity=1.0,
                                             lcmd=['d.vect', 'map=%s' % name])
-           
-    def OnMenuTree(self, event):
-        """!Show dialog with menu tree"""
-        dlg = MenuTreeWindow(self)
-        dlg.CentreOnScreen()
-        dlg.Show()
-    
+        
     def OnAboutGRASS(self, event):
         """!Display 'About GRASS' dialog"""
         win = AboutWindow(self)
-        win.Centre()
+        win.CentreOnScreen()
         win.Show(True)  
         
     def OnWorkspace(self, event):
@@ -879,48 +605,6 @@
         self.PopupMenu(menu)
         menu.Destroy()
 
-#    def OnWorkspaceNew(self, event=None):
-#        """!Create new workspace file
-#
-#        Erase current workspace settings first"""
-#
-#        Debug.msg(4, "GMFrame.OnWorkspaceNew():")
-#        
-#        # start new map display if no display is available
-#        if not self.current:
-#            self.NewDisplay()
-#        
-#        maptree = self.current.maptree
-#        
-#        # ask user to save current settings
-#        if maptree.GetCount() > 0:
-#             dlg = wx.MessageDialog(self, message=_("Current workspace is not empty. "
-#                                                    "Do you want to store current settings "
-#                                                    "to workspace file?"),
-#                                    caption=_("Create new workspace?"),
-#                                    style=wx.YES_NO | wx.YES_DEFAULT | \
-#                                        wx.CANCEL | wx.ICON_QUESTION)
-#             ret = dlg.ShowModal()
-#             if ret == wx.ID_YES:
-#                 self.OnWorkspaceSaveAs()
-#             elif ret == wx.ID_CANCEL:
-#                 dlg.Destroy()
-#                 return
-#             
-#             dlg.Destroy()
-#        
-#        # delete all items
-#        maptree.DeleteAllItems()
-#        
-#        # add new root element
-#        maptree.root = maptree.AddRoot("Map Layers")
-#        self.current.maptree.SetPyData(maptree.root, (None,None))
-#        
-#        # no workspace file loaded
-#        self.workspaceFile = None
-#        self.SetTitle(self.baseTitle)
-
-
     def OnWorkspaceNew(self, event = None):
         """!Create new workspace file
 
@@ -933,6 +617,8 @@
             self.NewDisplay()
         
         maptree = self.curr_page.maptree
+        maptree.root = maptree.AddRoot("Map Layers")
+        self.curr_page.maptree.SetPyData(maptree.root, (None,None))
         
         # ask user to save current settings
         if self.workspaceFile and self.workspaceChanged:
@@ -964,12 +650,11 @@
         self.workspaceFile = None
         self.workspaceChanged = False
         self.SetTitle(self.baseTitle)
-
         
     def OnWorkspaceOpen(self, event=None):
         """!Open file with workspace definition"""
         dlg = wx.FileDialog(parent=self, message=_("Choose workspace file"),
-                            defaultDir=os.getcwd(), wildcard="*.gxw")
+                            defaultDir=os.getcwd(), wildcard=_("GRASS Workspace File (*.gxw)|*.gxw"))
 
         filename = ''
         if dlg.ShowModal() == wx.ID_OK:
@@ -1005,7 +690,8 @@
         except Exception, err:
             raise gcmd.GStdError(_("Reading workspace file <%(file)s> failed.\n"
                                    "Invalid file, unable to parse XML document."
-                                   "\n\n%(err)s") % { 'file' : filename, 'err': err},
+                                   "\n\n%(err)s") % \
+                                     { 'file' : filename, 'err' : err },
                                  parent = self)
         
         busy = wx.BusyInfo(message=_("Please wait, loading workspace..."),
@@ -1025,17 +711,18 @@
         # start map displays first (list of layers can be empty)
         #
         displayId = 0
-        mapdisplay = []
+        mapdisplay = list()
         for display in gxwXml.displays:
-            mapdisplay.append(self.NewDisplay())
-            maptree = self.notebook.GetPage(displayId).maptree
+            mapdisp = self.NewDisplay(show=False)
+            mapdisplay.append(mapdisp)
+            maptree = self.gm_cb.GetPage(displayId).maptree
             
             # set windows properties
-            mapdisplay[-1].SetProperties(render=display['render'],
-                                         mode=display['mode'],
-                                         showCompExtent=display['showCompExtent'],
-                                         constrainRes=display['constrainRes'],
-                                         projection=display['projection']['enabled'])
+            mapdisp.SetProperties(render=display['render'],
+                                  mode=display['mode'],
+                                  showCompExtent=display['showCompExtent'],
+                                  constrainRes=display['constrainRes'],
+                                  projection=display['projection']['enabled'])
 
             if display['projection']['enabled']:
                 if display['projection']['epsg']:
@@ -1048,16 +735,21 @@
             # set position and size of map display
             if UserSettings.Get(group='workspace', key='posDisplay', subkey='enabled') is False:
                 if display['pos']:
-                    mapdisplay[-1].SetPosition(display['pos'])
+                    mapdisp.SetPosition(display['pos'])
                 if display['size']:
-                    mapdisplay[-1].SetSize(display['size'])
+                    mapdisp.SetSize(display['size'])
                     
             # set extent if defined
             if display['extent']:
                 w, s, e, n = display['extent']
-                maptree.Map.region = maptree.Map.GetRegion(w=w, s=s, e=e, n=n)
+                region = maptree.Map.region = maptree.Map.GetRegion(w=w, s=s, e=e, n=n)
+                mapdisp.GetWindow().ResetZoomHistory()
+                mapdisp.GetWindow().ZoomHistory(region['n'],
+                                                region['s'],
+                                                region['e'],
+                                                region['w'])
                 
-            mapdisplay[-1].Show()
+            mapdisp.Show()
             
             displayId += 1
     
@@ -1068,7 +760,7 @@
         #
         for layer in gxwXml.layers:
             display = layer['display']
-            maptree = self.notebook.GetPage(display).maptree
+            maptree = self.gm_cb.GetPage(display).maptree
             
             newItem = maptree.AddLayer(ltype=layer['type'],
                                        lname=layer['name'],
@@ -1095,7 +787,7 @@
         if maptree:
             # reverse list of map layers
             maptree.Map.ReverseListOfLayers()
-
+            
         for mdisp in mapdisplay:
             mdisp.MapWindow2D.UpdateMap()
 
@@ -1107,14 +799,14 @@
 
         if dialog.ShowModal() == wx.ID_OK:
             # start new map display if no display is available
-            if not self.current:
+            if not self.curr_page:
                 self.NewDisplay()
 
-            maptree = self.current.maptree
+            maptree = self.curr_page.maptree
             busy = wx.BusyInfo(message=_("Please wait, loading workspace..."),
                                parent=self)
             wx.Yield()
-
+            
             for layerName in dialog.GetMapLayers():
                 if dialog.GetLayerType() == 'raster':
                     cmd = ['d.rast', 'map=%s' % layerName]
@@ -1122,7 +814,7 @@
                     cmd = ['d.vect', 'map=%s' % layerName]
                 newItem = maptree.AddLayer(ltype=dialog.GetLayerType(),
                                            lname=layerName,
-                                           lchecked=True,
+                                           lchecked=False,
                                            lopacity=1.0,
                                            lcmd=cmd,
                                            lgroup=None)
@@ -1132,7 +824,7 @@
     def OnWorkspaceLoadGrcFile(self, event):
         """!Load map layers from GRC file (Tcl/Tk GUI) into map layer tree"""
         dlg = wx.FileDialog(parent=self, message=_("Choose GRC file to load"),
-                            defaultDir=os.getcwd(), wildcard="*.grc")
+                            defaultDir=os.getcwd(), wildcard=_("Old GRASS Workspace File (*.grc)|*.grc"))
 
         filename = ''
         if dlg.ShowModal() == wx.ID_OK:
@@ -1144,7 +836,7 @@
         Debug.msg(4, "GMFrame.OnWorkspaceLoadGrcFile(): filename=%s" % filename)
 
         # start new map display if no display is available
-        if not self.current:
+        if not self.curr_page:
             self.NewDisplay()
 
         busy = wx.BusyInfo(message=_("Please wait, loading workspace..."),
@@ -1169,9 +861,8 @@
 
     def OnWorkspaceSaveAs(self, event=None):
         """!Save workspace definition to selected file"""
-
         dlg = wx.FileDialog(parent=self, message=_("Choose file to save current workspace"),
-                            defaultDir=os.getcwd(), wildcard="*.gxw", style=wx.FD_SAVE)
+                            defaultDir=os.getcwd(), wildcard=_("GRASS Workspace File (*.gxw)|*.gxw"), style=wx.FD_SAVE)
 
         filename = ''
         if dlg.ShowModal() == wx.ID_OK:
@@ -1200,7 +891,6 @@
 
     def OnWorkspaceSave(self, event=None):
         """!Save file with workspace definition"""
-
         if self.workspaceFile:
             dlg = wx.MessageDialog(self, message=_("Workspace file <%s> already exists. "
                                                    "Do you want to overwrite this file?") % \
@@ -1211,6 +901,7 @@
             else:
                 Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
                 self.SaveToWorkspaceFile(self.workspaceFile)
+                self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
         else:
             self.OnWorkspaceSaveAs()
 
@@ -1242,27 +933,26 @@
         
         return True
     
-    def OnWorkspaceClose(self, event=None):
+    def OnWorkspaceClose(self, event = None):
         """!Close file with workspace definition
-
+        
         If workspace has been modified ask user to save the changes.
         """
-
         Debug.msg(4, "GMFrame.OnWorkspaceClose(): file=%s" % self.workspaceFile)
-        self.workspaceFile = None
-        self.SetTitle(self.baseTitle)
-
-        displays = []
-        for page in range(0, self.notebook.GetPageCount()):
-            displays.append(self.notebook.GetPage(page).maptree.mapdisplay)
         
+        displays = list()
+        for page in range(0, self.gm_cb.GetPageCount()):
+            displays.append(self.gm_cb.GetPage(page).maptree.mapdisplay)
+        
         for display in displays:
             display.OnCloseWindow(event)
         
+        self.workspaceFile = None
+        self.workspaceChanged = False
+        self.SetTitle(self.baseTitle)
         self.disp_idx = 0
         self.curr_page = None
         
-
     def RulesCmd(self, event, cmd = ''):
         """
         Launches dialog for commands that need rules
@@ -1297,6 +987,65 @@
     
                 self.goutput.RunCmd(cmdlist)
 
+    def OnXTermNoXMon(self, event):
+        """!
+        Run commands that need xterm
+        """
+        self.OnXTerm(event, need_xmon = False)
+        
+    def OnXTerm(self, event, need_xmon = True):
+        """!
+        Run commands that need interactive xmon
+
+        @param need_xmon True to start X monitor
+        """
+        # unset display mode
+        del os.environ['GRASS_RENDER_IMMEDIATE']
+        
+        if need_xmon:
+            # open next available xmon
+            xmonlist = []
+            
+            # make list of xmons that are not running
+            ret = gcmd.RunCommand('d.mon',
+                                  flags = 'L',
+                                  read = True)
+            
+            for line in ret.split('\n'):               
+                line = line.strip()
+                if line.startswith('x') and 'not running' in line:
+                    xmonlist.append(line[0:2])
+            
+            # find available xmon
+            xmon = xmonlist[0]
+            
+            # bring up the xmon
+            cmdlist = ['d.mon', xmon]
+            p = gcmd.Command(cmdlist, wait=False)
+        
+        # run the command        
+        command = self.GetMenuCmd(event)
+        command = ' '.join(command)
+        
+        gisbase = os.environ['GISBASE']
+        
+        if sys.platform == "win32":
+            runbat = os.path.join(gisbase,'etc','grass-run.bat')
+            cmdlist = ["start", runbat, runbat, command]
+        else:
+            if sys.platform == "darwin":
+                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-mac')
+            else:
+                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-wrapper')
+            
+            grassrun = os.path.join(gisbase,'etc','grass-run.sh')
+            cmdlist = [xtermwrapper, '-e', grassrun, command]
+        
+        p = gcmd.Command(cmdlist, wait=False)
+        
+        # reset display mode
+        os.environ['GRASS_RENDER_IMMEDIATE'] = 'TRUE'
+        
     def OnPreferences(self, event):
         """!General GUI preferences/settings"""
         if not self.dialogs['preferences']:
@@ -1330,95 +1079,63 @@
         self.profile.Refresh()
         self.profile.Update()
         
-    def DispMapCalculator(self, event):
+    def OnMapCalculator(self, event, cmd = ''):
+        """!Init map calculator for interactive creation of mapcalc statements
         """
-        Init map calculator for interactive creation of mapcalc statements
-        """
+
+        if event:
+            cmd = self.GetMenuCmd(event)
+
+        win = mapcalculator.MapCalcFrame(parent = self, title = _('GRASS GIS Map Calculator'),
+                                         cmd=cmd[0])
+        win.CentreOnScreen()
+        win.Show()
         
-        self.mapcalculator = mapcalculator.MapCalcFrame(self, wx.ID_ANY, title='',
-                                                        dimension=2)
+    def OnMapCalculator3D(self, event, cmd =''):
+        """!Init map calculator for interactive creation of mapcalc statements
+        """
+        if event:
+            cmd = self.GetMenuCmd(event)
 
-    def Disp3DMapCalculator(self, event):
+        win = mapcalculator.MapCalcFrame(parent = self, title = _('GRASS GIS Map Calculator (3D raster)'),
+                                         cmd=cmd[0])
+        win.CentreOnScreen()
+        win.Show()
+        
+    def OnVectorCleaning(self, event, cmd = ''):
+        """!Init interactive vector cleaning
         """
-        Init map calculator for interactive creation of mapcalc statements
-        """
         
-        self.mapcalculator = mapcalculator.MapCalcFrame(self, wx.ID_ANY, title='',
-                                                        dimension=3)
+        if event:
+            cmd = self.GetMenuCmd(event)
 
-    def AddToolbarButton(self, toolbar, label, icon, help, handler):
-        """!Adds button to the given toolbar"""
-
-        if not label:
-            toolbar.AddSeparator()
-            return
-        tool = toolbar.AddLabelTool(id=wx.ID_ANY, label=label, bitmap=icon, shortHelp=help)
-        self.Bind(wx.EVT_TOOL, handler, tool)
-
-    def ToolbarData(self):
-
-        return   (
-                 ('newdisplay', Icons["newdisplay"].GetBitmap(),
-                  Icons["newdisplay"].GetLabel(), self.OnNewDisplay),
-                 ('', '', '', ''),
-                 ('workspaceLoad', Icons["workspaceLoad"].GetBitmap(),
-                  Icons["workspaceLoad"].GetLabel(), self.OnWorkspace),
-                 ('workspaceOpen', Icons["workspaceOpen"].GetBitmap(),
-                  Icons["workspaceOpen"].GetLabel(), self.OnWorkspaceOpen),
-                 ('workspaceSave', Icons["workspaceSave"].GetBitmap(),
-                  Icons["workspaceSave"].GetLabel(), self.OnWorkspaceSave),
-                 ('', '', '', ''),
-                 ('addrast', Icons["addrast"].GetBitmap(),
-                  Icons["addrast"].GetLabel(), self.OnAddRaster),
-                 ('addshaded', Icons["addshaded"].GetBitmap(),
-                  _("Add various raster-based map layers"), self.OnAddRasterMisc),
-                 ('addvect', Icons["addvect"].GetBitmap(),
-                  Icons["addvect"].GetLabel(), self.OnAddVector),
-                 ('addthematic', Icons["addthematic"].GetBitmap(),
-                  _("Add various vector-based map layer"), self.OnAddVectorMisc),
-                 ('addcmd',  Icons["addcmd"].GetBitmap(),
-                  Icons["addcmd"].GetLabel(),  self.OnAddCommand),
-                 ('addgrp',  Icons["addgrp"].GetBitmap(),
-                  Icons["addgrp"].GetLabel(), self.OnAddGroup),
-                 ('addovl',  Icons["addovl"].GetBitmap(),
-                  Icons["addovl"].GetLabel(), self.OnAddOverlay),
-                 ('delcmd',  Icons["delcmd"].GetBitmap(),
-                  Icons["delcmd"].GetLabel(), self.OnDeleteLayer),
-                 ('', '', '', ''),
-                 ('attrtable', Icons["attrtable"].GetBitmap(),
-                  Icons["attrtable"].GetLabel(), self.OnShowAttributeTable)
-                  )
-
+        win = vclean.VectorCleaningFrame(parent = self, cmd = cmd[0])
+        win.CentreOnScreen()
+        win.Show()
+        
     def OnImportDxfFile(self, event):
         """!Convert multiple DXF layers to GRASS vector map layers"""
-        dlg = gdialogs.MultiImportDialog(parent=self, type='dxf',
-                                         title=_("Import DXF layers"))
+        dlg = gdialogs.DxfImportDialog(parent=self)
         dlg.ShowModal()
 
     def OnImportGdalLayers(self, event):
         """!Convert multiple GDAL layers to GRASS raster map layers"""
-        dlg = gdialogs.MultiImportDialog(parent=self, type='gdal',
-                                         title=_("Import GDAL layers"))
+        dlg = gdialogs.GdalImportDialog(parent=self)
         dlg.ShowModal()
 
     def OnLinkGdalLayers(self, event):
         """!Link multiple GDAL layers to GRASS raster map layers"""
-        dlg = gdialogs.MultiImportDialog(parent=self, type='gdal',
-                                         title=_("Link GDAL layers"),
-                                         link = True)
+        dlg = gdialogs.GdalImportDialog(parent=self, link = True)
         dlg.ShowModal()
         
     def OnImportOgrLayers(self, event):
         """!Convert multiple OGR layers to GRASS vector map layers"""
-        dlg = gdialogs.MultiImportDialog(parent=self, type='ogr',
-                                         title=_("Import OGR layers"))
+        dlg = gdialogs.GdalImportDialog(parent=self, ogr = True)
         dlg.ShowModal()
-    
+        
     def OnLinkOgrLayers(self, event):
         """!Links multiple OGR layers to GRASS vector map layers"""
-        dlg = gdialogs.MultiImportDialog(parent=self, type='ogr',
-                                         title=_("Link OGR layers"),
-                                         link = True)
+        dlg = gdialogs.GdalImportDialog(parent=self, ogr = True, link = True)
         dlg.ShowModal()
         
     def OnImportWMS(self, event):
@@ -1448,11 +1165,11 @@
         """
         Show attribute table of the given vector map layer
         """
-        if not self.current:
+        if not self.curr_page:
             self.MsgNoLayerSelected()
             return
         
-        layer = self.current.maptree.layer_selected
+        layer = self.curr_page.maptree.layer_selected
         # no map layer selected
         if not layer:
             self.MsgNoLayerSelected()
@@ -1460,7 +1177,7 @@
         
         # available only for vector map layers
         try:
-            maptype = self.current.maptree.type
+            maptype = self.curr_page.maptree.GetPyData(layer)[0]['maplayer'].type
         except:
             maptype = None
         
@@ -1472,15 +1189,15 @@
                           style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
             return
         
-
-        dcmd = self.current.maptree.cmd
+        if not self.curr_page.maptree.GetPyData(layer)[0]:
+            return
+        dcmd = self.curr_page.maptree.GetPyData(layer)[0]['cmd']
         if not dcmd:
             return
         
         busy = wx.BusyInfo(message=_("Please wait, loading attribute data..."),
                            parent=self)
         wx.Yield()
-     
         
         dbmanager = dbm.AttributeManager(parent=self, id=wx.ID_ANY,
                                          size=wx.Size(500, 300),
@@ -1498,7 +1215,7 @@
         """!Create new layer tree and map display instance"""
         self.NewDisplay()
 
-    def NewDisplay(self):
+    def NewDisplay(self, show=True):
         """!Create new layer tree, which will
         create an associated map display frame
 
@@ -1507,12 +1224,7 @@
         @return reference to mapdisplay intance
         """
         Debug.msg(1, "GMFrame.NewDisplay(): idx=%d" % self.disp_idx)
-
-        #wx.MessageBox(parent=self,
-        #              message=_("This part is under development. New display does not work when you change location and mapset"),
-         #             caption=_("Data Catalog"),
-         #             style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
-
+        
         # make a new page in the bookcontrol for the layer tree (on page 0 of the notebook)
 
         self.disp_idx = self.disp_idx + 1
@@ -1529,85 +1241,27 @@
         self.page = MapFrame(parent=self.notebook, id=wx.ID_ANY, Map=render.Map(),  size=globalvar.MAP_WINDOW_SIZE,frame=self)
         self.notebook.InsertPage(self.disp_idx,self.page, text="Display "+ str(self.disp_idx), select = True)
 
-        #self.current = self.notebook.GetCurrentPage()
-        #self.notebook.SetSelection(0)
 
-
-        
-
     # toolBar button handlers
     def OnAddRaster(self, event):
         """!Add raster map layer"""
-        #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)
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show=False)
         
-        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.current.maptree.AssignImageList(il)
-
-        
         self.AddRaster(event)
         
     def OnAddRasterMisc(self, event):
         """!Add raster menu"""
         # start new map display if no display is available
-        if not self.current:
-            self.NewDisplay()
+        if not self.curr_page:
+            self.NewDisplay(show=False)
 
         point = wx.GetMousePosition()
         rastmenu = wx.Menu()
 
         # add items to the menu
-        if self.current.maptree.mapdisplay.toolbars['nviz']:
+        if self.curr_page.maptree.mapdisplay.toolbars['nviz']:
             addrast3d = wx.MenuItem(rastmenu, -1, Icons ["addrast3d"].GetLabel())
             addrast3d.SetBitmap(Icons["addrast3d"].GetBitmap (self.iconsize))
             rastmenu.AppendItem(addrast3d)
@@ -1644,21 +1298,21 @@
         rastmenu.Destroy()
         
         # show map display
-        #self.curr_page.maptree.mapdisplay.Show()
+        self.curr_page.maptree.mapdisplay.Show()
 
     def OnAddVector(self, event):
         """!Add vector map layer"""
         # start new map display if no display is available
-        if not self.current:
-            self.NewDisplay()
+        if not self.curr_page:
+            self.NewDisplay(show=False)
         
         self.AddVector(event)
         
     def OnAddVectorMisc(self, event):
         """!Add vector menu"""
         # start new map display if no display is available
-        if not self.current:
-            self.NewDisplay()
+        if not self.curr_page:
+            self.NewDisplay(show=False)
 
         point = wx.GetMousePosition()
         vectmenu = wx.Menu()
@@ -1679,13 +1333,13 @@
         vectmenu.Destroy()
 
         # show map display
-        #self.curr_page.maptree.mapdisplay.Show()
+        self.curr_page.maptree.mapdisplay.Show()
 
     def OnAddOverlay(self, event):
-        """!Add overlay menu""" 
+        """!Add decoration overlay menu""" 
         # start new map display if no display is available
-        if not self.curent:
-            self.NewDisplay()
+        if not self.curr_page:
+            self.NewDisplay(show=False)
 
         point = wx.GetMousePosition()
         ovlmenu = wx.Menu()
@@ -1719,126 +1373,116 @@
         self.curr_page.maptree.mapdisplay.Show()
 
     def AddRaster(self, event):
-        if not self.current:
-            self.NewDisplay()
-            
-        #cmd = ['d.rast']
-        #menuform.GUI().ParseCommand(cmd,parentframe=self)
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('raster')
 
-        #self.current.maptree.AddLayer('raster') 
-        dlg =     AddLayer(parent=self, title = "Add Raster")
-        dlg.ShowModal()
-
-
     def AddRaster3d(self, event):
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('3d-raster')
 
-        self.current.maptree.AddLayer('3d-raster')
-
     def AddRGB(self, event):
         """!Add RGB layer"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('rgb')
 
-        self.current.maptree.AddLayer('rgb')
-
     def AddHIS(self, event):
         """!Add HIS layer"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('his')
 
-        self.current.maptree.AddLayer('his')
-
     def AddShaded(self, event):
         """!Add shaded relief map layer"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('shaded')
 
-        self.current.maptree.AddLayer('shaded')
-
     def AddRastarrow(self, event):
         """!Add raster flow arrows map"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('rastarrow')
 
-        self.current.maptree.AddLayer('rastarrow')
-
     def AddRastnum(self, event):
         """!Add raster map with cell numbers"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('rastnum')
 
-        self.current.maptree.AddLayer('rastnum')
-
     def AddVector(self, event):
         """!Add vector layer"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('vector')
 
-        self.current.maptree.AddLayer('vector')
-
     def AddThemeMap(self, event):
         """!Add thematic map layer"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('thememap')
 
-        self.current.maptree.AddLayer('thememap')
-
     def AddThemeChart(self, event):
         """!Add thematic chart layer"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('themechart')
 
-        self.current.maptree.AddLayer('themechart')
-
     def OnAddCommand(self, event):
         """!Add command line layer"""
-        if not self.current:
-            self.NewDisplay()
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show=False)
 
-        self.current.maptree.AddLayer('command')
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('command')
 
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+
     def OnAddGroup(self, event):
         """!Add layer group"""
-        if not self.current:
-            self.NewDisplay()
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show=False)
 
-        self.current.maptree.AddLayer('group')
+        self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('group')
 
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+
     def AddGrid(self, event):
         """!Add layer grid"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('grid')
 
-        self.current.maptree.AddLayer('grid')
-
     def AddGeodesic(self, event):
         """!Add layer geodesic"""
+        #self.notebook.SetSelection(0)
         self.curr_page.maptree.AddLayer('geodesic')
 
     def AddRhumb(self, event):
         """!Add layer rhumb"""
-        if not self.current:
-            self.NewDisplay()
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('rhumb')
 
-        self.current.maptree.AddLayer('rhumb')
-
     def OnAddLabels(self, event):
         """!Add layer vector labels"""
-        if not self.current:
-            self.NewDisplay()
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show=False)
 
-        self.current.maptree.AddLayer('labels')
+        #self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('labels')
 
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+
     def OnDeleteLayer(self, event):
         """
         Delete selected map display layer in GIS Manager tree widget
         """
+        if not self.curr_page or not self.curr_page.maptree.layer_selected:
+            self.MsgNoLayerSelected()
+            return
+
         if UserSettings.Get(group='manager', key='askOnRemoveLayer', subkey='enabled'):
             layerName = ''
-            for item in self.current.maptree.GetSelections():
-                name = str(self.current.maptree.GetItemText(item))
+            for item in self.curr_page.maptree.GetSelections():
+                name = str(self.curr_page.maptree.GetItemText(item))
                 idx = name.find('(opacity')
                 if idx > -1:
                     layerName += '<' + name[:idx].strip(' ') + '>,\n'
@@ -1863,87 +1507,98 @@
 
             dlg.Destroy()
 
-        for layer in self.current.maptree.GetSelections():
-            self.current.maptree.Delete(layer) 
-
-
-
-        item = self.current.maptree.item
-        try:
-            self.current.maptree.item.properties.Close(True)
-        except:
-            pass
-
-        #if item != self.current.maptree.root:
-           # Debug.msg (3, "LayerTree.OnDeleteLayer(): name=%s" % \
-            #               (self.current.maptree.GetItemText(item)))
-       # else:
-         #   self.current.maptree.root = None
-
-        # unselect item
-        self.current.maptree.Unselect()
-        self.current.maptree.layer_selected = None
-
-        #try:
-       # if self.current.maptree.GetPyData(item)[0]['type'] != 'group':
-        nb =        self.notebook.GetCurrentPage()
-        #print nb.maptree
-        index = self.notebook.GetSelection()
-        try:
-            nb.Map.DeleteLayer( self.ltree.layer[index])
-            nb.maptree.layer.remove(self.ltree.layer[index])
-        except:
-            pass
+        for layer in self.curr_page.maptree.GetSelections():
+            if self.curr_page.maptree.GetPyData(layer)[0]['type'] == 'group':
+                self.curr_page.maptree.DeleteChildren(layer)
+            self.curr_page.maptree.Delete(layer)
         
-        #except:
-         #   pass
-
-        # redraw map if auto-rendering is enabled
-        self.current.maptree.rerender = True
-        self.current.maptree.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)))
-
-        #self.current.Map.UpdateMap(render=True)
-
+    def OnKeyDown(self, event):
+        """!Key pressed"""
+        kc = event.GetKeyCode()
         
-    def OnKey(self, event):
-        """!Check hotkey"""
+        if event.ControlDown():
+            if kc == wx.WXK_TAB:
+                # switch layer list / command output
+                if self.notebook.GetSelection() == 0:
+                    self.notebook.SetSelection(1)
+                else:
+                    self.notebook.SetSelection(0)
+        
         try:
-            kc = chr(event.GetKeyCode())
+            ckc = chr(kc)
         except ValueError:
             event.Skip()
             return
         
-        if event.AltDown():
+        if event.CtrlDown():
             if kc == 'R':
                 self.OnAddRaster(None)
             elif kc == 'V':
                 self.OnAddVector(None)
         
         event.Skip()
+
+    def OnQuit(self, event):
+        """!Quit GRASS session (wxGUI and shell)"""
+        # quit wxGUI session
+        self.OnCloseWindow(event)
+
+        # quit GRASS shell
+        try:
+            pid = int(os.environ['GIS_LOCK'])
+        except (KeyError, ValueError):
+            sys.stderr.write('\n')
+            sys.stderr.write(_("WARNING: Unable to quit GRASS, uknown GIS_LOCK"))
+            return
         
+        os.kill(pid, signal.SIGQUIT)
+        
     def OnCloseWindow(self, event):
         """!Cleanup when wxGUI is quit"""
-        count = self.notebook.GetPageCount()
-        index = 0
-        while index < count:
-            self.current = self.notebook.GetPage(index)
-            #self.current.Map.Clean()
-            index = index+1
+        if not self.curr_page:
+            self._auimgr.UnInit()
+            self.Destroy()
+            return
+        
+        maptree = self.curr_page.maptree
+        if self.workspaceChanged and \
+                UserSettings.Get(group='manager', key='askOnQuit', subkey='enabled'):
+            if self.workspaceFile:
+                message = _("Do you want to save changes in the workspace?")
+            else:
+                message = _("Do you want to store current settings "
+                            "to workspace file?")
+            
+            # ask user to save current settings
+            if maptree.GetCount() > 0:
+                dlg = wx.MessageDialog(self,
+                                       message=message,
+                                       caption=_("Quit GRASS GUI"),
+                                       style=wx.YES_NO | wx.YES_DEFAULT |
+                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
+                ret = dlg.ShowModal()
+                if ret == wx.ID_YES:
+                    if not self.workspaceFile:
+                        self.OnWorkspaceSaveAs()
+                    else:
+                        self.SaveToWorkspaceFile(self.workspaceFile)
+                elif ret == wx.ID_CANCEL:
+                    event.Veto()
+                    dlg.Destroy()
+                    return
+                dlg.Destroy()
+        
+        # don't ask any more...
+        UserSettings.Set(group = 'manager', key = 'askOnQuit', subkey = 'enabled',
+                         value = False)
 
+        for page in range(self.notebook.GetPageCount()):
+            self.notebook.GetPage(0).maptree.mapdisplay.OnCloseWindow(event)
+
         self.notebook.DeleteAllPages()
+        
+        self._auimgr.UnInit()
         self.Destroy()
-
-
         
     def MsgNoLayerSelected(self):
         """!Show dialog message 'No layer selected'"""
@@ -1951,9 +1606,8 @@
                       message=_("No map layer selected. Operation cancelled."),
                       caption=_("Message"),
                       style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
-          
+    
 
-
     def OnMapsetChange(self,event):
         """
         Create the tree nodes based on selected location and mapset.
@@ -1961,8 +1615,7 @@
         """
        
         self.page = self.notebook.GetCurrentPage()
-        
-        self.page.maptree.AddTreeNodes(self.cmbLocation.GetValue(),self.cmbMapset.GetValue())	
+       
         self.gisrc['LOCATION_NAME'] = str(self.cmbLocation.GetValue())
         self.gisrc['MAPSET'] = str(self.cmbMapset.GetValue())
         self.update_grassrc(self.gisrc)

Modified: grass-addons/gui/wxpython/data_catalog/mapdisplay.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/mapdisplay.py	2010-06-17 20:18:34 UTC (rev 42585)
+++ grass-addons/gui/wxpython/data_catalog/mapdisplay.py	2010-06-19 03:33:21 UTC (rev 42586)
@@ -32,9 +32,9 @@
 import tempfile
 import copy
 import time
+import traceback
 
 
-
 gbase = os.getenv("GISBASE") 
 pypath = os.path.join(gbase,'etc','wxpython','gui_modules')
 sys.path.append(pypath)
@@ -46,7 +46,7 @@
 import wx.aui
 
 
-try:
+try: 
     import subprocess
 except:
     CompatPath = os.path.join(globalvar.ETCWXDIR)
@@ -65,17 +65,29 @@
 import gselect
 import disp_print
 import gcmd
-import dbm
+
 import histogram
 import profile
 import globalvar
 import utils
 import gdialogs
 import goutput
+import units
 from grass.script import core as grass
 from debug import Debug
 from preferences import globalSettings as UserSettings
+import dbm
+grassversion = os.getenv("GRASS_VERSION")
+if grassversion == "6.4.0.svn":
+	import dbm_dialogs
 
+from units import ConvertValue as UnitsConvertValue
+from vdigit import GV_LINES as VDigit_Lines_Type
+from vdigit import VDigitCategoryDialog
+from vdigit import VDigitZBulkDialog
+from vdigit import VDigitDuplicatesDialog
+from vdigit import PseudoDC as VDigitPseudoDC
+
 from tcp4ossim import zoomto 
 
 from LayerTree import LayerTree
@@ -93,2153 +105,9 @@
 ###
 # for standalone app
 cmdfilename = None
-class Command(Thread):
-    """
-    Creates thread which will observe the command file and see, if
-    there is new command to be executed
-    """
-    def __init__ (self, parent, Map):
-        Thread.__init__(self)
+from mapdisp_window import BufferedWindow
 
-        global cmdfilename
 
-        self.parent = parent
-        self.map = Map
-        self.cmdfile = open(cmdfilename, "r")
-
-    def run(self):
-        """
-        Run this in thread
-        """
-        dispcmd = []
-        while 1:
-            self.parent.redraw = False
-            line = self.cmdfile.readline().strip()
-            if line == "quit":
-                break
-
-            if line:
-                try:
-                    Debug.msg (3, "Command.run(): cmd=%s" % (line))
-
-                    self.map.AddLayer(item=None, type="raster",
-                                      name='',
-                                      command=line,
-                                      l_opacity=1)
-
-                    self.parent.redraw =True
-
-                except Exception, e:
-                    print "Command Thread: ",e
-
-            time.sleep(0.1)
-
-        sys.exit()
-
-class MapWindow(object):
-    """
-    Abstract map window class
-
-    Parent for BufferedWindow class (2D display mode) and
-    GLWindow (3D display mode)
-    """
-    def __init__(self, parent, id=wx.ID_ANY,
-                 pos=wx.DefaultPosition,
-                 size=wx.DefaultSize,
-                 style=wx.NO_FULL_REPAINT_ON_RESIZE,
-                 Map=None, tree=None, gismgr=None):
-        self.parent = parent # MapFrame
-
-        #
-        # mouse attributes like currently pressed buttons, position on
-        # the screen, begin and end of dragging, and type of drawing
-        #
-        self.mouse = {
-            'l'    : False,
-            'r'    : False,
-            'm'    : False,
-            'begin': [0, 0], # screen coordinates
-            'end'  : [0, 0],
-            'use'  : "pointer",
-            'box'  : "point"
-            }
-        
-    def EraseMap(self):
-        """
-        Erase the canvas (virtual method)
-        """
-        pass
-
-    def UpdateMap(self):
-        """
-        Updates the canvas anytime there is a change to the
-        underlaying images or to the geometry of the canvas.
-        """
-        pass
-
-    def OnLeftDown(self, event):
-        pass
-
-    def OnLeftUp(self, event):
-        pass
-
-    def OnMouseMotion(self, event):
-        pass
-
-    def OnZoomToMap(self, event):
-        pass
-
-    def OnZoomToRaster(self, event):
-        pass
-
-    def GetSelectedLayer(self, type = 'layer', multi = False):
-        """
-        Get selected layer from layer tree
-
-        @param type 'item' / 'layer' / 'nviz'
-        @param multi return first selected layer or all
-        
-        @return layer / map layer properties / nviz properties
-        @return None / [] on failure
-        """
-        ret = []
-        if not self.tree or \
-                not self.tree.GetSelection():
-            if multi:
-                return []
-            else:
-                return None
-        
-        if multi and \
-                type == 'item':
-            return self.tree.GetSelections()
-        
-        for item in self.tree.GetSelections():
-            if not item.IsChecked():
-                if multi:
-                    continue
-                else:
-                    return None
-
-            if type == 'item': # -> multi = False
-                return item
-        
-            try:
-                if type == 'nviz':
-                    layer = self.tree.GetPyData(item)[0]['nviz']
-                else:
-                    layer = self.tree.GetPyData(item)[0]['maplayer']
-            except:
-                layer = None
-
-            if multi:
-                ret.append(layer)
-            else:
-                return layer
-            
-        return ret
-
-class BufferedWindow(MapWindow, wx.Window):
-    """
-    A Buffered window class.
-
-    When the drawing needs to change, you app needs to call the
-    UpdateMap() method. Since the drawing is stored in a bitmap, you
-    can also save the drawing to file by calling the
-    SaveToFile(self,file_name,file_type) method.
-    """
-
-    def __init__(self, parent, id,
-                 pos = wx.DefaultPosition,
-                 size = wx.DefaultSize,
-                 style=wx.NO_FULL_REPAINT_ON_RESIZE,
-                 Map=None, tree=None, gismgr=None):
-
-        MapWindow.__init__(self, parent, id, pos, size, style,
-                           Map, tree, gismgr)
-        wx.Window.__init__(self, parent, id, pos, size, style)
-
-        self.Map = Map
-        self.tree = tree
-        self.gismanager = gismgr
-
-        mapframe= self.GetParent()
-        notebook=mapframe.GetParent()
-        self.gframe=notebook.GetParent()
-   
-
-        #
-        # Flags
-        #
-        self.resize = False # indicates whether or not a resize event has taken place
-        self.dragimg = None # initialize variable for map panning
-        self.flag = False
-
-        #
-        # Variable for drawing on DC
-        #
-        self.pen = None      # pen for drawing zoom boxes, etc.
-        self.polypen = None  # pen for drawing polylines (measurements, profiles, etc)
-        # List of wx.Point tuples defining a polyline (geographical coordinates)
-        self.polycoords = []
-        # ID of rubber band line
-        self.lineid = None
-        # ID of poly line resulting from cumulative rubber band lines (e.g. measurement)
-        self.plineid = None
-        
-        #
-        # Event bindings
-        #
-        self.Bind(wx.EVT_PAINT,        self.OnPaint)
-        self.Bind(wx.EVT_SIZE,         self.OnSize)
-        self.Bind(wx.EVT_IDLE,         self.OnIdle)
-        self.Bind(wx.EVT_MOTION,       self.MouseActions)
-        self.Bind(wx.EVT_MOUSE_EVENTS, self.MouseActions)
-        self.processMouse = True
-        
-        #
-        # Render output objects
-        #
-        self.mapfile = None   # image file to be rendered
-        self.img = ""         # wx.Image object (self.mapfile)
-        # used in digitization tool (do not redraw vector map)
-        self.imgVectorMap = None
-        # decoration overlays
-        self.overlays = {}
-        # images and their PseudoDC ID's for painting and dragging
-        self.imagedict = {}   
-        self.select = {}      # selecting/unselecting decorations for dragging
-        self.textdict = {}    # text, font, and color indexed by id
-        self.currtxtid = None # PseudoDC id for currently selected text
-
-        #
-        # Zoom objects
-        #
-        self.zoomhistory = [] # list of past zoom extents
-        self.currzoom = 0 # current set of extents in zoom history being used
-        
-        self.zoomtype = 1   # 1 zoom in, 0 no zoom, -1 zoom out
-        self.hitradius = 10 # distance for selecting map decorations
-        self.dialogOffset = 5 # offset for dialog (e.g. DisplayAttributesDialog)
-
-        # OnSize called to make sure the buffer is initialized.
-        # This might result in OnSize getting called twice on some
-        # platforms at initialization, but little harm done.
-        ### self.OnSize(None)
-
-        # create PseudoDC used for background map, map decorations like scales and legends
-        self.pdc = wx.PseudoDC()
-        # used for digitization tool
-        self.pdcVector = None
-        # decorations (region box, etc.)
-        self.pdcDec = wx.PseudoDC()
-        # pseudoDC for temporal objects (select box, measurement tool, etc.)
-        self.pdcTmp = wx.PseudoDC()
-        # redraw all pdc's, pdcTmp layer is redrawn always (speed issue)
-        self.redrawAll = True
-
-        # will store an off screen empty bitmap for saving to file
-        self._buffer = ''
-
-        self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None)
-
-        # vars for handling mouse clicks
-        self.dragid   = -1
-        self.lastpos  = (0, 0)
-
-    def Draw(self, pdc, img=None, drawid=None, pdctype='image', coords=[0, 0, 0, 0]):
-        """
-        Draws map and overlay decorations
-        """
-
-        if drawid == None:
-            if pdctype == 'image' and img:
-                drawid = self.imagedict[img]
-            elif pdctype == 'clear':
-                drawid == None
-            else:
-                drawid = wx.NewId()
-        
-        if img and pdctype == 'image':
-            # self.imagedict[img]['coords'] = coords
-            self.select[self.imagedict[img]['id']] = False # ?
-
-        pdc.BeginDrawing()
-
-        if drawid != 99:
-            bg = wx.TRANSPARENT_BRUSH
-        else:
-            bg = wx.Brush(self.GetBackgroundColour())
-
-        pdc.SetBackground(bg)
-        ### pdc.Clear()
-
-        Debug.msg (5, "BufferedWindow.Draw(): id=%s, pdctype=%s, coord=%s" % \
-                       (drawid, pdctype, coords))
-
-        # set PseudoDC id
-        if drawid is not None:
-            pdc.SetId(drawid)
-        
-        if pdctype == 'clear': # erase the display
-            bg = wx.WHITE_BRUSH
-            # bg = wx.Brush(self.GetBackgroundColour())
-            pdc.SetBackground(bg)
-            pdc.RemoveAll()
-            pdc.Clear()
-            pdc.EndDrawing()
-            
-            self.Refresh()
-            return
-
-        if pdctype == 'image': # draw selected image
-            bitmap = wx.BitmapFromImage(img)
-            w,h = bitmap.GetSize()
-            pdc.DrawBitmap(bitmap, coords[0], coords[1], True) # draw the composite map
-            pdc.SetIdBounds(drawid, (coords[0],coords[1], w, h))
-
-        elif pdctype == 'box': # draw a box on top of the map
-            if self.pen:
-                pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT))
-                pdc.SetPen(self.pen)
-                x2 = max(coords[0],coords[2])
-                x1 = min(coords[0],coords[2])
-                y2 = max(coords[1],coords[3])
-                y1 = min(coords[1],coords[3])
-                rwidth = x2-x1
-                rheight = y2-y1
-                rect = wx.Rect(x1,y1,rwidth,rheight)
-                pdc.DrawRectangleRect(rect)
-                pdc.SetIdBounds(drawid,rect)
-                # self.ovlcoords[drawid] = coords
-
-        elif pdctype == 'line': # draw a line on top of the map
-            if self.pen:
-                pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT))
-                pdc.SetPen(self.pen)
-                pdc.DrawLine(coords[0], coords[1], coords[2], coords[3])
-                pdc.SetIdBounds(drawid,(coords[0], coords[1], coords[2], coords[3]))
-                # self.ovlcoords[drawid] = coords
-
-        elif pdctype == 'polyline': # draw a polyline on top of the map
-            if self.polypen:
-                pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT))
-                pdc.SetPen(self.polypen)
-                pdc.DrawLines(coords)
-
-                # get bounding rectangle for polyline
-                xlist = []
-                ylist = []
-                if len(coords) > 0:
-                    for point in coords:
-                        x,y = point
-                        xlist.append(x)
-                        ylist.append(y)
-                    x1=min(xlist)
-                    x2=max(xlist)
-                    y1=min(ylist)
-                    y2=max(ylist)
-                    pdc.SetIdBounds(drawid,(x1,y1,x2,y2))
-                    # self.ovlcoords[drawid] = [x1,y1,x2,y2]
-
-        elif pdctype == 'point': # draw point
-            if self.pen:
-                pdc.SetPen(self.pen)
-                pdc.DrawPoint(coords[0], coords[1])
-                coordsBound = (coords[0] - 5,
-                               coords[1] - 5,
-                               coords[0] + 5,
-                               coords[1] + 5)
-                pdc.SetIdBounds(drawid, coordsBound)
-                # self.ovlcoords[drawid] = coords
-
-        elif pdctype == 'text': # draw text on top of map
-            if not img['active']:
-                return #only draw active text
-            if img.has_key('rotation'):
-                rotation = float(img['rotation'])
-            else:
-                rotation = 0.0
-            w, h = self.GetFullTextExtent(img['text'])[0:2]
-            pdc.SetFont(img['font'])
-            pdc.SetTextForeground(img['color'])
-            coords, w, h = self.TextBounds(img)
-            if rotation == 0:
-                pdc.DrawText(img['text'], coords[0], coords[1])
-            else:
-                pdc.DrawRotatedText(img['text'], coords[0], coords[1], rotation)
-            pdc.SetIdBounds(drawid, (coords[0], coords[1], w, h))
-            
-        pdc.EndDrawing()
-        
-        self.Refresh()
-        
-        return drawid
-
-    def TextBounds(self, textinfo):
-        """
-        Return text boundary data
-
-        @param textinfo text metadata (text, font, color, rotation)
-        @param coords reference point
-        """
-        if textinfo.has_key('rotation'):
-            rotation = float(textinfo['rotation'])
-        else:
-            rotation = 0.0
-        
-        coords = textinfo['coords']
-        
-        Debug.msg (4, "BufferedWindow.TextBounds(): text=%s, rotation=%f" % \
-                   (textinfo['text'], rotation))
-
-        self.Update()
-        ### self.Refresh()
-
-        self.SetFont(textinfo['font'])
-
-        w, h = self.GetTextExtent(textinfo['text'])
-
-        if rotation == 0:
-            coords[2], coords[3] = coords[0] + w, coords[1] + h
-            return coords, w, h
-
-        boxh = math.fabs(math.sin(math.radians(rotation)) * w) + h
-        boxw = math.fabs(math.cos(math.radians(rotation)) * w) + h
-        coords[2] = coords[0] + boxw
-        coords[3] = coords[1] + boxh
-        
-        return coords, boxw, boxh
-
-    def OnPaint(self, event):
-        """
-        Draw PseudoDC's to buffered paint DC
-
-        self.pdc for background and decorations
-        self.pdcVector for vector map which is edited
-        self.pdcTmp for temporaly drawn objects (self.polycoords)
-
-        If self.redrawAll is False on self.pdcTmp content is re-drawn
-        """
-        Debug.msg(4, "BufferedWindow.OnPaint(): redrawAll=%s" % self.redrawAll)
-        
-        dc = wx.BufferedPaintDC(self, self.buffer)
-        
-        ### dc.SetBackground(wx.Brush("White"))
-        dc.Clear()
-
-        # use PrepareDC to set position correctly
-        self.PrepareDC(dc)
-
-        # create a clipping rect from our position and size
-        # and update region
-        rgn = self.GetUpdateRegion().GetBox()
-        dc.SetClippingRect(rgn)
-
-        switchDraw = False
-        if self.redrawAll is None:
-            self.redrawAll = True
-            switchDraw = True
-        
-        if self.redrawAll: # redraw pdc and pdcVector
-            # draw to the dc using the calculated clipping rect
-            self.pdc.DrawToDCClipped(dc, rgn)
-
-            # draw vector map layer
-            if self.pdcVector:
-                # decorate with GDDC (transparency)
-                try:
-                    gcdc = wx.GCDC(dc)
-                    self.pdcVector.DrawToDCClipped(gcdc, rgn)
-                except NotImplementedError, e:
-                    print >> sys.stderr, e
-                    self.pdcVector.DrawToDCClipped(dc, rgn)
-
-            self.bufferLast = None
-        else: # do not redraw pdc and pdcVector
-            if self.bufferLast is None:
-                # draw to the dc
-                self.pdc.DrawToDC(dc)
-
-                if self.pdcVector:
-                    # decorate with GDDC (transparency)
-                    try:
-                        gcdc = wx.GCDC(dc)
-                        self.pdcVector.DrawToDC(gcdc)
-                    except NotImplementedError, e:
-                        print >> sys.stderr, e
-                        self.pdcVector.DrawToDC(dc)
-                        
-                # store buffered image
-                # self.bufferLast = wx.BitmapFromImage(self.buffer.ConvertToImage())
-                self.bufferLast = dc.GetAsBitmap(wx.Rect(0, 0, self.Map.width, self.Map.height))
-
-            pdcLast = wx.PseudoDC()
-            pdcLast.DrawBitmap(bmp=self.bufferLast, x=0, y=0)
-            pdcLast.DrawToDC(dc)
-
-        # draw decorations (e.g. region box)
-        try:
-            gcdc = wx.GCDC(dc)
-            self.pdcDec.DrawToDC(gcdc)
-        except NotImplementedError, e:
-            print >> sys.stderr, e
-            self.pdcDec.DrawToDC(dc)
-
-        # draw temporary object on the foreground
-        ### self.pdcTmp.DrawToDCClipped(dc, rgn)
-        self.pdcTmp.DrawToDC(dc)
-
-        if switchDraw:
-            self.redrawAll = False
-                
-    def OnSize(self, event):
-        """
-        Scale map image so that it is
-        the same size as the Window
-        """
-        Debug.msg(3, "BufferedWindow.OnSize():")
-
-        # set size of the input image
-        self.Map.ChangeMapSize(self.GetClientSize())
-        # align extent based on center point and display resolution
-        # this causes that image is not resized when display windows is resized
-        # self.Map.AlignExtentFromDisplay()
-
-        # Make new off screen bitmap: this bitmap will always have the
-        # current drawing in it, so it can be used to save the image to
-        # a file, or whatever.
-        self.buffer = wx.EmptyBitmap(max(1, self.Map.width), max(1, self.Map.height))
-
-        # get the image to be rendered
-        self.img = self.GetImage()
-
-        # update map display
-        if self.img and self.Map.width + self.Map.height > 0: # scale image during resize
-            self.img = self.img.Scale(self.Map.width, self.Map.height)
-            if len(self.Map.GetListOfLayers()) > 0:
-                self.UpdateMap()
-
-        # re-render image on idle
-        self.resize = True
-
-        # reposition checkbox in statusbar
-        self.parent.StatusbarReposition()
-
-        # update statusbar
-        self.parent.StatusbarUpdate()
-
-    def OnIdle(self, event):
-        """
-        Only re-render a composite map image from GRASS during
-        idle time instead of multiple times during resizing.
-        """
-        if self.resize:
-            self.UpdateMap(render=True)
-
-        event.Skip()
-
-    def SaveToFile(self, FileName, FileType):
-        """
-        This draws the psuedo DC to a buffer that
-        can be saved to a file.
-        """
-        dc = wx.BufferedPaintDC(self, self.buffer)
-        self.pdc.DrawToDC(dc)
-        if self.pdcVector:
-            self.pdcVector.DrawToDC(dc)
-        self.buffer.SaveFile(FileName, FileType)
-
-    def GetOverlay(self):
-        """
-        Converts rendered overlay files to wx.Image
-
-        Updates self.imagedict
-
-        @return list of images
-        """
-        imgs = []
-        for overlay in self.Map.GetListOfLayers(l_type="overlay", l_active=True):
-            if os.path.isfile(overlay.mapfile) and os.path.getsize(overlay.mapfile):
-                img = wx.Image(overlay.mapfile, wx.BITMAP_TYPE_ANY)
-                self.imagedict[img] = { 'id' : overlay.id,
-                                        'layer' : overlay }
-                imgs.append(img)
-
-        return imgs
-
-    def GetImage(self):
-        """
-        Converts redered map files to wx.Image
-
-        Updates self.imagedict (id=99)
-
-        @return wx.Image instance (map composition)
-        """
-        imgId = 99
-        if self.Map.mapfile and os.path.isfile(self.Map.mapfile) and \
-                os.path.getsize(self.Map.mapfile):
-            img = wx.Image(self.Map.mapfile, wx.BITMAP_TYPE_ANY)
-        else:
-            img = None
-
-        self.imagedict[img] = { 'id': imgId }
-
-        return img
-
-    def UpdateMap(self, render=True, renderVector=True):
-        """
-        Updates the canvas anytime there is a change to the
-        underlaying images or to the geometry of the canvas.
-
-        @param render re-render map composition
-        @param renderVector re-render vector map layer enabled for editing (used for digitizer)
-        """
-        if self.flag == True:
-            self.flag = False
-            start = time.clock()
-
-
-            self.resize = False
-
-            if len(self.Map.GetListOfLayers()) == 0:
-                return False
-            
-            if self.img is None:
-                render = True
-
-            #
-            # initialize process bar (only on 'render')
-            #
-            if render is True or renderVector is True:
-                self.parent.onRenderGauge.Show()
-                if self.parent.onRenderGauge.GetRange() > 0:
-                    self.parent.onRenderGauge.SetValue(1)
-            
-            #
-            # render background image if needed
-            #
-            
-            # update layer dictionary if there has been a change in layers
-            if self.tree and self.tree.reorder == True:
-                self.tree.ReorderLayers()
-                
-            # reset flag for auto-rendering
-            if self.tree:
-                self.tree.rerender = False
-            
-            if render:
-                # update display size
-                self.Map.ChangeMapSize(self.GetClientSize())
-                if self.parent.compResolution.IsChecked():
-                    # use computation region resolution for rendering
-                    windres = True
-                else:
-                    windres = False
-                self.mapfile = self.Map.Render(force=True, mapWindow=self.parent,
-                                               windres=windres)
-            else:
-                self.mapfile = self.Map.Render(force=False, mapWindow=self.parent)
-            
-            self.img = self.GetImage() # id=99
-                
-            #
-            # clear pseudoDcs
-            #
-            for pdc in (self.pdc,
-                        self.pdcDec,
-                        self.pdcTmp):
-                pdc.Clear()
-                pdc.RemoveAll()
-            
-            #
-            # draw background map image to PseudoDC
-            #
-            if not self.img:
-                self.Draw(self.pdc, pdctype='clear')
-            else:
-                try:
-                    id = self.imagedict[self.img]['id']
-                except:
-                    return False
-
-                self.Draw(self.pdc, self.img, drawid=id)
-
-            #
-            # render vector map layer
-            #
-            digitToolbar = self.parent.toolbars['vdigit']
-            if renderVector and digitToolbar and \
-                    digitToolbar.GetLayer():
-                # set region
-                self.parent.digit.driver.UpdateRegion()
-                # re-calculate threshold for digitization tool
-                self.parent.digit.driver.GetThreshold()
-                # draw map
-                self.pdcVector.Clear()
-                self.pdcVector.RemoveAll()
-                try:
-                    item = self.tree.FindItemByData('maplayer', digitToolbar.GetLayer())
-                except TypeError:
-                    item = None
-                
-                if item and self.tree.IsItemChecked(item):
-                    self.parent.digit.driver.DrawMap()
-
-                # translate tmp objects (pointer position)
-                if digitToolbar.GetAction() == 'moveLine':
-                    if  hasattr(self, "vdigitMove") and \
-                            self.vdigitMove.has_key('beginDiff'):
-                        # move line
-                        for id in self.vdigitMove['id']:
-                            # print self.pdcTmp.GetIdBounds(id)
-                            self.pdcTmp.TranslateId(id,
-                                                    self.vdigitMove['beginDiff'][0],
-                                                    self.vdigitMove['beginDiff'][1])
-                        del self.vdigitMove['beginDiff']
-            
-            #
-            # render overlays
-            #
-            for img in self.GetOverlay():
-                # draw any active and defined overlays
-                if self.imagedict[img]['layer'].IsActive():
-                    id = self.imagedict[img]['id']
-                    self.Draw(self.pdc, img=img, drawid=id,
-                              pdctype=self.overlays[id]['pdcType'], coords=self.overlays[id]['coords'])
-
-            for id in self.textdict.keys():
-                self.Draw(self.pdc, img=self.textdict[id], drawid=id,
-                          pdctype='text', coords=[10, 10, 10, 10])
-
-            # optionally draw computational extent box
-            self.DrawCompRegionExtent()
-
-            #
-            # redraw pdcTmp if needed
-            #
-            if len(self.polycoords) > 0:
-                self.DrawLines(self.pdcTmp)
-
-
-            if self.gframe.georectifying:
-                # -> georectifier (redraw GCPs)
-                if self.parent.toolbars['georect']:
-                    coordtype = 'gcpcoord'
-                else:
-                    coordtype = 'mapcoord'
-                self.gframe.georectifying.DrawGCP(coordtype)
-                
-            # 
-            # clear measurement
-            #
-            
-            if self.mouse["use"] == "measure":
-                self.ClearLines(pdc=self.pdcTmp)
-                self.polycoords = []
-                self.mouse['use'] = 'pointer'
-                self.mouse['box'] = 'point'
-                self.mouse['end'] = [0, 0]
-                self.SetCursor(self.parent.cursors["default"])
-                
-            stop = time.clock()
-
-            #
-            # hide process bar
-            #
-            self.parent.onRenderGauge.Hide()
-
-            #
-            # update statusbar
-            #
-            ### self.Map.SetRegion()
-            self.parent.StatusbarUpdate()
-            if grass.find_file(name = 'MASK', element = 'cell')['name']:
-                # mask found
-                self.parent.maskInfo.SetLabel(_('MASK'))
-            else:
-                self.parent.maskInfo.SetLabel('')
-            
-            Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s -> time=%g" % \
-                       (render, renderVector, (stop-start)))
-            
-            return True
-
-    def DrawCompRegionExtent(self):
-        """
-        Draw computational region extent in the display
-        
-        Display region is drawn as a blue box inside the computational region,
-        computational region inside a display region as a red box).
-        """
-        if hasattr(self, "regionCoords"):
-            compReg = self.Map.GetRegion()
-            dispReg = self.Map.GetCurrentRegion()
-            reg = None
-            if self.IsInRegion(dispReg, compReg):
-                self.polypen = wx.Pen(colour=wx.Colour(0, 0, 255, 128), width=3, style=wx.SOLID)
-                reg = dispReg
-            else:
-                self.polypen = wx.Pen(colour=wx.Colour(255, 0, 0, 128),
-                                      width=3, style=wx.SOLID)
-                reg = compReg
-            
-            self.regionCoords = []
-            self.regionCoords.append((reg['w'], reg['n']))
-            self.regionCoords.append((reg['e'], reg['n']))
-            self.regionCoords.append((reg['e'], reg['s']))
-            self.regionCoords.append((reg['w'], reg['s']))
-            self.regionCoords.append((reg['w'], reg['n']))
-            # draw region extent
-            self.DrawLines(pdc=self.pdcDec, polycoords=self.regionCoords)
-
-    def IsInRegion(self, region, refRegion):
-        """
-        Test if 'region' is inside of 'refRegion'
-
-        @param region input region
-        @param refRegion reference region (e.g. computational region)
-
-        @return True if region is inside of refRegion
-        @return False 
-        """
-        if region['s'] >= refRegion['s'] and \
-                region['n'] <= refRegion['n'] and \
-                region['w'] >= refRegion['w'] and \
-                region['e'] <= refRegion['e']:
-            return True
-
-        return False
-
-    def EraseMap(self):
-        """
-        Erase the canvas
-        """
-        self.Draw(self.pdc, pdctype='clear')
-                  
-        if self.pdcVector:
-            self.Draw(self.pdcVector, pdctype='clear')
-        
-        self.Draw(self.pdcDec, pdctype='clear')
-        self.Draw(self.pdcTmp, pdctype='clear')
-        
-    def DragMap(self, moveto):
-        """
-        Drag the entire map image for panning.
-        """
-
-        dc = wx.BufferedDC(wx.ClientDC(self))
-        dc.SetBackground(wx.Brush("White"))
-        dc.Clear()
-
-        self.dragimg = wx.DragImage(self.buffer)
-        self.dragimg.BeginDrag((0, 0), self)
-        self.dragimg.GetImageRect(moveto)
-        self.dragimg.Move(moveto)
-
-        self.dragimg.DoDrawImage(dc, moveto)
-        self.dragimg.EndDrag()
-
-        return True
-
-    def DragItem(self, id, event):
-        """!
-        Drag an overlay decoration item
-        """
-        if id == 99 or id == '' or id == None: return
-        Debug.msg (5, "BufferedWindow.DragItem(): id=%d" % id)
-        x, y = self.lastpos
-        dx = event.GetX() - x
-        dy = event.GetY() - y
-        self.pdc.SetBackground(wx.Brush(self.GetBackgroundColour()))
-        r = self.pdc.GetIdBounds(id)
-        ### FIXME in vdigit/pseudodc.i
-        if type(r) is list:
-            r = wx.Rect(r[0], r[1], r[2], r[3])
-        if id > 100: # text dragging
-            rtop = (r[0],r[1]-r[3],r[2],r[3])
-            r = r.Union(rtop)
-            rleft = (r[0]-r[2],r[1],r[2],r[3])
-            r = r.Union(rleft)
-        self.pdc.TranslateId(id, dx, dy)
-
-        r2 = self.pdc.GetIdBounds(id)
-        if type(r2) is list:
-            r2 = wx.Rect(r[0], r[1], r[2], r[3])
-        if id > 100: # text
-            self.textdict[id]['coords'] = r2
-        r = r.Union(r2)
-        r.Inflate(4,4)
-        self.RefreshRect(r, False)
-        self.lastpos = (event.GetX(), event.GetY())
-                
-    def MouseDraw(self, pdc=None, begin=None, end=None):
-        """
-        Mouse box or line from 'begin' to 'end'
-
-        If not given from self.mouse['begin'] to self.mouse['end'].
-
-        """
-        self.redrawAll = False
-        
-        if not pdc:
-            return
-
-        if begin is None:
-            begin = self.mouse['begin']
-        if end is None:
-            end   = self.mouse['end']
-
-        Debug.msg (5, "BufferedWindow.MouseDraw(): use=%s, box=%s, begin=%f,%f, end=%f,%f" % \
-                       (self.mouse['use'], self.mouse['box'],
-                        begin[0], begin[1], end[0], end[1]))
-
-        if self.mouse['box'] == "box":
-            boxid = wx.ID_NEW
-            mousecoords = [begin[0], begin[1],
-                           end[0], end[1]]
-            r = pdc.GetIdBounds(boxid)
-            r.Inflate(4,4)
-            pdc.ClearId(boxid)
-            self.RefreshRect(r, False)
-            pdc.SetId(boxid)
-            self.Draw(pdc, drawid=boxid, pdctype='box', coords=mousecoords)
-        elif self.mouse['box'] == "line" or self.mouse['box'] == 'point':
-            self.lineid = wx.ID_NEW
-            mousecoords = [begin[0], begin[1], \
-                           end[0], end[1]]
-            x1=min(begin[0],end[0])
-            x2=max(begin[0],end[0])
-            y1=min(begin[1],end[1])
-            y2=max(begin[1],end[1])
-            r = wx.Rect(x1,y1,x2-x1,y2-y1)
-            r.Inflate(4,4)
-            try:
-                pdc.ClearId(self.lineid)
-            except:
-                pass
-            self.RefreshRect(r, False)
-            pdc.SetId(self.lineid)
-
-            self.Draw(pdc, drawid=self.lineid, pdctype='line', coords=mousecoords)
-
-    def DrawLines(self, pdc=None, polycoords=None):
-        """
-        Draw polyline in PseudoDC
-
-        Set self.pline to wx.NEW_ID + 1
-
-        polycoords - list of polyline vertices, geographical coordinates
-        (if not given, self.polycoords is used)
-
-        """
-        if not pdc:
-            pdc = self.pdcTmp
-
-        if not polycoords:
-            polycoords = self.polycoords
-        
-        if len(polycoords) > 0:
-            self.plineid = wx.ID_NEW + 1
-            # convert from EN to XY
-            coords = []
-            for p in polycoords:
-                coords.append(self.Cell2Pixel(p))
-
-            self.Draw(pdc, drawid=self.plineid, pdctype='polyline', coords=coords)
-            
-            Debug.msg (4, "BufferedWindow.DrawLines(): coords=%s, id=%s" % \
-                           (coords, self.plineid))
-
-            return self.plineid
-
-        return -1
-
-    def DrawCross(self, pdc, coords, size, rotation=0,
-                  text=None, textAlign='lr', textOffset=(5, 5)):
-        """Draw cross in PseudoDC
-
-        @todo implement rotation
-
-        @param pdc PseudoDC
-        @param coord center coordinates
-        @param rotation rotate symbol
-        @param text draw also text (text, font, color, rotation)
-        @param textAlign alignment (default 'lower-right')
-        @textOffset offset for text (from center point)
-        """
-        Debug.msg(4, "BufferedWindow.DrawCross(): pdc=%s, coords=%s, size=%d" % \
-                  (pdc, coords, size))
-        coordsCross = ((coords[0] - size, coords[1], coords[0] + size, coords[1]),
-                       (coords[0], coords[1] - size, coords[0], coords[1] + size))
-
-        self.lineid = wx.NewId()
-        for lineCoords in coordsCross:
-            self.Draw(pdc, drawid=self.lineid, pdctype='line', coords=lineCoords)
-
-        if not text:
-            return self.lineid
-
-        if textAlign == 'ul':
-            coord = [coords[0] - textOffset[0], coords[1] - textOffset[1], 0, 0]
-        elif textAlign == 'ur':
-            coord = [coords[0] + textOffset[0], coords[1] - textOffset[1], 0, 0]
-        elif textAlign == 'lr':
-            coord = [coords[0] + textOffset[0], coords[1] + textOffset[1], 0, 0]
-        else:
-            coord = [coords[0] - textOffset[0], coords[1] + textOffset[1], 0, 0]
-        
-        self.Draw(pdc, img=text,
-                  pdctype='text', coords=coord)
-
-        return self.lineid
-
-    def MouseActions(self, event):
-        """
-        Mouse motion and button click notifier
-        """
-        if not self.processMouse:
-            return
-        
-        ### if self.redrawAll is False:
-        ###    self.redrawAll = True
-        
-        # zoom with mouse wheel
-        if event.GetWheelRotation() != 0:
-            self.OnMouseWheel(event)
-            
-        # left mouse button pressed
-        elif event.LeftDown():
-            self.OnLeftDown(event)
-
-        # left mouse button released
-        elif event.LeftUp():
-            self.OnLeftUp(event)
-
-        # dragging
-        elif event.Dragging():
-            self.OnDragging(event)
-
-        # double click
-        elif event.ButtonDClick():
-            self.OnButtonDClick(event)
-
-        # middle mouse button pressed
-        elif event.MiddleDown():
-            self.OnMiddleDown(event)
-
-        # right mouse button pressed
-        elif event.RightDown():
-            self.OnRightDown(event)
-
-        # right mouse button released
-        elif event.RightUp():
-            self.OnRightUp(event)
-
-        elif event.Moving():
-            self.OnMouseMoving(event)
-
-#        event.Skip()
-        
-    def OnMouseWheel(self, event):
-        """
-        Mouse wheel moved
-        """
-        self.processMouse = False
-        current  = event.GetPositionTuple()[:]
-        wheel = event.GetWheelRotation()
-        Debug.msg (5, "BufferedWindow.MouseAction(): wheel=%d" % wheel)
-        # zoom 1/2 of the screen, centered to current mouse position (TODO: settings)
-        begin = (current[0] - self.Map.width / 4,
-                 current[1] - self.Map.height / 4)
-        end   = (current[0] + self.Map.width / 4,
-                 current[1] + self.Map.height / 4)
-
-        if wheel > 0:
-            zoomtype = 1
-        else:
-            zoomtype = -1
-
-        # zoom
-        self.Zoom(begin, end, zoomtype)
-
-        # redraw map
-        self.UpdateMap()
-
-        ### self.OnPaint(None)
-
-        # update statusbar
-        self.parent.StatusbarUpdate()
-
-        self.Refresh()
-        self.processMouse = True
-#        event.Skip()
-
-    def OnDragging(self, event):
-        """
-        Mouse dragging with left button down
-        """
-        Debug.msg (5, "BufferedWindow.MouseAction(): Dragging")
-        current  = event.GetPositionTuple()[:]
-        previous = self.mouse['begin']
-        move = (current[0] - previous[0],
-                current[1] - previous[1])
-
-        digitToolbar = self.parent.toolbars['vdigit']
-
-        # dragging or drawing box with left button
-        if self.mouse['use'] == 'pan':
-            self.DragMap(move)
-
-        # dragging decoration overlay item
-        elif (self.mouse['use'] == 'pointer' and 
-                not digitToolbar and 
-                self.dragid != None):
-            self.DragItem(self.dragid, event)
-
-        # dragging anything else - rubber band box or line
-        else:
-            if (self.mouse['use'] == 'pointer' and 
-                not digitToolbar): return
-            self.mouse['end'] = event.GetPositionTuple()[:]
-            digitClass = self.parent.digit
-            if (event.LeftIsDown() and 
-                not (digitToolbar and 
-                    digitToolbar.GetAction() in ("moveLine",) and 
-                    digitClass.driver.GetSelected() > 0)):
-                # draw box only when left mouse button is pressed
-                self.MouseDraw(pdc=self.pdcTmp)
-      
-#        event.Skip()
-
-    def OnLeftDown(self, event):
-        """!
-        Left mouse button pressed
-        """
-        Debug.msg (5, "BufferedWindow.OnLeftDown(): use=%s" % \
-                   self.mouse["use"])
-
-        self.mouse['begin'] = event.GetPositionTuple()[:]
-        
-        if self.mouse["use"] in ["measure", "profile"]:
-            # measure or profile
-            if len(self.polycoords) == 0:
-                self.mouse['end'] = self.mouse['begin']
-                self.polycoords.append(self.Pixel2Cell(self.mouse['begin']))
-                self.ClearLines(pdc=self.pdcTmp)
-            else:
-                self.mouse['begin'] = self.mouse['end']
-        elif self.mouse['use'] == 'zoom':
-            pass
-
-        #
-        # vector digizer
-        #
-        elif self.mouse["use"] == "pointer" and \
-                self.parent.toolbars['vdigit']:
-            digitToolbar = self.parent.toolbars['vdigit']
-            digitClass   = self.parent.digit
-            
-            try:
-                mapLayer = digitToolbar.GetLayer().GetName()
-            except:
-                wx.MessageBox(parent=self,
-                              message=_("No vector map selected for editing."),
-                              caption=_("Vector digitizer"),
-                              style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
-                event.Skip()
-                return
-            
-            if digitToolbar.GetAction() not in ("moveVertex",
-                                                "addVertex",
-                                                "removeVertex",
-                                                "editLine"):
-                # set pen
-                self.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
-                self.polypen = wx.Pen(colour='dark green', width=2, style=wx.SOLID)
-
-            if digitToolbar.GetAction() in ("addVertex",
-                                            "removeVertex",
-                                            "splitLines"):
-                # unselect
-                digitClass.driver.SetSelected([])
-
-            if digitToolbar.GetAction() == "addLine":
-                self.OnLeftDownVDigitAddLine(event)
-            
-            elif digitToolbar.GetAction() == "editLine" and \
-                    hasattr(self, "vdigitMove"):
-                self.OnLeftDownVDigitEditLine(event)
-
-            elif digitToolbar.GetAction() in ("moveLine", 
-                                              "moveVertex",
-                                              "editLine") and \
-                    not hasattr(self, "vdigitMove"):
-                self.OnLeftDownVDigitMoveLine(event)
-
-            elif digitToolbar.GetAction() in ("displayAttrs"
-                                              "displayCats"):
-                self.OnLeftDownVDigitDisplayCA(event)
-            
-            elif digitToolbar.GetAction() in ("copyCats",
-                                              "copyAttrs"):
-                self.OnLeftDownVDigitCopyCA(event)
-            
-            elif digitToolbar.GetAction() == "copyLine":
-                self.OnLeftDownVDigitCopyLine(event)
-            
-            elif digitToolbar.GetAction() == "zbulkLine":
-                self.OnLeftDownVDigitBulkLine(event)
-            
-        elif self.mouse['use'] == 'pointer':
-            # get decoration or text id
-            self.idlist = []
-            self.dragid = ''
-            self.lastpos = self.mouse['begin']
-            idlist = self.pdc.FindObjects(self.lastpos[0], self.lastpos[1],
-                                          self.hitradius)
-            if 99 in idlist:
-                idlist.remove(99)                             
-            if idlist != []:
-                self.dragid = idlist[0] #drag whatever is on top
-        else:
-            pass
-
-        event.Skip()
-
-    def OnLeftUp(self, event):
-        """!
-        Left mouse button released
-        """
-        Debug.msg (5, "BufferedWindow.OnLeftUp(): use=%s" % \
-                       self.mouse["use"])
-        
-        self.mouse['end'] = event.GetPositionTuple()[:]
-        
-        if self.mouse['use'] in ["zoom", "pan"]:
-            # set region in zoom or pan
-            begin = self.mouse['begin']
-            end = self.mouse['end']
-            
-            if self.mouse['use'] == 'zoom':
-                # set region for click (zero-width box)
-                if begin[0] - end[0] == 0 or \
-                        begin[1] - end[1] == 0:
-                    # zoom 1/2 of the screen (TODO: settings)
-                    begin = (end[0] - self.Map.width / 4,
-                             end[1] - self.Map.height / 4)
-                    end   = (end[0] + self.Map.width / 4,
-                             end[1] + self.Map.height / 4)
-            
-            self.Zoom(begin, end, self.zoomtype)
-
-            # redraw map
-            self.flag=True
-            self.UpdateMap(render=True)
-
-            # update statusbar
-            self.parent.StatusbarUpdate()
-
-        elif self.mouse["use"] == "query":
-            # querying
-            self.parent.QueryMap(self.mouse['begin'][0],self.mouse['begin'][1])
-
-        elif self.mouse["use"] == "queryVector":
-            # editable mode for vector map layers
-            self.parent.QueryVector(self.mouse['begin'][0], self.mouse['begin'][1])
-
-            # clear temp canvas
-            self.flag=True
-            self.UpdateMap(render=False, renderVector=False)
-            
-        elif self.mouse["use"] in ["measure", "profile"]:
-            # measure or profile
-            if self.mouse["use"] == "measure":
-                self.parent.MeasureDist(self.mouse['begin'], self.mouse['end'])
-
-            self.polycoords.append(self.Pixel2Cell(self.mouse['end']))
-            self.ClearLines(pdc=self.pdcTmp)
-            self.DrawLines(pdc=self.pdcTmp)
-        
-        elif self.mouse["use"] == "pointer" and \
-                self.parent.GetLayerManager().georectifying:
-            # -> georectifying
-            coord = self.Pixel2Cell(self.mouse['end'])
-            if self.parent.toolbars['georect']:
-                coordtype = 'gcpcoord'
-            else:
-                coordtype = 'mapcoord'
-
-            self.parent.GetLayerManager().georectifying.SetGCPData(coordtype, coord, self)
-            self.flag=True
-            self.UpdateMap(render=False, renderVector=False)
-
-        elif self.mouse["use"] == "pointer" and self.parent.toolbars['vdigit']:
-            # digitization tool active
-            digitToolbar = self.parent.toolbars['vdigit']
-            digitClass   = self.parent.digit
-            
-            if hasattr(self, "vdigitMove"):
-                if len(digitClass.driver.GetSelected()) == 0:
-                    self.vdigitMove['begin'] = self.Pixel2Cell(self.mouse['begin']) # left down
-                
-                # eliminate initial mouse moving efect
-                self.mouse['begin'] = self.mouse['end'] 
-
-            if digitToolbar.GetAction() in ("deleteLine",
-                                            "moveLine",
-                                            "moveVertex",
-                                            "copyCats",
-                                            "copyAttrs",
-                                            "editLine",
-                                            "flipLine",
-                                            "mergeLine",
-                                            "snapLine",
-                                            "queryLine",
-                                            "breakLine",
-                                            "typeConv",
-                                            "connectLine"):
-                self.OnLeftUpVDigitVarious(event)
-
-            elif digitToolbar.GetAction() in ("splitLine",
-                                              "addVertex",
-                                              "removeVertex"):
-                self.OnLeftUpVDigitModifyLine(event)
-
-            elif digitToolbar.GetAction() == "copyLine":
-                self.OnLeftUpVDigitCopyLine(event)
-            
-            elif digitToolbar.GetAction() == "zbulkLine" and \
-                    len(self.polycoords) == 2:
-                self.OnLeftUpVDigitBulkLine(event)
-            
-            elif digitToolbar.GetAction() == "connectLine":
-                self.OnLeftUpConnectLine(event)
-            
-            if len(digitClass.driver.GetSelected()) > 0:
-                self.redrawAll = None
-            
-        elif (self.mouse['use'] == 'pointer' and 
-                self.dragid >= 0):
-            # end drag of overlay decoration
-            
-            if self.dragid < 99 and self.overlays.has_key(self.dragid):
-                self.overlays[self.dragid]['coords'] = self.pdc.GetIdBounds(self.dragid)
-            elif self.dragid > 100 and self.textdict.has_key(self.dragid):
-                self.textdict[self.dragid]['coords'] = self.pdc.GetIdBounds(self.dragid)
-            else:
-                pass
-            self.dragid = None
-            self.currtxtid = None
-
-
-    def OnButtonDClick(self, event):
-        """
-        Mouse button double click
-        """
-        Debug.msg (5, "BufferedWindow.OnButtonDClick(): use=%s" % \
-                   self.mouse["use"])
-
-        if self.mouse["use"] == "measure":
-            # measure
-            self.ClearLines(pdc=self.pdcTmp)
-            self.polycoords = []
-            self.mouse['use'] = 'pointer'
-            self.mouse['box'] = 'point'
-            self.mouse['end'] = [0, 0]
-            self.Refresh()
-            self.SetCursor(self.parent.cursors["default"])
-        elif self.mouse["use"] == "profile":
-            # profile
-            pass
-        #                self.pdc.ClearId(self.lineid)
-        #                self.pdc.ClearId(self.plineid)
-        #                print 'coordinates: ',self.polycoords
-        #                self.polycoords = []
-        #                self.mouse['begin'] = self.mouse['end'] = [0, 0]
-        #                self.Refresh()
-        elif self.mouse['use'] == 'pointer' and self.parent.toolbars['vdigit']:
-            # digitization tool
-            pass
-        else:
-            # select overlay decoration options dialog
-            clickposition = event.GetPositionTuple()[:]
-            idlist  = self.pdc.FindObjects(clickposition[0], clickposition[1], self.hitradius)
-            if idlist == []:
-                return
-            self.dragid = idlist[0]
-
-            # self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid)
-            if self.dragid > 100:
-                self.currtxtid = self.dragid
-                self.parent.OnAddText(None)
-            elif self.dragid == 0:
-                self.parent.OnAddBarscale(None)
-            elif self.dragid == 1:
-                self.parent.OnAddLegend(None)
-                
-#        event.Skip()
-
-    def OnRightDown(self, event):
-        """
-        Right mouse button pressed
-        """
-        Debug.msg (5, "BufferedWindow.OnRightDown(): use=%s" % \
-                   self.mouse["use"])
-                   
-        digitToolbar = self.parent.toolbars['vdigit']
-        if digitToolbar:
-            digitClass = self.parent.digit
-            # digitization tool (confirm action)
-            if digitToolbar.GetAction() in ["moveLine", "moveVertex"] and \
-                    hasattr(self, "vdigitMove"):
-
-                pFrom = self.vdigitMove['begin']
-                pTo = self.Pixel2Cell(event.GetPositionTuple())
-                
-                move = (pTo[0] - pFrom[0],
-                        pTo[1] - pFrom[1])
-                
-                if digitToolbar.GetAction() == "moveLine":
-                    # move line
-                    if digitClass.MoveSelectedLines(move) < 0:
-                        return
-                elif digitToolbar.GetAction() == "moveVertex":
-                    # move vertex
-                    if digitClass.MoveSelectedVertex(pFrom, move) < 0:
-                        return
-                
-                del self.vdigitMove
-                
-        event.Skip()
-
-    def OnRightUp(self, event):
-        """
-        Right mouse button released
-        """
-        Debug.msg (5, "BufferedWindow.OnRightUp(): use=%s" % \
-                   self.mouse["use"])
-
-        digitToolbar = self.parent.toolbars['vdigit']
-        if digitToolbar:
-            digitClass = self.parent.digit
-            # digitization tool (confirm action)
-            if digitToolbar.GetAction() == "addLine" and \
-                    digitToolbar.GetAction('type') in ["line", "boundary"]:
-                # -> add new line / boundary
-                try:
-                    map = digitToolbar.GetLayer().GetName()
-                except:
-                    map = None
-                    wx.MessageBox(parent=self,
-                                  message=_("No vector map selected for editing."),
-                                  caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
-                    
-                if map:
-                    # mapcoords = []
-                    # xy -> EN
-                    # for coord in self.polycoords:
-                    #    mapcoords.append(self.Pixel2Cell(coord))
-                    if digitToolbar.GetAction('type') == 'line':
-                        line = True
-                    else:
-                        line = False
-
-                    if len(self.polycoords) < 2: # ignore 'one-point' lines
-                        return
-                    
-                    fid = digitClass.AddLine(map, line, self.polycoords)
-                    if fid < 0:
-                        return
-                    
-                    position = self.Cell2Pixel(self.polycoords[-1])
-                    self.polycoords = []
-                    self.UpdateMap(render=False)
-                    self.redrawAll = True
-                    self.Refresh()
-                    
-                    # add new record into atribute table
-                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled') is True:
-                        posWindow = self.ClientToScreen((position[0] + self.dialogOffset,
-                                                         position[1] + self.dialogOffset))
-
-                        # select attributes based on layer and category
-                        cats = { fid : {
-                                UserSettings.Get(group='vdigit', key="layer", subkey='value') :
-                                    (UserSettings.Get(group='vdigit', key="category", subkey='value'), )
-                                }}
-
-                        addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
-                                                                   cats=cats,
-                                                                   pos=posWindow,
-                                                                   action="add")
-                        if addRecordDlg.mapDBInfo and \
-                               addRecordDlg.ShowModal() == wx.ID_OK:
-                            sqlfile = tempfile.NamedTemporaryFile(mode="w")
-                            for sql in addRecordDlg.GetSQLString():
-                                sqlfile.file.write(sql + ";\n")
-                            sqlfile.file.flush()
-                            executeCommand = gcmd.Command(cmd=["db.execute",
-                                                              "--q",
-                                                              "input=%s" % sqlfile.name])
-            elif digitToolbar.GetAction() == "deleteLine":
-                # -> delete selected vector features
-                if digitClass.DeleteSelectedLines() < 0:
-                    return
-            elif digitToolbar.GetAction() == "splitLine":
-                # split line
-                if digitClass.SplitLine(self.Pixel2Cell(self.mouse['begin'])) < 0:
-                    return
-            elif digitToolbar.GetAction() == "addVertex":
-                # add vertex
-                if digitClass.AddVertex(self.Pixel2Cell(self.mouse['begin'])) < 0:
-                    return
-            elif digitToolbar.GetAction() == "removeVertex":
-                # remove vertex
-                if digitClass.RemoveVertex(self.Pixel2Cell(self.mouse['begin'])) < 0:
-                    return
-            elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
-                try:
-                    if digitToolbar.GetAction() == 'copyCats':
-                        if digitClass.CopyCats(self.copyCatsList,
-                                               self.copyCatsIds, copyAttrb=False) < 0:
-                            return
-                    else:
-                        if digitClass.CopyCats(self.copyCatsList,
-                                               self.copyCatsIds, copyAttrb=True) < 0:
-                            return
-                    
-                    del self.copyCatsList
-                    del self.copyCatsIds
-                except AttributeError:
-                    pass
-            elif digitToolbar.GetAction() == "editLine" and \
-                    hasattr(self, "vdigitMove"):
-                line = digitClass.driver.GetSelected()
-                if digitClass.EditLine(line, self.polycoords) < 0:
-                    return
-                
-                del self.vdigitMove
-                
-            elif digitToolbar.GetAction() == "flipLine":
-                if digitClass.FlipLine() < 0:
-                    return
-            elif digitToolbar.GetAction() == "mergeLine":
-                if digitClass.MergeLine() < 0:
-                    return
-            elif digitToolbar.GetAction() == "breakLine":
-                if digitClass.BreakLine() < 0:
-                    return
-            elif digitToolbar.GetAction() == "snapLine":
-                if digitClass.SnapLine() < 0:
-                    return
-            elif digitToolbar.GetAction() == "connectLine":
-                if len(digitClass.driver.GetSelected()) > 1:
-                    if digitClass.ConnectLine() < 0:
-                        return
-            elif digitToolbar.GetAction() == "copyLine":
-                if digitClass.CopyLine(self.copyIds) < 0:
-                    return
-                del self.copyIds
-                if self.layerTmp:
-                    self.Map.DeleteLayer(self.layerTmp)
-                    self.UpdateMap(render=True, renderVector=False)
-                del self.layerTmp
-
-            elif digitToolbar.GetAction() == "zbulkLine" and len(self.polycoords) == 2:
-                pos1 = self.polycoords[0]
-                pos2 = self.polycoords[1]
-
-                selected = digitClass.driver.GetSelected()
-                dlg = VDigitZBulkDialog(parent=self, title=_("Z bulk-labeling dialog"),
-                                        nselected=len(selected))
-                if dlg.ShowModal() == wx.ID_OK:
-                    if digitClass.ZBulkLines(pos1, pos2, dlg.value.GetValue(),
-                                            dlg.step.GetValue()) < 0:
-                        return
-                self.UpdateMap(render=False, renderVector=True)
-            elif digitToolbar.GetAction() == "typeConv":
-                # -> feature type conversion
-                # - point <-> centroid
-                # - line <-> boundary
-                if digitClass.TypeConvForSelectedLines() < 0:
-                    return
-
-            if digitToolbar.GetAction() != "addLine":
-                # unselect and re-render
-                digitClass.driver.SetSelected([])
-                self.polycoords = []
-                self.UpdateMap(render=False)
-
-            self.redrawAll = True
-            self.Refresh()
-        
-        event.Skip()
-
-    def OnMiddleDown(self, event):
-        """
-        Middle mouse button pressed
-        """
-        digitToolbar = self.parent.toolbars['vdigit']
-        # digitization tool
-        if self.mouse["use"] == "pointer" and digitToolbar:
-            digitClass = self.parent.digit
-            if (digitToolbar.GetAction() == "addLine" and \
-                    digitToolbar.GetAction('type') in ["line", "boundary"]) or \
-                    digitToolbar.GetAction() == "editLine":
-                # add line or boundary -> remove last point from the line
-                try:
-                    removed = self.polycoords.pop()
-                    Debug.msg(4, "BufferedWindow.OnMiddleDown(): polycoords_poped=%s" % \
-                                  [removed,])
-
-                    self.mouse['begin'] = self.Cell2Pixel(self.polycoords[-1])
-                except:
-                    pass
-
-                if digitToolbar.GetAction() == "editLine":
-                    # remove last vertex & line
-                    if len(self.vdigitMove['id']) > 1:
-                        self.vdigitMove['id'].pop()
-
-                self.UpdateMap(render=False, renderVector=False)
-
-            elif digitToolbar.GetAction() in ["deleteLine", "moveLine", "splitLine",
-                                              "addVertex", "removeVertex", "moveVertex",
-                                              "copyCats", "flipLine", "mergeLine",
-                                              "snapLine", "connectLine", "copyLine",
-                                              "queryLine", "breakLine", "typeConv"]:
-                # varios tools -> unselected selected features
-                digitClass.driver.SetSelected([])
-                if digitToolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] and \
-                        hasattr(self, "vdigitMove"):
-
-                    del self.vdigitMove
-                    
-                elif digitToolbar.GetAction() == "copyCats":
-                    try:
-                        del self.copyCatsList
-                        del self.copyCatsIds
-                    except AttributeError:
-                        pass
-                
-                elif digitToolbar.GetAction() == "copyLine":
-                    del self.copyIds
-                    if self.layerTmp:
-                        self.Map.DeleteLayer(self.layerTmp)
-                        self.UpdateMap(render=True, renderVector=False)
-                    del self.layerTmp
-
-                self.polycoords = []
-                self.UpdateMap(render=False) # render vector
-
-            elif digitToolbar.GetAction() == "zbulkLine":
-                # reset polyline
-                self.polycoords = []
-                digitClass.driver.SetSelected([])
-                self.UpdateMap(render=False)
-            
-            self.redrawAll = True
-            
-    def OnMouseMoving(self, event):
-        """
-        Motion event and no mouse buttons were pressed
-        """
-        digitToolbar = self.parent.toolbars['vdigit']
-        if self.mouse["use"] == "pointer" and digitToolbar:
-            digitClass = self.parent.digit
-            self.mouse['end'] = event.GetPositionTuple()[:]
-            Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \
-                           (self.mouse['end'][0], self.mouse['end'][1]))
-            if digitToolbar.GetAction() == "addLine" and digitToolbar.GetAction('type') in ["line", "boundary"]:
-                if len(self.polycoords) > 0:
-                    self.MouseDraw(pdc=self.pdcTmp, begin=self.Cell2Pixel(self.polycoords[-1]))
-            elif digitToolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] \
-                    and hasattr(self, "vdigitMove"):
-                dx = self.mouse['end'][0] - self.mouse['begin'][0]
-                dy = self.mouse['end'][1] - self.mouse['begin'][1]
-                
-                if len(self.vdigitMove['id']) > 0:
-                    # draw lines on new position
-                    if digitToolbar.GetAction() == "moveLine":
-                        # move line
-                        for id in self.vdigitMove['id']:
-                            self.pdcTmp.TranslateId(id, dx, dy)
-                    elif digitToolbar.GetAction() in ["moveVertex", "editLine"]:
-                        # move vertex ->
-                        # (vertex, left vertex, left line,
-                        # right vertex, right line)
-
-                        # do not draw static lines
-                        if digitToolbar.GetAction() == "moveVertex":
-                            self.polycoords = []
-                            ### self.pdcTmp.TranslateId(self.vdigitMove['id'][0], dx, dy)
-                            self.pdcTmp.RemoveId(self.vdigitMove['id'][0])
-                            if self.vdigitMove['id'][1] > 0: # previous vertex
-                                x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.vdigitMove['id'][1])[0:2])
-                                self.pdcTmp.RemoveId(self.vdigitMove['id'][1]+1)
-                                self.polycoords.append((x, y))
-                            ### x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.vdigitMove['id'][0])[0:2])
-                            self.polycoords.append(self.Pixel2Cell(self.mouse['end']))
-                            if self.vdigitMove['id'][2] > 0: # next vertex
-                                x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.vdigitMove['id'][2])[0:2])
-                                self.pdcTmp.RemoveId(self.vdigitMove['id'][2]-1)
-                                self.polycoords.append((x, y))
-                            
-                            self.ClearLines(pdc=self.pdcTmp)
-                            self.DrawLines(pdc=self.pdcTmp)
-
-                        else: # edit line
-                            try:
-                                if self.vdigitMove['id'][-1] > 0: # previous vertex
-                                    self.MouseDraw(pdc=self.pdcTmp,
-                                                   begin=self.Cell2Pixel(self.polycoords[-1]))
-                            except: # no line
-                                self.vdigitMove['id'] = []
-                                self.polycoords = []
-
-                self.Refresh() # TODO: use RefreshRect()
-                self.mouse['begin'] = self.mouse['end']
-
-            elif digitToolbar.GetAction() == "zbulkLine":
-                if len(self.polycoords) == 1:
-                    # draw mouse moving
-                    self.MouseDraw(self.pdcTmp)
-
-        event.Skip()
-
-    def ClearLines(self, pdc=None):
-        """
-        Clears temporary drawn lines from PseudoDC
-        """
-        if not pdc:
-            pdc=self.pdcTmp
-        try:
-            pdc.ClearId(self.lineid)
-            pdc.RemoveId(self.lineid)
-        except:
-            pass
-
-        try:
-            pdc.ClearId(self.plineid)
-            pdc.RemoveId(self.plineid)
-        except:
-            pass
-
-        Debug.msg(4, "BufferedWindow.ClearLines(): lineid=%s, plineid=%s" %
-                  (self.lineid, self.plineid))
-
-        ### self.Refresh()
-
-        return True
-
-    def Pixel2Cell(self, (x, y)):
-        """
-        Convert image coordinates to real word coordinates
-
-        Input : int x, int y
-        Output: float x, float y
-        """
-
-        try:
-            x = int(x)
-            y = int(y)
-        except:
-            return None
-
-        if self.Map.region["ewres"] > self.Map.region["nsres"]:
-            res = self.Map.region["ewres"]
-        else:
-            res = self.Map.region["nsres"]
-
-        w = self.Map.region["center_easting"] - (self.Map.width / 2) * res
-        n = self.Map.region["center_northing"] + (self.Map.height / 2) * res
-
-        east  = w + x * res
-        north = n - y * res
-
-        # extent does not correspond with whole map canvas area...
-        # east  = self.Map.region['w'] + x * self.Map.region["ewres"]
-        # north = self.Map.region['n'] - y * self.Map.region["nsres"]
-
-        return (east, north)
-
-    def Cell2Pixel(self, (east, north)):
-        """
-        Convert real word coordinates to image coordinates
-        """
-
-        try:
-            east  = float(east)
-            north = float(north)
-        except:
-            return None
-
-        if self.Map.region["ewres"] > self.Map.region["nsres"]:
-            res = self.Map.region["ewres"]
-        else:
-            res = self.Map.region["nsres"]
-
-        w = self.Map.region["center_easting"] - (self.Map.width / 2) * res
-        n = self.Map.region["center_northing"] + (self.Map.height / 2) * res
-
-        # x = int((east  - w) / res)
-        # y = int((n - north) / res)
-
-        x = (east  - w) / res
-        y = (n - north) / res
-
-        return (x, y)
-
-    def Zoom(self, begin, end, zoomtype):
-        """
-        Calculates new region while (un)zoom/pan-ing
-        """
-        x1, y1 = begin
-        x2, y2 = end
-        newreg = {}
-
-        # threshold - too small squares do not make sense
-        # can only zoom to windows of > 5x5 screen pixels
-        if abs(x2-x1) > 5 and abs(y2-y1) > 5 and zoomtype != 0:
-
-            if x1 > x2:
-                x1, x2 = x2, x1
-            if y1 > y2:
-                y1, y2 = y2, y1
-
-            # zoom in
-            if zoomtype > 0:
-                newreg['w'], newreg['n'] = self.Pixel2Cell((x1, y1))
-                newreg['e'], newreg['s'] = self.Pixel2Cell((x2, y2))
-
-            # zoom out
-            elif zoomtype < 0:
-                newreg['w'], newreg['n'] = self.Pixel2Cell((-x1 * 2, -y1 * 2))
-                newreg['e'], newreg['s'] = self.Pixel2Cell((self.Map.width  + 2 * \
-                                                                (self.Map.width  - x2),
-                                                            self.Map.height + 2 * \
-                                                                (self.Map.height - y2)))
-        # pan
-        elif zoomtype == 0:
-            dx = x1 - x2
-            dy = y1 - y2
-            newreg['w'], newreg['n'] = self.Pixel2Cell((dx, dy))
-            newreg['e'], newreg['s'] = self.Pixel2Cell((self.Map.width  + dx,
-                                                        self.Map.height + dy))
-
-        # if new region has been calculated, set the values
-        if newreg != {}:
-            # LL locations
-            if self.parent.Map.projinfo['proj'] == 'll':
-                if newreg['n'] > 90.0:
-                    newreg['n'] = 90.0
-                if newreg['s'] < -90.0:
-                    newreg['s'] = -90.0
-            
-            ce = newreg['w'] + (newreg['e'] - newreg['w']) / 2
-            cn = newreg['s'] + (newreg['n'] - newreg['s']) / 2
-            
-            if hasattr(self, "vdigitMove"):
-                # xo = self.Cell2Pixel((self.Map.region['center_easting'], self.Map.region['center_northing']))
-                # xn = self.Cell2Pixel(ce, cn))
-                tmp = self.Pixel2Cell(self.mouse['end'])
-            
-            # calculate new center point and display resolution
-            self.Map.region['center_easting'] = ce
-            self.Map.region['center_northing'] = cn
-            self.Map.region["ewres"] = (newreg['e'] - newreg['w']) / self.Map.width
-            self.Map.region["nsres"] = (newreg['n'] - newreg['s']) / self.Map.height
-            self.Map.AlignExtentFromDisplay()
-
-            if hasattr(self, "vdigitMove"):
-                tmp1 = self.mouse['end']
-                tmp2 = self.Cell2Pixel(self.vdigitMove['begin'])
-                dx = tmp1[0] - tmp2[0]
-                dy = tmp1[1] - tmp2[1]
-                self.vdigitMove['beginDiff'] = (dx, dy)
-                for id in self.vdigitMove['id']:
-                    self.pdcTmp.RemoveId(id)
-            
-            self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
-                             self.Map.region['e'], self.Map.region['w'])
-
-        if self.redrawAll is False:
-            self.redrawAll = True
-
-    def ZoomBack(self):
-        """
-        Zoom to previous extents in zoomhistory list
-        """
-
-        zoom = []
-        if len(self.zoomhistory) > 1:
-            self.zoomhistory.pop()
-            zoom = self.zoomhistory[len(self.zoomhistory)-1]
-            # (n, s, e, w)
-        if zoom:
-            # zoom to selected region
-            self.Map.region['center_easting'] = zoom[3] + \
-                (zoom[2] - zoom[3]) / 2
-            self.Map.region['center_northing'] = zoom[1] + \
-                (zoom[0] - zoom[1]) / 2
-            self.Map.region["ewres"] = (zoom[2] - zoom[3]) / self.Map.width
-            self.Map.region["nsres"] = (zoom[0] - zoom[1]) / self.Map.height
-            self.Map.AlignExtentFromDisplay()
-
-            # update map
-            self.UpdateMap()
-
-            # update statusbar
-            self.parent.StatusbarUpdate()
-
-    def ZoomHistory(self, n, s, e, w):
-        """
-        Manages a list of last 10 zoom extents
-
-        Return removed history item if exists
-        """
-        removed = None
-        self.zoomhistory.append((n,s,e,w))
-
-        if len(self.zoomhistory) > 10:
-            removed = self.zoomhistory.pop(0)
-
-        if removed:
-            Debug.msg(4, "BufferedWindow.ZoomHistory(): hist=%s, removed=%s" %
-                      (self.zoomhistory, removed))
-        else:
-            Debug.msg(4, "BufferedWindow.ZoomHistory(): hist=%s" %
-                      (self.zoomhistory))
-
-        return removed
-
-    def OnZoomToMap(self, event):
-        """
-        Set display extents to match selected raster (including NULLs)
-        or vector map.
-        """
-        self.ZoomToMap()
-
-    def OnZoomToRaster(self, event):
-        """
-        Set display extents to match selected raster map (ignore NULLs)
-        """
-        self.ZoomToMap(zoom=True)
-        
-    def ZoomToMap(self, layer = None, zoom = False):
-        """
-        Set display extents to match selected raster
-        or vector map.
-        """
-        zoomreg = {}
-
-        if not layer:
-            layer = self.GetSelectedLayer(multi = True)
-        
-        if not layer:
-            return
-
-        rast = []
-        vect = []
-        updated = False
-        for l in layer:
-            # only raster/vector layers are currently supported
-            if l.type == 'raster':
-                rast.append(l.name)
-            elif l.type == 'vector':
-                if self.parent.digit and l.name == self.parent.digit.map and \
-                        self.parent.digit.type == 'vdigit':
-                    w, s, b, e, n, t = self.parent.digit.driver.GetMapBoundingBox()
-                    self.Map.GetRegion(n=n, s=s, w=w, e=e,
-                                       update=True)
-                    updated = True
-                else:
-                    vect.append(l.name)
-
-        if not updated:
-            self.Map.GetRegion(rast = rast,
-                               vect = vect,
-                               update = True)
-        
-        self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
-                         self.Map.region['e'], self.Map.region['w'])
-
-
-        self.flag=True
-
-        self.UpdateMap()
-
-        self.parent.StatusbarUpdate()
-
-    def ZoomToWind(self, event):
-        """
-        Set display geometry to match computational
-        region settings (set with g.region)
-        """
-        self.Map.region = self.Map.GetRegion()
-        ### self.Map.SetRegion(windres=True)
-
-        self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
-                         self.Map.region['e'], self.Map.region['w'])
-
-        self.UpdateMap()
-
-        self.parent.StatusbarUpdate()
-
-    def ZoomToDefault(self, event):
-        """
-        Set display geometry to match default region settings
-        """
-        self.Map.region = self.Map.GetRegion(default=True)
-        self.Map.AdjustRegion() # aling region extent to the display
-
-        self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
-                         self.Map.region['e'], self.Map.region['w'])
-
-        self.UpdateMap()
-
-        self.parent.StatusbarUpdate()
-        
-    def DisplayToWind(self, event):
-        """
-        Set computational region (WIND file) to
-        match display extents
-        """
-        tmpreg = os.getenv("GRASS_REGION")
-        if tmpreg:
-            del os.environ["GRASS_REGION"]
-
-        # We ONLY want to set extents here. Don't mess with resolution. Leave that
-        # for user to set explicitly with g.region
-        new = self.Map.AlignResolution()
-        
-        cmdRegion = ["g.region", "--o",
-                     "n=%f"    % new['n'],
-                     "s=%f"    % new['s'],
-                     "e=%f"    % new['e'],
-                     "w=%f"    % new['w'],
-                     "rows=%d" % int(new['rows']),
-                     "cols=%d" % int(new['cols'])]
-        
-        p = gcmd.Command(cmdRegion)
-
-        if tmpreg:
-            os.environ["GRASS_REGION"] = tmpreg
-
-    def ZoomToSaved(self, event):
-        """!Set display geometry to match extents in
-        saved region file
-        """
-        dlg = gdialogs.SavedRegion(parent = self, id = wx.ID_ANY,
-                                   title = _("Zoom to saved region extents"),
-                                   pos=wx.DefaultPosition, size=wx.DefaultSize,
-                                   style=wx.DEFAULT_DIALOG_STYLE,
-                                   loadsave='load')
-        
-        if dlg.ShowModal() == wx.ID_CANCEL:
-            dlg.Destroy()
-            return
-        
-        wind = dlg.wind
-        
-        self.Map.GetRegion(regionName = wind,
-                           update = True)
-        
-        dlg.Destroy()
-        
-        self.ZoomHistory(self.Map.region['n'],
-                         self.Map.region['s'],
-                         self.Map.region['e'],
-                         self.Map.region['w'])
-        
-        self.UpdateMap()
-    
-    def SaveDisplayRegion(self, event):
-        """
-        Save display extents to named region file.
-        """
-
-        dlg = gdialogs.SavedRegion(parent = self, id = wx.ID_ANY,
-                                   title = _("Save display extents to region file"),
-                                   pos=wx.DefaultPosition, size=wx.DefaultSize,
-                                   style=wx.DEFAULT_DIALOG_STYLE,
-                                   loadsave='save')
-        if dlg.ShowModal() == wx.ID_CANCEL:
-            dlg.Destroy()
-            return
-        
-        wind = dlg.wind
-        
-        # test to see if it already exists and ask permission to overwrite
-        windpath = os.path.join(self.Map.env["GISDBASE"], self.Map.env["LOCATION_NAME"],
-                                self.Map.env["MAPSET"], "windows", wind)
-        
-        if windpath and not os.path.exists(windpath):
-            self.SaveRegion(wind)
-        elif windpath and os.path.exists(windpath):
-            overwrite = wx.MessageBox(_("Region file <%s> already exists. "
-                                        "Do you want to overwrite it?") % (wind),
-                                      _("Warning"), wx.YES_NO | wx.CENTRE)
-            if (overwrite == wx.YES):
-                self.SaveRegion(wind)
-        else:
-            pass
-
-        dlg.Destroy()
-
-    def SaveRegion(self, wind):
-        """
-        Save region settings
-        """
-        ### new = self.Map.AlignResolution()
-        new = self.Map.GetCurrentRegion()
-        
-        cmdRegion = ["g.region",
-                     "-u",
-                     "n=%f" % new['n'],
-                     "s=%f" % new['s'],
-                     "e=%f" % new['e'],
-                     "w=%f" % new['w'],
-                     "rows=%d" % new['rows'],
-                     "cols=%d" % new['cols'],
-                     "save=%s" % wind,
-                     "--o"]
-
-        tmpreg = os.getenv("GRASS_REGION")
-        if tmpreg:
-            del os.environ["GRASS_REGION"]
-        
-        p = gcmd.Command(cmdRegion)
-
-        if tmpreg:
-            os.environ["GRASS_REGION"] = tmpreg
-
-    def Distance(self, beginpt, endpt, screen=True):
-        """Calculete distance
-
-        LL-locations not supported
-
-        @todo Use m.distance
-
-        @param beginpt first point
-        @param endpt second point
-        @param screen True for screen coordinates otherwise EN
-        """
-        x1, y1 = beginpt
-        x2, y2 = endpt
-        if screen:
-            dEast  = (x2 - x1) * self.Map.region["ewres"]
-            dNorth = (y2 - y1) * self.Map.region["nsres"]
-        else:
-            dEast  = (x2 - x1)
-            dNorth = (y2 - y1)
-            
-
-        return (math.sqrt(math.pow((dEast),2) + math.pow((dNorth),2)), (dEast, dNorth))
-
-
-
 class MapFrame(wx.Panel):
     """
     Main frame for map display window. Drawing takes place in child double buffered
@@ -2262,7 +130,7 @@
         @param page notebook page with layer tree
         @param Map instance of render.Map
         """
-        self.gismanager = gismgr   # Layer Manager object
+        self.gismanager = frame   # Layer Manager object
         self._layerManager = gismgr
         self.Map        = Map       # instance of render.Map
         self.tree       = tree      # Layer Manager layer tree object
@@ -2292,8 +160,8 @@
         #wx.Frame.__init__(self, parent, id, title, pos, size, style)
 
 
-        wx.Panel.__init__(self, parent, id, pos, size, style,name="pg_panel")
-        #self.SetName("MapWindow")
+        wx.Panel.__init__(self, parent, id, pos, size, style)
+        self.SetName("MapWindow")
 
         #
         # set the size & system icon
@@ -2314,6 +182,7 @@
       
 
         self._mgr = wx.aui.AuiManager(self)
+        self._layerManager = self.frame
         
         #self._layerManager.goutput = goutput.GMConsole(self.parent.GetParent(), pageid=1)
         #self._layerManager.goutput.Hide()
@@ -2431,11 +300,32 @@
         # Init map display (buffered DC & set default cursor)
         #
 
-        self.MapWindow2D = BufferedWindow(self, id=wx.ID_ANY,   Map=self.Map, tree=self.tree, gismgr=self._layerManager)
+        self.gisrc  = self.read_gisrc()
+        self.viewInfo = True        #to display v/r.info on mapdisplay
+        self.gisdbase = self.gisrc['GISDBASE'] 
+
+        parent1 = self.GetParent()
+        
+        frame = parent1.GetParent()
+
+        self.lmgr= frame
+
+        self.maptree = LayerTree(self, id=wx.ID_ANY, pos=wx.DefaultPosition,
+                                                      size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS
+                                                      |wx.TR_LINES_AT_ROOT|wx.TR_HIDE_ROOT,
+                                                      gisdbase=self.gisdbase,Map = self.Map,lmgr=self.gismanager,frame=frame)
+
+
+
+        self.tree=self.maptree
+
+        self.MapWindow2D = BufferedWindow(self, id=wx.ID_ANY,   Map=self.Map, tree=self.tree, lmgr=self._layerManager)
+
+        self.tree.MapWindow = self.MapWindow2D
         # default is 2D display mode
         self.MapWindow = self.MapWindow2D
         self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion)
-        self.MapWindow.Bind(wx.EVT_LEFT_DOWN, self.OnClick) 
+        #self.MapWindow.Bind(wx.EVT_LEFT_DOWN, self.OnClick) 
         self.MapWindow.SetCursor(self.cursors["default"])
         # used by Nviz (3D display mode)
         self.MapWindow3D = None 
@@ -2494,17 +384,8 @@
 
         pos = wx.Point(700,10)
 
-        self.gisrc  = self.read_gisrc()
-        self.viewInfo = True        #to display v/r.info on mapdisplay
-        self.gisdbase = self.gisrc['GISDBASE'] 
 
-        parent1 = self.GetParent()
-        
-        rightpanel = parent1.GetParent()
 
-        #splitter= rightpanel.GetParent()
-        self.lmgr= rightpanel
-
         self.onRenderGauge = wx.Gauge(parent=self.statusbar, id=wx.ID_ANY,
                                       range=0, style=wx.GA_HORIZONTAL)
 
@@ -2518,10 +399,7 @@
                                                      "Default value for new map displays can "
                                                      "be set up in 'User GUI settings' dialog.")))
 
-        self.maptree = LayerTree(self, id=wx.ID_ANY, pos=wx.DefaultPosition,
-                                                      size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS
-                                                      |wx.TR_LINES_AT_ROOT|wx.TR_HIDE_ROOT,
-                                                      gisdbase=self.gisdbase)
+
         #self.maptree.SetBackgroundColour("red")
 
         self._mgr.AddPane(self.maptree, wx.aui.AuiPaneInfo().Left().
@@ -2533,27 +411,6 @@
 
         #r.rightSizer.Add(self.maptree)
 
-    def OnClick(self,event): 
-	 	        if self.frame.radiobox.GetSelection() == 0: 
-	 	            x, y = self.MapWindow.Pixel2Cell(event.GetPosition()) 
-	 	            out = subprocess.Popen(['m.proj', '-o'], stdout=subprocess.PIPE,  stdin=subprocess.PIPE).communicate("%s %s" % (x,y))[0] 
-	 	            f = out.replace("'"," ").replace('d',' ').replace('"',' ').replace('\n','').split('\t') 
-	 	            lon = f[0].split(' ') 
-	 	            lat = f[1].split(' ')[:-1] 
-	 	            if lat[-1] == 'N': 
-	 	                signlat = 1 
-	 	            if lat[-1] == 'S': 
-	 	                signlat = -1 
-	 	            if lon[-1] == 'E': 
-	 	                signlon = 1 
-	 	            if lon[-1] == 'W': 
-	 	                signlon = -1 
-	 	            lat = (float(lat[0]) + (float(lat[1]) / 60) + float(lat[2]) / 3600) * float(signlat) 
-	 	            lon = (float(lon[0]) + (float(lon[1]) / 60) + float(lon[2]) / 3600) * float(signlon) 
-	 	            self.frame.mInfo.SetValue(str(lat) + ' , ' + str(lon)) 
-	 	            zoomto(str(lon),str(lat),15000) 
-	 	        event.Skip() 
-
     def read_gisrc(self):
 	    """
 	    Read variables gisrc file
@@ -2575,14 +432,15 @@
 	    return rc
 
 
-    def AddToolbar(self, name):
-        """
-        Add defined toolbar to the window
 
+    def AddToolbar(self, name):
+        """!Add defined toolbar to the window
+        
         Currently known toolbars are:
-        - map basic map toolbar
-        - digit vector digitizer
-        - georect georectifier
+         - 'map'     - basic map toolbar
+         - 'vdigit'  - vector digitizer
+         - 'georect' - georectifier
+         - 'nviz'    - 3D view mode
         """
         # default toolbar
         if name == "map":
@@ -2649,7 +507,7 @@
         # nviz
         elif name == "nviz":
             import nviz
-
+            
             # check for GLCanvas and OpenGL
             msg = None
             if not nviz.haveGLCanvas:
@@ -2661,7 +519,7 @@
                 msg = _("Unable to switch to 3D display mode.\nThe Nviz python extension "
                         "was not found or loaded properly.\n"
                         "Switching back to 2D display mode.\n\nDetails: %s" % nviz.errorMsg)
-
+            
             if msg:
                 self.toolbars['map'].combo.SetValue (_("2D view"))
                 wx.MessageBox(parent=self,
@@ -2669,52 +527,42 @@
                               caption=_("Error"),
                               style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
                 return
-
-            #
+            
             # add Nviz toolbar and disable 2D display mode tools
-            #
             self.toolbars['nviz'] = toolbars.NvizToolbar(self, self.Map)
             self.toolbars['map'].Enable2D(False)
-
-            #
+            
             # update layer tree (-> enable 3d-rasters)
-            #
             if self.tree:
                 self.tree.EnableItemType(type='3d-raster', enable=True)
-
-            self.toggleStatus.Enable(False)
             
-            #
             # update status bar
-            #
             self.statusbarWin['toggle'].Enable(False)
 
-            #
             # erase map window
-            #
             self.MapWindow.EraseMap()
 
             self.statusbar.SetStatusText(_("Please wait, loading data..."), 0)
             
-            #
             # create GL window & NVIZ toolbar
-            #
             if not self.MapWindow3D:
                 self.MapWindow3D = nviz.GLWindow(self, id=wx.ID_ANY,
                                                  Map=self.Map, tree=self.tree, lmgr=self._layerManager)
-                # -> show after paint
-                self.nvizToolWin = nviz.NvizToolWindow(self, id=wx.ID_ANY,
-                                                       mapWindow=self.MapWindow3D)
+                self.MapWindow = self.MapWindow3D
+                
+                # add Nviz notebookpage
+                self._layerManager.AddNviz()
+                
                 self.MapWindow3D.OnPaint(None) # -> LoadData
                 self.MapWindow3D.Show()
                 self.MapWindow3D.UpdateView(None)
+            else:
+                self.MapWindow = self.MapWindow3D
+                # add Nviz notebookpage
+                self._layerManager.AddNviz()
             
-            self.nvizToolWin.Show()
-
-            #
             # switch from MapWindow to MapWindowGL
             # add nviz toolbar
-            #
             self._mgr.DetachPane(self.MapWindow2D)
             self.MapWindow2D.Hide()
             self._mgr.AddPane(self.MapWindow3D, wx.aui.AuiPaneInfo().CentrePane().
@@ -2729,18 +577,15 @@
                               BottomDockable(False).TopDockable(True).
                               CloseButton(False).Layer(2))
             
-            self.MapWindow = self.MapWindow3D
             self.SetStatusText("", 0)
             
         self._mgr.Update()
 
     def RemoveToolbar (self, name):
-        """
-        Removes toolbar from the window
+        """!Removes toolbar from the window
 
-        TODO: Only hide, activate by calling AddToolbar()
+        @todo Only hide, activate by calling AddToolbar()
         """
-
         # cannot hide main toolbar
         if name == "map":
             return
@@ -2755,8 +600,6 @@
         self.toolbars[name] = None
 
         if name == 'nviz':
-            # hide nviz tools
-            self.nvizToolWin.Hide()
             # unload data
             #            self.MapWindow3D.Reset()
             # switch from MapWindowGL to MapWindow
@@ -2768,18 +611,20 @@
                               CloseButton(False).DestroyOnClose(True).
                               Layer(0))
             self.MapWindow = self.MapWindow2D
+            # remove nviz notebook page
+            self._layerManager.RemoveNviz()
             
-            #
             # update layer tree (-> disable 3d-rasters)
-            #
             if self.tree:
                 self.tree.EnableItemType(type='3d-raster', enable=False)
+            
+           
             self.MapWindow.UpdateMap()
             
         self.toolbars['map'].combo.SetValue (_("2D view"))
         self.toolbars['map'].Enable2D(True)
         self.statusbarWin['toggle'].Enable(True)
-        self.toggleStatus.Enable(True)
+
         self._mgr.Update()
 
     def __InitDisplay(self):
@@ -2820,12 +665,6 @@
         
         event.Skip()
 
-    def OnToggleStatus(self, event):
-        """
-        Toggle status text
-        """
-        self.StatusbarUpdate()
-
     def OnMotion(self, event):
         """
         Mouse moved
@@ -2833,7 +672,14 @@
         """
         # update statusbar if required
         if self.statusbarWin['toggle'].GetSelection() == 0: # Coordinates
-            e, n = self.MapWindow.Pixel2Cell(event.GetPositionTuple())
+            precision = int(UserSettings.Get(group = 'projection', key = 'format',
+                                             subkey = 'precision'))
+            format = UserSettings.Get(group = 'projection', key = 'format',
+                                      subkey = 'll')
+            try:
+                e, n = self.MapWindow.Pixel2Cell(event.GetPositionTuple())
+            except AttributeError:
+                return
             if self.toolbars['vdigit'] and \
                     self.toolbars['vdigit'].GetAction() == 'addLine' and \
                     self.toolbars['vdigit'].GetAction('type') in ('line', 'boundary') and \
@@ -2846,17 +692,43 @@
                     distance_tot += self.MapWindow.Distance(self.MapWindow.polycoords[idx-1],
                                                             self.MapWindow.polycoords[idx],
                                                             screen=False )[0]
-                self.statusbar.SetStatusText("%.2f, %.2f (seg: %.2f; tot: %.2f)" % \
-                                                 (e, n, distance_seg, distance_tot), 0)
+                self.statusbar.SetStatusText("%.*f, %.*f (seg: %.*f; tot: %.*f)" % \
+                                                 (precision, e, precision, n,
+                                                  precision, distance_seg,
+                                                  precision, distance_tot), 0)
             else:
-                if self.Map.projinfo['proj'] == 'll':
-                    self.statusbar.SetStatusText("%s" % utils.Deg2DMS(e, n), 0)
+                if self.statusbarWin['projection'].IsChecked():
+                    if not UserSettings.Get(group='projection', key='statusbar', subkey='proj4'):
+                        self.statusbar.SetStatusText(_("Projection not defined (check the settings)"), 0)
+                    else:
+                        proj, coord  = utils.ReprojectCoordinates(coord = (e, n),
+                                                                  projOut = UserSettings.Get(group='projection',
+                                                                                             key='statusbar',
+                                                                                             subkey='proj4'),
+                                                                  flags = 'd')
+                    
+                        if coord:
+                            e, n = coord
+                            if proj in ('ll', 'latlong', 'longlat') and format == 'DMS':
+                                self.statusbar.SetStatusText("%s" % \
+                                                                 utils.Deg2DMS(e, n, precision = precision),
+                                                             0)
+                            else:
+                                self.statusbar.SetStatusText("%.*f; %.*f" % \
+                                                                 (precision, e, precision, n), 0)
+                        else:
+                            self.statusbar.SetStatusText(_("Error in projection (check the settings)"), 0)
                 else:
-                    self.statusbar.SetStatusText("%.2f, %.2f" % (e, n), 0)
-        
+                    if self.Map.projinfo['proj'] == 'll' and format == 'DMS':
+                        self.statusbar.SetStatusText("%s" % \
+                                                         utils.Deg2DMS(e, n, precision = precision),
+                                                     0)
+                    else:
+                        self.statusbar.SetStatusText("%.*f; %.*f" % \
+                                                         (precision, e, precision, n), 0)
+                
         event.Skip()
 
-
     def OnDraw(self, event):
         """
         Re-display current map composition
@@ -3424,12 +1296,26 @@
     def SaveToFile(self, event):
         """!Save map to image
         """
-        filetype, ltype = gdialogs.GetImageHandlers(self.MapWindow.img)
+        if self.toolbars['nviz']:
+            filetype = "PPM file (*.ppm)|*.ppm|TIF file (*.tif)|*.tif"
+            ltype = [{ 'ext' : 'ppm', 'type' : -1 },
+                     { 'ext' : 'tif', 'type' : wx.BITMAP_TYPE_TIF }]
+        else:
+            filetype, ltype = gdialogs.GetImageHandlers(self.MapWindow.img)
         
+        # get size
+        dlg = gdialogs.ImageSizeDialog(self)
+        dlg.CentreOnParent()
+        if dlg.ShowModal() != wx.ID_OK:
+            dlg.Destroy()
+            return
+        width, height = dlg.GetValues()
+        dlg.Destroy()
+        
+        # get filename
         dlg = wx.FileDialog(parent = self,
-                            message = _("Choose a file name to save the image (no need to add extension)"),
-                            defaultDir = "",
-                            defaultFile = "",
+                            message = _("Choose a file name to save the image "
+                                        "(no need to add extension)"),
                             wildcard = filetype,
                             style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
         
@@ -3445,7 +1331,8 @@
             if ext != extType:
                 path = base + '.' + extType
             
-            self.MapWindow.SaveToFile(path, type)
+            self.MapWindow.SaveToFile(path, fileType,
+                                      width, height)
             
         dlg.Destroy()
 
@@ -3781,6 +1668,7 @@
         @param name name of map layer
         @param useId use feature id instead of category 
         """
+
         # color settings from ATM
         color = UserSettings.Get(group='atm', key='highlight', subkey='color')
         colorStr = str(color[0]) + ":" + \
@@ -4161,42 +2049,79 @@
         self.params[type] = params
         self.propwin[type] = propwin
 
-    def OnZoomMenu(self, event):
+    def OnZoomToMap(self, event):
+        """!
+        Set display extents to match selected raster (including NULLs)
+        or vector map.
         """
-        Zoom menu
+        self.MapWindow.ZoomToMap()
+
+    def OnZoomToRaster(self, event):
+        """!
+        Set display extents to match selected raster map (ignore NULLs)
         """
+        self.MapWindow.ZoomToMap(ignoreNulls = True)
+
+    def OnZoomToWind(self, event):
+        """!Set display geometry to match computational region
+        settings (set with g.region)
+        """
+        self.MapWindow.ZoomToWind()
+        
+    def OnZoomToDefault(self, event):
+        """!Set display geometry to match default region settings
+        """
+        self.MapWindow.ZoomToDefault()
+        
+    def OnZoomToSaved(self, event):
+        """!Set display geometry to match extents in
+        saved region file
+        """
+        self.MapWindow.ZoomToSaved()
+        
+    def OnDisplayToWind(self, event):
+        """!Set computational region (WIND file) to match display
+        extents
+        """
+        self.MapWindow.DisplayToWind()
+ 
+    def SaveDisplayRegion(self, event):
+        """!Save display extents to named region file.
+        """
+        self.MapWindow.SaveDisplayRegion()
+        
+    def OnZoomMenu(self, event):
+        """!Popup Zoom menu
+        """
         point = wx.GetMousePosition()
         zoommenu = wx.Menu()
         # Add items to the menu
-        zoommap = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to selected map(s)'))
-        zoommenu.AppendItem(zoommap)
-        self.Bind(wx.EVT_MENU, self.MapWindow.OnZoomToMap, zoommap)
 
         zoomwind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to computational region (set with g.region)'))
         zoommenu.AppendItem(zoomwind)
-        self.Bind(wx.EVT_MENU, self.MapWindow.ZoomToWind, zoomwind)
+        self.Bind(wx.EVT_MENU, self.OnZoomToWind, zoomwind)
 
         zoomdefault = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to default region'))
         zoommenu.AppendItem(zoomdefault)
-        self.Bind(wx.EVT_MENU, self.MapWindow.ZoomToDefault, zoomdefault)
+        self.Bind(wx.EVT_MENU, self.OnZoomToDefault, zoomdefault)
 
         zoomsaved = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to saved region'))
         zoommenu.AppendItem(zoomsaved)
-        self.Bind(wx.EVT_MENU, self.MapWindow.ZoomToSaved, zoomsaved)
+        self.Bind(wx.EVT_MENU, self.OnZoomToSaved, zoomsaved)
 
         savewind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Set computational region from display'))
         zoommenu.AppendItem(savewind)
-        self.Bind(wx.EVT_MENU, self.MapWindow.DisplayToWind, savewind)
+        self.Bind(wx.EVT_MENU, self.OnDisplayToWind, savewind)
 
         savezoom = wx.MenuItem(zoommenu, wx.ID_ANY, _('Save display geometry to named region'))
         zoommenu.AppendItem(savezoom)
-        self.Bind(wx.EVT_MENU, self.MapWindow.SaveDisplayRegion, savezoom)
+        self.Bind(wx.EVT_MENU, self.SaveDisplayRegion, savezoom)
 
-        # Popup the menu.  If an item is selected then its handler
+        # Popup the menu. If an item is selected then its handler
         # will be called before PopupMenu returns.
         self.PopupMenu(zoommenu)
         zoommenu.Destroy()
-
+        
     def SetProperties(self, render=False, mode=0, showCompExtent=False,
                       constrainRes=False, projection=False):
         """!Set properies of map display window"""

Deleted: grass-addons/gui/wxpython/data_catalog/toolbars.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/toolbars.py	2010-06-17 20:18:34 UTC (rev 42585)
+++ grass-addons/gui/wxpython/data_catalog/toolbars.py	2010-06-19 03:33:21 UTC (rev 42586)
@@ -1,1440 +0,0 @@
-"""!
- at package toolbar
-
- at brief wxGUI toolbar widgets
-
-Classes:
- - AbstractToolbar
- - MapToolbar
- - GRToolbar
- - GCPToolbar
- - VDigitToolbar
- - ProfileToolbar
- - NvizToolbar
- - ModelToolbar
-
-(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
- at author Jachym Cepicky
- at author Martin Landa <landa.martin gmail.com>
-"""
-
-import os
-import sys
-import platform
-
-from grass.script import core as grass
-
-import wx
-
-import globalvar
-import gcmd
-import gdialogs
-import vdigit
-from vdigit import VDigitSettingsDialog as VDigitSettingsDialog
-from debug import Debug as Debug
-from preferences import globalSettings as UserSettings
-
-gmpath = os.path.join(globalvar.ETCWXDIR, "icons")
-sys.path.append(gmpath)
-from icon import Icons as Icons
-
-class AbstractToolbar(wx.ToolBar):
-    """!Abstract toolbar class"""
-    def __init__(self, parent):
-        self.parent = parent
-        wx.ToolBar.__init__(self, parent = self.parent, id = wx.ID_ANY)
-    
-        self.action = dict()
-        
-        self.Bind(wx.EVT_TOOL, self.OnTool)
-        
-        self.SetToolBitmapSize(globalvar.toolbarSize)
-        
-    def InitToolbar(self, toolData):
-        """!Initialize toolbar, add tools to the toolbar
-        """
-        for tool in toolData:
-            self.CreateTool(*tool)
-        
-        self._data = toolData
-        
-    def ToolbarData(self):
-        """!Toolbar data (virtual)"""
-        return None
-    
-    def CreateTool(self, tool, label, bitmap, kind,
-                   shortHelp, longHelp, handler):
-        """!Add tool to the toolbar
-        
-        @return id of tool
-        """
-        bmpDisabled=wx.NullBitmap
-        
-        if label:
-            Debug.msg(3, "CreateTool(): tool=%d, label=%s bitmap=%s" % \
-                  (tool, label, bitmap))
-            
-            toolWin = self.AddLabelTool(tool, label, bitmap,
-                                        bmpDisabled, kind,
-                                        shortHelp, longHelp)
-            self.Bind(wx.EVT_TOOL, handler, toolWin)
-        else: # separator
-            self.AddSeparator()
-        
-        return tool
-    
-    def EnableLongHelp(self, enable=True):
-        """!Enable/disable long help
-        
-        @param enable True for enable otherwise disable
-        """
-        for tool in self._data:
-            if tool[0] == '': # separator
-                continue
-            
-            if enable:
-                self.SetToolLongHelp(tool[0], tool[5])
-            else:
-                self.SetToolLongHelp(tool[0], "")
-        
-    def OnTool(self, event):
-        """!Tool selected"""
-        if self.parent.GetName() == "GCPFrame":
-            return
-        
-        if self.parent.toolbars['vdigit']:
-            # update vdigit toolbar (unselect currently selected tool)
-            id = self.parent.toolbars['vdigit'].GetAction(type='id')
-            self.parent.toolbars['vdigit'].ToggleTool(id, False)
-        
-        if event:
-            # deselect previously selected tool
-            id = self.action.get('id', -1)
-            if id != event.GetId():
-                self.ToggleTool(self.action['id'], False)
-            else:
-                self.ToggleTool(self.action['id'], True)
-            
-            self.action['id'] = event.GetId()
-            
-            event.Skip()
-        else:
-            # initialize toolbar
-            self.ToggleTool(self.action['id'], True)
-        
-    def GetAction(self, type='desc'):
-        """!Get current action info"""
-        return self.action.get(type, '')
-    
-    def SelectDefault(self, event):
-        """!Select default tool"""
-        self.ToggleTool(self.defaultAction['id'], True)
-        self.defaultAction['bind'](event)
-        self.action = { 'id' : self.defaultAction['id'],
-                        'desc' : self.defaultAction.get('desc', '') }
-        
-    def FixSize(self, width):
-	"""!Fix toolbar width on Windows
-        
-	@todo Determine why combobox causes problems here
-	"""
-        if platform.system() == 'Windows':
-            size = self.GetBestSize()
-            self.SetSize((size[0] + width, size[1]))
-
-    def Enable(self, tool, enable = True):
-        """!Enable defined tool
-        
-        @param tool name
-        @param enable True to enable otherwise disable tool
-        """
-        try:
-            id = getattr(self, tool)
-        except AttributeError:
-            return
-        
-        self.EnableTool(id, enable)
-        
-class MapToolbar(AbstractToolbar):
-    """!Map Display toolbar
-    """
-    def __init__(self, parent, mapcontent):
-        """!Map Display constructor
-
-        @param parent reference to MapFrame
-        @param mapcontent reference to render.Map (registred by MapFrame)
-        """
-        self.mapcontent = mapcontent # render.Map
-        AbstractToolbar.__init__(self, parent = parent) # MapFrame
-        
-        self.InitToolbar(self.ToolbarData())
-        
-        # optional tools
-        self.combo = wx.ComboBox(parent=self, id=wx.ID_ANY, value=_('2D view'),
-                                 choices=[_('2D view'), _('3D view'), _('Digitize')],
-                                 style=wx.CB_READONLY, size=(90, -1))
-        
-        self.comboid = self.AddControl(self.combo)
-        self.parent.Bind(wx.EVT_COMBOBOX, self.OnSelectTool, self.comboid)
-        
-        # realize the toolbar
-        self.Realize()
-        
-        # workaround for Mac bug. May be fixed by 2.8.8, but not before then.
-        self.combo.Hide()
-        self.combo.Show()
-        
-        self.action = { 'id' : self.pointer }
-        self.defaultAction = { 'id' : self.pointer,
-                               'bind' : self.parent.OnPointer }
-        
-        self.OnTool(None)
-        
-        self.EnableTool(self.zoomback, False)
-        
-        self.FixSize(width = 90)
-        
-    def ToolbarData(self):
-        """!Toolbar data"""
-        self.displaymap = wx.NewId()
-        self.rendermap = wx.NewId()
-        self.erase = wx.NewId()
-        self.pointer = wx.NewId()
-        self.query = wx.NewId()
-        self.pan = wx.NewId()
-        self.zoomin = wx.NewId()
-        self.zoomout = wx.NewId()
-        self.zoomback = wx.NewId()
-        self.zoommenu = wx.NewId()
-        self.analyze = wx.NewId()
-        self.dec = wx.NewId()
-        self.savefile = wx.NewId()
-        self.printmap = wx.NewId()
-        
-        # tool, label, bitmap, kind, shortHelp, longHelp, handler
-        return (
-            (self.displaymap, "displaymap", Icons["displaymap"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["displaymap"].GetLabel(), Icons["displaymap"].GetDesc(),
-             self.parent.OnDraw),
-            (self.rendermap, "rendermap", Icons["rendermap"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["rendermap"].GetLabel(), Icons["rendermap"].GetDesc(),
-             self.parent.OnRender),
-            (self.erase, "erase", Icons["erase"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(),
-             self.parent.OnErase),
-            ("", "", "", "", "", "", ""),
-            (self.pointer, "pointer", Icons["pointer"].GetBitmap(),
-             wx.ITEM_CHECK, Icons["pointer"].GetLabel(), Icons["pointer"].GetDesc(),
-             self.parent.OnPointer),
-            (self.query, "query", Icons["query"].GetBitmap(),
-             wx.ITEM_CHECK, Icons["query"].GetLabel(), Icons["query"].GetDesc(),
-             self.parent.OnQuery),
-            (self.pan, "pan", Icons["pan"].GetBitmap(),
-             wx.ITEM_CHECK, Icons["pan"].GetLabel(), Icons["pan"].GetDesc(),
-             self.parent.OnPan),
-            (self.zoomin, "zoom_in", Icons["zoom_in"].GetBitmap(),
-             wx.ITEM_CHECK, Icons["zoom_in"].GetLabel(), Icons["zoom_in"].GetDesc(),
-             self.parent.OnZoomIn),
-            (self.zoomout, "zoom_out", Icons["zoom_out"].GetBitmap(),
-             wx.ITEM_CHECK, Icons["zoom_out"].GetLabel(), Icons["zoom_out"].GetDesc(),
-             self.parent.OnZoomOut),
-            (self.zoomback, "zoom_back", Icons["zoom_back"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["zoom_back"].GetLabel(), Icons["zoom_back"].GetDesc(),
-             self.parent.OnZoomBack),
-            (self.zoommenu, "zoommenu", Icons["zoommenu"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["zoommenu"].GetLabel(), Icons["zoommenu"].GetDesc(),
-             self.parent.OnZoomMenu),
-            ("", "", "", "", "", "", ""),
-            (self.analyze, "analyze", Icons["analyze"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["analyze"].GetLabel(), Icons["analyze"].GetDesc(),
-             self.parent.OnAnalyze),
-            ("", "", "", "", "", "", ""),
-            (self.dec, "overlay", Icons["overlay"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["overlay"].GetLabel(), Icons["overlay"].GetDesc(),
-             self.parent.OnDecoration),
-            ("", "", "", "", "", "", ""),
-            (self.savefile, "savefile", Icons["savefile"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["savefile"].GetLabel(), Icons["savefile"].GetDesc(),
-             self.parent.SaveToFile),
-            (self.printmap, "printmap", Icons["printmap"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["printmap"].GetLabel(), Icons["printmap"].GetDesc(),
-             self.parent.PrintMenu),
-            ("", "", "", "", "", "", "")
-            )
-    
-    def OnSelectTool(self, event):
-        """!
-        Select / enable tool available in tools list
-        """
-        tool =  event.GetSelection()
-        
-        if tool == 0:
-            self.ExitToolbars()
-            self.Enable2D(True)
-        
-        elif tool == 1 and not self.parent.toolbars['nviz']:
-            self.ExitToolbars()
-            self.parent.AddToolbar("nviz")
-            
-        elif tool == 2 and not self.parent.toolbars['vdigit']:
-            self.ExitToolbars()
-            self.parent.AddToolbar("vdigit")
-            self.parent.MapWindow.SetFocus()
-        
-    def ExitToolbars(self):
-        if self.parent.toolbars['vdigit']:
-            self.parent.toolbars['vdigit'].OnExit()
-        if self.parent.toolbars['nviz']:       
-            self.parent.toolbars['nviz'].OnExit()
-    
-    def Enable2D(self, enabled):
-        """!Enable/Disable 2D display mode specific tools"""
-        for tool in (self.pointer,
-                     self.query,
-                     self.pan,
-                     self.zoomin,
-                     self.zoomout,
-                     self.zoomback,
-                     self.zoommenu,
-                     self.analyze,
-                     self.dec,
-                     self.savefile,
-                     self.printmap):
-            self.EnableTool(tool, enabled)
-        
-class GRToolbar(AbstractToolbar):
-    """
-    Georectification toolbar
-    """
-    def __init__(self, parent, mapcontent):
-        """!
-        Georectification toolbar constructor
-
-        @param parent reference to MapFrame
-        @param mapcontent reference to render.Map (registred by MapFrame)
-        """
-        self.mapcontent = mapcontent
-        AbstractToolbar.__init__(self, parent)
-        
-        self.InitToolbar(self.ToolbarData())
-        
-        # realize the toolbar
-        self.Realize()
-        
-        self.action = { 'id' : self.gcpset }
-        self.defaultAction = { 'id' : self.gcpset,
-                               'bind' : self.parent.OnPointer }
-        
-        self.OnTool(None)
-        
-        self.EnableTool(self.zoomback, False)
-        
-    def ToolbarData(self):
-        """!Toolbar data"""
-        self.displaymap = wx.NewId()
-        self.rendermap = wx.NewId()
-        self.erase = wx.NewId()
-        self.gcpset = wx.NewId()
-        self.pan = wx.NewId()
-        self.zoomin = wx.NewId()
-        self.zoomout = wx.NewId()
-        self.zoomback = wx.NewId()
-        self.zoomtomap = wx.NewId()
-        
-        # tool, label, bitmap, kind, shortHelp, longHelp, handler
-        return (
-            (self.displaymap, "displaymap", Icons["displaymap"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["displaymap"].GetLabel(), Icons["displaymap"].GetDesc(),
-             self.parent.OnDraw),
-            (self.rendermap, "rendermap", Icons["rendermap"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["rendermap"].GetLabel(), Icons["rendermap"].GetDesc(),
-             self.parent.OnRender),
-            (self.erase, "erase", Icons["erase"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(),
-             self.parent.OnErase),
-            ("", "", "", "", "", "", ""),
-            (self.gcpset, "grGcpSet", Icons["grGcpSet"].GetBitmap(),
-             wx.ITEM_RADIO, Icons["grGcpSet"].GetLabel(), Icons["grGcpSet"].GetDesc(),
-             self.parent.OnPointer),
-            (self.pan, "pan", Icons["pan"].GetBitmap(),
-             wx.ITEM_RADIO, Icons["pan"].GetLabel(), Icons["pan"].GetDesc(),
-             self.parent.OnPan),
-            (self.zoomin, "zoom_in", Icons["zoom_in"].GetBitmap(),
-             wx.ITEM_RADIO, Icons["zoom_in"].GetLabel(), Icons["zoom_in"].GetDesc(),
-             self.parent.OnZoomIn),
-            (self.zoomout, "zoom_out", Icons["zoom_out"].GetBitmap(),
-             wx.ITEM_RADIO, Icons["zoom_out"].GetLabel(), Icons["zoom_out"].GetDesc(),
-             self.parent.OnZoomOut),
-            (self.zoomback, "zoom_back", Icons["zoom_back"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["zoom_back"].GetLabel(), Icons["zoom_back"].GetDesc(),
-             self.parent.OnZoomBack),
-            (self.zoomtomap, "zoomtomap", Icons["zoommenu"].GetBitmap(),
-             wx.ITEM_NORMAL, _("Zoom to map"), _("Zoom to displayed map"),
-             self.OnZoomMap),
-            )
-    
-    def OnZoomMap(self, event):
-        """!Zoom to selected map"""
-        self.parent.MapWindow.ZoomToMap(layers = self.mapcontent.GetListOfLayers())
-        if event:
-            event.Skip()
-        
-class GCPToolbar(AbstractToolbar):
-    """!
-    Toolbar for managing ground control points during georectification
-
-    @param parent reference to GCP widget
-    """
-    def __init__(self, parent):
-        AbstractToolbar.__init__(self, parent)
-        
-        self.InitToolbar(self.ToolbarData())
-        
-        # realize the toolbar
-        self.Realize()
-
-    def ToolbarData(self):
-        self.gcpSave = wx.NewId()
-        self.gcpAdd = wx.NewId()
-        self.gcpDelete = wx.NewId()
-        self.gcpClear = wx.NewId()
-        self.gcpReload = wx.NewId()
-        self.rms = wx.NewId()
-        self.georect = wx.NewId()
-        self.settings = wx.NewId()
-        self.quit = wx.NewId()
-
-        return (
-            (self.gcpSave, 'grGcpSave', Icons["grGcpSave"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["grGcpSave"].GetLabel(), Icons["grGcpSave"].GetDesc(),
-             self.parent.SaveGCPs),
-            (self.gcpAdd, 'grGrGcpAdd', Icons["grGcpAdd"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["grGcpAdd"].GetLabel(), Icons["grGcpAdd"].GetDesc(),
-             self.parent.AddGCP),
-            (self.gcpDelete, 'grGrGcpDelete', Icons["grGcpDelete"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["grGcpDelete"].GetLabel(), Icons["grGcpDelete"].GetDesc(), 
-             self.parent.DeleteGCP),
-            (self.gcpClear, 'grGcpClear', Icons["grGcpClear"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["grGcpClear"].GetLabel(), Icons["grGcpClear"].GetDesc(), 
-             self.parent.ClearGCP),
-            (self.gcpReload, 'grGcpReload', Icons["grGcpReload"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["grGcpReload"].GetLabel(), Icons["grGcpReload"].GetDesc(), 
-             self.parent.ReloadGCPs),
-
-            ("", "", "", "", "", "", ""),
-            (self.rms, 'grGcpRms', Icons["grGcpRms"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["grGcpRms"].GetLabel(), Icons["grGcpRms"].GetDesc(),
-             self.parent.OnRMS),
-            (self.georect, 'grGeorect', Icons["grGeorect"].GetBitmap(), 
-             wx.ITEM_NORMAL, Icons["grGeorect"].GetLabel(), Icons["grGeorect"].GetDesc(),
-             self.parent.OnGeorect),
-            ("", "", "", "", "", "", ""),
-            (self.settings, 'grSettings', Icons["grSettings"].GetBitmap(), 
-             wx.ITEM_NORMAL, Icons["grSettings"].GetLabel(), Icons["grSettings"].GetDesc(),
-             self.parent.OnSettings),
-            (self.quit, 'grGcpQuit', Icons["grGcpQuit"].GetBitmap(), 
-             wx.ITEM_NORMAL, Icons["grGcpQuit"].GetLabel(), Icons["grGcpQuit"].GetDesc(),
-             self.parent.OnQuit)
-            )
-    
-class VDigitToolbar(AbstractToolbar):
-    """
-    Toolbar for digitization
-    """
-    def __init__(self, parent, mapcontent, layerTree=None, log=None):
-        self.mapcontent    = mapcontent # Map class instance
-        self.layerTree     = layerTree  # reference to layer tree associated to map display
-        self.log           = log        # log area
-        AbstractToolbar.__init__(self, parent)
-        
-        # currently selected map layer for editing (reference to MapLayer instance)
-        self.mapLayer = None
-        # list of vector layers from Layer Manager (only in the current mapset)
-        self.layers   = [] 
-        
-        self.comboid    = None
-        
-        # only one dialog can be open
-        self.settingsDialog   = None
-        
-        # create toolbars (two rows optionally)
-        self.InitToolbar(self.ToolbarData())
-        self.Bind(wx.EVT_TOOL, self.OnTool)
-        
-        # default action (digitize new point, line, etc.)
-        self.action = { 'desc' : 'addLine',
-                        'type' : 'point',
-                        'id'   : self.addPoint }
-        
-        # list of available vector maps
-        self.UpdateListOfLayers(updateTool=True)
-        
-        # realize toolbar
-        self.Realize()
-        # workaround for Mac bug. May be fixed by 2.8.8, but not before then.
-        self.combo.Hide()
-        self.combo.Show()
-        
-        # disable undo/redo
-        self.EnableTool(self.undo, False)
-        
-        # toogle to pointer by default
-        self.OnTool(None)
-        
-        self.FixSize(width = 105)
-        
-    def ToolbarData(self):
-        """!
-        Toolbar data
-        """
-        data = []
-        
-        self.addPoint = wx.NewId()
-        self.addLine = wx.NewId()
-        self.addBoundary = wx.NewId()
-        self.addCentroid = wx.NewId()
-        self.moveVertex = wx.NewId()
-        self.addVertex = wx.NewId()
-        self.removeVertex = wx.NewId()
-        self.splitLine = wx.NewId()
-        self.editLine = wx.NewId()
-        self.moveLine = wx.NewId()
-        self.deleteLine = wx.NewId()
-        self.additionalTools = wx.NewId()
-        self.displayCats = wx.NewId()
-        self.displayAttr = wx.NewId()
-        self.copyCats = wx.NewId()
-        self.undo = wx.NewId()
-        self.settings = wx.NewId()
-        self.exit = wx.NewId()
-        
-        data = [("", "", "", "", "", "", ""),
-                (self.addPoint, "digAddPoint", Icons["digAddPoint"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digAddPoint"].GetLabel(), Icons["digAddPoint"].GetDesc(),
-                 self.OnAddPoint),
-                (self.addLine, "digAddLine", Icons["digAddLine"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digAddLine"].GetLabel(), Icons["digAddLine"].GetDesc(),
-                 self.OnAddLine),
-                (self.addBoundary, "digAddBoundary", Icons["digAddBoundary"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digAddBoundary"].GetLabel(), Icons["digAddBoundary"].GetDesc(),
-                 self.OnAddBoundary),
-                (self.addCentroid, "digAddCentroid", Icons["digAddCentroid"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digAddCentroid"].GetLabel(), Icons["digAddCentroid"].GetDesc(),
-                 self.OnAddCentroid),
-                (self.moveVertex, "digMoveVertex", Icons["digMoveVertex"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digMoveVertex"].GetLabel(), Icons["digMoveVertex"].GetDesc(),
-                 self.OnMoveVertex),
-                (self.addVertex, "digAddVertex", Icons["digAddVertex"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digAddVertex"].GetLabel(), Icons["digAddVertex"].GetDesc(),
-                 self.OnAddVertex),
-                (self.removeVertex, "digRemoveVertex", Icons["digRemoveVertex"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digRemoveVertex"].GetLabel(), Icons["digRemoveVertex"].GetDesc(),
-                 self.OnRemoveVertex),
-                (self.splitLine, "digSplitLine", Icons["digSplitLine"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digSplitLine"].GetLabel(), Icons["digSplitLine"].GetDesc(),
-                 self.OnSplitLine),
-                (self.editLine, "digEditLine", Icons["digEditLine"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digEditLine"].GetLabel(), Icons["digEditLine"].GetDesc(),
-                 self.OnEditLine),
-                (self.moveLine, "digMoveLine", Icons["digMoveLine"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digMoveLine"].GetLabel(), Icons["digMoveLine"].GetDesc(),
-                 self.OnMoveLine),
-                (self.deleteLine, "digDeleteLine", Icons["digDeleteLine"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digDeleteLine"].GetLabel(), Icons["digDeleteLine"].GetDesc(),
-                 self.OnDeleteLine),
-                (self.displayCats, "digDispCats", Icons["digDispCats"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digDispCats"].GetLabel(), Icons["digDispCats"].GetDesc(),
-                 self.OnDisplayCats),
-                (self.copyCats, "digCopyCats", Icons["digCopyCats"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digCopyCats"].GetLabel(), Icons["digCopyCats"].GetDesc(),
-                 self.OnCopyCA),
-                (self.displayAttr, "digDispAttr", Icons["digDispAttr"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digDispAttr"].GetLabel(), Icons["digDispAttr"].GetDesc(),
-                 self.OnDisplayAttr),
-                (self.additionalTools, "digAdditionalTools", Icons["digAdditionalTools"].GetBitmap(),
-                 wx.ITEM_CHECK, Icons["digAdditionalTools"].GetLabel(),
-                 Icons["digAdditionalTools"].GetDesc(),
-                 self.OnAdditionalToolMenu),
-                ("", "", "", "", "", "", ""),
-                (self.undo, "digUndo", Icons["digUndo"].GetBitmap(),
-                 wx.ITEM_NORMAL, Icons["digUndo"].GetLabel(), Icons["digUndo"].GetDesc(),
-                 self.OnUndo),
-                # data.append((self.undo, "digRedo", Icons["digRedo"].GetBitmap(),
-                #             wx.ITEM_NORMAL, Icons["digRedo"].GetLabel(), Icons["digRedo"].GetDesc(),
-                #             self.OnRedo))
-                (self.settings, "digSettings", Icons["digSettings"].GetBitmap(),
-                 wx.ITEM_NORMAL, Icons["digSettings"].GetLabel(), Icons["digSettings"].GetDesc(),
-                 self.OnSettings),
-                (self.exit, "digExit", Icons["quit"].GetBitmap(),
-                 wx.ITEM_NORMAL, Icons["digExit"].GetLabel(), Icons["digExit"].GetDesc(),
-                 self.OnExit)]
-        
-        return data
-    
-    def OnTool(self, event):
-        """!Tool selected -> disable selected tool in map toolbar"""
-        id = self.parent.toolbars['map'].GetAction(type='id')
-        self.parent.toolbars['map'].ToggleTool(id, False)
-        
-        # set cursor
-        cursor = self.parent.cursors["cross"]
-        self.parent.MapWindow.SetCursor(cursor)
-        
-        # pointer
-        self.parent.OnPointer(None)
-        
-        if event:
-            # deselect previously selected tool
-            id = self.action.get('id', -1)
-            if id != event.GetId():
-                self.ToggleTool(self.action['id'], False)
-            else:
-                self.ToggleTool(self.action['id'], True)
-            
-            self.action['id'] = event.GetId()
-            
-            event.Skip()
-        
-        self.ToggleTool(self.action['id'], True)
-        
-        # clear tmp canvas
-        if self.action['id'] != id:
-            self.parent.MapWindow.ClearLines(pdc=self.parent.MapWindow.pdcTmp)
-            if self.parent.digit and \
-                    len(self.parent.digit.driver.GetSelected()) > 0:
-                # cancel action
-                self.parent.MapWindow.OnMiddleDown(None)
-        
-        # set focus
-        self.parent.MapWindow.SetFocus()
-        
-    def OnAddPoint(self, event):
-        """!Add point to the vector map Laier"""
-        Debug.msg (2, "VDigitToolbar.OnAddPoint()")
-        self.action = { 'desc' : "addLine",
-                        'type' : "point",
-                        'id'   : self.addPoint }
-        self.parent.MapWindow.mouse['box'] = 'point'
-        
-    def OnAddLine(self, event):
-        """!Add line to the vector map layer"""
-        Debug.msg (2, "VDigitToolbar.OnAddLine()")
-        self.action = { 'desc' : "addLine",
-                        'type' : "line",
-                        'id'   : self.addLine }
-        self.parent.MapWindow.mouse['box'] = 'line'
-        ### self.parent.MapWindow.polycoords = [] # reset temp line
-                
-    def OnAddBoundary(self, event):
-        """!Add boundary to the vector map layer"""
-        Debug.msg (2, "VDigitToolbar.OnAddBoundary()")
-        if self.action['desc'] != 'addLine' or \
-                self.action['type'] != 'boundary':
-            self.parent.MapWindow.polycoords = [] # reset temp line
-        self.action = { 'desc' : "addLine",
-                        'type' : "boundary",
-                        'id'   : self.addBoundary }
-        self.parent.MapWindow.mouse['box'] = 'line'
-        
-    def OnAddCentroid(self, event):
-        """!Add centroid to the vector map layer"""
-        Debug.msg (2, "VDigitToolbar.OnAddCentroid()")
-        self.action = { 'desc' : "addLine",
-                        'type' : "centroid",
-                        'id'   : self.addCentroid }
-        self.parent.MapWindow.mouse['box'] = 'point'
-
-    def OnExit (self, event=None):
-        """!Quit digitization tool"""
-        # stop editing of the currently selected map layer
-        if self.mapLayer:
-            self.StopEditing()
-        
-        # close dialogs if still open
-        if self.settingsDialog:
-            self.settingsDialog.OnCancel(None)
-            
-        # set default mouse settings
-        self.parent.MapWindow.mouse['use'] = "pointer"
-        self.parent.MapWindow.mouse['box'] = "point"
-        self.parent.MapWindow.polycoords = []
-        
-        # disable the toolbar
-        self.parent.RemoveToolbar("vdigit")
-                
-    def OnMoveVertex(self, event):
-        """!Move line vertex"""
-        Debug.msg(2, "Digittoolbar.OnMoveVertex():")
-        self.action = { 'desc' : "moveVertex",
-                        'id'   : self.moveVertex }
-        self.parent.MapWindow.mouse['box'] = 'point'
-
-    def OnAddVertex(self, event):
-        """!Add line vertex"""
-        Debug.msg(2, "Digittoolbar.OnAddVertex():")
-        self.action = { 'desc' : "addVertex",
-                        'id'   : self.addVertex }
-        self.parent.MapWindow.mouse['box'] = 'point'
-        
-    def OnRemoveVertex(self, event):
-        """!Remove line vertex"""
-        Debug.msg(2, "Digittoolbar.OnRemoveVertex():")
-        self.action = { 'desc' : "removeVertex",
-                        'id'   : self.removeVertex }
-        self.parent.MapWindow.mouse['box'] = 'point'
-
-    def OnSplitLine(self, event):
-        """!Split line"""
-        Debug.msg(2, "Digittoolbar.OnSplitLine():")
-        self.action = { 'desc' : "splitLine",
-                        'id'   : self.splitLine }
-        self.parent.MapWindow.mouse['box'] = 'point'
-
-    def OnEditLine(self, event):
-        """!Edit line"""
-        Debug.msg(2, "Digittoolbar.OnEditLine():")
-        self.action = { 'desc' : "editLine",
-                        'id'   : self.editLine }
-        self.parent.MapWindow.mouse['box'] = 'line'
-
-    def OnMoveLine(self, event):
-        """!Move line"""
-        Debug.msg(2, "Digittoolbar.OnMoveLine():")
-        self.action = { 'desc' : "moveLine",
-                        'id'   : self.moveLine }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnDeleteLine(self, event):
-        """!Delete line"""
-        Debug.msg(2, "Digittoolbar.OnDeleteLine():")
-        self.action = { 'desc' : "deleteLine",
-                        'id'   : self.deleteLine }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnDisplayCats(self, event):
-        """!Display/update categories"""
-        Debug.msg(2, "Digittoolbar.OnDisplayCats():")
-        self.action = { 'desc' : "displayCats",
-                        'id'   : self.displayCats }
-        self.parent.MapWindow.mouse['box'] = 'point'
-
-    def OnDisplayAttr(self, event):
-        """!Display/update attributes"""
-        Debug.msg(2, "Digittoolbar.OnDisplayAttr():")
-        self.action = { 'desc' : "displayAttrs",
-                        'id'   : self.displayAttr }
-        self.parent.MapWindow.mouse['box'] = 'point'
-
-    def OnCopyCA(self, event):
-        """!Copy categories/attributes menu"""
-        point = wx.GetMousePosition()
-        toolMenu = wx.Menu()
-        # Add items to the menu
-        cats = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                           text=_('Copy categories'),
-                           kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(cats)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnCopyCats, cats)
-        if self.action['desc'] == "copyCats":
-            cats.Check(True)
-        
-        attrb = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                            text=_('Duplicate attributes'),
-                            kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(attrb)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnCopyAttrb, attrb)
-        if self.action['desc'] == "copyAttrs":
-            attrb.Check(True)
-        
-        # Popup the menu.  If an item is selected then its handler
-        # will be called before PopupMenu returns.
-        self.parent.MapWindow.PopupMenu(toolMenu)
-        toolMenu.Destroy()
-        
-        if self.action['desc'] == "addPoint":
-            self.ToggleTool(self.copyCats, False)
-        
-    def OnCopyCats(self, event):
-        """!Copy categories"""
-        if self.action['desc'] == 'copyCats': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.copyCats, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnCopyCats():")
-        self.action = { 'desc' : "copyCats",
-                        'id'   : self.copyCats }
-        self.parent.MapWindow.mouse['box'] = 'point'
-
-    def OnCopyAttrb(self, event):
-        if self.action['desc'] == 'copyAttrs': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.copyCats, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnCopyAttrb():")
-        self.action = { 'desc' : "copyAttrs",
-                        'id'   : self.copyCats }
-        self.parent.MapWindow.mouse['box'] = 'point'
-        
-    def OnUndo(self, event):
-        """!Undo previous changes"""
-        self.parent.digit.Undo()
-        
-        event.Skip()
-
-    def EnableUndo(self, enable=True):
-        """!Enable 'Undo' in toolbar
-        
-        @param enable False for disable
-        """
-        if enable:
-            if self.GetToolEnabled(self.undo) is False:
-                self.EnableTool(self.undo, True)
-        else:
-            if self.GetToolEnabled(self.undo) is True:
-                self.EnableTool(self.undo, False)
-        
-    def OnSettings(self, event):
-        """!Show settings dialog"""
-        if self.parent.digit is None:
-            reload(vdigit)
-            from vdigit import VDigit as VDigit
-            try:
-                self.parent.digit = VDigit(mapwindow=self.parent.MapWindow)
-            except SystemExit:
-                self.parent.digit = None
-        
-        if not self.settingsDialog:
-            self.settingsDialog = VDigitSettingsDialog(parent=self.parent, title=_("Digitization settings"),
-                                                       style=wx.DEFAULT_DIALOG_STYLE)
-            self.settingsDialog.Show()
-
-    def OnAdditionalToolMenu(self, event):
-        """!Menu for additional tools"""
-        point = wx.GetMousePosition()
-        toolMenu = wx.Menu()
-        # Add items to the menu
-        copy = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                           text=_('Copy features from (background) vector map'),
-                           kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(copy)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnCopy, copy)
-        if self.action['desc'] == "copyLine":
-            copy.Check(True)
-        
-        flip = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                           text=_('Flip selected lines/boundaries'),
-                           kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(flip)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnFlip, flip)
-        if self.action['desc'] == "flipLine":
-            flip.Check(True)
-        
-        merge = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                            text=_('Merge selected lines/boundaries'),
-                            kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(merge)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnMerge, merge)
-        if self.action['desc'] == "mergeLine":
-            merge.Check(True)
-        
-        breakL = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                             text=_('Break selected lines/boundaries at intersection'),
-                             kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(breakL)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnBreak, breakL)
-        if self.action['desc'] == "breakLine":
-            breakL.Check(True)
-        
-        snap = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                           text=_('Snap selected lines/boundaries (only to nodes)'),
-                           kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(snap)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnSnap, snap)
-        if self.action['desc'] == "snapLine":
-            snap.Check(True)
-        
-        connect = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                              text=_('Connect selected lines/boundaries'),
-                              kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(connect)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnConnect, connect)
-        if self.action['desc'] == "connectLine":
-            connect.Check(True)
-        
-        query = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                            text=_('Query features'),
-                            kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(query)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnQuery, query)
-        if self.action['desc'] == "queryLine":
-            query.Check(True)
-        
-        zbulk = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                            text=_('Z bulk-labeling of 3D lines'),
-                            kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(zbulk)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnZBulk, zbulk)
-        if self.action['desc'] == "zbulkLine":
-            zbulk.Check(True)
-        
-        typeconv = wx.MenuItem(parentMenu=toolMenu, id=wx.ID_ANY,
-                               text=_('Feature type conversion'),
-                               kind=wx.ITEM_CHECK)
-        toolMenu.AppendItem(typeconv)
-        self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnTypeConversion, typeconv)
-        if self.action['desc'] == "typeConv":
-            typeconv.Check(True)
-        
-        # Popup the menu.  If an item is selected then its handler
-        # will be called before PopupMenu returns.
-        self.parent.MapWindow.PopupMenu(toolMenu)
-        toolMenu.Destroy()
-        
-        if self.action['desc'] == 'addPoint':
-            self.ToggleTool(self.additionalTools, False)
-        
-    def OnCopy(self, event):
-        """!Copy selected features from (background) vector map"""
-        if self.action['desc'] == 'copyLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnCopy():")
-        self.action = { 'desc' : "copyLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnFlip(self, event):
-        """!Flip selected lines/boundaries"""
-        if self.action['desc'] == 'flipLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnFlip():")
-        self.action = { 'desc' : "flipLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnMerge(self, event):
-        """!Merge selected lines/boundaries"""
-        if self.action['desc'] == 'mergeLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnMerge():")
-        self.action = { 'desc' : "mergeLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnBreak(self, event):
-        """!Break selected lines/boundaries"""
-        if self.action['desc'] == 'breakLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnBreak():")
-        self.action = { 'desc' : "breakLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnSnap(self, event):
-        """!Snap selected features"""
-        if self.action['desc'] == 'snapLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnSnap():")
-        self.action = { 'desc' : "snapLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnConnect(self, event):
-        """!Connect selected lines/boundaries"""
-        if self.action['desc'] == 'connectLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnConnect():")
-        self.action = { 'desc' : "connectLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnQuery(self, event):
-        """!Query selected lines/boundaries"""
-        if self.action['desc'] == 'queryLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnQuery(): %s" % \
-                      UserSettings.Get(group='vdigit', key='query', subkey='selection'))
-        self.action = { 'desc' : "queryLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnZBulk(self, event):
-        """!Z bulk-labeling selected lines/boundaries"""
-        if not self.parent.digit.driver.Is3D():
-            wx.MessageBox(parent=self.parent,
-                          message=_("Vector map is not 3D. Operation canceled."),
-                          caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
-            return
-        
-        if self.action['desc'] == 'zbulkLine': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnZBulk():")
-        self.action = { 'desc' : "zbulkLine",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'line'
-
-    def OnTypeConversion(self, event):
-        """!Feature type conversion
-
-        Supported conversions:
-         - point <-> centroid
-         - line <-> boundary
-        """
-        if self.action['desc'] == 'typeConv': # select previous action
-            self.ToggleTool(self.addPoint, True)
-            self.ToggleTool(self.additionalTools, False)
-            self.OnAddPoint(event)
-            return
-        
-        Debug.msg(2, "Digittoolbar.OnTypeConversion():")
-        self.action = { 'desc' : "typeConv",
-                        'id'   : self.additionalTools }
-        self.parent.MapWindow.mouse['box'] = 'box'
-
-    def OnSelectMap (self, event):
-        """
-        Select vector map layer for editing
-
-        If there is a vector map layer already edited, this action is
-        firstly terminated. The map layer is closed. After this the
-        selected map layer activated for editing.
-        """
-        if event.GetSelection() == 0: # create new vector map layer
-            if self.mapLayer:
-                openVectorMap = self.mapLayer.GetName(fullyQualified=False)['name']
-            else:
-                openVectorMap = None
-            mapName = gdialogs.CreateNewVector(self.parent,
-                                               exceptMap = openVectorMap, log = self.log,
-                                               cmd = (('v.edit',
-                                                       { 'tool' : 'create' },
-                                                       'map')),
-                                               disableAdd=True)[0]
-            if mapName:
-                # add layer to map layer tree
-                if self.layerTree:
-                    self.layerTree.AddLayer(ltype='vector',
-                                            lname=mapName,
-                                            lchecked=True,
-                                            lopacity=1.0,
-                                            lcmd=['d.vect', 'map=%s' % mapName])
-                    
-                    vectLayers = self.UpdateListOfLayers(updateTool=True)
-                    selection = vectLayers.index(mapName)
-                else:
-                    pass # TODO (no Layer Manager)
-            else:
-                self.combo.SetValue(_('Select vector map'))
-                return 
-        else:
-            selection = event.GetSelection() - 1 # first option is 'New vector map'
-        
-        # skip currently selected map
-        if self.layers[selection] == self.mapLayer:
-            return False
-        
-        if self.mapLayer:
-            # deactive map layer for editing
-            self.StopEditing()
-        
-        # select the given map layer for editing
-        self.StartEditing(self.layers[selection])
-        
-        event.Skip()
-
-        return True
-    
-    def StartEditing (self, mapLayer):
-        """
-        Start editing selected vector map layer.
-
-        @param mapLayer reference to MapLayer instance
-        """
-        # deactive layer
-        self.mapcontent.ChangeLayerActive(mapLayer, False)
-        
-        # clean map canvas
-        ### self.parent.MapWindow.EraseMap()
-        
-        # unset background map if needed
-        if mapLayer:
-            if UserSettings.Get(group='vdigit', key='bgmap',
-                                subkey='value', internal=True) == mapLayer.GetName():
-                UserSettings.Set(group='vdigit', key='bgmap',
-                                 subkey='value', value='', internal=True)
-            
-            self.parent.statusbar.SetStatusText(_("Please wait, "
-                                                  "opening vector map <%s> for editing...") % \
-                                                    mapLayer.GetName(),
-                                                0)
-        
-        # reload vdigit module
-        reload(vdigit)
-        from vdigit import VDigit as VDigit
-        # use vdigit's PseudoDC
-        self.parent.MapWindow.DefinePseudoDC(vdigit = True)
-        self.parent.digit = VDigit(mapwindow=self.parent.MapWindow)
-        
-        self.mapLayer = mapLayer
-        
-        # open vector map
-        try:
-            if not self.parent.MapWindow.CheckPseudoDC():
-                raise gcmd.DigitError(parent=self.parent,
-                                      message=_("Unable to initialize display driver of vector "
-                                                "digitizer. See 'Command output' for details."))
-            self.parent.digit.SetMapName(mapLayer.GetName())
-        except gcmd.DigitError, e:
-            self.mapLayer = None
-            self.StopEditing()
-            print >> sys.stderr, e # wxMessageBox
-            return False
-        
-        # update toolbar
-        self.combo.SetValue(mapLayer.GetName())
-        self.parent.toolbars['map'].combo.SetValue (_('Digitize'))
-        
-        Debug.msg (4, "VDigitToolbar.StartEditing(): layer=%s" % mapLayer.GetName())
-        
-        # change cursor
-        if self.parent.MapWindow.mouse['use'] == 'pointer':
-            self.parent.MapWindow.SetCursor(self.parent.cursors["cross"])
-        
-        # create pseudoDC for drawing the map
-        self.parent.MapWindow.pdcVector = vdigit.PseudoDC()
-        self.parent.digit.driver.SetDevice(self.parent.MapWindow.pdcVector)
-
-        if not self.parent.MapWindow.resize:
-            self.parent.MapWindow.UpdateMap(render=True)
-        
-        opacity = mapLayer.GetOpacity(float=True)
-        if opacity < 1.0:
-            alpha = int(opacity * 255)
-            self.parent.digit.driver.UpdateSettings(alpha)
-        
-        return True
-
-    def StopEditing(self):
-        """!Stop editing of selected vector map layer.
-
-        @return True on success
-        @return False on failure
-        """
-        # use wx's PseudoDC
-        self.parent.MapWindow.DefinePseudoDC(vdigit = False)
-        
-        self.combo.SetValue (_('Select vector map'))
-        
-        # save changes
-        if self.mapLayer:
-            Debug.msg (4, "VDigitToolbar.StopEditing(): layer=%s" % self.mapLayer.GetName())
-            if UserSettings.Get(group='vdigit', key='saveOnExit', subkey='enabled') is False:
-                if self.parent.digit.GetUndoLevel() > -1:
-                    dlg = wx.MessageDialog(parent=self.parent,
-                                           message=_("Do you want to save changes "
-                                                     "in vector map <%s>?") % self.mapLayer.GetName(),
-                                           caption=_("Save changes?"),
-                                           style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
-                    if dlg.ShowModal() == wx.ID_NO:
-                        # revert changes
-                        self.parent.digit.Undo(0)
-                    dlg.Destroy()
-            
-            self.parent.statusbar.SetStatusText(_("Please wait, "
-                                                  "closing and rebuilding topology of "
-                                                  "vector map <%s>...") % self.mapLayer.GetName(),
-                                                0)
-        
-            self.parent.digit.SetMapName(None) # -> close map
-        
-            # re-active layer 
-            item = self.parent.tree.FindItemByData('maplayer', self.mapLayer)
-            if item and self.parent.tree.IsItemChecked(item):
-                self.mapcontent.ChangeLayerActive(self.mapLayer, True)
-        
-        # change cursor
-        self.parent.MapWindow.SetCursor(self.parent.cursors["default"])
-        
-        # disable pseudodc for vector map layer
-        self.parent.MapWindow.pdcVector = None
-        self.parent.digit.driver.SetDevice(None)
-        
-        # close dialogs
-        for dialog in ('attributes', 'category'):
-            if self.parent.dialogs[dialog]:
-                self.parent.dialogs[dialog].Close()
-                self.parent.dialogs[dialog] = None
-        
-        self.parent.digit.__del__() # FIXME: destructor is not called here (del)
-        self.parent.digit = None
-        
-        self.mapLayer = None
-        
-        self.parent.MapWindow.redrawAll = True
-        
-        return True
-    
-    def UpdateListOfLayers (self, updateTool=False):
-        """!
-        Update list of available vector map layers.
-        This list consists only editable layers (in the current mapset)
-
-        Optionally also update toolbar
-        """
-        Debug.msg (4, "VDigitToolbar.UpdateListOfLayers(): updateTool=%d" % \
-                   updateTool)
-        
-        layerNameSelected = None
-         # name of currently selected layer
-        if self.mapLayer:
-            layerNameSelected = self.mapLayer.GetName()
-        
-        # select vector map layer in the current mapset
-        layerNameList = []
-        self.layers = self.mapcontent.GetListOfLayers(l_type="vector",
-                                                      l_mapset=grass.gisenv()['MAPSET'])
-        for layer in self.layers:
-            if not layer.name in layerNameList: # do not duplicate layer
-                layerNameList.append (layer.GetName())
-        
-        if updateTool: # update toolbar
-            if not self.mapLayer:
-                value = _('Select vector map')
-            else:
-                value = layerNameSelected
-
-            if not self.comboid:
-                self.combo = wx.ComboBox(self, id=wx.ID_ANY, value=value,
-                                         choices=[_('New vector map'), ] + layerNameList, size=(115, -1),
-                                         style=wx.CB_READONLY)
-                self.comboid = self.InsertControl(0, self.combo)
-                self.parent.Bind(wx.EVT_COMBOBOX, self.OnSelectMap, self.comboid)
-            else:
-                self.combo.SetItems([_('New vector map'), ] + layerNameList)
-            
-            self.Realize()
-        
-        return layerNameList
-
-    def GetLayer(self):
-        """!Get selected layer for editing -- MapLayer instance"""
-        return self.mapLayer
-    
-class ProfileToolbar(AbstractToolbar):
-    """!
-    Toolbar for profiling raster map
-    """ 
-    def __init__(self, parent):
-        AbstractToolbar.__init__(self, parent)
-        
-        self.InitToolbar(self.ToolbarData())
-        
-        # realize the toolbar
-        self.Realize()
-        
-    def ToolbarData(self):
-        """!Toolbar data"""
-        self.transect = wx.NewId()
-        self.addraster = wx.NewId()
-        self.draw = wx.NewId()
-        self.options = wx.NewId()
-        self.drag = wx.NewId()
-        self.zoom = wx.NewId()
-        self.unzoom = wx.NewId()
-        self.erase = wx.NewId()
-        self.save = wx.NewId()
-        self.printer = wx.NewId()
-        self.quit = wx.NewId()
-                
-        # tool, label, bitmap, kind, shortHelp, longHelp, handler
-        return   (
-            (self.addraster, 'raster', Icons["addrast"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["addrast"].GetLabel(), Icons["addrast"].GetDesc(),
-             self.parent.OnSelectRaster),
-            (self.transect, 'transect', Icons["transect"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["transect"].GetLabel(), Icons["transect"].GetDesc(),
-             self.parent.OnDrawTransect),
-            (self.draw, 'profiledraw', Icons["profiledraw"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["profiledraw"].GetLabel(), Icons["profiledraw"].GetDesc(),
-             self.parent.OnCreateProfile),
-            (self.options, 'options', Icons["profileopt"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["profileopt"].GetLabel(), Icons["profileopt"].GetDesc(),
-             self.parent.ProfileOptionsMenu),
-            (self.drag, 'drag', Icons['pan'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["pan"].GetLabel(), Icons["pan"].GetDesc(),
-             self.parent.OnDrag),
-            (self.zoom, 'zoom', Icons['zoom_in'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["zoom_in"].GetLabel(), Icons["zoom_in"].GetDesc(),
-             self.parent.OnZoom),
-            (self.unzoom, 'unzoom', Icons['zoom_back'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["zoom_back"].GetLabel(), Icons["zoom_back"].GetDesc(),
-             self.parent.OnRedraw),
-            (self.erase, 'erase', Icons["erase"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(),
-             self.parent.OnErase),
-            ("", "", "", "", "", "", ""),
-            (self.save, 'save', Icons["savefile"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["savefile"].GetLabel(), Icons["savefile"].GetDesc(),
-             self.parent.SaveToFile),
-            (self.printer, 'print', Icons["printmap"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["printmap"].GetLabel(), Icons["printmap"].GetDesc(),
-             self.parent.PrintMenu),
-            (self.quit, 'quit', Icons["quit"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["quit"].GetLabel(), Icons["quit"].GetDesc(),
-             self.parent.OnQuit),
-            )
-    
-class NvizToolbar(AbstractToolbar):
-    """!
-    Nviz toolbar
-    """
-    def __init__(self, parent, mapcontent):
-        self.mapcontent = mapcontent
-        AbstractToolbar.__init__(self, parent)
-        
-        self.InitToolbar(self.ToolbarData())
-        
-        # realize the toolbar
-        self.Realize()
-        
-    def ToolbarData(self):
-        """!Toolbar data"""
-        self.settings = wx.NewId()
-        self.quit = wx.NewId()
-        
-        # tool, label, bitmap, kind, shortHelp, longHelp, handler
-        return   (
-            (self.settings, "settings", Icons["nvizSettings"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["nvizSettings"].GetLabel(), Icons["nvizSettings"].GetDesc(),
-             self.OnSettings),
-            (self.quit, 'quit', Icons["quit"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["quit"].GetLabel(), Icons["quit"].GetDesc(),
-             self.OnExit),
-            )
-    
-    def OnSettings(self, event):
-        win = self.parent.nvizToolWin
-        if not win.IsShown():
-            self.parent.nvizToolWin.Show()
-        else:
-            self.parent.nvizToolWin.Hide()
-
-    def OnExit (self, event=None):
-        """!Quit nviz tool (swith to 2D mode)"""
-        # hide dialogs if still open
-        if self.parent.nvizToolWin:
-            self.parent.nvizToolWin.Hide()
-        
-        # set default mouse settings
-        self.parent.MapWindow.mouse['use'] = "pointer"
-        self.parent.MapWindow.mouse['box'] = "point"
-        self.parent.MapWindow.polycoords = []
-        
-        # disable the toolbar
-        self.parent.RemoveToolbar("nviz")
-
-class ModelToolbar(AbstractToolbar):
-    """!Graphical modeler toolbar (see gmodeler.py)
-    """
-    def __init__(self, parent):
-        AbstractToolbar.__init__(self, parent)
-        
-        self.InitToolbar(self.ToolbarData())
-        
-        # realize the toolbar
-        self.Realize()
-        
-    def ToolbarData(self):
-        """!Toolbar data"""
-        self.new = wx.NewId()
-        self.open = wx.NewId()
-        self.save = wx.NewId()
-        self.image = wx.NewId()
-        self.python = wx.NewId()
-        self.action = wx.NewId()
-        self.data = wx.NewId()
-        self.relation = wx.NewId()
-        self.run = wx.NewId()
-        self.validate = wx.NewId()
-        self.quit = wx.NewId()
-        
-        # tool, label, bitmap, kind, shortHelp, longHelp, handler
-        return (
-            (self.new, 'new', Icons['modelNew'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelNew'].GetLabel(), Icons['modelNew'].GetDesc(),
-             self.parent.OnModelNew),
-            (self.open, 'open', Icons['modelOpen'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelOpen'].GetLabel(), Icons['modelOpen'].GetDesc(),
-             self.parent.OnModelOpen),
-            (self.save, 'save', Icons['modelSave'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelSave'].GetLabel(), Icons['modelSave'].GetDesc(),
-             self.parent.OnModelSave),
-            (self.image, 'image', Icons['modelToImage'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelToImage'].GetLabel(), Icons['modelToImage'].GetDesc(),
-             self.parent.OnExportImage),
-            (self.python, 'python', Icons['modelToPython'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelToPython'].GetLabel(), Icons['modelToPython'].GetDesc(),
-             self.parent.OnExportPython),
-            ('', '', '', '', '', '', ''),
-            (self.data, 'data', Icons['modelDataAdd'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelDataAdd'].GetLabel(), Icons['modelDataAdd'].GetDesc(),
-             self.parent.OnAddData),
-            (self.action, 'action', Icons['modelActionAdd'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelActionAdd'].GetLabel(), Icons['modelActionAdd'].GetDesc(),
-             self.parent.OnAddAction),
-            (self.relation, 'relation', Icons['modelRelation'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelRelation'].GetLabel(), Icons['modelRelation'].GetDesc(),
-             self.parent.OnDefineRelation),
-            ('', '', '', '', '', '', ''),
-            (self.run, 'run', Icons['modelRun'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelRun'].GetLabel(), Icons['modelRun'].GetDesc(),
-             self.parent.OnRunModel),
-            (self.validate, 'validate', Icons['modelValidate'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['modelValidate'].GetLabel(), Icons['modelValidate'].GetDesc(),
-             self.parent.OnValidateModel),
-            ('', '', '', '', '', '', ''),
-            (self.quit, 'quit', Icons['quit'].GetBitmap(),
-             wx.ITEM_NORMAL, Icons['quit'].GetLabel(), Icons['quit'].GetDesc(),
-             self.parent.OnCloseWindow),
-            )
-    
-    



More information about the grass-commit mailing list