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

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Apr 25 06:45:30 EDT 2010


Author: rashadkm
Date: 2010-04-25 06:45:29 -0400 (Sun, 25 Apr 2010)
New Revision: 42029

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
   grass-addons/gui/wxpython/data_catalog/toolbars.py
Log:
fixed for zoom and pan

Modified: grass-addons/gui/wxpython/data_catalog/LayerTree.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/LayerTree.py	2010-04-25 07:47:36 UTC (rev 42028)
+++ grass-addons/gui/wxpython/data_catalog/LayerTree.py	2010-04-25 10:45:29 UTC (rev 42029)
@@ -66,8 +66,11 @@
 
         self.gisdbase = gisdbase
 
+        self.layer_selected = None
 
+
         self.Map = None
+        self.root = None
         #if self.Map is not None:
         #    print self.Map.width
 
@@ -97,6 +100,7 @@
         for panel in child:
               if panel.GetName() == "pg_panel":
                 self.mapdisplay = panel
+                break
 
         self.MapWindow = self.mapdisplay.MapWindow2D
         self.Bind(CT.EVT_TREE_ITEM_CHECKED,     self.OnLayerChecked)
@@ -128,6 +132,8 @@
         frame = notebook.GetParent()
 
 
+
+
         if not self.ItemHasChildren(item):
             self.mapname =  self.GetItemText(item) + "@" + frame.cmbMapset.GetValue()
             #for f in frames:
@@ -137,7 +143,9 @@
             if pText == "Raster Map" :
                 if checked == True:
                     self.cmd= ['d.rast', str("map=" + self.mapname)]
-                    self.MapWindow.Map.AddLayer(type='raster', name=self.mapname, command=self.cmd)
+                    maplayer = self.MapWindow.Map.AddLayer(type='raster', name=self.mapname, command=self.cmd)
+                    self.layer_selected = maplayer
+                    self.type = 'raster'
                 else:
                     layers =  self.MapWindow.Map.GetListOfLayers( l_type='raster', l_name=self.mapname)
                     for layer in layers:
@@ -150,7 +158,9 @@
             if pText == "Vector Map" :
                 if checked == True:
                     self.cmd= ['d.vect', str("map=" + self.mapname)]
-                    self.MapWindow.Map.AddLayer(type='vector', name=self.mapname, command=self.cmd)
+                    maplayer = self.MapWindow.Map.AddLayer(type='vector', name=self.mapname, command=self.cmd)
+                    self.layer_selected = maplayer
+                    self.type = 'vector'
                 else:
                     layers =  self.MapWindow.Map.GetListOfLayers( l_type='vector', l_name=self.mapname)
                     for layer in layers:
@@ -165,17 +175,18 @@
 
 
 
+
     def AddTreeNodes(self,location,mapset):
         """
         Adds tree nodes. raster,vector and dbf files are identified using 
         their directory structure.
         """
         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")
+        self.root = self.AddRoot("Map Layers")
+        self.SetPyData(self.root, (None,None))
+        node_raster = self.AppendItem(self.root, "Raster Map")
+        node_vector = self.AppendItem(self.root, "Vector Map")
+        node_dbf = self.AppendItem(self.root, "DBF")
         treeNodes = [node_raster,node_vector,node_dbf]
 
         glocs = glob.glob(os.path.join(self.gisdbase,location, mapset,"*"))

Modified: grass-addons/gui/wxpython/data_catalog/catalog.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/catalog.py	2010-04-25 07:47:36 UTC (rev 42028)
+++ grass-addons/gui/wxpython/data_catalog/catalog.py	2010-04-25 10:45:29 UTC (rev 42029)
@@ -505,12 +505,17 @@
         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,frame=self,flag=True,gismgr=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.disp_idx = self.disp_idx + 1
         self.notebook.AddPage(self.pg_panel, text="Display "+ str(self.disp_idx), select = True)
 
+        self.goutput = goutput.GMConsole(self, pageid=1)
+        self.outpage = self.notebook.AddPage(self.goutput, text=_("Command console"))
 
+        self.notebook.SetSelection(0)
+
+
        # self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
        # self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnPageClosed)
 
@@ -1441,7 +1446,7 @@
         
         # available only for vector map layers
         try:
-            maptype = self.current.maptree.GetPyData(layer)[0]['maplayer'].type
+            maptype = self.current.maptree.type
         except:
             maptype = None
         
@@ -1453,15 +1458,15 @@
                           style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
             return
         
-        if not self.current.maptree.GetPyData(layer)[0]:
-            return
-        dcmd = self.current.maptree.GetPyData(layer)[0]['cmd']
+
+        dcmd = self.current.maptree.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),
@@ -1508,9 +1513,10 @@
 
         
         self.page = MapFrame(parent=self.notebook, id=wx.ID_ANY, Map=render.Map(),  size=globalvar.MAP_WINDOW_SIZE,frame=self)
-        self.notebook.AddPage(self.page, text="Display "+ str(self.disp_idx), select = True)
+        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)
 
 
         
@@ -1701,9 +1707,15 @@
     def AddRaster(self, event):
         if not self.current:
             self.NewDisplay()
+            
+        #cmd = ['d.rast']
+        #menuform.GUI().ParseCommand(cmd,parentframe=self)
 
-        self.current.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()
@@ -1911,7 +1923,7 @@
         index = 0
         while index < count:
             self.current = self.notebook.GetPage(index)
-            self.current.Map.Clean()
+            #self.current.Map.Clean()
             index = index+1
 
         self.notebook.DeleteAllPages()
@@ -1969,7 +1981,7 @@
 
         
     def OnRunScript():
-        print "for grass"
+        print "for grass7"
 
     def OnQuit():
         print "for grass7"
@@ -2018,42 +2030,20 @@
         self.Bind(wx.EVT_COMBOBOX,self.OnMapsetChange,self.cmbMapset)
         self.Bind(wx.EVT_COMBOBOX,self.OnLocationChange,self.cmbLocation)
 
-        #Event bindings for tree -(display,popup,label edit.)
-        #self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.ltree.OnDisplay,self.ltree)
-        #self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK,self.ltree.OnTreePopUp,self.ltree)
-        #self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.ltree.OnEndRename,self.ltree)
-       # self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.ltree.OnBeginRename,self.ltree)
 
-	    #Event bindings for tree menu
-        #self.Bind(wx.EVT_MENU,self.ltree.OnCopy,id=self.ltree.ID_COPY)
-        #self.Bind(wx.EVT_MENU,self.ltree.OnRename,id=self.ltree.ID_REN)
-        #self.Bind(wx.EVT_MENU,self.ltree.OnDelete,id=self.ltree.ID_DEL)
-        #self.Bind(wx.EVT_MENU,self.ltree.OnOssim,id=self.ltree.ID_OSSIM)
 
-
         self.Bind(wx.EVT_CLOSE,    self.OnCloseWindow)
 
 	    #Event bindings for v/r.info checkbox
 	    #self.Bind(wx.EVT_CHECKBOX, self.OnToggleInfo,self.chkInfo)
-	    #self.Bind(wx.EVT_CHECKBOX, self.OnToggleExpand,self.treeExpand)
-
-    def OnToggleExpand(self,event):
-        if self.treeExpand.IsChecked():
-            if not self.gmconsole:
-                self.gmconsole = GLog(parent=self)
-               # self.gmconsole.show()
-#                sys.exit(0)
-            else:
-                self.gmconsole.Raise()
-        else:
-            self.gmconsole.Destroy()
+       
  
     def doLayout(self):
 
 	    #combo panel sizers
         self.cmbSizer.Add(self.cmbLocation)
         self.cmbSizer.Add(self.cmbMapset)
-        self.cmbSizer.Add(self.treeExpand)
+        #self.cmbSizer.Add(self.treeExpand)
         #splitter window sizers
         self.mSizer.Add(self.cmbPanel,flag=wx.EXPAND)
         #self.mSizer.Add(self.win, 1, wx.EXPAND)
@@ -2124,7 +2114,7 @@
 #End of DataCatalog class
 
 
-
+    
 class CatalogApp(wx.App):
 
     def OnInit(self):

Modified: grass-addons/gui/wxpython/data_catalog/mapdisplay.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/mapdisplay.py	2010-04-25 07:47:36 UTC (rev 42028)
+++ grass-addons/gui/wxpython/data_catalog/mapdisplay.py	2010-04-25 10:45:29 UTC (rev 42029)
@@ -58,6 +58,12 @@
 grassPath = os.path.join(globalvar.ETCDIR, "python")
 sys.path.append(grassPath)
 
+import icons
+gmpath = icons.__path__[0]
+sys.path.append(gmpath)
+
+from icon  import Icons
+
 import render
 import toolbars
 import menuform
@@ -66,11 +72,12 @@
 import gcmd
 import dbm
 import histogram
-import profile
+import gui_modules.profile as profile
 import globalvar
 import utils
 import gdialogs
 import goutput
+import gui_modules.goutput as goutput
 from grass.script import core as grass
 from debug import Debug
 from preferences import globalSettings as UserSettings
@@ -263,14 +270,13 @@
         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
@@ -314,7 +320,7 @@
         #
         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)
@@ -324,14 +330,8 @@
         # 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()
+        self.DefinePseudoDC()
+
         # redraw all pdc's, pdcTmp layer is redrawn always (speed issue)
         self.redrawAll = True
 
@@ -339,16 +339,61 @@
         self._buffer = ''
 
         self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None)
-
+        self.Bind(wx.EVT_KEY_DOWN , self.OnKeyDown)
+        
         # vars for handling mouse clicks
         self.dragid   = -1
         self.lastpos  = (0, 0)
 
+
+
+
+
+
+
+    def DefinePseudoDC(self, vdigit = False):
+        """!Define PseudoDC class to use
+
+        @vdigit True to use PseudoDC from vdigit
+        """
+        # create PseudoDC used for background map, map decorations like scales and legends
+        self.pdc = self.PseudoDC(vdigit)
+        # used for digitization tool
+        self.pdcVector = None
+        # decorations (region box, etc.)
+        self.pdcDec = self.PseudoDC(vdigit)
+        # pseudoDC for temporal objects (select box, measurement tool, etc.)
+        self.pdcTmp = self.PseudoDC(vdigit)
+        
+    def PseudoDC(self, vdigit = False):
+        """!Create PseudoDC instance"""
+        if vdigit:
+            PseudoDC = VDigitPseudoDC
+        else:
+            PseudoDC = wx.PseudoDC
+        
+        return PseudoDC()
+    
+    def CheckPseudoDC(self):
+        """!Try to draw background
+        
+        @return True on success
+        @return False on failure
+        """
+        try:
+            self.pdc.BeginDrawing()
+            self.pdc.SetBackground(wx.Brush(self.GetBackgroundColour()))
+            self.pdc.BeginDrawing()
+        except StandardError, e:
+            traceback.print_exc(file = sys.stderr)
+            return False
+        
+        return True
+    
     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]
@@ -369,6 +414,7 @@
             bg = wx.Brush(self.GetBackgroundColour())
 
         pdc.SetBackground(bg)
+        
         ### pdc.Clear()
 
         Debug.msg (5, "BufferedWindow.Draw(): id=%s, pdctype=%s, coord=%s" % \
@@ -393,7 +439,7 @@
             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))
+            pdc.SetIdBounds(drawid, wx.Rect(coords[0],coords[1], w, h))
 
         elif pdctype == 'box': # draw a box on top of the map
             if self.pen:
@@ -405,24 +451,30 @@
                 y1 = min(coords[1],coords[3])
                 rwidth = x2-x1
                 rheight = y2-y1
-                rect = wx.Rect(x1,y1,rwidth,rheight)
+                rect = wx.Rect(x1, y1, rwidth, rheight)
                 pdc.DrawRectangleRect(rect)
-                pdc.SetIdBounds(drawid,rect)
-                # self.ovlcoords[drawid] = coords
-
+                pdc.SetIdBounds(drawid, rect)
+                
         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]))
+                pdc.DrawLinePoint(wx.Point(coords[0], coords[1]),wx.Point(coords[2], coords[3]))
+                pdc.SetIdBounds(drawid, wx.Rect(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)
+                ### pdc.DrawLines(coords)
+                if (len(coords) < 2):
+                    return
+                i = 1
+                while i < len(coords):
+                    pdc.DrawLinePoint(wx.Point(coords[i-1][0], coords[i-1][1]),
+                                      wx.Point(coords[i][0], coords[i][1]))
+                    i += 1
 
                 # get bounding rectangle for polyline
                 xlist = []
@@ -436,9 +488,9 @@
                     x2=max(xlist)
                     y1=min(ylist)
                     y2=max(ylist)
-                    pdc.SetIdBounds(drawid,(x1,y1,x2,y2))
+                    pdc.SetIdBounds(drawid, wx.Rect(x1,y1,x2,y2))
                     # self.ovlcoords[drawid] = [x1,y1,x2,y2]
-
+                    
         elif pdctype == 'point': # draw point
             if self.pen:
                 pdc.SetPen(self.pen)
@@ -447,7 +499,7 @@
                                coords[1] - 5,
                                coords[0] + 5,
                                coords[1] + 5)
-                pdc.SetIdBounds(drawid, coordsBound)
+                pdc.SetIdBounds(drawid, wx.Rect(coordsBound))
                 # self.ovlcoords[drawid] = coords
 
         elif pdctype == 'text': # draw text on top of map
@@ -465,7 +517,7 @@
                 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.SetIdBounds(drawid, wx.Rect(coords[0], coords[1], w, h))
             
         pdc.EndDrawing()
         
@@ -474,7 +526,7 @@
         return drawid
 
     def TextBounds(self, textinfo):
-        """
+        """!
         Return text boundary data
 
         @param textinfo text metadata (text, font, color, rotation)
@@ -508,8 +560,28 @@
         
         return coords, boxw, boxh
 
+    def OnKeyDown(self, event):
+        """!Key pressed"""
+        shift = event.ShiftDown()
+        kc = event.GetKeyCode()
+        
+        vdigitToolbar = self.parent.toolbars['vdigit']
+        ### vdigit
+        if vdigitToolbar:
+            event = None
+            if not shift:
+                if kc == ord('P'):
+                    event = wx.CommandEvent(winid = vdigitToolbar.addPoint)
+                    tool = vdigitToolbar.OnAddPoint
+                elif kc == ord('L'):
+                    event = wx.CommandEvent(winid = vdigitToolbar.addLine)
+                    tool = vdigitToolbar.OnAddLine
+            if event:
+                vdigitToolbar.OnTool(event)
+                tool(event)
+        
     def OnPaint(self, event):
-        """
+        """!
         Draw PseudoDC's to buffered paint DC
 
         self.pdc for background and decorations
@@ -519,7 +591,7 @@
         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"))
@@ -571,8 +643,8 @@
                 # 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 = self.PseudoDC(vdigit = False)
+            pdcLast.DrawBitmap(self.bufferLast, 0, 0, False)
             pdcLast.DrawToDC(dc)
 
         # draw decorations (e.g. region box)
@@ -591,7 +663,7 @@
             self.redrawAll = False
                 
     def OnSize(self, event):
-        """
+        """!
         Scale map image so that it is
         the same size as the Window
         """
@@ -610,7 +682,7 @@
 
         # 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)
@@ -627,7 +699,7 @@
         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.
         """
@@ -637,7 +709,7 @@
         event.Skip()
 
     def SaveToFile(self, FileName, FileType):
-        """
+        """!
         This draws the psuedo DC to a buffer that
         can be saved to a file.
         """
@@ -648,7 +720,7 @@
         self.buffer.SaveFile(FileName, FileType)
 
     def GetOverlay(self):
-        """
+        """!
         Converts rendered overlay files to wx.Image
 
         Updates self.imagedict
@@ -666,7 +738,7 @@
         return imgs
 
     def GetImage(self):
-        """
+        """!
         Converts redered map files to wx.Image
 
         Updates self.imagedict (id=99)
@@ -685,185 +757,181 @@
         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()
+        start = time.clock()
+        
+        self.resize = False
 
+        # if len(self.Map.GetListOfLayers()) == 0:
+        #    return False
+        
+        if self.img is None:
+            render = True
 
-            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)
+        #
+        # initialize process bar (only on 'render')
+        #
+        if render is True or renderVector is True:
+            self.parent.statusbarWin['progress'].Show()
+            if self.parent.statusbarWin['progress'].GetRange() > 0:
+                self.parent.statusbarWin['progress'].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.statusbarWin['resolution'].IsChecked():
+                # use computation region resolution for rendering
+                windres = True
             else:
-                self.mapfile = self.Map.Render(force=False, mapWindow=self.parent)
+                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
             
-            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
+        #
+        # 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.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
+            if self.pdcVector:
                 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']
+            try:
+                item = self.tree.FindItemByData('maplayer', digitToolbar.GetLayer())
+            except TypeError:
+                item = None
             
-            #
-            # 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'])
+            if item and self.tree.IsItemChecked(item):
+                self.parent.digit.driver.DrawMap()
 
-            for id in self.textdict.keys():
-                self.Draw(self.pdc, img=self.textdict[id], drawid=id,
-                          pdctype='text', coords=[10, 10, 10, 10])
+            # 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']:
+                        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'])
 
-            # 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'))
+        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 not self.parent.IsStandalone() and \
+                self.parent.GetLayerManager().georectifying:
+            # -> georectifier (redraw GCPs)
+            if self.parent.toolbars['georect']:
+                coordtype = 'gcpcoord'
             else:
-                self.parent.maskInfo.SetLabel('')
+                coordtype = 'mapcoord'
+            self.parent.GetLayerManager().georectifying.DrawGCP(coordtype)
             
-            Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s -> time=%g" % \
-                       (render, renderVector, (stop-start)))
+        # 
+        # 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"])
             
-            return True
+        stop = time.clock()
+        
+        #
+        # hide process bar
+        #
+        self.parent.statusbarWin['progress'].Hide()
 
+        #
+        # update statusbar 
+        #
+        ### self.Map.SetRegion()
+        self.parent.StatusbarUpdate()
+        if grass.find_file(name = 'MASK', element = 'cell')['name']:
+            # mask found
+            self.parent.statusbarWin['mask'].SetLabel(_('MASK'))
+        else:
+            self.parent.statusbarWin['mask'].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,
@@ -891,7 +959,7 @@
             self.DrawLines(pdc=self.pdcDec, polycoords=self.regionCoords)
 
     def IsInRegion(self, region, refRegion):
-        """
+        """!
         Test if 'region' is inside of 'refRegion'
 
         @param region input region
@@ -909,7 +977,7 @@
         return False
 
     def EraseMap(self):
-        """
+        """!
         Erase the canvas
         """
         self.Draw(self.pdc, pdctype='clear')
@@ -921,25 +989,25 @@
         self.Draw(self.pdcTmp, pdctype='clear')
         
     def DragMap(self, moveto):
-        """
+        """!
         Drag the entire map image for panning.
+
+        @param moveto dx,dy
         """
-
         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
@@ -949,6 +1017,9 @@
         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)
@@ -957,6 +1028,8 @@
         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)
@@ -965,13 +1038,13 @@
         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
+#        self.redrawAll = False
         
         if not pdc:
             return
@@ -990,8 +1063,13 @@
             mousecoords = [begin[0], begin[1],
                            end[0], end[1]]
             r = pdc.GetIdBounds(boxid)
-            r.Inflate(4,4)
-            pdc.ClearId(boxid)
+            if type(r) is list:
+                r = wx.Rect(r[0], r[1], r[2], r[3])
+            r.Inflate(4, 4)
+            try:
+                pdc.ClearId(boxid)
+            except:
+                pass
             self.RefreshRect(r, False)
             pdc.SetId(boxid)
             self.Draw(pdc, drawid=boxid, pdctype='box', coords=mousecoords)
@@ -1011,11 +1089,10 @@
                 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
@@ -1048,7 +1125,7 @@
 
     def DrawCross(self, pdc, coords, size, rotation=0,
                   text=None, textAlign='lr', textOffset=(5, 5)):
-        """Draw cross in PseudoDC
+        """!Draw cross in PseudoDC
 
         @todo implement rotation
 
@@ -1086,7 +1163,7 @@
         return self.lineid
 
     def MouseActions(self, event):
-        """
+        """!
         Mouse motion and button click notifier
         """
         if not self.processMouse:
@@ -1119,6 +1196,10 @@
         elif event.MiddleDown():
             self.OnMiddleDown(event)
 
+        # middle mouse button relesed
+        elif event.MiddleUp():
+            self.OnMiddleUp(event)
+        
         # right mouse button pressed
         elif event.RightDown():
             self.OnRightDown(event)
@@ -1129,11 +1210,11 @@
 
         elif event.Moving():
             self.OnMouseMoving(event)
-
-#        event.Skip()
         
+        # event.Skip()
+        
     def OnMouseWheel(self, event):
-        """
+        """!
         Mouse wheel moved
         """
         self.processMouse = False
@@ -1145,7 +1226,7 @@
                  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:
@@ -1167,7 +1248,7 @@
 #        event.Skip()
 
     def OnDragging(self, event):
-        """
+        """!
         Mouse dragging with left button down
         """
         Debug.msg (5, "BufferedWindow.MouseAction(): Dragging")
@@ -1175,19 +1256,20 @@
         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':
+        if self.mouse['use'] == 'pan' or \
+                event.MiddleIsDown():
             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 
@@ -1200,18 +1282,336 @@
                     digitClass.driver.GetSelected() > 0)):
                 # draw box only when left mouse button is pressed
                 self.MouseDraw(pdc=self.pdcTmp)
-      
-#        event.Skip()
+        
+        # event.Skip()
 
+    def OnLeftDownVDigitAddLine(self, event):
+        """!
+        Left mouse button down - vector digitizer add new line
+        action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        try:
+            mapLayer = digitToolbar.GetLayer().GetName()
+        except:
+            return
+        
+        if digitToolbar.GetAction('type') in ["point", "centroid"]:
+            # add new point
+            if digitToolbar.GetAction('type') == 'point':
+                point = True
+            else:
+                point = False
+
+            east, north = self.Pixel2Cell(self.mouse['begin'])
+            fid = digitClass.AddPoint(mapLayer, point, east, north)
+            if fid < 0:
+                return
+
+            self.UpdateMap(render=False) # redraw map
+            
+            # add new record into atribute table
+            if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled')  is True:
+                # 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'), )
+                        }}
+                
+                posWindow = self.ClientToScreen((self.mouse['end'][0] + self.dialogOffset,
+                                                 self.mouse['end'][1] + self.dialogOffset))
+                
+                addRecordDlg = dbm_dialogs.DisplayAttributesDialog(parent=self, map=mapLayer,
+                                                                   cats=cats,
+                                                                   pos=posWindow,
+                                                                   action="add")
+
+                if not point:
+                    self.__geomAttrb(fid, addRecordDlg, 'area', digitClass,
+                                     digitToolbar.GetLayer())
+                    self.__geomAttrb(fid, addRecordDlg, 'perimeter', digitClass,
+                                     digitToolbar.GetLayer())
+
+                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()
+                    
+                    gcmd.RunCommand('db.execute',
+                                    parent = self,
+                                    quiet = True, 
+                                    input = sqlfile.name)
+                
+                if addRecordDlg.mapDBInfo:
+                    self.__updateATM()
+        
+        elif digitToolbar.GetAction('type') in ["line", "boundary"]:
+            # add new point to the line
+            self.polycoords.append(self.Pixel2Cell(event.GetPositionTuple()[:]))
+            self.DrawLines(pdc=self.pdcTmp)
+    
+    def __geomAttrb(self, fid, dialog, attrb, digit, mapLayer):
+        """!Trac geometry attributes?"""
+        item = self.tree.FindItemByData('maplayer', mapLayer)
+        vdigit = self.tree.GetPyData(item)[0]['vdigit']
+        if vdigit and \
+                vdigit.has_key('geomAttr') and \
+                vdigit['geomAttr'].has_key(attrb):
+            val = -1
+            if attrb == 'length':
+                val = digit.GetLineLength(fid)
+                type = attrb
+            elif attrb == 'area':
+                val = digit.GetAreaSize(fid)
+                type = attrb
+            elif attrb == 'perimeter':
+                val = digit.GetAreaPerimeter(fid)
+                type = 'length'
+            
+            if val > 0:
+                layer = int(UserSettings.Get(group='vdigit', key="layer", subkey='value'))
+                column = vdigit['geomAttr'][attrb]['column']
+                val = UnitsConvertValue(val, type, vdigit['geomAttr'][attrb]['units'])
+                dialog.SetColumnValue(layer, column, val)
+                dialog.OnReset()
+        
+    def __geomAttrbUpdate(self, fids):
+        """!Update geometry atrributes of currently selected features
+
+        @param fid list feature id
+        """
+        mapLayer = self.parent.toolbars['vdigit'].GetLayer()
+        vectorName =  mapLayer.GetName()
+        digit = self.parent.digit
+        item = self.tree.FindItemByData('maplayer', mapLayer)
+        vdigit = self.tree.GetPyData(item)[0]['vdigit']
+        
+        if vdigit is None or not vdigit.has_key('geomAttr'):
+            return
+        
+        dbInfo = gselect.VectorDBInfo(vectorName)
+        sqlfile = tempfile.NamedTemporaryFile(mode="w")
+        for fid in fids:
+            for layer, cats in digit.GetLineCats(fid).iteritems():
+                table = dbInfo.GetTable(layer)
+                for attrb, item in vdigit['geomAttr'].iteritems():
+                    val = -1
+                    if attrb == 'length':
+                        val = digit.GetLineLength(fid)
+                        type = attrb
+                    elif attrb == 'area':
+                        val = digit.GetAreaSize(fid)
+                        type = attrb
+                    elif attrb == 'perimeter':
+                        val = digit.GetAreaPerimeter(fid)
+                        type = 'length'
+
+                    if val < 0:
+                        continue
+                    val = UnitsConvertValue(val, type, item['units'])
+                    
+                    for cat in cats:
+                        sqlfile.write('UPDATE %s SET %s = %f WHERE %s = %d;\n' % \
+                                          (table, item['column'], val,
+                                           dbInfo.GetKeyColumn(layer), cat))
+            sqlfile.file.flush()
+            gcmd.RunCommand('db.execute',
+                            parent = True,
+                            quiet = True,
+                            input = sqlfile.name)
+            
+    def __updateATM(self):
+        """!Update open Attribute Table Manager
+
+        @todo: use AddDataRow() instead
+        """
+        # update ATM
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitVector = digitToolbar.GetLayer().GetName()
+                            
+        for atm in self.lmgr.dialogs['atm']:
+            atmVector = atm.GetVectorName()
+            if atmVector == digitVector:
+                layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
+                # TODO: use AddDataRow instead
+                atm.LoadData(layer)
+        
+    def OnLeftDownVDigitEditLine(self, event):
+        """!
+        Left mouse button down - vector digitizer edit linear feature
+        - add new vertex.
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        self.polycoords.append(self.Pixel2Cell(self.mouse['begin']))
+        self.vdigitMove['id'].append(wx.NewId())
+        self.DrawLines(pdc=self.pdcTmp)
+
+    def OnLeftDownVDigitMoveLine(self, event):
+        """!
+        Left mouse button down - vector digitizer move feature/vertex,
+        edit linear feature
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        self.vdigitMove = {}
+        # geographic coordinates of initial position (left-down)
+        self.vdigitMove['begin'] = None
+        # list of ids to modify    
+        self.vdigitMove['id'] = []
+        # ids geographic coordinates
+        self.vdigitMove['coord'] = {}
+                
+        if digitToolbar.GetAction() in ["moveVertex", "editLine"]:
+            # set pen
+            pcolor = UserSettings.Get(group='vdigit', key="symbol",
+                                      subkey=["highlight", "color"])
+            self.pen = self.polypen = wx.Pen(colour=pcolor,
+                                             width=2, style=wx.SHORT_DASH)
+            self.pdcTmp.SetPen(self.polypen)
+
+    def OnLeftDownVDigitDisplayCA(self, event):
+        """!
+        Left mouse button down - vector digitizer display categories
+        or attributes action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        try:
+            mapLayer = digitToolbar.GetLayer().GetName()
+        except:
+            return
+        
+        coords = self.Pixel2Cell(self.mouse['begin'])
+        
+        # unselect
+        digitClass.driver.SetSelected([])
+        
+        # select feature by point
+        cats = {}
+        if digitClass.driver.SelectLineByPoint(coords,
+                                               digitClass.GetSelectType()) is None:
+            return
+
+        if UserSettings.Get(group='vdigit', key='checkForDupl',
+                            subkey='enabled'):
+            lines = digitClass.driver.GetSelected()
+        else:
+            lines = (digitClass.driver.GetSelected()[0],) # only first found
+                        
+        for line in lines:
+            cats[line] = digitClass.GetLineCats(line)
+                   
+        posWindow = self.ClientToScreen((self.mouse['end'][0] + self.dialogOffset,
+                                         self.mouse['end'][1] + self.dialogOffset))
+    
+        if digitToolbar.GetAction() == "displayAttrs":
+            # select attributes based on coordinates (all layers)
+            if self.parent.dialogs['attributes'] is None:
+                self.parent.dialogs['attributes'] = \
+                    dbm_dialogs.DisplayAttributesDialog(parent=self, map=mapLayer,
+                                                        cats=cats,
+                                                        action="update")
+            else:
+                # upgrade dialog
+                self.parent.dialogs['attributes'].UpdateDialog(cats=cats)
+
+            if self.parent.dialogs['attributes']:
+                if len(cats.keys()) > 0:
+                    # highlight feature & re-draw map
+                    if not self.parent.dialogs['attributes'].IsShown():
+                        self.parent.dialogs['attributes'].Show()
+                else:
+                    if self.parent.dialogs['attributes'] and \
+                            self.parent.dialogs['attributes'].IsShown():
+                        self.parent.dialogs['attributes'].Hide()
+
+        else: # displayCats
+            if self.parent.dialogs['category'] is None:
+                # open new dialog
+                dlg = VDigitCategoryDialog(parent=self,
+                                           map=mapLayer,
+                                           cats=cats,
+                                           pos=posWindow,
+                                           title=_("Update categories"))
+                self.parent.dialogs['category'] = dlg
+            else:
+                # update currently open dialog
+                self.parent.dialogs['category'].UpdateDialog(cats=cats)
+                            
+            if self.parent.dialogs['category']:
+                if len(cats.keys()) > 0:
+                    # highlight feature & re-draw map
+                    if not self.parent.dialogs['category'].IsShown():
+                        self.parent.dialogs['category'].Show()
+                else:
+                    if self.parent.dialogs['category'].IsShown():
+                        self.parent.dialogs['category'].Hide()
+                
+        self.UpdateMap(render=False)
+ 
+    def OnLeftDownVDigitCopyCA(self, event):
+        """!
+        Left mouse button down - vector digitizer copy categories
+        or attributes action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        if not hasattr(self, "copyCatsList"):
+            self.copyCatsList = []
+        else:
+            self.copyCatsIds = []
+            self.mouse['box'] = 'box'
+        
+    def OnLeftDownVDigitCopyLine(self, event):
+        """!
+        Left mouse button down - vector digitizer copy lines action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        if not hasattr(self, "copyIds"):
+            self.copyIds = []
+            self.layerTmp = None
+        
+    def OnLeftDownVDigitBulkLine(self, event):
+        """!
+        Left mouse button down - vector digitizer label 3d vector
+        lines
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        if len(self.polycoords) > 1: # start new line
+            self.polycoords = []
+            self.ClearLines(pdc=self.pdcTmp)
+        self.polycoords.append(self.Pixel2Cell(event.GetPositionTuple()[:]))
+        if len(self.polycoords) == 1:
+            begin = self.Pixel2Cell(self.polycoords[-1])
+            end   = self.Pixel2Cell(self.mouse['end'])
+        else:
+            end   = self.Pixel2Cell(self.polycoords[-1])
+            begin = self.Pixel2Cell(self.mouse['begin'])
+            
+            self.DrawLines(self.pdcTmp, polycoords = (begin, end))
+        
     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:
@@ -1222,247 +1622,351 @@
                 self.mouse['begin'] = self.mouse['end']
         elif self.mouse['use'] == 'zoom':
             pass
-        elif self.mouse["use"] == "pointer" and self.parent.toolbars['vdigit']:
-            # digitization
+
+        #
+        # vector digizer
+        #
+        elif self.mouse["use"] == "pointer" and \
+                self.parent.toolbars['vdigit']:
             digitToolbar = self.parent.toolbars['vdigit']
             digitClass   = self.parent.digit
-            east, north = self.Pixel2Cell(self.mouse['begin'])
-
+            
             try:
-                map = digitToolbar.GetLayer().GetName()
+                mapLayer = 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)
+                              caption=_("Vector digitizer"),
+                              style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
                 event.Skip()
                 return
-
-            # calculate position of 'update record' dialog
-            position = self.mouse['begin']
-            posWindow = self.ClientToScreen((position[0] + self.dialogOffset,
-                                             position[1] + self.dialogOffset))
-
-            if digitToolbar.GetAction() not in ("moveVertex", "addVertex",
-                                                "removeVertex", "editLine"):
+            
+            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"):
+            if digitToolbar.GetAction() in ("addVertex",
+                                            "removeVertex",
+                                            "splitLines"):
                 # unselect
                 digitClass.driver.SetSelected([])
 
             if digitToolbar.GetAction() == "addLine":
-                if digitToolbar.GetAction('type') in ["point", "centroid"]:
-                    # add new point
-                    if digitToolbar.GetAction('type') == 'point':
-                        point = True
-                    else:
-                        point = False
+                self.OnLeftDownVDigitAddLine(event)
+            
+            elif digitToolbar.GetAction() == "editLine" and \
+                    hasattr(self, "vdigitMove"):
+                self.OnLeftDownVDigitEditLine(event)
 
-                    fid = digitClass.AddPoint(map, point, east, north)
-                    if fid < 0:
-                        return
+            elif digitToolbar.GetAction() in ("moveLine", 
+                                              "moveVertex",
+                                              "editLine") and \
+                    not hasattr(self, "vdigitMove"):
+                self.OnLeftDownVDigitMoveLine(event)
 
-                    self.UpdateMap(render=False) # redraw map
-
-                    # add new record into atribute table
-                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled')  is True:
-                        # 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('type') in ["line", "boundary"]:
-                    # add new point to the line
-                    self.polycoords.append(self.Pixel2Cell(event.GetPositionTuple()[:]))
-                    self.DrawLines(pdc=self.pdcTmp)
+            elif digitToolbar.GetAction() in ("displayAttrs"
+                                              "displayCats"):
+                self.OnLeftDownVDigitDisplayCA(event)
             
-            elif digitToolbar.GetAction() == "editLine" and hasattr(self, "vdigitMove"):
-                self.polycoords.append(self.Pixel2Cell(self.mouse['begin']))
-                self.vdigitMove['id'].append(wx.NewId())
-                self.DrawLines(pdc=self.pdcTmp)
+            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
 
-            elif digitToolbar.GetAction() == "deleteLine":
-                pass
+        event.Skip()
 
-            elif digitToolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] and \
-                    not hasattr(self, "vdigitMove"):
-                self.vdigitMove = {}
-                # geographic coordinates of initial position (left-down)
-                self.vdigitMove['begin'] = None
-                # list of ids to modify    
-                self.vdigitMove['id'] = []
-                # ids geographic coordinates
-                self.vdigitMove['coord'] = {}
+    def OnLeftUpVDigitVarious(self, event):
+        """!
+        Left mouse button up - vector digitizer various actions
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        pos1 = self.Pixel2Cell(self.mouse['begin'])
+        pos2 = self.Pixel2Cell(self.mouse['end'])
+        
+        nselected = 0
+        # -> delete line || move line || move vertex
+        if digitToolbar.GetAction() in ("moveVertex",
+                                        "editLine"):
+            if len(digitClass.driver.GetSelected()) == 0:
+                nselected = digitClass.driver.SelectLineByPoint(pos1, type=VDigit_Lines_Type)
                 
-                if digitToolbar.GetAction() in ["moveVertex", "editLine"]:
-                    # set pen
-                    pcolor = UserSettings.Get(group='vdigit', key="symbol",
-                                              subkey=["highlight", "color"])
-                    self.pen = self.polypen = wx.Pen(colour=pcolor,
-                                                     width=2, style=wx.SHORT_DASH)
-                    self.pdcTmp.SetPen(self.polypen)
-
-            elif digitToolbar.GetAction() == "splitLine":
-                # unselect
+                if digitToolbar.GetAction() == "editLine":
+                    try:
+                        selVertex = digitClass.driver.GetSelectedVertex(pos1)[0]
+                    except IndexError:
+                        selVertex = None
+                        
+                    if selVertex:
+                        # self.UpdateMap(render=False)
+                        ids = digitClass.driver.GetSelected(grassId=False)
+                        # move this line to tmp layer
+                        self.polycoords = []
+                        for id in ids:
+                            if id % 2: # register only vertices
+                                e, n = self.Pixel2Cell(self.pdcVector.GetIdBounds(id)[0:2])
+                                self.polycoords.append((e, n))
+                        digitClass.driver.DrawSelected(False) 
+                                
+                        if selVertex < ids[-1] / 2:
+                            # choose first or last node of line
+                            self.vdigitMove['id'].reverse()
+                            self.polycoords.reverse()
+                    else:
+                        # unselect
+                        digitClass.driver.SetSelected([])
+                        del self.vdigitMove
+                
+                    self.UpdateMap(render=False)
+            
+        elif digitToolbar.GetAction() in ("copyCats",
+                                          "copyAttrs"):
+            if not hasattr(self, "copyCatsIds"):
+                # 'from' -> select by point
+                nselected = digitClass.driver.SelectLineByPoint(pos1, digitClass.GetSelectType())
+                if nselected:
+                    self.copyCatsList = digitClass.driver.GetSelected()
+            else:
+                # -> 'to' -> select by bbox
                 digitClass.driver.SetSelected([])
+                # return number of selected features (by box/point)
+                nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
+                                                               digitClass.GetSelectType())
+                if nselected == 0:
+                    if digitClass.driver.SelectLineByPoint(pos1,
+                                                           digitClass.GetSelectType()) is not None:
+                        nselected = 1
+                        
+                if nselected > 0:
+                    self.copyCatsIds = digitClass.driver.GetSelected()
 
-            elif digitToolbar.GetAction() in ["displayAttrs", "displayCats"]:
-                qdist = digitClass.driver.GetThreshold(type='selectThresh')
-                coords = (east, north)
-                if digitClass.type == 'vdigit':
-                    # unselect
-                    digitClass.driver.SetSelected([])
+        elif digitToolbar.GetAction() == "queryLine":
+            selected = digitClass.SelectLinesByQuery(pos1, pos2)
+            nselected = len(selected)
+            if nselected > 0:
+                digitClass.driver.SetSelected(selected)
 
-                    # select feature by point
-                    cats = {}
-                    if digitClass.driver.SelectLineByPoint(coords,
-                                                        digitClass.GetSelectType()) is not None:
-                        if UserSettings.Get(group='vdigit', key='checkForDupl',
-                                            subkey='enabled'):
-                            lines = digitClass.driver.GetSelected()
-                        else:
-                            lines = (digitClass.driver.GetSelected()[0],) # only first found
-                        
-                        for line in lines:
-                            cats[line] = digitClass.GetLineCats(line)
+        else:
+            # -> moveLine || deleteLine, etc. (select by point/box)
+            if digitToolbar.GetAction() == 'moveLine' and \
+                    len(digitClass.driver.GetSelected()) > 0:
+                nselected = 0
+            else:
+                if digitToolbar.GetAction() == 'moveLine':
+                    drawSeg = True
+                else:
+                    drawSeg = False
+
+                nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
+                                                               digitClass.GetSelectType(),
+                                                               drawSeg)
                     
-                if digitToolbar.GetAction() == "displayAttrs":
-                    # select attributes based on coordinates (all layers)
-                    if self.parent.dialogs['attributes'] is None:
-                        if digitClass.type == 'vedit':
-                            self.parent.dialogs['attributes'] = dbm.DisplayAttributesDialog(parent=self, map=map,
-                                                                                            query=(coords, qdist),
-                                                                                            pos=posWindow,
-                                                                                            action="update")
-                        else:
-                            self.parent.dialogs['attributes'] = dbm.DisplayAttributesDialog(parent=self, map=map,
-                                                                                            cats=cats,
-                                                                                            action="update")
-                    else:
-                        # update currently open dialog
-                        if digitClass.type == 'vedit':
-                            self.parent.dialogs['attributes'].UpdateDialog(query=(coords, qdist))
-                        else:
-                            # upgrade dialog
-                            self.parent.dialogs['attributes'].UpdateDialog(cats=cats)
+                if nselected == 0:
+                    if digitClass.driver.SelectLineByPoint(pos1,
+                                                           digitClass.GetSelectType()) is not None:
+                        nselected = 1
+        
+        if nselected > 0:
+            if digitToolbar.GetAction() in ("moveLine",
+                                            "moveVertex"):
+                # get pseudoDC id of objects which should be redrawn
+                if digitToolbar.GetAction() == "moveLine":
+                    # -> move line
+                    self.vdigitMove['id'] = digitClass.driver.GetSelected(grassId=False)
+                    self.vdigitMove['coord'] = digitClass.driver.GetSelectedCoord()
+                else: # moveVertex
+                    self.vdigitMove['id'] = digitClass.driver.GetSelectedVertex(pos1)
+                    if len(self.vdigitMove['id']) == 0: # no vertex found
+                        digitClass.driver.SetSelected([])
+                
+            #
+            # check for duplicates
+            #
+            if UserSettings.Get(group='vdigit', key='checkForDupl', subkey='enabled') is True:
+                dupl = digitClass.driver.GetDuplicates()
+                self.UpdateMap(render=False)
+                    
+                if dupl:
+                    posWindow = self.ClientToScreen((self.mouse['end'][0] + self.dialogOffset,
+                                                     self.mouse['end'][1] + self.dialogOffset))
+                    
+                    dlg = VDigitDuplicatesDialog(parent=self, data=dupl, pos=posWindow)
+                    
+                    if dlg.ShowModal() == wx.ID_OK:
+                        digitClass.driver.UnSelect(dlg.GetUnSelected())
+                        # update selected
+                        self.UpdateMap(render=False)
+                
+            if digitToolbar.GetAction() != "editLine":
+                # -> move line || move vertex
+                self.UpdateMap(render=False)
+        
+        else: # no vector object found
+            if not (digitToolbar.GetAction() in ("moveLine",
+                                                 "moveVertex") and \
+                        len(self.vdigitMove['id']) > 0):
+                # avoid left-click when features are already selected
+                self.UpdateMap(render=False, renderVector=False)
+        
+    def OnLeftUpVDigitModifyLine(self, event):
+        """!
+        Left mouse button up - vector digitizer split line, add/remove
+        vertex action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        pos1 = self.Pixel2Cell(self.mouse['begin'])
+        
+        pointOnLine = digitClass.driver.SelectLineByPoint(pos1,
+                                                          type=VDigit_Lines_Type)
 
-                    if self.parent.dialogs['attributes']:
-                        if len(cats.keys()) > 0:
-                            # highlight feature & re-draw map
-                            if not self.parent.dialogs['attributes'].IsShown():
-                                self.parent.dialogs['attributes'].Show()
-                        else:
-                            if self.parent.dialogs['attributes'] and \
-                                   self.parent.dialogs['attributes'].IsShown():
-                                self.parent.dialogs['attributes'].Hide()
+        if not pointOnLine:
+            return
 
-                else: # displayCats
-                    if self.parent.dialogs['category'] is None:
-                        # open new dialog
-                        if digitClass.type == 'vedit':
-                            dlg = VDigitCategoryDialog(parent=self,
-                                                        map=map,
-                                                        query=(coords, qdist),
-                                                        pos=posWindow,
-                                                        title=_("Update categories"))
-                            self.parent.dialogs['category'] = dlg
-                        else:
-                            dlg = VDigitCategoryDialog(parent=self,
-                                                       map=map,
-                                                       cats=cats,
-                                                       pos=posWindow,
-                                                       title=_("Update categories"))
-                            self.parent.dialogs['category'] = dlg
-                    else:
-                        # update currently open dialog
-                        if digitClass.type == 'vedit':
-                            self.parent.dialogs['category'].UpdateDialog(query=(coords, qdist))
-                        else:
-                            # upgrade dialog
-                            self.parent.dialogs['category'].UpdateDialog(cats=cats)
-                            
-                    if self.parent.dialogs['category']:
-                        if len(cats.keys()) > 0:
-                            # highlight feature & re-draw map
-                            ### digitClass.driver.SetSelected(line)
-                            if not self.parent.dialogs['category'].IsShown():
-                                self.parent.dialogs['category'].Show()
-                        else:
-                            if self.parent.dialogs['category'].IsShown():
-                                self.parent.dialogs['category'].Hide()
-                
+        if digitToolbar.GetAction() in ["splitLine", "addVertex"]:
+            self.UpdateMap(render=False) # highlight object
+            self.DrawCross(pdc=self.pdcTmp, coords=self.Cell2Pixel(pointOnLine),
+                           size=5)
+        else: # removeVertex
+            # get only id of vertex
+            try:
+                id = digitClass.driver.GetSelectedVertex(pos1)[0]
+            except IndexError:
+                id = None
+
+            if id:
+                x, y = self.pdcVector.GetIdBounds(id)[0:2]
+                self.pdcVector.RemoveId(id)
+                self.UpdateMap(render=False) # highlight object
+                self.DrawCross(pdc=self.pdcTmp, coords=(x, y),
+                               size=5)
+            else:
+                # unselect
+                digitClass.driver.SetSelected([])
                 self.UpdateMap(render=False)
 
-            elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
-                if not hasattr(self, "copyCatsList"):
-                    self.copyCatsList = []
-                else:
-                    self.copyCatsIds = []
-                    self.mouse['box'] = 'box'
+    def OnLeftUpVDigitCopyLine(self, event):
+        """!
+        Left mouse button up - vector digitizer copy feature action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        pos1 = self.Pixel2Cell(self.mouse['begin'])
+        pos2 = self.Pixel2Cell(self.mouse['end'])
+        
+        if UserSettings.Get(group='vdigit', key='bgmap',
+                            subkey='value', internal=True) == '':
+            # no background map -> copy from current vector map layer
+            nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
+                                                           digitClass.GetSelectType())
 
-            elif digitToolbar.GetAction() == "copyLine":
-                self.copyIds = []
-                self.layerTmp = None
-
-            elif digitToolbar.GetAction() == "zbulkLine":
-                if len(self.polycoords) > 1: # start new line
-                    self.polycoords = []
-                    self.ClearLines(pdc=self.pdcTmp)
-                self.polycoords.append(self.Pixel2Cell(event.GetPositionTuple()[:]))
-                if len(self.polycoords) == 1:
-                    begin = self.Pixel2Cell(self.polycoords[-1])
-                    end   = self.Pixel2Cell(self.mouse['end'])
+            if nselected > 0:
+                # highlight selected features
+                self.UpdateMap(render=False)
+            else:
+                self.UpdateMap(render=False, renderVector=False)
+        else:
+            # copy features from background map
+            self.copyIds += digitClass.SelectLinesFromBackgroundMap(pos1, pos2)
+            if len(self.copyIds) > 0:
+                color = UserSettings.Get(group='vdigit', key='symbol',
+                                         subkey=['highlight', 'color'])
+                colorStr = str(color[0]) + ":" + \
+                    str(color[1]) + ":" + \
+                    str(color[2])
+                dVectTmp = ['d.vect',
+                            'map=%s' % UserSettings.Get(group='vdigit', key='bgmap',
+                                                        subkey='value', internal=True),
+                            'cats=%s' % utils.ListOfCatsToRange(self.copyIds),
+                            '-i',
+                            'color=%s' % colorStr,
+                            'fcolor=%s' % colorStr,
+                            'type=point,line,boundary,centroid',
+                            'width=2']
+                        
+                if not self.layerTmp:
+                    self.layerTmp = self.Map.AddLayer(type='vector',
+                                                      name=globalvar.QUERYLAYER,
+                                                      command=dVectTmp)
                 else:
-                    end   = self.Pixel2Cell(self.polycoords[-1])
-                    begin = self.Pixel2Cell(self.mouse['begin'])
+                    self.layerTmp.SetCmd(dVectTmp)
+                
+                self.UpdateMap(render=True, renderVector=False)
+            else:
+                self.UpdateMap(render=False, renderVector=False)
+            
+            self.redrawAll = None
+            
+    def OnLeftUpVDigitBulkLine(self, event):
+        """!
+        Left mouse button up - vector digitizer z-bulk line action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        # select lines to be labeled
+        pos1 = self.polycoords[0]
+        pos2 = self.polycoords[1]
+        nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
+                                                       digitClass.GetSelectType())
 
-                    self.DrawLines(self.pdcTmp, polycoords = [begin, end])
-        elif self.mouse['use'] == 'pointer':
-            # get decoration or text id
-            self.idlist = []
-            self.dragid = ''
-            self.lastpos = self.mouse['begin']
-            idlist = self.pdc.FindObjects(x=self.lastpos[0], y=self.lastpos[1],
-                                          radius=self.hitradius)
-                                          
-            if 99 in idlist: idlist.remove(99)                             
-            if idlist != [] :
-                self.dragid = idlist[0] #drag whatever is on top
+        if nselected > 0:
+            # highlight selected features
+            self.UpdateMap(render=False)
+            self.DrawLines(pdc=self.pdcTmp) # redraw temp line
         else:
-            pass
+            self.UpdateMap(render=False, renderVector=False)
 
-        event.Skip()
-
+    def OnLeftUpVDigitConnectLine(self, event):
+        """!
+        Left mouse button up - vector digitizer connect line action
+        """
+        digitToolbar = self.parent.toolbars['vdigit']
+        digitClass   = self.parent.digit
+        
+        if len(digitClass.driver.GetSelected()) > 0:
+            self.UpdateMap(render=False)
+        
     def OnLeftUp(self, event):
-        """
+        """!
         Left mouse button released
         """
         Debug.msg (5, "BufferedWindow.OnLeftUp(): use=%s" % \
-                   self.mouse["use"])
-
+                       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 \
@@ -1472,7 +1976,7 @@
                              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
@@ -1501,7 +2005,8 @@
             self.ClearLines(pdc=self.pdcTmp)
             self.DrawLines(pdc=self.pdcTmp)
         
-        elif self.mouse["use"] == "pointer" and self.parent.gismanager.georectifying:
+        elif self.mouse["use"] == "pointer" and \
+                self.parent.GetLayerManager().georectifying:
             # -> georectifying
             coord = self.Pixel2Cell(self.mouse['end'])
             if self.parent.toolbars['georect']:
@@ -1509,242 +2014,54 @@
             else:
                 coordtype = 'mapcoord'
 
-            self.parent.gismanager.georectifying.SetGCPData(coordtype, coord, self)
+            self.parent.GetLayerManager().georectifying.SetGCPData(coordtype, coord, self)
             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
-
-            pos1 = self.Pixel2Cell(self.mouse['begin'])
-            pos2 = self.Pixel2Cell(self.mouse['end'])
-
+            
             if hasattr(self, "vdigitMove"):
                 if len(digitClass.driver.GetSelected()) == 0:
-                    self.vdigitMove['begin'] = pos1 # left down
-                ### else:
-                ###    dx = pos2[0] - pos1[0] ### ???
-                ###    dy = pos2[1] - pos1[1]
-                ###    self.vdigitMove = (self.vdigitMove['begin'][0] + dx,
-                ###                       self.vdigitMove['begin'][1] + dy)
+                    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"]:
-                nselected = 0
-                # -> delete line || move line || move vertex
-                if digitToolbar.GetAction() in ["moveVertex", "editLine"]:
-                    if len(digitClass.driver.GetSelected()) == 0:
-                        nselected = digitClass.driver.SelectLineByPoint(pos1, type=VDigit_Lines_Type)
-                        if digitToolbar.GetAction() == "editLine":
-                            try:
-                                selVertex = digitClass.driver.GetSelectedVertex(pos1)[0]
-                            except IndexError:
-                                selVertex = None
+            if digitToolbar.GetAction() in ("deleteLine",
+                                            "moveLine",
+                                            "moveVertex",
+                                            "copyCats",
+                                            "copyAttrs",
+                                            "editLine",
+                                            "flipLine",
+                                            "mergeLine",
+                                            "snapLine",
+                                            "queryLine",
+                                            "breakLine",
+                                            "typeConv",
+                                            "connectLine"):
+                self.OnLeftUpVDigitVarious(event)
 
-                            if selVertex:
-                                # self.UpdateMap(render=False)
-                                ids = digitClass.driver.GetSelected(grassId=False)
-                                # move this line to tmp layer
-                                self.polycoords = []
-                                for id in ids:
-                                    if id % 2: # register only vertices
-                                        e, n = self.Pixel2Cell(self.pdcVector.GetIdBounds(id)[0:2])
-                                        self.polycoords.append((e, n))
-                                    # self.pdcVector.RemoveId(id)
-                                digitClass.driver.DrawSelected(False) 
-                                
-                                if selVertex < ids[-1] / 2:
-                                    # choose first or last node of line
-                                    self.vdigitMove['id'].reverse()
-                                    self.polycoords.reverse()
-                            else:
-                                # unselect
-                                digitClass.driver.SetSelected([])
-                                del self.vdigitMove
-                                
-                            self.UpdateMap(render=False)
+            elif digitToolbar.GetAction() in ("splitLine",
+                                              "addVertex",
+                                              "removeVertex"):
+                self.OnLeftUpVDigitModifyLine(event)
 
-                        
-                elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
-                    if not hasattr(self, "copyCatsIds"):
-                        # 'from' -> select by point
-                        nselected = digitClass.driver.SelectLineByPoint(pos1, digitClass.GetSelectType())
-                        if nselected:
-                            self.copyCatsList = digitClass.driver.GetSelected()
-                    else:
-                        # -> 'to' -> select by bbox
-                        digitClass.driver.SetSelected([])
-                        # return number of selected features (by box/point)
-                        nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                                       digitClass.GetSelectType())
-                        if nselected == 0:
-                            if digitClass.driver.SelectLineByPoint(pos1,
-                                                                   digitClass.GetSelectType()) is not None:
-                                nselected = 1
-
-                        if nselected > 0:
-                            self.copyCatsIds = digitClass.driver.GetSelected()
-
-                elif digitToolbar.GetAction() == "queryLine":
-                    selected = digitClass.SelectLinesByQuery(pos1, pos2)
-                    nselected = len(selected)
-                    if nselected > 0:
-                        digitClass.driver.SetSelected(selected)
-
-                else:
-                    # -> moveLine || deleteLine, etc. (select by point/box)
-                    if digitToolbar.GetAction() == 'moveLine' and \
-                           len(digitClass.driver.GetSelected()) > 0:
-                        nselected = 0
-                    else:
-                        if digitToolbar.GetAction() == 'moveLine':
-                            drawSeg = True
-                        else:
-                            drawSeg = False
-                        nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                                       digitClass.GetSelectType(),
-                                                                       drawSeg)
-                        
-                        if nselected == 0:
-                            if digitClass.driver.SelectLineByPoint(pos1,
-                                                                   digitClass.GetSelectType()) is not None:
-                                nselected = 1
-                
-                if nselected > 0:
-                    if digitToolbar.GetAction() in ["moveLine", "moveVertex"]:
-                        # get pseudoDC id of objects which should be redrawn
-                        if digitToolbar.GetAction() == "moveLine":
-                            # -> move line
-                            self.vdigitMove['id'] = digitClass.driver.GetSelected(grassId=False)
-                            self.vdigitMove['coord'] = digitClass.driver.GetSelectedCoord()
-                        elif digitToolbar.GetAction() == "moveVertex":
-                            # -> move vertex
-                            self.vdigitMove['id'] = digitClass.driver.GetSelectedVertex(pos1)
-                            if len(self.vdigitMove['id']) == 0: # no vertex found
-                                digitClass.driver.SetSelected([])
-
-                                   
-                    #
-                    # check for duplicates
-                    #
-                    if UserSettings.Get(group='vdigit', key='checkForDupl', subkey='enabled') is True:
-                        dupl = digitClass.driver.GetDuplicates()
-                        self.UpdateMap(render=False)
-
-                        if dupl:
-                            posWindow = self.ClientToScreen((self.mouse['end'][0] + self.dialogOffset,
-                                                             self.mouse['end'][1] + self.dialogOffset))
-                            
-                            dlg = VDigitDuplicatesDialog(parent=self, data=dupl, pos=posWindow)
-
-                            if dlg.ShowModal() == wx.ID_OK:
-                                digitClass.driver.UnSelect(dlg.GetUnSelected())
-                                # update selected
-                                self.UpdateMap(render=False)
-
-                    if digitToolbar.GetAction() != "editLine":
-                        # -> move line || move vertex
-                        self.UpdateMap(render=False)
-
-                else: # no vector object found
-                    if not (digitToolbar.GetAction() in ["moveLine", "moveVertex"] and \
-                                len(self.vdigitMove['id']) > 0):
-                        # avoid left-click when features are already selected
-                        self.UpdateMap(render=False, renderVector=False)
-
-            elif digitToolbar.GetAction() in ["splitLine", "addVertex", "removeVertex"]:
-                pointOnLine = digitClass.driver.SelectLineByPoint(pos1,
-                                                                  type=VDigit_Lines_Type)
-                if pointOnLine:
-                    if digitToolbar.GetAction() in ["splitLine", "addVertex"]:
-                        self.UpdateMap(render=False) # highlight object
-                        self.DrawCross(pdc=self.pdcTmp, coords=self.Cell2Pixel(pointOnLine),
-                                       size=5)
-                    elif digitToolbar.GetAction() == "removeVertex":
-                        # get only id of vertex
-                        try:
-                            id = digitClass.driver.GetSelectedVertex(pos1)[0]
-                        except IndexError:
-                            id = None
-
-                        if id:
-                            x, y = self.pdcVector.GetIdBounds(id)[0:2]
-                            self.pdcVector.RemoveId(id)
-                            self.UpdateMap(render=False) # highlight object
-                            self.DrawCross(pdc=self.pdcTmp, coords=(x, y),
-                                           size=5)
-                        else:
-                            # unselect
-                            digitClass.driver.SetSelected([])
-                            self.UpdateMap(render=False)
-                            
             elif digitToolbar.GetAction() == "copyLine":
-                if UserSettings.Get(group='vdigit', key='bgmap',
-                                    subkey='value', internal=True) == '':
-                    # no background map -> copy from current vector map layer
-                    nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                                   digitClass.GetSelectType())
-
-                    if nselected > 0:
-                        # highlight selected features
-                        self.UpdateMap(render=False)
-                    else:
-                        self.UpdateMap(render=False, renderVector=False)
-                else:
-                    # copy features from background map
-                    self.copyIds = digitClass.SelectLinesFromBackgroundMap(pos1, pos2)
-                    if len(self.copyIds) > 0:
-                        color = UserSettings.Get(group='vdigit', key='symbol',
-                                                 subkey=['highlight', 'color'])
-                        colorStr = str(color[0]) + ":" + \
-                            str(color[1]) + ":" + \
-                            str(color[2])
-                        dVectTmp = ['d.vect',
-                                    'map=%s' % UserSettings.Get(group='vdigit', key='bgmap',
-                                                                subkey='value', internal=True),
-                                    'cats=%s' % utils.ListOfCatsToRange(self.copyIds),
-                                    '-i',
-                                    'color=%s' % colorStr,
-                                    'fcolor=%s' % colorStr,
-                                    'type=point,line,boundary,centroid',
-                                    'width=2']
-                        
-                        self.layerTmp = self.Map.AddLayer(type='vector',
-                                                          name=globalvar.QUERYLAYER,
-                                                          command=dVectTmp)
-                        self.UpdateMap(render=True, renderVector=False)
-                    else:
-                        self.UpdateMap(render=False, renderVector=False)
-                    self.redrawAll = None
-
-            elif digitToolbar.GetAction() == "zbulkLine" and len(self.polycoords) == 2:
-                # select lines to be labeled
-                pos1 = self.polycoords[0]
-                pos2 = self.polycoords[1]
-                nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                               digitClass.GetSelectType())
-
-                if nselected > 0:
-                    # highlight selected features
-                    self.UpdateMap(render=False)
-                    self.DrawLines(pdc=self.pdcTmp) # redraw temp line
-                else:
-                    self.UpdateMap(render=False, renderVector=False)
-
+                self.OnLeftUpVDigitCopyLine(event)
+            
+            elif digitToolbar.GetAction() == "zbulkLine" and \
+                    len(self.polycoords) == 2:
+                self.OnLeftUpVDigitBulkLine(event)
+            
             elif digitToolbar.GetAction() == "connectLine":
-                if len(digitClass.driver.GetSelected()) > 0:
-                    self.UpdateMap(render=False)
-                    
+                self.OnLeftUpConnectLine(event)
+            
             if len(digitClass.driver.GetSelected()) > 0:
                 self.redrawAll = None
-                ### self.OnPaint(None)
-                
+            
         elif (self.mouse['use'] == 'pointer' and 
                 self.dragid >= 0):
             # end drag of overlay decoration
@@ -1757,15 +2074,9 @@
                 pass
             self.dragid = None
             self.currtxtid = None
-#            self.UpdateMap(render=True)
-            
-        else:
-            pass
-                                              
-#        event.Skip()
-
+        
     def OnButtonDClick(self, event):
-        """
+        """!
         Mouse button double click
         """
         Debug.msg (5, "BufferedWindow.OnButtonDClick(): use=%s" % \
@@ -1780,18 +2091,15 @@
             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
+
+        elif self.mouse['use'] == 'pointer' and \
+                self.parent.toolbars['vdigit']:
+            # vector digitizer
             pass
+
         else:
             # select overlay decoration options dialog
             clickposition = event.GetPositionTuple()[:]
@@ -1808,11 +2116,9 @@
                 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" % \
@@ -1822,7 +2128,8 @@
         if digitToolbar:
             digitClass = self.parent.digit
             # digitization tool (confirm action)
-            if digitToolbar.GetAction() in ["moveLine", "moveVertex"] and \
+            if digitToolbar.GetAction() in ("moveLine",
+                                            "moveVertex") and \
                     hasattr(self, "vdigitMove"):
 
                 pFrom = self.vdigitMove['begin']
@@ -1837,15 +2144,18 @@
                         return
                 elif digitToolbar.GetAction() == "moveVertex":
                     # move vertex
-                    if digitClass.MoveSelectedVertex(pFrom, move) < 0:
+                    fid = digitClass.MoveSelectedVertex(pFrom, move)
+                    if fid < 0:
                         return
+
+                    self.__geomAttrbUpdate([fid,])
                 
                 del self.vdigitMove
                 
         event.Skip()
 
     def OnRightUp(self, event):
-        """
+        """!
         Right mouse button released
         """
         Debug.msg (5, "BufferedWindow.OnRightUp(): use=%s" % \
@@ -1890,7 +2200,9 @@
                     self.Refresh()
                     
                     # add new record into atribute table
-                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled') is True:
+                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled') and \
+                            (line is True or \
+                                 (not line and fid > 0)):
                         posWindow = self.ClientToScreen((position[0] + self.dialogOffset,
                                                          position[1] + self.dialogOffset))
 
@@ -1899,36 +2211,54 @@
                                 UserSettings.Get(group='vdigit', key="layer", subkey='value') :
                                     (UserSettings.Get(group='vdigit', key="category", subkey='value'), )
                                 }}
+                        
+                        addRecordDlg = dbm_dialogs.DisplayAttributesDialog(parent=self, map=map,
+                                                                           cats=cats,
+                                                                           pos=posWindow,
+                                                                           action="add")
 
-                        addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
-                                                                   cats=cats,
-                                                                   pos=posWindow,
-                                                                   action="add")
+                        self.__geomAttrb(fid, addRecordDlg, 'length', digitClass,
+                                         digitToolbar.GetLayer())
+                        # auto-placing centroid
+                        self.__geomAttrb(fid, addRecordDlg, 'area', digitClass,
+                                         digitToolbar.GetLayer())
+                        self.__geomAttrb(fid, addRecordDlg, 'perimeter', digitClass,
+                                         digitToolbar.GetLayer())
+
                         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])
+                            gcmd.RunCommand('db.execute',
+                                            parent = True,
+                                            quiet = True,
+                                            input = sqlfile.name)
+                        
+                        if addRecordDlg.mapDBInfo:
+                            self.__updateATM()
+            
             elif digitToolbar.GetAction() == "deleteLine":
                 # -> delete selected vector features
                 if digitClass.DeleteSelectedLines() < 0:
                     return
+                self.__updateATM()
             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:
+                fid = digitClass.AddVertex(self.Pixel2Cell(self.mouse['begin']))
+                if fid < 0:
                     return
             elif digitToolbar.GetAction() == "removeVertex":
                 # remove vertex
-                if digitClass.RemoveVertex(self.Pixel2Cell(self.mouse['begin'])) < 0:
+                fid = digitClass.RemoveVertex(self.Pixel2Cell(self.mouse['begin']))
+                if fid < 0:
                     return
+                self.__geomAttrbUpdate([fid,])
             elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
                 try:
                     if digitToolbar.GetAction() == 'copyCats':
@@ -1944,6 +2274,9 @@
                     del self.copyCatsIds
                 except AttributeError:
                     pass
+                
+                self.__updateATM()
+                
             elif digitToolbar.GetAction() == "editLine" and \
                     hasattr(self, "vdigitMove"):
                 line = digitClass.driver.GetSelected()
@@ -1986,7 +2319,7 @@
                                         nselected=len(selected))
                 if dlg.ShowModal() == wx.ID_OK:
                     if digitClass.ZBulkLines(pos1, pos2, dlg.value.GetValue(),
-                                            dlg.step.GetValue()) < 0:
+                                             dlg.step.GetValue()) < 0:
                         return
                 self.UpdateMap(render=False, renderVector=True)
             elif digitToolbar.GetAction() == "typeConv":
@@ -2004,13 +2337,15 @@
 
             self.redrawAll = True
             self.Refresh()
-        
+            
         event.Skip()
 
     def OnMiddleDown(self, event):
-        """
+        """!
         Middle mouse button pressed
         """
+        self.mouse['begin'] = event.GetPositionTuple()[:]
+        
         digitToolbar = self.parent.toolbars['vdigit']
         # digitization tool
         if self.mouse["use"] == "pointer" and digitToolbar:
@@ -2071,9 +2406,27 @@
                 self.UpdateMap(render=False)
             
             self.redrawAll = True
-            
+
+    def OnMiddleUp(self, event):
+        """!
+        Middle mouse button released
+        """
+        self.mouse['end'] = event.GetPositionTuple()[:]
+        
+        # set region in zoom or pan
+        begin = self.mouse['begin']
+        end = self.mouse['end']
+        
+        self.Zoom(begin, end, 0) # no zoom
+        
+        # redraw map
+        self.UpdateMap(render=True)
+        
+        # update statusbar
+        self.parent.StatusbarUpdate()
+        
     def OnMouseMoving(self, event):
-        """
+        """!
         Motion event and no mouse buttons were pressed
         """
         digitToolbar = self.parent.toolbars['vdigit']
@@ -2140,7 +2493,7 @@
         event.Skip()
 
     def ClearLines(self, pdc=None):
-        """
+        """!
         Clears temporary drawn lines from PseudoDC
         """
         if not pdc:
@@ -2165,7 +2518,7 @@
         return True
 
     def Pixel2Cell(self, (x, y)):
-        """
+        """!
         Convert image coordinates to real word coordinates
 
         Input : int x, int y
@@ -2196,7 +2549,7 @@
         return (east, north)
 
     def Cell2Pixel(self, (east, north)):
-        """
+        """!
         Convert real word coordinates to image coordinates
         """
 
@@ -2223,7 +2576,7 @@
         return (x, y)
 
     def Zoom(self, begin, end, zoomtype):
-        """
+        """!
         Calculates new region while (un)zoom/pan-ing
         """
         x1, y1 = begin
@@ -2299,95 +2652,120 @@
             self.redrawAll = True
 
     def ZoomBack(self):
+        """!Zoom to previous extents in zoomhistory list
         """
-        Zoom to previous extents in zoomhistory list
-        """
-
-        zoom = []
+        zoom = list()
+        
         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()
+            zoom = self.zoomhistory[-1]
+        
+        # disable tool if stack is empty
+        if len(self.zoomhistory) < 2: # disable tool
+            if self.parent.GetName() == 'MapWindow':
+                toolbar = self.parent.toolbars['map']
+            elif self.parent.GetName() == 'GRMapWindow':
+                toolbar = self.parent.toolbars['georect']
+            
+            toolbar.Enable('zoomback', enable = False)
+        
+        # zoom to selected region
+        self.Map.GetRegion(n = zoom[0], s = zoom[1],
+                           e = zoom[2], w = zoom[3],
+                           update = True)
+        # update map
+        self.UpdateMap()
+        
+        # update statusbar
+        self.parent.StatusbarUpdate()
 
-            # 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
+        @param n,s,e,w north, south, east, west
+
+        @return removed history item if exists (or None)
         """
         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))
+        
+        # update toolbar
+        if len(self.zoomhistory) > 1:
+            enable = True
+        else:
+            enable = False
 
+        if self.parent.GetName() == 'pg_panel':
+            toolbar = self.parent.toolbars['map']
+        elif self.parent.GetName() == 'GRMapWindow':
+            toolbar = self.parent.toolbars['georect']
+        
+        toolbar.Enable('zoomback', enable)
+        
         return removed
 
+    def ResetZoomHistory(self):
+        """!Reset zoom history"""
+        self.zoomhistory = list()
+        
     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)
+        self.ZoomToMap(ignoreNulls = True)
         
-    def ZoomToMap(self, layer = None, zoom = False):
-        """
+    def ZoomToMap(self, layers = None, ignoreNulls = False, render = True):
+        """!
         Set display extents to match selected raster
-        or vector map.
+        or vector map(s).
+
+        @param layer list of layers to be zoom to
+        @param ignoreNulls True to ignore null-values
+        @param render True to re-render display
         """
         zoomreg = {}
 
-        if not layer:
-            layer = self.GetSelectedLayer(multi = True)
+        if not layers:
+            layers = self.GetSelectedLayer(multi = True)
         
-        if not layer:
+        if not layers:
             return
-
+        
         rast = []
         vect = []
         updated = False
-        for l in layer:
+        for l in layers:
             # 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':
+                digitToolbar = self.parent.toolbars['vdigit']
+                if digitToolbar and digitToolbar.GetLayer() == l:
                     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,
@@ -2395,13 +2773,14 @@
         
         self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
                          self.Map.region['e'], self.Map.region['w'])
+        
+        if render:
+            self.UpdateMap()
 
-        self.UpdateMap()
-
         self.parent.StatusbarUpdate()
-
+        
     def ZoomToWind(self, event):
-        """
+        """!
         Set display geometry to match computational
         region settings (set with g.region)
         """
@@ -2416,7 +2795,7 @@
         self.parent.StatusbarUpdate()
 
     def ZoomToDefault(self, event):
-        """
+        """!
         Set display geometry to match default region settings
         """
         self.Map.region = self.Map.GetRegion(default=True)
@@ -2430,7 +2809,7 @@
         self.parent.StatusbarUpdate()
         
     def DisplayToWind(self, event):
-        """
+        """!
         Set computational region (WIND file) to
         match display extents
         """
@@ -2441,17 +2820,16 @@
         # 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()
+        gcmd.RunCommand('g.region',
+                        parent = self,
+                        overwrite = True,
+                        n = new['n'],
+                        s = new['s'],
+                        e = new['e'],
+                        w = new['w'],
+                        rows = int(new['rows']),
+                        cols = int(new['cols']))
         
-        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
 
@@ -2459,19 +2837,22 @@
         """!Set display geometry to match extents in
         saved region file
         """
-        dlg = gdialogs.SavedRegion(parent = self, id = wx.ID_ANY,
+        dlg = gdialogs.SavedRegion(parent = self,
                                    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:
+        if dlg.ShowModal() == wx.ID_CANCEL or not dlg.wind:
             dlg.Destroy()
             return
         
-        wind = dlg.wind
+        if not grass.find_file(name = dlg.wind, element = 'windows')['name']:
+            wx.MessageBox(parent = self,
+                          message = _("Region <%s> not found. Operation canceled.") % dlg.wind,
+                          caption = _("Error"), style = wx.ICON_ERROR | wx.OK | wx.CENTRE)
+            dlg.Destroy()
+            return
         
-        self.Map.GetRegion(regionName = wind,
+        self.Map.GetRegion(regionName = dlg.wind,
                            update = True)
         
         dlg.Destroy()
@@ -2482,69 +2863,61 @@
                          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,
+        dlg = gdialogs.SavedRegion(parent = self,
                                    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:
+        
+        if dlg.ShowModal() == wx.ID_CANCEL or not dlg.wind:
             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 grass.find_file(name = dlg.wind, element = 'windows')['name']:
+            overwrite = wx.MessageBox(parent = self,
+                                      message = _("Region file <%s> already exists. "
+                                                  "Do you want to overwrite it?") % (dlg.wind),
+                                      caption = _("Warning"), style = wx.YES_NO | wx.CENTRE)
             if (overwrite == wx.YES):
-                self.SaveRegion(wind)
+                self.SaveRegion(dlg.wind)
         else:
-            pass
-
+            self.SaveRegion(dlg.wind)
+        
         dlg.Destroy()
 
     def SaveRegion(self, wind):
+        """!Save region settings
+
+        @param wind region name
         """
-        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)
-
+        gcmd.RunCommand('g.region',
+                        overwrite = True,
+                        parent = self,
+                        flags = 'u',
+                        n = new['n'],
+                        s = new['s'],
+                        e = new['e'],
+                        w = new['w'],
+                        rows = int(new['rows']),
+                        cols = int(new['cols']),
+                        save = wind)
+        
         if tmpreg:
             os.environ["GRASS_REGION"] = tmpreg
 
     def Distance(self, beginpt, endpt, screen=True):
-        """Calculete distance
+        """!Calculete distance
 
         LL-locations not supported
 
@@ -2562,12 +2935,10 @@
         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
@@ -2601,6 +2972,7 @@
         self.statusFlag = flag
         self.statusbar = None
 
+
         #FIX THIS
 
         
@@ -2674,13 +3046,13 @@
                                                                   key='statusbarMode',
                                                                   subkey='selection'))
 
-        self.statusbar.Bind(wx.EVT_CHOICE, self.OnToggleStatus, self.statusbarWin['toggle'])
+#        self.statusbar.Bind(wx.EVT_CHOICE, self.OnToggleStatus, self.statusbarWin['toggle'])
 
         # auto-rendering checkbox
         self.statusbarWin['render'] = wx.CheckBox(parent=self.statusbar, id=wx.ID_ANY,
                                                   label=_("Render"))
 
-        self.statusbar.Bind(wx.EVT_CHECKBOX, self.OnToggleRender, self.statusbarWin['render'])
+    #    self.statusbar.Bind(wx.EVT_CHECKBOX, self.OnToggleRender, self.statusbarWin['render'])
 
         self.statusbarWin['render'].SetValue(UserSettings.Get(group='display',
                                                               key='autoRendering',
@@ -2760,7 +3132,7 @@
         self.MapWindow2D = BufferedWindow(self, id=wx.ID_ANY,   Map=self.Map, tree=self.tree, gismgr=self._layerManager)
         # default is 2D display mode
         self.MapWindow = self.MapWindow2D
-        #self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion)
+        self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion)
         self.MapWindow.SetCursor(self.cursors["default"])
         # used by Nviz (3D display mode)
         self.MapWindow3D = None 
@@ -2847,6 +3219,8 @@
                                                       size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS
                                                       |wx.TR_LINES_AT_ROOT|wx.TR_HIDE_ROOT,
                                                       gisdbase=self.gisdbase)
+
+        self.tree = self.maptree
         #self.maptree.SetBackgroundColour("red")
 
         self._mgr.AddPane(self.maptree, wx.aui.AuiPaneInfo().Left().
@@ -2854,6 +3228,9 @@
                                         CloseButton(False).DestroyOnClose(True).
                                         Layer(0).Caption("Map Tree"))
 
+
+
+
         self._mgr.Update()
 
         #r.rightSizer.Add(self.maptree)
@@ -2892,14 +3269,14 @@
         if name == "map":
             self.toolbars['map'] = toolbars.MapToolbar(self, self.Map)
 
-            self._mgr.AddPane(self.toolbars['map'].toolbar,
+            self._mgr.AddPane(self.toolbars['map'],
                               wx.aui.AuiPaneInfo().
                               Name("maptoolbar").Caption(_("Map Toolbar")).
                               ToolbarPane().Top().
                               LeftDockable(False).RightDockable(False).
                               BottomDockable(False).TopDockable(True).
                               CloseButton(False).Layer(2).
-                              BestSize((self.toolbars['map'].GetToolbar().GetSize())))
+                              BestSize((self.toolbars['map'].GetSize())))
 	
         # vector digitizer
         elif name == "vdigit":
@@ -2921,20 +3298,19 @@
                 log = self._layerManager.goutput
             else:
                 log = None
-            self.toolbars['vdigit'] = toolbars.VDigitToolbar(parent=self, map=self.Map,
+            self.toolbars['vdigit'] = toolbars.VDigitToolbar(parent=self, mapcontent=self.Map,
                                                              layerTree=self.tree,
                                                              log=log)
-
-            for toolRow in range(0, self.toolbars['vdigit'].numOfRows):
-                self._mgr.AddPane(self.toolbars['vdigit'].toolbar[toolRow],
-                                  wx.aui.AuiPaneInfo().
-                                  Name("vdigittoolbar" + str(toolRow)).Caption(_("Vector digitizer toolbar")).
-                                  ToolbarPane().Top().Row(toolRow + 1).
-                                  LeftDockable(False).RightDockable(False).
-                                  BottomDockable(False).TopDockable(True).
-                                  CloseButton(False).Layer(2).
-                                  BestSize((self.toolbars['vdigit'].GetToolbar().GetSize())))
-	
+            
+            self._mgr.AddPane(self.toolbars['vdigit'],
+                              wx.aui.AuiPaneInfo().
+                              Name("vdigittoolbar").Caption(_("Vector digitizer toolbar")).
+                              ToolbarPane().Top().Row(1).
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2).
+                              BestSize((self.toolbars['vdigit'].GetSize())))
+            
             # change mouse to draw digitized line
             self.MapWindow.mouse['box'] = "point"
             self.MapWindow.zoomtype = 0
@@ -2944,7 +3320,7 @@
         elif name == "georect":
             self.toolbars['georect'] = toolbars.GRToolbar(self, self.Map)
 
-            self._mgr.AddPane(self.toolbars['georect'].toolbar,
+            self._mgr.AddPane(self.toolbars['georect'],
                               wx.aui.AuiPaneInfo().
                               Name("georecttoolbar").Caption(_("Georectification toolbar")).
                               ToolbarPane().Top().
@@ -3003,7 +3379,8 @@
             # create GL window & NVIZ toolbar
             #
             if not self.MapWindow3D:
-                self.MapWindow3D = nviz.GLWindow(self, id=wx.ID_ANY, Map=self.Map, tree=self.maptree, gismgr=self._layerManager)
+                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)
@@ -3023,7 +3400,7 @@
                               Dockable(False).BestSize((-1,-1)).
                               CloseButton(False).DestroyOnClose(True).
                               Layer(0))
-            self._mgr.AddPane(self.toolbars['nviz'].toolbar,
+            self._mgr.AddPane(self.toolbars['nviz'],
                               wx.aui.AuiPaneInfo().
                               Name("nviztoolbar").Caption(_("Nviz toolbar")).
                               ToolbarPane().Top().Row(1).
@@ -3032,7 +3409,7 @@
                               CloseButton(False).Layer(2))
             
             self.MapWindow = self.MapWindow3D
-            self.frame.SetStatusText("", 0)
+            self.SetStatusText("", 0)
             
         self._mgr.Update()
 
@@ -3048,12 +3425,11 @@
             return
         elif name == "vdigit":
             # TODO: not destroy only hide
-            for toolRow in range(0, self.toolbars['vdigit'].numOfRows):
-                self._mgr.DetachPane (self.toolbars['vdigit'].toolbar[toolRow])
-                self.toolbars['vdigit'].toolbar[toolRow].Destroy()
+            self._mgr.DetachPane(self.toolbars['vdigit'])
+            self.toolbars['vdigit'].Destroy()
         else:
-            self._mgr.DetachPane (self.toolbars[name].toolbar)
-            self.toolbars[name].toolbar.Destroy()
+            self._mgr.DetachPane (self.toolbars[name])
+            self.toolbars[name].Destroy()
 
         self.toolbars[name] = None
 
@@ -3310,10 +3686,8 @@
         """
         Erase the canvas
         """
-
         self.MapWindow.EraseMap()
 
-
     def OnZoomRegion(self, event):
         """
         Zoom to region
@@ -3751,63 +4125,29 @@
             win.SetSize((w, h))
 
     def SaveToFile(self, event):
+        """!Save map to image
         """
-        Save image to file
-        """
-        lext = []
-        for h in self.MapWindow.img.GetHandlers():
-            lext.append(h.GetExtension())
+        filetype, ltype = gdialogs.GetImageHandlers(self.MapWindow.img)
         
-        filetype =  "BMP file (*.bmp)|*.bmp|"
-        if 'gif' in lext:
-            filetype += "GIF file (*.gif)|*.gif|"
-        if 'jpg' in lext:
-            filetype += "JPG file (*.jpg)|*.jpg|"
-        if 'pcx' in lext:
-            filetype += "PCX file (*.pcx)|*.pcx|"
-        if 'png' in lext:
-            filetype += "PNG file (*.png)|*.png|"
-        if 'pnm' in lext:
-            filetype += "PNM file (*.pnm)|*.pnm|"
-        if 'tif' in lext:
-            filetype += "TIF file (*.tif)|*.tif|"
-        if 'xpm' in lext:
-            filetype += "XPM file (*.xpm)|*.xpm"
-
-        dlg = wx.FileDialog(self, _("Choose a file name to save the image (no need to add extension)"),
+        dlg = wx.FileDialog(parent = self,
+                            message = _("Choose a file name to save the image (no need to add extension)"),
                             defaultDir = "",
                             defaultFile = "",
                             wildcard = filetype,
-                            style=wx.SAVE|wx.FD_OVERWRITE_PROMPT)
+                            style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
+        
         if dlg.ShowModal() == wx.ID_OK:
             path = dlg.GetPath()
-            if path == None: return
-            base = os.path.splitext(dlg.GetPath())[0]
-            ext = os.path.splitext(dlg.GetPath())[1]
-            if dlg.GetFilterIndex() == 0:
-                type = wx.BITMAP_TYPE_BMP
-                if ext != '.bmp': path = base+'.bmp'
-            if dlg.GetFilterIndex() == 1:
-                type = wx.BITMAP_TYPE_GIF
-                if ext != '.gif': path = base+'.gif'
-            elif dlg.GetFilterIndex() == 2:
-                type = wx.BITMAP_TYPE_JPEG
-                if ext != '.jpg': path = base+'.jpg'
-            elif dlg.GetFilterIndex() == 3:
-                type = wx.BITMAP_TYPE_GIF
-                if ext != '.pcx': path = base+'.pcx'
-            elif dlg.GetFilterIndex() == 4:
-                type = wx.BITMAP_TYPE_PNG
-                if ext != '.png': path = base+'.png'
-            elif dlg.GetFilterIndex() == 5:
-                type = wx.BITMAP_TYPE_PNM
-                if ext != '.pnm': path = base+'.pnm'
-            elif dlg.GetFilterIndex() == 6:
-                type = wx.BITMAP_TYPE_TIF
-                if ext != '.tif': path = base+'.tif'
-            elif dlg.GetFilterIndex() == 7:
-                type = wx.BITMAP_TYPE_XPM
-                if ext != '.xpm': path = base+'.xpm'
+            if not path:
+                dlg.Destroy()
+                return
+            
+            base, ext = os.path.splitext(path)
+            fileType = ltype[dlg.GetFilterIndex()]['type']
+            extType  = ltype[dlg.GetFilterIndex()]['ext']
+            if ext != extType:
+                path = base + '.' + extType
+            
             self.MapWindow.SaveToFile(path, type)
             
         dlg.Destroy()
@@ -3837,8 +4177,7 @@
         printmenu.Destroy()
 
     def OnCloseWindow(self, event):
-        """
-        Window closed.
+        """!Window closed.
         Also close associated layer tree page
         """
         pgnum = None
@@ -3853,7 +4192,7 @@
 
         if self.toolbars['nviz']:
             self.toolbars['nviz'].OnExit()
-
+        
         if not self._layerManager:
             self.Destroy()
         elif self.page:
@@ -3862,11 +4201,14 @@
                 self.layerbook.DeletePage(pgnum)
         
     def GetRender(self):
+        """!Returns current instance of render.Map()
         """
-        Returns the current instance of render.Map()
-        """
         return self.Map
 
+    def GetWindow(self):
+        """!Get map window"""
+        return self.MapWindow
+    
     def OnQueryDisplay(self, event):
         """
         Query currrent raster/vector map layers (display mode)
@@ -4148,11 +4490,25 @@
             str(color[1]) + ":" + \
             str(color[2])
 
+        # icon used in vector display and its size
+        icon = ''
+        size = 0
+        vparam = self.tree.GetPyData(self.tree.layer_selected)[0]['cmd']
+        for p in vparam:
+            if '=' in p:
+                parg,pval = p.split('=')
+                if parg == 'icon': icon = pval
+                elif parg == 'size': size = int(pval)
+
         pattern = ["d.vect",
                    "map=%s" % name,
                    "color=%s" % colorStr,
                    "fcolor=%s" % colorStr,
                    "width=%d"  % UserSettings.Get(group='atm', key='highlight', subkey='width')]
+        if icon != '':
+            pattern.append('icon=%s' % icon)
+        if size > 0:
+            pattern.append('size=%i' % size)
         
         if useId:
             cmd = pattern
@@ -4278,7 +4634,7 @@
             mstring = 'segment = %s %s\ttotal distance = %s %s' \
                 % (strdist,dunits,strtotdist,tdunits)
 
-        self.gismanager.goutput.WriteLog(mstring)
+        self._layerManager.goutput.WriteLog(mstring)
 
         return dist
 
@@ -4558,7 +4914,7 @@
         
     def IsStandalone(self):
         """!Check if Map display is standalone"""
-        if self.gismanager:
+        if self._layerManager:
             return False
         
         return True
@@ -4569,8 +4925,7 @@
         @return window reference
         @return None (if standalone)
         """
-        return self.gismanager
+        return self._layerManager
     
 # end of class MapFrame
 
-

Modified: grass-addons/gui/wxpython/data_catalog/toolbars.py
===================================================================
--- grass-addons/gui/wxpython/data_catalog/toolbars.py	2010-04-25 07:47:36 UTC (rev 42028)
+++ grass-addons/gui/wxpython/data_catalog/toolbars.py	2010-04-25 10:45:29 UTC (rev 42029)
@@ -1,7 +1,7 @@
-"""
+"""!
 @package toolbar
 
- at brief Toolbars for Map Display window
+ at brief wxGUI toolbar widgets
 
 Classes:
  - AbstractToolbar
@@ -11,87 +11,85 @@
  - VDigitToolbar
  - ProfileToolbar
  - NvizToolbar
+ - ModelToolbar
 
-(C) 2007-2008 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.
+(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.
 
 @author Michael Barton
 @author Jachym Cepicky
 @author Martin Landa <landa.martin gmail.com>
 """
 
-import wx
-import os, sys
+import os
+import sys
 import platform
 
+from grass.script import core as grass
+
+import wx
+
 import globalvar
 import gcmd
-version = os.getenv("GRASS_VERSION")
-if version == "6.4.0svn":
-    import grassenv
-
 import gdialogs
 import vdigit
 from vdigit import VDigitSettingsDialog as VDigitSettingsDialog
 from debug import Debug as Debug
-from icon import Icons as Icons
 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(object):
-    """Abstract toolbar class"""
-    def __init__(self):
-        pass
+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)
     
-    def InitToolbar(self, parent, toolbar, toolData):
-        """Initialize toolbar, i.e. add tools to the toolbar
-
-        @return list of ids (of added tools)
+        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(parent, toolbar, *tool)
-
-        self._toolbar = toolbar
+            self.CreateTool(*tool)
+        
         self._data = toolData
         
-        self.parent = parent
-        
     def ToolbarData(self):
-        """Toolbar data"""
+        """!Toolbar data (virtual)"""
         return None
-
-    def CreateTool(self, parent, toolbar, tool, label, bitmap, kind,
+    
+    def CreateTool(self, tool, label, bitmap, kind,
                    shortHelp, longHelp, handler):
-        """Add tool to the toolbar
-
+        """!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 = toolbar.AddLabelTool(tool, label, bitmap,
-                                           bmpDisabled, kind,
-                                           shortHelp, longHelp)
-            parent.Bind(wx.EVT_TOOL, handler, toolWin)
-        else: # add separator
-            toolbar.AddSeparator()
-
+            
+            toolWin = self.AddLabelTool(tool, label, bitmap,
+                                        bmpDisabled, kind,
+                                        shortHelp, longHelp)
+            self.Bind(wx.EVT_TOOL, handler, toolWin)
+        else: # separator
+            self.AddSeparator()
+        
         return tool
-
-    def GetToolbar(self):
-        """Get toolbar widget reference"""
-        return self._toolbar
-
+    
     def EnableLongHelp(self, enable=True):
-        """Enable/disable long help
-
+        """!Enable/disable long help
+        
         @param enable True for enable otherwise disable
         """
         for tool in self._data:
@@ -99,94 +97,109 @@
                 continue
             
             if enable:
-                self._toolbar.SetToolLongHelp(tool[0], tool[5])
+                self.SetToolLongHelp(tool[0], tool[5])
             else:
-                self._toolbar.SetToolLongHelp(tool[0], "")
-
+                self.SetToolLongHelp(tool[0], "")
+        
     def OnTool(self, event):
-        """Tool selected"""
+        """!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'].GetToolbar().ToggleTool(id, False)
+            self.parent.toolbars['vdigit'].ToggleTool(id, False)
         
         if event:
             # deselect previously selected tool
             id = self.action.get('id', -1)
             if id != event.GetId():
-                self._toolbar.ToggleTool(self.action['id'], False)
+                self.ToggleTool(self.action['id'], False)
             else:
-                self._toolbar.ToggleTool(self.action['id'], True)
+                self.ToggleTool(self.action['id'], True)
             
             self.action['id'] = event.GetId()
             
             event.Skip()
         else:
             # initialize toolbar
-            self._toolbar.ToggleTool(self.action['id'], True)
-    
+            self.ToggleTool(self.action['id'], True)
+        
     def GetAction(self, type='desc'):
-        """Get current action info"""
+        """!Get current action info"""
         return self.action.get(type, '')
-
+    
     def SelectDefault(self, event):
-        """Select default tool"""
-        self._toolbar.ToggleTool(self.defaultAction['id'], True)
+        """!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
+	"""!Fix toolbar width on Windows
         
 	@todo Determine why combobox causes problems here
 	"""
         if platform.system() == 'Windows':
-            size = self._toolbar.GetBestSize()
-            self._toolbar.SetSize((size[0] + width, size[1]))
+            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
     """
-    Main Map Display toolbar
-    """
+    def __init__(self, parent, mapcontent):
+        """!Map Display constructor
 
-    def __init__(self, mapdisplay, map):
-        AbstractToolbar.__init__(self)
-
-        self.mapcontent = map
-        self.mapdisplay = mapdisplay
-
-        self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY)
-        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
-
-        self.InitToolbar(self.mapdisplay, self.toolbar, self.ToolbarData())
+        @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.toolbar, id=wx.ID_ANY, value=_('2D view'),
+        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.toolbar.AddControl(self.combo)
-        self.mapdisplay.Bind(wx.EVT_COMBOBOX, self.OnSelectTool, self.comboid)
-
+        self.comboid = self.AddControl(self.combo)
+        self.parent.Bind(wx.EVT_COMBOBOX, self.OnSelectTool, self.comboid)
+        
         # realize the toolbar
-        self.toolbar.Realize()
+        self.Realize()
         
         # workaround for Mac bug. May be fixed by 2.8.8, but not before then.
         self.combo.Hide()
         self.combo.Show()
         
-        # default action
         self.action = { 'id' : self.pointer }
         self.defaultAction = { 'id' : self.pointer,
-                               'bind' : self.mapdisplay.OnPointer }
+                               'bind' : self.parent.OnPointer }
+        
         self.OnTool(None)
         
+        self.EnableTool(self.zoomback, False)
+        
         self.FixSize(width = 90)
         
     def ToolbarData(self):
-        """Toolbar data"""
-
+        """!Toolbar data"""
         self.displaymap = wx.NewId()
         self.rendermap = wx.NewId()
         self.erase = wx.NewId()
@@ -201,60 +214,60 @@
         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.mapdisplay.OnDraw),
+             self.parent.OnDraw),
             (self.rendermap, "rendermap", Icons["rendermap"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["rendermap"].GetLabel(), Icons["rendermap"].GetDesc(),
-             self.mapdisplay.OnRender),
+             self.parent.OnRender),
             (self.erase, "erase", Icons["erase"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(),
-             self.mapdisplay.OnErase),
+             self.parent.OnErase),
             ("", "", "", "", "", "", ""),
             (self.pointer, "pointer", Icons["pointer"].GetBitmap(),
              wx.ITEM_CHECK, Icons["pointer"].GetLabel(), Icons["pointer"].GetDesc(),
-             self.mapdisplay.OnPointer),
+             self.parent.OnPointer),
             (self.query, "query", Icons["query"].GetBitmap(),
              wx.ITEM_CHECK, Icons["query"].GetLabel(), Icons["query"].GetDesc(),
-             self.mapdisplay.OnQuery),
+             self.parent.OnQuery),
             (self.pan, "pan", Icons["pan"].GetBitmap(),
              wx.ITEM_CHECK, Icons["pan"].GetLabel(), Icons["pan"].GetDesc(),
-             self.mapdisplay.OnPan),
+             self.parent.OnPan),
             (self.zoomin, "zoom_in", Icons["zoom_in"].GetBitmap(),
              wx.ITEM_CHECK, Icons["zoom_in"].GetLabel(), Icons["zoom_in"].GetDesc(),
-             self.mapdisplay.OnZoomIn),
+             self.parent.OnZoomIn),
             (self.zoomout, "zoom_out", Icons["zoom_out"].GetBitmap(),
              wx.ITEM_CHECK, Icons["zoom_out"].GetLabel(), Icons["zoom_out"].GetDesc(),
-             self.mapdisplay.OnZoomOut),
+             self.parent.OnZoomOut),
             (self.zoomback, "zoom_back", Icons["zoom_back"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["zoom_back"].GetLabel(), Icons["zoom_back"].GetDesc(),
-             self.mapdisplay.OnZoomBack),
+             self.parent.OnZoomBack),
             (self.zoommenu, "zoommenu", Icons["zoommenu"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["zoommenu"].GetLabel(), Icons["zoommenu"].GetDesc(),
-             self.mapdisplay.OnZoomMenu),
+             self.parent.OnZoomMenu),
             ("", "", "", "", "", "", ""),
             (self.analyze, "analyze", Icons["analyze"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["analyze"].GetLabel(), Icons["analyze"].GetDesc(),
-             self.mapdisplay.OnAnalyze),
+             self.parent.OnAnalyze),
             ("", "", "", "", "", "", ""),
             (self.dec, "overlay", Icons["overlay"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["overlay"].GetLabel(), Icons["overlay"].GetDesc(),
-             self.mapdisplay.OnDecoration),
+             self.parent.OnDecoration),
             ("", "", "", "", "", "", ""),
             (self.savefile, "savefile", Icons["savefile"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["savefile"].GetLabel(), Icons["savefile"].GetDesc(),
-             self.mapdisplay.SaveToFile),
+             self.parent.SaveToFile),
             (self.printmap, "printmap", Icons["printmap"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["printmap"].GetLabel(), Icons["printmap"].GetDesc(),
-             self.mapdisplay.PrintMenu),
+             self.parent.PrintMenu),
             ("", "", "", "", "", "", "")
             )
-
+    
     def OnSelectTool(self, event):
-        """
+        """!
         Select / enable tool available in tools list
         """
         tool =  event.GetSelection()
@@ -262,23 +275,24 @@
         if tool == 0:
             self.ExitToolbars()
             self.Enable2D(True)
-
-        elif tool == 1 and not self.mapdisplay.toolbars['nviz']:
+        
+        elif tool == 1 and not self.parent.toolbars['nviz']:
             self.ExitToolbars()
-            self.mapdisplay.AddToolbar("nviz")
+            self.parent.AddToolbar("nviz")
             
-        elif tool == 2 and not self.mapdisplay.toolbars['vdigit']:
+        elif tool == 2 and not self.parent.toolbars['vdigit']:
             self.ExitToolbars()
-            self.mapdisplay.AddToolbar("vdigit")
-
+            self.parent.AddToolbar("vdigit")
+            self.parent.MapWindow.SetFocus()
+        
     def ExitToolbars(self):
-        if self.mapdisplay.toolbars['vdigit']:
-            self.mapdisplay.toolbars['vdigit'].OnExit()
-        if self.mapdisplay.toolbars['nviz']:       
-            self.mapdisplay.toolbars['nviz'].OnExit()
-
+        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"""
+        """!Enable/Disable 2D display mode specific tools"""
         for tool in (self.pointer,
                      self.query,
                      self.pan,
@@ -290,30 +304,37 @@
                      self.dec,
                      self.savefile,
                      self.printmap):
-            self.toolbar.EnableTool(tool, enabled)
-
+            self.EnableTool(tool, enabled)
+        
 class GRToolbar(AbstractToolbar):
     """
-    Georectification Display toolbar
+    Georectification toolbar
     """
+    def __init__(self, parent, mapcontent):
+        """!
+        Georectification toolbar constructor
 
-    def __init__(self, mapdisplay, map):
-        self.mapcontent = map
-        self.mapdisplay = mapdisplay
-
-        self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY)
-
-        # self.SetToolBar(self.toolbar)
-        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
-
-        self.InitToolbar(self.mapdisplay, self.toolbar, self.ToolbarData())
-
+        @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.toolbar.Realize()
-
+        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"""
-
+        """!Toolbar data"""
         self.displaymap = wx.NewId()
         self.rendermap = wx.NewId()
         self.erase = wx.NewId()
@@ -323,68 +344,60 @@
         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.mapdisplay.OnDraw),
+             self.parent.OnDraw),
             (self.rendermap, "rendermap", Icons["rendermap"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["rendermap"].GetLabel(), Icons["rendermap"].GetDesc(),
-             self.mapdisplay.OnRender),
+             self.parent.OnRender),
             (self.erase, "erase", Icons["erase"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(),
-             self.mapdisplay.OnErase),
+             self.parent.OnErase),
             ("", "", "", "", "", "", ""),
             (self.gcpset, "grGcpSet", Icons["grGcpSet"].GetBitmap(),
              wx.ITEM_RADIO, Icons["grGcpSet"].GetLabel(), Icons["grGcpSet"].GetDesc(),
-             self.mapdisplay.OnPointer),
+             self.parent.OnPointer),
             (self.pan, "pan", Icons["pan"].GetBitmap(),
              wx.ITEM_RADIO, Icons["pan"].GetLabel(), Icons["pan"].GetDesc(),
-             self.mapdisplay.OnPan),
+             self.parent.OnPan),
             (self.zoomin, "zoom_in", Icons["zoom_in"].GetBitmap(),
              wx.ITEM_RADIO, Icons["zoom_in"].GetLabel(), Icons["zoom_in"].GetDesc(),
-             self.mapdisplay.OnZoomIn),
+             self.parent.OnZoomIn),
             (self.zoomout, "zoom_out", Icons["zoom_out"].GetBitmap(),
              wx.ITEM_RADIO, Icons["zoom_out"].GetLabel(), Icons["zoom_out"].GetDesc(),
-             self.mapdisplay.OnZoomOut),
+             self.parent.OnZoomOut),
             (self.zoomback, "zoom_back", Icons["zoom_back"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["zoom_back"].GetLabel(), Icons["zoom_back"].GetDesc(),
-             self.mapdisplay.OnZoomBack),
+             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"""
-        layer = self.mapcontent.GetListOfLayers()[0]
-
-        self.mapdisplay.MapWindow.ZoomToMap(layer=layer)
-
-        event.Skip()
+        """!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, tbframe):
-        self.parent  = parent # GCP
-        self.tbframe = tbframe
-
-        self.toolbar = wx.ToolBar(parent=self.tbframe, id=wx.ID_ANY)
-
-        # self.SetToolBar(self.toolbar)
-        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
-
-        self.InitToolbar(self.tbframe, self.toolbar, self.ToolbarData())
-
+    def __init__(self, parent):
+        AbstractToolbar.__init__(self, parent)
+        
+        self.InitToolbar(self.ToolbarData())
+        
         # realize the toolbar
-        self.toolbar.Realize()
+        self.Realize()
 
     def ToolbarData(self):
-        
         self.gcpSave = wx.NewId()
         self.gcpAdd = wx.NewId()
         self.gcpDelete = wx.NewId()
@@ -432,38 +445,26 @@
     """
     Toolbar for digitization
     """
-
-    def __init__(self, parent, map, layerTree=None, log=None):
-        self.mapcontent    = map       # Map class instance
-        self.parent        = parent    # MapFrame
-        self.layerTree     = layerTree # reference to layer tree associated to map display
-        self.log           = log       # log area
+    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.toolbar = []
-        self.numOfRows = 1 # number of rows for toolbar
-        for row in range(0, self.numOfRows):
-            self.toolbar.append(wx.ToolBar(parent=self.parent, id=wx.ID_ANY))
-            self.toolbar[row].SetToolBitmapSize(globalvar.toolbarSize)
-            self.toolbar[row].Bind(wx.EVT_TOOL, self.OnTool)
-            
-            # create toolbar
-            if self.numOfRows ==  1:
-                rowdata=None
-            else:
-                rowdata = row
-            self.InitToolbar(self.parent, self.toolbar[row], self.ToolbarData(rowdata))
-
+        self.InitToolbar(self.ToolbarData())
+        self.Bind(wx.EVT_TOOL, self.OnTool)
+        
         # default action (digitize new point, line, etc.)
         self.action = { 'desc' : 'addLine',
                         'type' : 'point',
@@ -471,141 +472,135 @@
         
         # list of available vector maps
         self.UpdateListOfLayers(updateTool=True)
-
+        
         # realize toolbar
-        for row in range(0, self.numOfRows):
-            self.toolbar[row].Realize()
-            # workaround for Mac bug. May be fixed by 2.8.8, but not before then.
-            self.combo.Hide()
-            self.combo.Show()
-
-
+        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.toolbar[0].EnableTool(self.undo, False)
+        self.EnableTool(self.undo, False)
         
         # toogle to pointer by default
         self.OnTool(None)
         
         self.FixSize(width = 105)
         
-    def ToolbarData(self, row=None):
-        """
+    def ToolbarData(self):
+        """!
         Toolbar data
         """
         data = []
-        if row is None or row == 0:
-            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()
-
-            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)]
-
-        if row is None or row == 1:
-            self.undo = wx.NewId()
-            self.settings = wx.NewId()
-            self.exit = wx.NewId()
-
-            data.append(("", "", "", "", "", "", ""))
-            data.append((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))
-            data.append((self.settings, "digSettings", Icons["digSettings"].GetBitmap(),
-                         wx.ITEM_NORMAL, Icons["digSettings"].GetLabel(), Icons["digSettings"].GetDesc(),
-                         self.OnSettings))
-            data.append((self.exit, "digExit", Icons["quit"].GetBitmap(),
-                         wx.ITEM_NORMAL, Icons["digExit"].GetLabel(), Icons["digExit"].GetDesc(),
-                         self.OnExit))
-
+        
+        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"""
-        # update map toolbar (unselect currently selected tool)
+        """!Tool selected -> disable selected tool in map toolbar"""
         id = self.parent.toolbars['map'].GetAction(type='id')
-        self.parent.toolbars['map'].toolbar.ToggleTool(id, False)
-
+        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.toolbar[0].ToggleTool(self.action['id'], False)
+                self.ToggleTool(self.action['id'], False)
             else:
-                self.toolbar[0].ToggleTool(self.action['id'], True)
+                self.ToggleTool(self.action['id'], True)
             
             self.action['id'] = event.GetId()
+            
             event.Skip()
-        else:
-            # initialize toolbar
-            self.toolbar[0].ToggleTool(self.action['id'], True)
-
+        
+        self.ToggleTool(self.action['id'], True)
+        
         # clear tmp canvas
         if self.action['id'] != id:
             self.parent.MapWindow.ClearLines(pdc=self.parent.MapWindow.pdcTmp)
@@ -614,25 +609,28 @@
                 # cancel action
                 self.parent.MapWindow.OnMiddleDown(None)
         
+        # set focus
+        self.parent.MapWindow.SetFocus()
+        
     def OnAddPoint(self, event):
-        """Add point to the vector map Laier"""
+        """!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"""
+        """!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"""
+        """!Add boundary to the vector map layer"""
         Debug.msg (2, "VDigitToolbar.OnAddBoundary()")
         if self.action['desc'] != 'addLine' or \
                 self.action['type'] != 'boundary':
@@ -641,9 +639,9 @@
                         'type' : "boundary",
                         'id'   : self.addBoundary }
         self.parent.MapWindow.mouse['box'] = 'line'
-
+        
     def OnAddCentroid(self, event):
-        """Add centroid to the vector map layer"""
+        """!Add centroid to the vector map layer"""
         Debug.msg (2, "VDigitToolbar.OnAddCentroid()")
         self.action = { 'desc' : "addLine",
                         'type' : "centroid",
@@ -651,90 +649,88 @@
         self.parent.MapWindow.mouse['box'] = 'point'
 
     def OnExit (self, event=None):
-        """Quit digitization tool"""
+        """!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)
-        
-        # disable the toolbar
-        self.parent.RemoveToolbar ("vdigit")
-
+            
         # 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"""
+        """!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"""
+        """!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"""
+        """!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"""
+        """!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"""
+        """!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"""
+        """!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"""
+        """!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"""
+        """!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"""
+        """!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"""
+        """!Copy categories/attributes menu"""
         point = wx.GetMousePosition()
         toolMenu = wx.Menu()
         # Add items to the menu
@@ -745,7 +741,7 @@
         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)
@@ -753,20 +749,20 @@
         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.toolbar[0].ToggleTool(self.copyCats, False)
+            self.ToggleTool(self.copyCats, False)
         
     def OnCopyCats(self, event):
-        """Copy categories"""
+        """!Copy categories"""
         if self.action['desc'] == 'copyCats': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.copyCats, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.copyCats, False)
             self.OnAddPoint(event)
             return
         
@@ -777,8 +773,8 @@
 
     def OnCopyAttrb(self, event):
         if self.action['desc'] == 'copyAttrs': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.copyCats, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.copyCats, False)
             self.OnAddPoint(event)
             return
         
@@ -788,38 +784,40 @@
         self.parent.MapWindow.mouse['box'] = 'point'
         
     def OnUndo(self, event):
-        """Undo previous changes"""
+        """!Undo previous changes"""
         self.parent.digit.Undo()
-
+        
         event.Skip()
 
     def EnableUndo(self, enable=True):
-        """Enable 'Undo' in toolbar
-
+        """!Enable 'Undo' in toolbar
+        
         @param enable False for disable
         """
         if enable:
-            if self.toolbar[0].GetToolEnabled(self.undo) is False:
-                self.toolbar[0].EnableTool(self.undo, True)
+            if self.GetToolEnabled(self.undo) is False:
+                self.EnableTool(self.undo, True)
         else:
-            if self.toolbar[0].GetToolEnabled(self.undo) is True:
-                self.toolbar[0].EnableTool(self.undo, False)
+            if self.GetToolEnabled(self.undo) is True:
+                self.EnableTool(self.undo, False)
         
     def OnSettings(self, event):
-        """Show settings dialog"""
-
+        """!Show settings dialog"""
         if self.parent.digit is None:
             reload(vdigit)
-            from vdigit import Digit as Digit
-            self.parent.digit = Digit(mapwindow=self.parent.MapWindow)
-            
+            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"""
+        """!Menu for additional tools"""
         point = wx.GetMousePosition()
         toolMenu = wx.Menu()
         # Add items to the menu
@@ -830,7 +828,7 @@
         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)
@@ -838,7 +836,7 @@
         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)
@@ -846,7 +844,7 @@
         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)
@@ -854,7 +852,7 @@
         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)
@@ -862,7 +860,7 @@
         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)
@@ -870,7 +868,7 @@
         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)
@@ -878,7 +876,7 @@
         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)
@@ -886,7 +884,7 @@
         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)
@@ -894,20 +892,20 @@
         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.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.additionalTools, False)
         
     def OnCopy(self, event):
-        """Copy selected features from (background) vector map"""
+        """!Copy selected features from (background) vector map"""
         if self.action['desc'] == 'copyLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -917,10 +915,10 @@
         self.parent.MapWindow.mouse['box'] = 'box'
 
     def OnFlip(self, event):
-        """Flip selected lines/boundaries"""
+        """!Flip selected lines/boundaries"""
         if self.action['desc'] == 'flipLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -930,10 +928,10 @@
         self.parent.MapWindow.mouse['box'] = 'box'
 
     def OnMerge(self, event):
-        """Merge selected lines/boundaries"""
+        """!Merge selected lines/boundaries"""
         if self.action['desc'] == 'mergeLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -943,10 +941,10 @@
         self.parent.MapWindow.mouse['box'] = 'box'
 
     def OnBreak(self, event):
-        """Break selected lines/boundaries"""
+        """!Break selected lines/boundaries"""
         if self.action['desc'] == 'breakLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -956,10 +954,10 @@
         self.parent.MapWindow.mouse['box'] = 'box'
 
     def OnSnap(self, event):
-        """Snap selected features"""
+        """!Snap selected features"""
         if self.action['desc'] == 'snapLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -969,10 +967,10 @@
         self.parent.MapWindow.mouse['box'] = 'box'
 
     def OnConnect(self, event):
-        """Connect selected lines/boundaries"""
+        """!Connect selected lines/boundaries"""
         if self.action['desc'] == 'connectLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -982,10 +980,10 @@
         self.parent.MapWindow.mouse['box'] = 'box'
 
     def OnQuery(self, event):
-        """Query selected lines/boundaries"""
+        """!Query selected lines/boundaries"""
         if self.action['desc'] == 'queryLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -996,7 +994,7 @@
         self.parent.MapWindow.mouse['box'] = 'box'
 
     def OnZBulk(self, event):
-        """Z bulk-labeling selected lines/boundaries"""
+        """!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."),
@@ -1004,8 +1002,8 @@
             return
         
         if self.action['desc'] == 'zbulkLine': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -1015,15 +1013,15 @@
         self.parent.MapWindow.mouse['box'] = 'line'
 
     def OnTypeConversion(self, event):
-        """Feature type conversion
+        """!Feature type conversion
 
         Supported conversions:
          - point <-> centroid
          - line <-> boundary
         """
         if self.action['desc'] == 'typeConv': # select previous action
-            self.toolbar[0].ToggleTool(self.addPoint, True)
-            self.toolbar[0].ToggleTool(self.additionalTools, False)
+            self.ToggleTool(self.addPoint, True)
+            self.ToggleTool(self.additionalTools, False)
             self.OnAddPoint(event)
             return
         
@@ -1046,8 +1044,10 @@
             else:
                 openVectorMap = None
             mapName = gdialogs.CreateNewVector(self.parent,
-                                               exceptMap=openVectorMap, log=self.log,
-                                               cmdDef=(['v.edit', 'tool=create'], "map"),
+                                               exceptMap = openVectorMap, log = self.log,
+                                               cmd = (('v.edit',
+                                                       { 'tool' : 'create' },
+                                                       'map')),
                                                disableAdd=True)[0]
             if mapName:
                 # add layer to map layer tree
@@ -1067,18 +1067,18 @@
                 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
@@ -1091,33 +1091,41 @@
         """
         # deactive layer
         self.mapcontent.ChangeLayerActive(mapLayer, False)
-
+        
         # clean map canvas
         ### self.parent.MapWindow.EraseMap()
-
+        
         # unset background map if needed
-        if UserSettings.Get(group='vdigit', key='bgmap',
-                            subkey='value', internal=True) == mapLayer.GetName():
-            UserSettings.Set(group='vdigit', key='bgmap',
-                             subkey='value', value='', internal=True)
+        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)
         
-        self.parent.statusbar.SetStatusText(_("Please wait, "
-                                              "opening vector map <%s> for editing...") % \
-                                                mapLayer.GetName(),
-                                            0)
-        
         # reload vdigit module
         reload(vdigit)
-        from vdigit import Digit as Digit
-        self.parent.digit = Digit(mapwindow=self.parent.MapWindow)
+        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
         
@@ -1137,7 +1145,7 @@
 
         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)
@@ -1145,50 +1153,51 @@
         
         return True
 
-    def StopEditing (self):
-        """Stop editing of selected vector map layer.
+    def StopEditing(self):
+        """!Stop editing of selected vector map layer.
 
         @return True on success
         @return False on failure
         """
-        if not self.mapLayer:
-            return False
+        # use wx's PseudoDC
+        self.parent.MapWindow.DefinePseudoDC(vdigit = False)
         
-        Debug.msg (4, "VDigitToolbar.StopEditing(): layer=%s" % self.mapLayer.GetName())
         self.combo.SetValue (_('Select vector map'))
         
         # save changes
-        if UserSettings.Get(group='vdigit', key='saveOnExit', subkey='enabled') is False:
-            if self.parent.digit.GetUndoLevel() > 0:
-                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()
+        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.statusbar.SetStatusText(_("Please wait, "
-                                              "closing and rebuilding topology of "
-                                              "vector map <%s>...") % self.mapLayer.GetName(),
-                                            0)
+            self.parent.digit.SetMapName(None) # -> close map
         
-        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)
         
-        # 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]:
@@ -1205,29 +1214,28 @@
         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=grassenv.GetGRASSVariable('MAPSET'))
+                                                      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')
@@ -1235,43 +1243,36 @@
                 value = layerNameSelected
 
             if not self.comboid:
-                self.combo = wx.ComboBox(self.toolbar[self.numOfRows-1], id=wx.ID_ANY, value=value,
-                                         choices=[_('New vector map'), ] + layerNameList, size=(85, -1),
+                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.toolbar[self.numOfRows-1].InsertControl(0, self.combo)
+                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.toolbar[self.numOfRows-1].Realize()
-
+            self.Realize()
+        
         return layerNameList
 
     def GetLayer(self):
-        """Get selected layer for editing -- MapLayer instance"""
+        """!Get selected layer for editing -- MapLayer instance"""
         return self.mapLayer
-
+    
 class ProfileToolbar(AbstractToolbar):
-    """
+    """!
     Toolbar for profiling raster map
     """ 
-    def __init__(self, parent, tbframe):
-        self.parent  = parent # GCP
-        self.tbframe = tbframe
-
-        self.toolbar = wx.ToolBar(parent=self.tbframe, id=wx.ID_ANY)
-
-        # self.SetToolBar(self.toolbar)
-        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
-
-        self.InitToolbar(self.tbframe, self.toolbar, self.ToolbarData())
-
+    def __init__(self, parent):
+        AbstractToolbar.__init__(self, parent)
+        
+        self.InitToolbar(self.ToolbarData())
+        
         # realize the toolbar
-        self.toolbar.Realize()
-
+        self.Realize()
+        
     def ToolbarData(self):
-        """Toolbar data"""
-
+        """!Toolbar data"""
         self.transect = wx.NewId()
         self.addraster = wx.NewId()
         self.draw = wx.NewId()
@@ -1323,29 +1324,23 @@
             )
     
 class NvizToolbar(AbstractToolbar):
-    """
+    """!
     Nviz toolbar
     """
-    def __init__(self, parent, map):
-        self.parent     = parent
-        self.mapcontent = map
-
-        self.toolbar = wx.ToolBar(parent=self.parent, id=wx.ID_ANY)
-
-        # self.SetToolBar(self.toolbar)
-        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
-
-        self.InitToolbar(self.parent, self.toolbar, self.ToolbarData())
-
+    def __init__(self, parent, mapcontent):
+        self.mapcontent = mapcontent
+        AbstractToolbar.__init__(self, parent)
+        
+        self.InitToolbar(self.ToolbarData())
+        
         # realize the toolbar
-        self.toolbar.Realize()
-
+        self.Realize()
+        
     def ToolbarData(self):
-        """Toolbar data"""
-
+        """!Toolbar data"""
         self.settings = wx.NewId()
         self.quit = wx.NewId()
-                
+        
         # tool, label, bitmap, kind, shortHelp, longHelp, handler
         return   (
             (self.settings, "settings", Icons["nvizSettings"].GetBitmap(),
@@ -1355,7 +1350,7 @@
              wx.ITEM_NORMAL, Icons["quit"].GetLabel(), Icons["quit"].GetDesc(),
              self.OnExit),
             )
-
+    
     def OnSettings(self, event):
         win = self.parent.nvizToolWin
         if not win.IsShown():
@@ -1364,17 +1359,82 @@
             self.parent.nvizToolWin.Hide()
 
     def OnExit (self, event=None):
-        """Quit nviz tool (swith to 2D mode)"""
-
+        """!Quit nviz tool (swith to 2D mode)"""
         # hide dialogs if still open
         if self.parent.nvizToolWin:
             self.parent.nvizToolWin.Hide()
-
-        # disable the toolbar
-        self.parent.RemoveToolbar ("nviz")
-
+        
         # 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