[GRASS-SVN] r45385 - grass/trunk/gui/wxpython/gui_modules

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Feb 12 04:59:05 EST 2011


Author: martinl
Date: 2011-02-12 01:59:05 -0800 (Sat, 12 Feb 2011)
New Revision: 45385

Added:
   grass/trunk/gui/wxpython/gui_modules/mapdisp_vdigit.py
Modified:
   grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py
   grass/trunk/gui/wxpython/gui_modules/mapdisp.py
   grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
   grass/trunk/gui/wxpython/gui_modules/toolbars.py
   grass/trunk/gui/wxpython/gui_modules/wxvdigit.py
Log:
wxGUI/vdigit: vdigit related code moved from mapdisp_window to
mapdisp_vdigit
(merge r45384 from devbr6)


Modified: grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py	2011-02-12 09:54:41 UTC (rev 45384)
+++ grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py	2011-02-12 09:59:05 UTC (rev 45385)
@@ -1,4 +1,4 @@
-"""
+"""!
 @package dbm_dialogs.py
 
 @brief DBM-related dialogs
@@ -7,7 +7,7 @@
  - DisplayAttributesDialog
  - ModifyTableRecord
 
-(C) 2007-2010 by the GRASS Development Team
+(C) 2007-2011 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
@@ -31,27 +31,26 @@
 from dbm_base    import VectorDBInfo
 
 class DisplayAttributesDialog(wx.Dialog):
-    """
-    Standard dialog used to add/update/display attributes linked
-    to the vector map.
-
-    Attribute data can be selected based on layer and category number
-    or coordinates.
-
-    @param parent
-    @param map vector map
-    @param query query coordinates and distance (used for v.edit)
-    @param cats {layer: cats}
-    @param line feature id (requested for cats)
-    @param style
-    @param pos
-    @param action (add, update, display)
-    """
     def __init__(self, parent, map,
                  query=None, cats=None, line=None,
                  style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                  pos=wx.DefaultPosition,
                  action="add"):
+        """!Standard dialog used to add/update/display attributes linked
+        to the vector map.
+        
+        Attribute data can be selected based on layer and category number
+        or coordinates.
+        
+        @param parent
+        @param map vector map
+        @param query query coordinates and distance (used for v.edit)
+        @param cats {layer: cats}
+        @param line feature id (requested for cats)
+        @param style
+        @param pos
+        @param action (add, update, display)
+        """
         self.parent = parent # mapdisplay.BufferedWindow
         self.map    = map
         self.action = action
@@ -268,14 +267,15 @@
                         self.FindWindowById(id).SetValue(str(value))
 
     def OnCancel(self, event):
-        """!Cancel button pressed"""
+        """!Cancel button pressed
+        """
         self.parent.parent.dialogs['attributes'] = None
-        if self.parent.parent.digit:
-            self.parent.parent.digit.GetDisplay().SetSelected([])
+        if self.parent.digit:
+            self.parent.digit.GetDisplay().SetSelected([])
             self.parent.UpdateMap(render = False)
         else:
             self.parent.parent.OnRender(None)
-
+        
         self.Close()
 
     def OnSubmit(self, event):
@@ -502,15 +502,16 @@
                 break
         
 class ModifyTableRecord(wx.Dialog):
-    """!Dialog for inserting/updating table record"""
     def __init__(self, parent, id, title, data, keyEditable=(-1, True),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
-        """
+        """!Dialog for inserting/updating table record
+
         Notes:
-         'Data' is a list: [(column, value)]
-         'KeyEditable' (id, editable?) indicates if textarea for key column
-          is editable(True) or not.
+        'Data' is a list: [(column, value)]
+        'KeyEditable' (id, editable?) indicates if textarea for key column
+        is editable(True) or not.
         """
+        # parent -> VDigitWindow
         wx.Dialog.__init__(self, parent, id, title, style=style)
         
         self.CenterOnParent()

Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp.py	2011-02-12 09:54:41 UTC (rev 45384)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp.py	2011-02-12 09:59:05 UTC (rev 45385)
@@ -245,6 +245,8 @@
         # default is 2D display mode
         self.MapWindow = self.MapWindow2D
         self.MapWindow.SetCursor(self.cursors["default"])
+        # used by vector digitizer
+        self.MapWindowVDigit = None
         # used by Nviz (3D display mode)
         self.MapWindow3D = None 
 
@@ -275,11 +277,6 @@
         self.printopt = disp_print.PrintOptions(self, self.MapWindow)
         
         #
-        # Initialization of digitization tool
-        #
-        self.digit = None
-
-        #
         # Init zoom history
         #
         self.MapWindow.ZoomHistory(self.Map.region['n'],
@@ -311,7 +308,7 @@
         # default toolbar
         if name == "map":
             self.toolbars['map'] = toolbars.MapToolbar(self, self.Map)
-
+            
             self._mgr.AddPane(self.toolbars['map'],
                               wx.aui.AuiPaneInfo().
                               Name("maptoolbar").Caption(_("Map toolbar")).
@@ -324,6 +321,7 @@
         # vector digitizer
         elif name == "vdigit":
             from vdigit import haveVDigit
+            
             if not haveVDigit:
                 from vdigit import errorMsg
                 msg = _("Unable to start wxGUI vector digitizer.\nDo you want to start "
@@ -347,10 +345,28 @@
                 log = self._layerManager.goutput
             else:
                 log = None
+            
+            if not self.MapWindowVDigit:
+                from mapdisp_vdigit import VDigitWindow
+                self.MapWindowVDigit = VDigitWindow(self, id = wx.ID_ANY,
+                                                    Map = self.Map, tree = self.tree,
+                                                    lmgr = self._layerManager)
+                self.MapWindowVDigit.Show()
+            
+            self.MapWindow = self.MapWindowVDigit
+            
+            self._mgr.DetachPane(self.MapWindow2D)
+            self.MapWindow2D.Hide()
+            
             self.toolbars['vdigit'] = toolbars.VDigitToolbar(parent = self, mapcontent = self.Map,
                                                              layerTree = self.tree,
                                                              log = log)
+            self.MapWindowVDigit.SetToolbar(self.toolbars['vdigit'])
             
+            self._mgr.AddPane(self.MapWindowVDigit, wx.aui.AuiPaneInfo().CentrePane().
+                              Dockable(False).BestSize((-1,-1)).
+                              CloseButton(False).DestroyOnClose(True).
+                              Layer(0))
             self._mgr.AddPane(self.toolbars['vdigit'],
                               wx.aui.AuiPaneInfo().
                               Name("vdigittoolbar").Caption(_("Vector digitizer toolbar")).
@@ -359,12 +375,12 @@
                               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
-            self.MapWindow.pen     = wx.Pen(colour = 'red',   width = 2, style = wx.SOLID)
-            self.MapWindow.polypen = wx.Pen(colour = 'green', width = 2, style = wx.SOLID)
+            self.MapWindow.zoomtype     = 0
+            self.MapWindow.pen          = wx.Pen(colour = 'red',   width = 2, style = wx.SOLID)
+            self.MapWindow.polypen      = wx.Pen(colour = 'green', width = 2, style = wx.SOLID)
         # georectifier
         elif name == "georect":
             self.toolbars['georect'] = toolbars.GRToolbar(self, self.Map)
@@ -397,7 +413,7 @@
             
             # update status bar
             self.statusbarWin['toggle'].Enable(False)
-
+            
             # erase map window
             self.MapWindow.EraseMap()
             
@@ -541,8 +557,8 @@
             self.MapWindow.ClearLines()
         
         # deselect features in vdigit
-        if self.toolbars['vdigit'] and self.digit:
-            self.digit.GetDisplay().SetSelected([])
+        if self.toolbars['vdigit']:
+            self.MapWindow.display.SetSelected([])
             self.MapWindow.UpdateMap(render = True, renderVector = True)
         else:
             self.MapWindow.UpdateMap(render = True)

Copied: grass/trunk/gui/wxpython/gui_modules/mapdisp_vdigit.py (from rev 45384, grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_vdigit.py)
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp_vdigit.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp_vdigit.py	2011-02-12 09:59:05 UTC (rev 45385)
@@ -0,0 +1,1064 @@
+"""!
+ at package mapdisp_vdigit.py
+
+ at brief Map display canvas extended for vector digitizer
+
+See also vdigit.py, wxvdriver.py and wxvdigit.py
+
+Classes:
+ - VDigitWindow
+
+(C) 2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Martin Landa <landa.martin gmail.com>
+"""
+
+import wx
+
+import dbm_dialogs
+
+from debug import Debug
+from mapdisp_window import BufferedWindow
+from preferences import globalSettings as UserSettings
+
+from vdigit import VDigitCategoryDialog
+from vdigit import VDigitZBulkDialog
+from vdigit import VDigitDuplicatesDialog
+
+class VDigitWindow(BufferedWindow):
+    """!A Buffered window extended for vector digitizer.
+    """
+    def __init__(self, parent, id = wx.ID_ANY,
+                 Map = None, tree = None, lmgr = None,
+                 style = wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
+        BufferedWindow.__init__(self, parent, id, Map, tree, lmgr,
+                                style, **kwargs)
+        
+        self.pdcVector = wx.PseudoDC()
+        self.toolbar   = self.parent.toolbars['vdigit']
+        self.digit     = None
+        
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+        
+    def SetToolbar(self, toolbar):
+        """!Set up related toolbar
+        """
+        self.toolbar = toolbar
+        
+    def _onMotion(self, coord, precision):
+        """!Track mouse motion and update statusbar (see self.Motion)
+
+        @parem coord easting, northing
+        @param precision formatting precision
+        """
+        e, n = coord
+        
+        if self.toolbar.GetAction() != 'addLine' or \
+                self.toolbar.GetAction('type') not in ('line', 'boundary') or \
+                len(self.polycoords) == 0:
+            return False
+        
+        # for linear feature show segment and total length
+        distance_seg = self.Distance(self.polycoords[-1],
+                                     (e, n), screen = False)[0]
+        distance_tot = distance_seg
+        for idx in range(1, len(self.polycoords)):
+            distance_tot += self.Distance(self.polycoords[idx-1],
+                                          self.polycoords[idx],
+                                          screen = False)[0]
+        self.parent.statusbar.SetStatusText("%.*f, %.*f (seg: %.*f; tot: %.*f)" % \
+                                                (precision, e, precision, n,
+                                                 precision, distance_seg,
+                                                 precision, distance_tot), 0)
+        
+        return True
+    
+    def OnKeyDown(self, event):
+        """!Key pressed"""
+        shift = event.ShiftDown()
+        kc = event.GetKeyCode()
+        
+        event = None
+        if not shift:
+            if kc == ord('P'):
+                event = wx.CommandEvent(winid = self.toolbar.addPoint)
+                tool = self.toolbar.OnAddPoint
+            elif kc == ord('L'):
+                event = wx.CommandEvent(winid = self.toolbar.addLine)
+                tool = self.toolbar.OnAddLine
+        if event:
+            self.toolbar.OnTool(event)
+            tool(event)
+        
+    def _updateMap(self):
+        if not self.toolbar or \
+                not self.toolbar.GetLayer():
+            return
+        
+        # set region
+        self.digit.GetDisplay().UpdateRegion()
+        # re-calculate threshold for digitization tool
+        # self.parent.digit.GetDisplay().GetThreshold()
+        # draw map
+        # self.pdcVector.Clear()
+        self.pdcVector.RemoveAll()
+        
+        try:
+            item = self.tree.FindItemByData('maplayer', self.toolbar.GetLayer())
+        except TypeError:
+            item = None
+        
+        if item and self.tree.IsItemChecked(item):
+            self.redrawAll = True
+            self.digit.GetDisplay().DrawMap()
+        
+        # translate tmp objects (pointer position)
+        if self.toolbar.GetAction() == 'moveLine':
+            if self.moveInfo.has_key('beginDiff'):
+                # move line
+                for id in self.moveInfo['id']:
+                    self.pdcTmp.TranslateId(id,
+                                            self.moveInfo['beginDiff'][0],
+                                            self.moveInfo['beginDiff'][1])
+                del self.moveInfo['beginDiff']
+        
+    def OnLeftDownAddLine(self, event):
+        """!Left mouse button pressed - add new feature
+        """
+        try:
+            mapLayer = self.toolbar.GetLayer().GetName()
+        except:
+            return
+        
+        if self.toolbar.GetAction('type') in ['point', 'centroid']:
+            # add new point / centroiud
+            east, north = self.Pixel2Cell(self.mouse['begin'])
+            nfeat, fids = self.digit.AddFeature(self.toolbar.GetAction('type'), [(east, north)])
+            if nfeat < 1:
+                return
+            
+            self.UpdateMap(render = False) # redraw map
+            
+            # add new record into atribute table
+            if UserSettings.Get(group = 'vdigit', key = "addRecord", subkey = 'enabled'):
+                # select attributes based on layer and category
+                cats = { fids[0] : {
+                        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 self.toolbar.GetAction('type') == 'centroid':
+                    for fid in fids:
+                        self._geomAttrb(fid, addRecordDlg, 'area')
+                        self._geomAttrb(fid, addRecordDlg, 'perimeter')
+                
+                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 self.toolbar.GetAction('type') in ["line", "boundary", "area"]:
+            # add new point to the line
+            self.polycoords.append(self.Pixel2Cell(event.GetPositionTuple()[:]))
+            self.DrawLines(pdc = self.pdcTmp)
+        
+    def _geomAttrb(self, fid, dialog, attrb):
+        """!Define geometry attributes
+        """
+        mapLayer = self.toolbar.GetLayer()
+        item = self.tree.FindItemByData('maplayer', mapLayer)
+        vdigit = self.tree.GetPyData(item)[0]['vdigit']
+        if not vdigit or \
+                not vdigit.has_key('geomAttr') or \
+                not vdigit['geomAttr'].has_key(attrb):
+            return
+        
+        val = -1
+        if attrb == 'length':
+            val = self.digit.GetLineLength(fid)
+            type = attrb
+        elif attrb == 'area':
+            val = self.digit.GetAreaSize(fid)
+            type = attrb
+        elif attrb == 'perimeter':
+            val = self.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()
+        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 self.digit.GetLineCats(fid).iteritems():
+                table = dbInfo.GetTable(layer)
+                for attrb, item in vdigit['geomAttr'].iteritems():
+                    val = -1
+                    if attrb == 'length':
+                        val = self.digit.GetLineLength(fid)
+                        type = attrb
+                    elif attrb == 'area':
+                        val = self.digit.GetAreaSize(fid)
+                        type = attrb
+                    elif attrb == 'perimeter':
+                        val = self.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
+        digitVector = self.toolbar.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 OnLeftDownEditLine(self, event):
+        """!Left mouse button pressed - edit linear feature - add new
+        vertex.
+        """
+        self.polycoords.append(self.Pixel2Cell(self.mouse['begin']))
+        self.moveInfo['id'].append(wx.NewId())
+        self.DrawLines(pdc = self.pdcTmp)
+        
+    def OnLeftDownMoveLine(self, event):
+        """!Left mouse button pressed - vector digitizer move
+        feature/vertex, edit linear feature
+        """
+        self.moveInfo = {}
+        # geographic coordinates of initial position (left-down)
+        self.moveInfo['begin'] = None
+        # list of ids to modify    
+        self.moveInfo['id'] = []
+        
+        if self.toolbar.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 OnLeftDownDisplayCA(self, event):
+        """!Left mouse button pressed - vector digitizer display categories
+        or attributes action
+        """
+        try:
+            mapLayer = self.toolbar.GetLayer().GetName()
+        except:
+            return
+        
+        coords = self.Pixel2Cell(self.mouse['begin'])
+        
+        # unselect
+        self.digit.GetDisplay().SetSelected([])
+        
+        # select feature by point
+        cats = {}
+        if self.digit.GetDisplay().SelectLineByPoint(coords) is None:
+            return
+        
+        if UserSettings.Get(group = 'vdigit', key = 'checkForDupl',
+                            subkey = 'enabled'):
+            lines = self.digit.GetDisplay().GetSelected()
+        else:
+            lines = (self.digit.GetDisplay().GetSelected()[0],) # only first found
+                        
+        for line in lines:
+            cats[line] = self.digit.GetLineCats(line)
+        
+        posWindow = self.ClientToScreen((self.mouse['end'][0] + self.dialogOffset,
+                                         self.mouse['end'][1] + self.dialogOffset))
+        
+        if self.toolbar.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, renderVector = True)
+        
+    def OnLeftDownCopyCA(self, event):
+        """!Left mouse button pressed - vector digitizer copy
+        categories or attributes action
+        """
+        if not hasattr(self, "copyCatsList"):
+            self.copyCatsList = []
+        else:
+            self.copyCatsIds = []
+            self.mouse['box'] = 'box'
+        
+    def OnLeftDownCopyLine(self, event):
+        """!Left mouse button pressed - vector digitizer copy lines
+        action
+        """
+        if not hasattr(self, "copyIds"):
+            self.copyIds = []
+            self.layerTmp = None
+        
+    def OnLeftDownBulkLine(self, event):
+        """!Left mouse button pressed - vector digitizer label 3D
+        vector lines
+        """
+        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 OnLeftDownUndo(self, event):
+        """!Left mouse button pressed with control key - vector
+        digitizer undo functionality
+        """
+        if self.mouse["use"] != "pointer" or not self.toolbar:
+            return
+        
+        digitClass = self.parent.digit
+        if (self.toolbar.GetAction() == "addLine" and \
+                self.toolbar.GetAction('type') in ["line", "boundary", "area"]) or \
+                self.toolbar.GetAction() == "editLine":
+            # add line or boundary -> remove last point from the line
+            try:
+                removed = self.polycoords.pop()
+                Debug.msg(4, "BufferedWindow.OnMiddleDown(): polycoords_poped=%s" % \
+                              [removed,])
+                # self.mouse['begin'] = self.Cell2Pixel(self.polycoords[-1])
+            except:
+                pass
+            
+        if self.toolbar.GetAction() == "editLine":
+            # remove last vertex & line
+            if len(self.moveInfo['id']) > 1:
+                self.moveInfo['id'].pop()
+                
+            self.UpdateMap(render = False, renderVector = False)
+            
+        elif self.toolbar.GetAction() in ["deleteLine", "moveLine", "splitLine",
+                                          "addVertex", "removeVertex", "moveVertex",
+                                          "copyCats", "flipLine", "mergeLine",
+                                          "snapLine", "connectLine", "copyLine",
+                                          "queryLine", "breakLine", "typeConv"]:
+            # varios tools -> unselected selected features
+            self.digit.GetDisplay().SetSelected([])
+            if self.toolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] and \
+                    hasattr(self, "moveInfo"):
+                del self.moveInfo
+                
+            elif self.toolbar.GetAction() == "copyCats":
+                try:
+                    del self.copyCatsList
+                    del self.copyCatsIds
+                except AttributeError:
+                    pass
+                
+            elif self.toolbar.GetAction() == "copyLine":
+                del self.copyIds
+                if self.layerTmp:
+                    self.Map.DeleteLayer(self.layerTmp)
+                    self.UpdateMap(render = True, renderVector = False)
+                del self.layerTmp
+
+            self.polycoords = []
+            self.UpdateMap(render = False) # render vector
+        
+        elif self.toolbar.GetAction() == "zbulkLine":
+            # reset polyline
+            self.polycoords = []
+            self.digit.GetDisplay().SetSelected([])
+            self.UpdateMap(render = False)
+        
+        self.redrawAll = True
+        self.UpdateMap(render = False, renderVector = False)
+
+    def _onLeftDown(self, event):
+        """!Left mouse button donw - vector digitizer various actions
+        """
+        try:
+            mapLayer = self.toolbar.GetLayer().GetName()
+        except:
+            wx.MessageBox(parent = self,
+                          message = _("No vector map selected for editing."),
+                          caption = _("Vector digitizer"),
+                          style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
+            event.Skip()
+            return
+    
+        if self.toolbar.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 self.toolbar.GetAction() in ("addVertex",
+                                        "removeVertex",
+                                        "splitLines"):
+            # unselect
+            self.digit.GetDisplay().SetSelected([])
+
+        if self.toolbar.GetAction() == "addLine":
+            self.OnLeftDownAddLine(event)
+            
+        elif self.toolbar.GetAction() == "editLine" and \
+                hasattr(self, "moveInfo"):
+            self.OnLeftDownEditLine(event)
+
+        elif self.toolbar.GetAction() in ("moveLine", 
+                                          "moveVertex",
+                                          "editLine") and \
+                                          not hasattr(self, "moveInfo"):
+                                          self.OnLeftDownVDigitMoveLine(event)
+        
+        elif self.toolbar.GetAction() in ("displayAttrs"
+                                          "displayCats"):
+            self.OnLeftDownDisplayCA(event)
+            
+        elif self.toolbar.GetAction() in ("copyCats",
+                                          "copyAttrs"):
+            self.OnLeftDownCopyCA(event)
+            
+        elif self.toolbar.GetAction() == "copyLine":
+            self.OnLeftDownCopyLine(event)
+            
+        elif self.toolbar.GetAction() == "zbulkLine":
+            self.OnLeftDownBulkLine(event)
+        
+    def _onLeftUp(self, event):
+        """!Left mouse button released - vector digitizer various
+        actions
+        """
+        pos1 = self.Pixel2Cell(self.mouse['begin'])
+        pos2 = self.Pixel2Cell(self.mouse['end'])
+        
+        nselected = 0
+        # -> delete line || move line || move vertex
+        if self.toolbar.GetAction() in ("moveVertex",
+                                        "editLine"):
+            if len(self.digit.GetDisplay().GetSelected()) == 0:
+                nselected = self.digit.GetDisplay().SelectLineByPoint(pos1)['point']
+                
+                if self.toolbar.GetAction() == "editLine":
+                    try:
+                        selVertex = self.digit.GetDisplay().GetSelectedVertex(pos1)[0]
+                    except IndexError:
+                        selVertex = None
+                        
+                    if selVertex:
+                        # self.UpdateMap(render=False)
+                        ids = self.digit.GetDisplay().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.digit.GetDisplay().DrawSelected(False) 
+                                
+                        if selVertex < ids[-1] / 2:
+                            # choose first or last node of line
+                            self.moveInfo['id'].reverse()
+                            self.polycoords.reverse()
+                    else:
+                        # unselect
+                        self.digit.GetDisplay().SetSelected([])
+                        del self.moveInfo
+                
+                    self.UpdateMap(render = False)
+            
+        elif self.toolbar.GetAction() in ("copyCats",
+                                          "copyAttrs"):
+            if not hasattr(self, "copyCatsIds"):
+                # 'from' -> select by point
+                nselected = self.digit.GetDisplay().SelectLineByPoint(pos1)['point']
+                if nselected:
+                    self.copyCatsList = self.digit.GetDisplay().GetSelected()
+            else:
+                # -> 'to' -> select by bbox
+                self.digit.GetDisplay().SetSelected([])
+                # return number of selected features (by box/point)
+                nselected = self.digit.GetDisplay().SelectLinesByBox((pos1, pos2))
+                if nselected == 0:
+                    if self.digit.GetDisplay().SelectLineByPoint(pos1) is not None:
+                        nselected = 1
+                        
+                if nselected > 0:
+                    self.copyCatsIds = self.digit.GetDisplay().GetSelected()
+        
+        elif self.toolbar.GetAction() == "queryLine":
+            selected = digitClass.SelectLinesByQuery(bbox = (pos1, pos2))
+            nselected = len(selected)
+            if nselected > 0:
+                self.digit.GetDisplay().SetSelected(selected)
+        
+        else:
+            # -> moveLine || deleteLine, etc. (select by point/box)
+            if self.toolbar.GetAction() == 'moveLine' and \
+                    len(self.digit.GetDisplay().GetSelected()) > 0:
+                nselected = 0
+            else:
+                if self.toolbar.GetAction() == 'moveLine':
+                    drawSeg = True
+                else:
+                    drawSeg = False
+                
+                nselected = self.digit.GetDisplay().SelectLinesByBox(bbox = (pos1, pos2),
+                                                                     drawSeg = drawSeg)
+                if nselected == 0:
+                    if self.digit.GetDisplay().SelectLineByPoint(pos1) is not None:
+                        nselected = 1
+        
+        if nselected > 0:
+            if self.toolbar.GetAction() in ("moveLine",
+                                            "moveVertex"):
+                # get pseudoDC id of objects which should be redrawn
+                if self.toolbar.GetAction() == "moveLine":
+                    # -> move line
+                    self.moveInfo['id'] = self.digit.GetDisplay().GetSelected(grassId = False)
+                else: # moveVertex
+                    self.moveInfo['id'] = self.digit.GetDisplay().GetSelectedVertex(pos1)
+                    if len(self.moveInfo['id']) == 0: # no vertex found
+                        self.digit.GetDisplay().SetSelected([])
+            
+            #
+            # check for duplicates
+            #
+            if UserSettings.Get(group = 'vdigit', key = 'checkForDupl', subkey = 'enabled'):
+                dupl = self.digit.GetDisplay().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:
+                        self.digit.GetDisplay().UnSelect(dlg.GetUnSelected())
+                        # update selected
+                        self.UpdateMap(render = False)
+                
+            if self.toolbar.GetAction() != "editLine":
+                # -> move line || move vertex
+                self.UpdateMap(render = False)
+        
+        else: # no vector object found
+            if not (self.toolbar.GetAction() in ("moveLine",
+                                                 "moveVertex") and \
+                        hasattr(self, "moveInfo") and \
+                        len(self.moveInfo['id']) > 0):
+                # avoid left-click when features are already selected
+                self.UpdateMap(render = False, renderVector = False)
+        
+    def OnLeftUpModifyLine(self, event):
+        """!Left mouse button released - vector digitizer split line,
+        add/remove vertex action
+        """
+        pos1 = self.Pixel2Cell(self.mouse['begin'])
+        
+        pointOnLine = self.digit.GetDisplay().SelectLineByPoint(pos1)['point']
+        if not pointOnLine:
+            return
+        
+        if self.toolbar.GetAction() in ["splitLine", "addVertex"]:
+            self.UpdateMap(render = False) # highlight object
+            self.DrawCross(pdc = self.pdcTmp, coords = self.Cell2Pixel((pointOnLine[0], pointOnLine[1])),
+                           size = 5)
+        else: # removeVertex
+            # get only id of vertex
+            try:
+                id = self.digit.GetDisplay().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
+                self.digit.GetDisplay().SetSelected([])
+                self.UpdateMap(render = False)
+        
+    def OnLeftUpCopyLine(self, event):
+        """!Left mouse button released - vector digitizer copy feature
+        action
+        """
+        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 = self.digit.GetDisplay().SelectLinesByBox((pos1, pos2))
+            
+            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 += self.digit.SelectLinesFromBackgroundMap(bbox = (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:
+                    self.layerTmp.SetCmd(dVectTmp)
+                
+                self.UpdateMap(render = True, renderVector = False)
+            else:
+                self.UpdateMap(render = False, renderVector = False)
+            
+            self.redrawAll = None
+            
+    def OnLeftUpBulkLine(self, event):
+        """!Left mouse button released - vector digitizer z-bulk line
+        action
+        """
+        # select lines to be labeled
+        pos1 = self.polycoords[0]
+        pos2 = self.polycoords[1]
+        nselected = self.digit.GetDisplay().SelectLinesByBox((pos1, pos2))
+        
+        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)
+            
+    def OnLeftUpConnectLine(self, event):
+        """!Left mouse button released - vector digitizer connect line
+        action
+        """
+        if len(self.digit.GetDisplay().GetSelected()) > 0:
+            self.UpdateMap(render = False)
+        
+    def OnLeftUp(self, event):
+        if hasattr(self, "infoMove"):
+            if len(digitClass.GetDisplay().GetSelected()) == 0:
+                self.moveInfo['begin'] = self.Pixel2Cell(self.mouse['begin']) # left down
+            
+            # eliminate initial mouse moving efect
+            self.mouse['begin'] = self.mouse['end'] 
+        
+        if self.toolbar.GetAction() in ("deleteLine",
+                                        "moveLine",
+                                        "moveVertex",
+                                        "copyCats",
+                                        "copyAttrs",
+                                        "editLine",
+                                        "flipLine",
+                                        "mergeLine",
+                                        "snapLine",
+                                        "queryLine",
+                                        "breakLine",
+                                        "typeConv",
+                                        "connectLine"):
+            self._onLeftUp(event)
+        
+        elif self.toolbar.GetAction() in ("splitLine",
+                                          "addVertex",
+                                          "removeVertex"):
+            self.OnLeftUpModifyLine(event)
+        
+        elif self.toolbar.GetAction() == "copyLine":
+            self.OnLeftUpCopyLine(event)
+            
+        elif self.toolbar.GetAction() == "zbulkLine" and \
+                len(self.polycoords) == 2:
+            self.OnLeftUpBulkLine(event)
+        
+        elif self.toolbar.GetAction() == "connectLine":
+            self.OnLeftUpConnectLine(event)
+        
+        if len(self.digit.GetDisplay().GetSelected()) > 0:
+            self.redrawAll = None
+        
+    def _onRightDown(self, event):
+        # digitization tool (confirm action)
+        if self.toolbar.GetAction() in ("moveLine", "moveVertex") and \
+                hasattr(self, "moveInfo"):
+            pFrom = self.moveInfo['begin']
+            pTo = self.Pixel2Cell(event.GetPositionTuple())
+            
+            move = (pTo[0] - pFrom[0],
+                    pTo[1] - pFrom[1])
+            
+            if self.toolbar.GetAction() == "moveLine":
+                # move line
+                if self.digit.MoveSelectedLines(move) < 0:
+                    return
+            elif self.toolbar.GetAction() == "moveVertex":
+                # move vertex
+                fid = self.digit.MoveSelectedVertex(pFrom, move)
+                if fid < 0:
+                    return
+                
+                self._geomAttrbUpdate([fid,])
+            
+            del self.moveInfo
+        
+    def _onRightUp(self, event):
+        """!Right mouse button released
+        """
+        # digitization tool (confirm action)
+        if self.toolbar.GetAction() == "addLine" and \
+                self.toolbar.GetAction('type') in ["line", "boundary", "area"]:
+            # -> add new line / boundary
+            try:
+                mapName = self.toolbar.GetLayer().GetName()
+            except:
+                mapName = None
+                gcmd.GError(parent = self,
+                            message = _("No vector map selected for editing."))
+                    
+            if mapName:
+                if self.toolbar.GetAction('type') == 'line':
+                    line = True
+                else:
+                    line = False
+                    
+                if len(self.polycoords) < 2: # ignore 'one-point' lines
+                    return
+                    
+                nfeat, fids = self.digit.AddFeature(self.toolbar.GetAction('type'), self.polycoords)
+                if nfeat < 0:
+                    return
+                    
+                position = self.Cell2Pixel(self.polycoords[-1])
+                self.polycoords = []
+                self.UpdateMap(render = False)
+                self.redrawAll = True
+                self.Refresh()
+                
+            # add new record into atribute table
+                if UserSettings.Get(group = 'vdigit', key = "addRecord", subkey = 'enabled') and \
+                        (line is True or \
+                             (not line and nfeat > 0)):
+                    posWindow = self.ClientToScreen((position[0] + self.dialogOffset,
+                                                     position[1] + self.dialogOffset))
+                        
+                    # select attributes based on layer and category
+                    cats = { fids[0] : {
+                            UserSettings.Get(group = 'vdigit', key = "layer", subkey = 'value') :
+                                (UserSettings.Get(group = 'vdigit', key = "category", subkey = 'value'), )
+                            }}
+                    
+                    addRecordDlg = dbm_dialogs.DisplayAttributesDialog(parent = self, map = mapName,
+                                                                       cats = cats,
+                                                                       pos = posWindow,
+                                                                       action = "add")
+                    
+                    for fid in fids:
+                        self._geomAttrb(fid, addRecordDlg, 'length')
+                        # auto-placing centroid
+                        self._geomAttrb(fid, addRecordDlg, 'area')
+                        self._geomAttrb(fid, addRecordDlg, 'perimeter')
+
+                    
+                    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 = True,
+                                        quiet = True,
+                                        input = sqlfile.name)
+                        
+                    if addRecordDlg.mapDBInfo:
+                        self._updateATM()
+            
+        elif self.toolbar.GetAction() == "deleteLine":
+            # -> delete selected vector features
+            if self.digit.DeleteSelectedLines() < 0:
+                return
+            self._updateATM()
+        elif self.toolbar.GetAction() == "splitLine":
+            # split line
+            if self.digit.SplitLine(self.Pixel2Cell(self.mouse['begin'])) < 0:
+                return
+        elif self.toolbar.GetAction() == "addVertex":
+            # add vertex
+            fid = self.digit.AddVertex(self.Pixel2Cell(self.mouse['begin']))
+            if fid < 0:
+                return
+        elif self.toolbar.GetAction() == "removeVertex":
+            # remove vertex
+            fid = self.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin']))
+            if fid < 0:
+                return
+            self._geomAttrbUpdate([fid,])
+        elif self.toolbar.GetAction() in ("copyCats", "copyAttrs"):
+            try:
+                if self.toolbar.GetAction() == 'copyCats':
+                    if self.digit.CopyCats(self.copyCatsList,
+                                           self.copyCatsIds, copyAttrb = False) < 0:
+                        return
+                else:
+                    if self.digit.CopyCats(self.copyCatsList,
+                                           self.copyCatsIds, copyAttrb = True) < 0:
+                        return
+                
+                del self.copyCatsList
+                del self.copyCatsIds
+            except AttributeError:
+                pass
+            
+            self._updateATM()
+                
+        elif self.toolbar.GetAction() == "editLine" and \
+                hasattr(self, "moveInfo"):
+            line = self.digit.GetDisplay().GetSelected()
+            if self.digit.EditLine(line, self.polycoords) < 0:
+                return
+                
+            del self.moveInfo
+                
+        elif self.toolbar.GetAction() == "flipLine":
+            if self.digit.FlipLine() < 0:
+                return
+        elif self.toolbar.GetAction() == "mergeLine":
+            if self.digit.MergeLine() < 0:
+                return
+        elif self.toolbar.GetAction() == "breakLine":
+            if self.digit.BreakLine() < 0:
+                return
+        elif self.toolbar.GetAction() == "snapLine":
+            if self.digit.SnapLine() < 0:
+                return
+        elif self.toolbar.GetAction() == "connectLine":
+            if len(self.digit.GetDisplay().GetSelected()) > 1:
+                if self.digit.ConnectLine() < 0:
+                    return
+        elif self.toolbar.GetAction() == "copyLine":
+            if self.digit.CopyLine(self.copyIds) < 0:
+                return
+            del self.copyIds
+            if self.layerTmp:
+                self.Map.DeleteLayer(self.layerTmp)
+                self.UpdateMap(render = True, renderVector = False)
+            del self.layerTmp
+        
+        elif self.toolbar.GetAction() == "zbulkLine" and len(self.polycoords) == 2:
+            pos1 = self.polycoords[0]
+            pos2 = self.polycoords[1]
+            
+            selected = self.digit.GetDisplay().GetSelected()
+            dlg = VDigitZBulkDialog(parent = self, title = _("Z bulk-labeling dialog"),
+                                    nselected = len(selected))
+            if dlg.ShowModal() == wx.ID_OK:
+                if self.digit.ZBulkLines(pos1, pos2, dlg.value.GetValue(),
+                                         dlg.step.GetValue()) < 0:
+                    return
+            self.UpdateMap(render = False, renderVector = True)
+        elif self.toolbar.GetAction() == "typeConv":
+            # -> feature type conversion
+            # - point <-> centroid
+            # - line <-> boundary
+            if self.digit.TypeConvForSelectedLines() < 0:
+                return
+
+        if self.toolbar.GetAction() != "addLine":
+            # unselect and re-render
+            self.digit.GetDisplay().SetSelected([])
+            self.polycoords = []
+            self.UpdateMap(render = False)
+        
+    def _onMouseMoving(self, event):
+        self.mouse['end'] = event.GetPositionTuple()[:]
+        
+        Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \
+                       (self.mouse['end'][0], self.mouse['end'][1]))
+        
+        if self.toolbar.GetAction() == "addLine" and \
+                self.toolbar.GetAction('type') in ["line", "boundary", "area"]:
+            if len(self.polycoords) > 0:
+                self.MouseDraw(pdc = self.pdcTmp, begin = self.Cell2Pixel(self.polycoords[-1]))
+        
+        elif self.toolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] \
+                and hasattr(self, "moveInfo"):
+            dx = self.mouse['end'][0] - self.mouse['begin'][0]
+            dy = self.mouse['end'][1] - self.mouse['begin'][1]
+            
+            if len(self.moveInfo['id']) > 0:
+                # draw lines on new position
+                if self.toolbar.GetAction() == "moveLine":
+                    # move line
+                    for id in self.moveInfo['id']:
+                        self.pdcTmp.TranslateId(id, dx, dy)
+                elif self.toolbar.GetAction() in ["moveVertex", "editLine"]:
+                    # move vertex ->
+                    # (vertex, left vertex, left line,
+                    # right vertex, right line)
+                    
+                    # do not draw static lines
+                    if self.toolbar.GetAction() == "moveVertex":
+                        self.polycoords = []
+                        ### self.pdcTmp.TranslateId(self.moveInfo['id'][0], dx, dy)
+                        self.pdcTmp.RemoveId(self.moveInfo['id'][0])
+                        if self.moveInfo['id'][1] > 0: # previous vertex
+                            x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.moveInfo['id'][1])[0:2])
+                            self.pdcTmp.RemoveId(self.moveInfo['id'][1] + 1)
+                            self.polycoords.append((x, y))
+                        ### x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.moveInfo['id'][0])[0:2])
+                        self.polycoords.append(self.Pixel2Cell(self.mouse['end']))
+                        if self.moveInfo['id'][2] > 0: # next vertex
+                            x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.moveInfo['id'][2])[0:2])
+                            self.pdcTmp.RemoveId(self.moveInfo['id'][2]-1)
+                            self.polycoords.append((x, y))
+                        
+                        self.ClearLines(pdc = self.pdcTmp)
+                        self.DrawLines(pdc = self.pdcTmp)
+                        
+                    else: # edit line
+                        try:
+                            if self.moveInfo['id'][-1] > 0: # previous vertex
+                                self.MouseDraw(pdc = self.pdcTmp,
+                                               begin = self.Cell2Pixel(self.polycoords[-1]))
+                        except: # no line
+                            self.moveInfo['id'] = []
+                            self.polycoords = []
+                
+            self.Refresh() # TODO: use RefreshRect()
+            self.mouse['begin'] = self.mouse['end']
+            
+        elif self.toolbar.GetAction() == "zbulkLine":
+            if len(self.polycoords) == 1:
+                # draw mouse moving
+                self.MouseDraw(self.pdcTmp)
+                
+    def _zoom(self, event):
+        tmp1 = self.mouse['end']
+        tmp2 = self.Cell2Pixel(self.moveInfo['begin'])
+        dx = tmp1[0] - tmp2[0]
+        dy = tmp1[1] - tmp2[1]
+        self.moveInfo['beginDiff'] = (dx, dy)
+        for id in self.moveInfo['id']:
+            self.pdcTmp.RemoveId(id)
+        

Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py	2011-02-12 09:54:41 UTC (rev 45384)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py	2011-02-12 09:59:05 UTC (rev 45385)
@@ -29,7 +29,6 @@
 import grass.script as grass
 
 import dbm
-import dbm_dialogs
 import gdialogs
 import gcmd
 import utils
@@ -38,16 +37,12 @@
 from debug import Debug
 from preferences import globalSettings as UserSettings
 from units import ConvertValue as UnitsConvertValue
-from vdigit import GV_LINES as VDigit_Lines_Type
-from vdigit import VDigitCategoryDialog
-from vdigit import VDigitZBulkDialog
-from vdigit import VDigitDuplicatesDialog
 
 class MapWindow(object):
-    """!Abstract map window class
-
-    Parent for BufferedWindow class (2D display mode) and
-    GLWindow (3D display mode)
+    """!Abstract map display window class
+    
+    Superclass for BufferedWindow class (2D display mode), and GLWindow
+    (3D display mode).
     """
     def __init__(self, parent, id = wx.ID_ANY,
                  Map = None, tree = None, lmgr = None, **kwargs):
@@ -64,30 +59,9 @@
             'use'  : "pointer",
             'box'  : "point"
             }
-        
-    def EraseMap(self):
-        """!Erase the canvas (virtual method)
-        """
-        pass
 
-    def UpdateMap(self):
-        """!Updates the canvas anytime there is a change to the
-        underlaying images or to the geometry of the canvas.
-        """
-        pass
-
-    def OnLeftDown(self, event):
-        pass
-
-    def OnLeftUp(self, event):
-        pass
-
-    def OnKeyDown(self, event):
-        pass
-    
     def OnMotion(self, event):
-        """!Mouse moved
-        Track mouse motion and update status bar
+        """!Track mouse motion and update statusbar
         """
         if self.parent.statusbarWin['toggle'].GetSelection() == 0: # Coordinates
             precision = int(UserSettings.Get(group = 'projection', key = 'format',
@@ -100,23 +74,11 @@
                 self.parent.statusbar.SetStatusText("", 0)
                 return
             
-            if self.parent.toolbars['vdigit'] and \
-                    self.parent.toolbars['vdigit'].GetAction() == 'addLine' and \
-                    self.parent.toolbars['vdigit'].GetAction('type') in ('line', 'boundary') and \
-                    len(self.polycoords) > 0:
-                # for linear feature show segment and total length
-                distance_seg = self.Distance(self.polycoords[-1],
-                                             (e, n), screen = False)[0]
-                distance_tot = distance_seg
-                for idx in range(1, len(self.polycoords)):
-                    distance_tot += self.Distance(self.polycoords[idx-1],
-                                                  self.polycoords[idx],
-                                                  screen = False)[0]
-                self.parent.statusbar.SetStatusText("%.*f, %.*f (seg: %.*f; tot: %.*f)" % \
-                                                 (precision, e, precision, n,
-                                                  precision, distance_seg,
-                                                  precision, distance_tot), 0)
-            else:
+            updated = False
+            if hasattr(self, "digit"):
+                updated = self._onMotion((e, n), precision)
+
+            if not updated:
                 if self.parent.statusbarWin['projection'].IsChecked():
                     if not UserSettings.Get(group = 'projection', key = 'statusbar', subkey = 'proj4'):
                         self.parent.statusbar.SetStatusText(_("Projection not defined (check the settings)"), 0)
@@ -144,14 +106,9 @@
                     else:
                         self.parent.statusbar.SetStatusText("%.*f; %.*f" % \
                                                                 (precision, e, precision, n), 0)
+        
         event.Skip()
 
-    def OnZoomToMap(self, event):
-        pass
-
-    def OnZoomToRaster(self, event):
-        pass
-    
     def GetLayerByName(self, name, mapType, dataType = 'layer'):
         """!Get layer from layer tree by nam
         
@@ -181,7 +138,7 @@
     
     def GetSelectedLayer(self, type = 'layer', multi = False):
         """!Get selected layer from layer tree
-
+        
         @param type 'item' / 'layer' / 'nviz'
         @param multi return first selected layer or all
         
@@ -226,12 +183,14 @@
         return ret
     
 class BufferedWindow(MapWindow, wx.Window):
-    """!A Buffered window class.
+    """!A Buffered window class (2D view mode)
 
+    Superclass for VDigitWindow (vector digitizer).
+    
     When the drawing needs to change, you app needs to call the
     UpdateMap() method. Since the drawing is stored in a bitmap, you
     can also save the drawing to file by calling the
-    SaveToFile(self,file_name,file_type) method.
+    SaveToFile() method.
     """
     def __init__(self, parent, id = wx.ID_ANY,
                  Map = None, tree = None, lmgr = None,
@@ -242,7 +201,7 @@
         # flags
         self.resize = False # indicates whether or not a resize event has taken place
         self.dragimg = None # initialize variable for map panning
-
+        
         # variables for drawing on DC
         self.pen = None      # pen for drawing zoom boxes, etc.
         self.polypen = None  # pen for drawing polylines (measurements, profiles, etc)
@@ -257,7 +216,6 @@
         self.Bind(wx.EVT_PAINT,        self.OnPaint)
         self.Bind(wx.EVT_SIZE,         self.OnSize)
         self.Bind(wx.EVT_IDLE,         self.OnIdle)
-        ### self.Bind(wx.EVT_MOTION,       self.MouseActions)
         self.Bind(wx.EVT_MOUSE_EVENTS, self.MouseActions)
         self.Bind(wx.EVT_MOTION,       self.OnMotion)
         
@@ -273,34 +231,33 @@
         self.select = {}      # selecting/unselecting decorations for dragging
         self.textdict = {}    # text, font, and color indexed by id
         self.currtxtid = None # PseudoDC id for currently selected text
-
+        
         # zoom objects
         self.zoomhistory  = [] # list of past zoom extents
         self.currzoom     = 0  # current set of extents in zoom history being used
         self.zoomtype     = 1  # 1 zoom in, 0 no zoom, -1 zoom out
         self.hitradius    = 10 # distance for selecting map decorations
         self.dialogOffset = 5  # offset for dialog (e.g. DisplayAttributesDialog)
-
+        
         # OnSize called to make sure the buffer is initialized.
         # This might result in OnSize getting called twice on some
         # platforms at initialization, but little harm done.
         ### self.OnSize(None)
-
-        self.DefinePseudoDC()
+        
+        self._definePseudoDC()
         # redraw all pdc's, pdcTmp layer is redrawn always (speed issue)
         self.redrawAll = True
-
+        
         # will store an off screen empty bitmap for saving to file
-        self._buffer = ''
-
+        self._buffer = None
+        
         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):
+        
+    def _definePseudoDC(self):
         """!Define PseudoDC objects to use
         """
         # create PseudoDC used for background map, map decorations like scales and legends
@@ -311,7 +268,7 @@
         self.pdcDec = wx.PseudoDC()
         # pseudoDC for temporal objects (select box, measurement tool, etc.)
         self.pdcTmp = wx.PseudoDC()
-    
+        
     def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0, 0, 0, 0]):
         """!Draws map and overlay decorations
         """
@@ -326,25 +283,23 @@
         if img and pdctype == 'image':
             # self.imagedict[img]['coords'] = coords
             self.select[self.imagedict[img]['id']] = False # ?
-
+        
         pdc.BeginDrawing()
-
+        
         if drawid != 99:
             bg = wx.TRANSPARENT_BRUSH
         else:
             bg = wx.Brush(self.GetBackgroundColour())
-
+        
         pdc.SetBackground(bg)
         
-        ### pdc.Clear()
-
         Debug.msg (5, "BufferedWindow.Draw(): id=%s, pdctype = %s, coord=%s" % \
                        (drawid, pdctype, coords))
-
+        
         # set PseudoDC id
         if drawid is not None:
             pdc.SetId(drawid)
-        
+            
         if pdctype == 'clear': # erase the display
             bg = wx.WHITE_BRUSH
             # bg = wx.Brush(self.GetBackgroundColour())
@@ -355,13 +310,13 @@
             
             self.Refresh()
             return
-
+        
         if pdctype == 'image': # draw selected image
             bitmap = wx.BitmapFromImage(img)
             w,h = bitmap.GetSize()
             pdc.DrawBitmap(bitmap, coords[0], coords[1], True) # draw the composite map
             pdc.SetIdBounds(drawid, wx.Rect(coords[0],coords[1], w, h))
-
+        
         elif pdctype == 'box': # draw a box on top of the map
             if self.pen:
                 pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT))
@@ -382,13 +337,11 @@
                 pdc.SetPen(self.pen)
                 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)
                 if (len(coords) < 2):
                     return
                 i = 1
@@ -396,7 +349,7 @@
                     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 = []
                 ylist = []
@@ -411,7 +364,7 @@
                     y2 = max(ylist)
                     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)
@@ -421,11 +374,10 @@
                                coords[0] + 5,
                                coords[1] + 5)
                 pdc.SetIdBounds(drawid, wx.Rect(coordsBound))
-                # self.ovlcoords[drawid] = coords
-
+        
         elif pdctype == 'text': # draw text on top of map
             if not img['active']:
-                return #only draw active text
+                return # only draw active text
             if img.has_key('rotation'):
                 rotation = float(img['rotation'])
             else:
@@ -439,16 +391,16 @@
             else:
                 pdc.DrawRotatedText(img['text'], coords[0], coords[1], rotation)
             pdc.SetIdBounds(drawid, wx.Rect(coords[0], coords[1], w, h))
-            
+        
         pdc.EndDrawing()
         
         self.Refresh()
         
         return drawid
-
+    
     def TextBounds(self, textinfo):
         """!Return text boundary data
-
+        
         @param textinfo text metadata (text, font, color, rotation)
         @param coords reference point
         """
@@ -461,18 +413,17 @@
         
         Debug.msg (4, "BufferedWindow.TextBounds(): text=%s, rotation=%f" % \
                    (textinfo['text'], rotation))
-
+        
         self.Update()
-        ### self.Refresh()
-
+        
         self.SetFont(textinfo['font'])
-
+        
         w, h = self.GetTextExtent(textinfo['text'])
-
+        
         if rotation == 0:
             coords[2], coords[3] = coords[0] + w, coords[1] + h
             return coords, w, h
-
+        
         boxh = math.fabs(math.sin(math.radians(rotation)) * w) + h
         boxw = math.fabs(math.cos(math.radians(rotation)) * w) + h
         coords[2] = coords[0] + boxw
@@ -480,40 +431,14 @@
         
         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
-        self.pdcVector for vector map which is edited
-        self.pdcTmp for temporaly drawn objects (self.polycoords)
-
+        
         If self.redrawAll is False on self.pdcTmp content is re-drawn
         """
         Debug.msg(4, "BufferedWindow.OnPaint(): redrawAll=%s" % self.redrawAll)
         
         dc = wx.BufferedPaintDC(self, self.buffer)
-        
-        ### dc.SetBackground(wx.Brush("White"))
         dc.Clear()
         
         # use PrepareDC to set position correctly
@@ -534,7 +459,7 @@
             self.pdc.DrawToDCClipped(dc, rgn)
             
             # draw vector map layer
-            if self.pdcVector:
+            if hasattr(self, "digit"):
                 # decorate with GDDC (transparency)
                 try:
                     gcdc = wx.GCDC(dc)
@@ -549,7 +474,7 @@
                 # draw to the dc
                 self.pdc.DrawToDC(dc)
                 
-                if self.pdcVector:
+                if isinstace(self, VDigitWindow):
                     # decorate with GDDC (transparency)
                     try:
                         gcdc = wx.GCDC(dc)
@@ -557,7 +482,7 @@
                     except NotImplementedError, e:
                         print >> sys.stderr, e
                         self.pdcVector.DrawToDC(dc)
-                        
+                
                 # store buffered image
                 # self.bufferLast = wx.BitmapFromImage(self.buffer.ConvertToImage())
                 self.bufferLast = dc.GetAsBitmap(wx.Rect(0, 0, self.Map.width, self.Map.height))
@@ -604,23 +529,23 @@
             self.img = self.img.Scale(self.Map.width, self.Map.height)
             if len(self.Map.GetListOfLayers()) > 0:
                 self.UpdateMap()
-
+        
         # re-render image on idle
         self.resize = True
 
         # reposition checkbox in statusbar
         self.parent.StatusbarReposition()
-
+        
         # update statusbar
         self.parent.StatusbarUpdate()
-
+        
     def OnIdle(self, event):
         """!Only re-render a composite map image from GRASS during
         idle time instead of multiple times during resizing.
         """
         if self.resize:
             self.UpdateMap(render = True)
-
+        
         event.Skip()
 
     def SaveToFile(self, FileName, FileType, width, height):
@@ -655,11 +580,10 @@
         self.Refresh()
         
     def GetOverlay(self):
-        """!
-        Converts rendered overlay files to wx.Image
-
+        """!Converts rendered overlay files to wx.Image
+        
         Updates self.imagedict
-
+        
         @return list of images
         """
         imgs = []
@@ -671,12 +595,12 @@
                 imgs.append(img)
 
         return imgs
-
+    
     def GetImage(self):
         """!Converts redered map files to wx.Image
-
+        
         Updates self.imagedict (id=99)
-
+        
         @return wx.Image instance (map composition)
         """
         imgId = 99
@@ -691,8 +615,7 @@
         return img
 
     def UpdateMap(self, render = True, renderVector = True):
-        """!
-        Updates the canvas anytime there is a change to the
+        """!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
@@ -702,9 +625,6 @@
         
         self.resize = False
         
-        # if len(self.Map.GetListOfLayers()) == 0:
-        #    return False
-        
         if self.img is None:
             render = True
         
@@ -771,38 +691,8 @@
         #
         # render vector map layer
         #
-        digitToolbar = self.parent.toolbars['vdigit']
-        if renderVector and digitToolbar and \
-                digitToolbar.GetLayer():
-            # set region
-            self.parent.digit.GetDisplay().UpdateRegion()
-            # re-calculate threshold for digitization tool
-            # self.parent.digit.GetDisplay().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.redrawAll = True
-                self.parent.digit.GetDisplay().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']:
-                        self.pdcTmp.TranslateId(id,
-                                                self.vdigitMove['beginDiff'][0],
-                                                self.vdigitMove['beginDiff'][1])
-                    del self.vdigitMove['beginDiff']
-        
+        if renderVector and hasattr(self, "digit"):
+            self._updateMap()
         #
         # render overlays
         #
@@ -922,25 +812,23 @@
                 region['w'] >= refRegion['w'] and \
                 region['e'] <= refRegion['e']:
             return True
-
+        
         return False
 
     def EraseMap(self):
-        """!
-        Erase the canvas
+        """!Erase map canvas
         """
         self.Draw(self.pdc, pdctype = 'clear')
-                  
-        if self.pdcVector:
+        
+        if hasattr(self, "digit"):
             self.Draw(self.pdcVector, pdctype = 'clear')
         
         self.Draw(self.pdcDec, pdctype = 'clear')
         self.Draw(self.pdcTmp, pdctype = 'clear')
         
     def DragMap(self, moveto):
-        """!
-        Drag the entire map image for panning.
-
+        """!Drag the entire map image for panning.
+        
         @param moveto dx,dy
         """
         dc = wx.BufferedDC(wx.ClientDC(self))
@@ -956,8 +844,7 @@
         self.dragimg.EndDrag()
         
     def DragItem(self, id, event):
-        """!
-        Drag an overlay decoration item
+        """!Drag an overlay decoration item
         """
         if id == 99 or id == '' or id == None: return
         Debug.msg (5, "BufferedWindow.DragItem(): id=%d" % id)
@@ -966,7 +853,6 @@
         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
@@ -975,7 +861,7 @@
             rleft = (r[0]-r[2],r[1],r[2],r[3])
             r = r.Union(rleft)
         self.pdc.TranslateId(id, dx, dy)
-
+        
         r2 = self.pdc.GetIdBounds(id)
         if type(r2) is list:
             r2 = wx.Rect(r[0], r[1], r[2], r[3])
@@ -987,26 +873,22 @@
         self.lastpos = (event.GetX(), event.GetY())
                 
     def MouseDraw(self, pdc = None, begin = None, end = None):
-        """!
-        Mouse box or line from 'begin' to 'end'
-
+        """!Mouse box or line from 'begin' to 'end'
+        
         If not given from self.mouse['begin'] to self.mouse['end'].
-
         """
-#        self.redrawAll = False
-        
         if not pdc:
             return
-
+        
         if begin is None:
             begin = self.mouse['begin']
         if end is None:
             end   = self.mouse['end']
-
+        
         Debug.msg (5, "BufferedWindow.MouseDraw(): use=%s, box=%s, begin=%f,%f, end=%f,%f" % \
                        (self.mouse['use'], self.mouse['box'],
                         begin[0], begin[1], end[0], end[1]))
-
+        
         if self.mouse['box'] == "box":
             boxid = wx.ID_NEW
             mousecoords = [begin[0], begin[1],
@@ -1022,6 +904,7 @@
             self.RefreshRect(r, False)
             pdc.SetId(boxid)
             self.Draw(pdc, drawid = boxid, pdctype = 'box', coords = mousecoords)
+        
         elif self.mouse['box'] == "line" or self.mouse['box'] == 'point':
             self.lineid = wx.ID_NEW
             mousecoords = [begin[0], begin[1], \
@@ -1041,18 +924,16 @@
             self.Draw(pdc, drawid = self.lineid, pdctype = 'line', coords = mousecoords)
 
     def DrawLines(self, pdc = None, polycoords = None):
-        """!
-        Draw polyline in PseudoDC
-
+        """!Draw polyline in PseudoDC
+        
         Set self.pline to wx.NEW_ID + 1
-
+        
         polycoords - list of polyline vertices, geographical coordinates
         (if not given, self.polycoords is used)
-
         """
         if not pdc:
             pdc = self.pdcTmp
-
+        
         if not polycoords:
             polycoords = self.polycoords
         
@@ -1067,9 +948,9 @@
             
             Debug.msg (4, "BufferedWindow.DrawLines(): coords=%s, id=%s" % \
                            (coords, self.plineid))
-
+            
             return self.plineid
-
+        
         return -1
 
     def DrawCross(self, pdc, coords, size, rotation = 0,
@@ -1093,10 +974,10 @@
         self.lineid = wx.NewId()
         for lineCoords in coordsCross:
             self.Draw(pdc, drawid = self.lineid, pdctype = 'line', coords = lineCoords)
-
+        
         if not text:
             return self.lineid
-
+        
         if textAlign == 'ul':
             coord = [coords[0] - textOffset[0], coords[1] - textOffset[1], 0, 0]
         elif textAlign == 'ur':
@@ -1108,19 +989,15 @@
         
         self.Draw(pdc, img = text,
                   pdctype = 'text', coords = coord)
-
+        
         return self.lineid
 
     def MouseActions(self, event):
-        """!
-        Mouse motion and button click notifier
+        """!Mouse motion and button click notifier
         """
         if not self.processMouse:
             return
         
-        ### if self.redrawAll is False:
-        ###    self.redrawAll = True
-        
         # zoom with mouse wheel
         if event.GetWheelRotation() != 0:
             self.OnMouseWheel(event)
@@ -1128,23 +1005,23 @@
         # left mouse button pressed
         elif event.LeftDown():
             self.OnLeftDown(event)
-
+        
         # left mouse button released
         elif event.LeftUp():
             self.OnLeftUp(event)
-
+        
         # dragging
         elif event.Dragging():
             self.OnDragging(event)
-
+        
         # double click
         elif event.ButtonDClick():
             self.OnButtonDClick(event)
-
+        
         # middle mouse button pressed
         elif event.MiddleDown():
             self.OnMiddleDown(event)
-
+        
         # middle mouse button relesed
         elif event.MiddleUp():
             self.OnMiddleUp(event)
@@ -1152,22 +1029,19 @@
         # right mouse button pressed
         elif event.RightDown():
             self.OnRightDown(event)
-
+        
         # right mouse button released
         elif event.RightUp():
             self.OnRightUp(event)
-
+        
         elif event.Entering():
             self.OnMouseEnter(event)
-
+        
         elif event.Moving():
             self.OnMouseMoving(event)
-        
-        # event.Skip()
-        
+                
     def OnMouseWheel(self, event):
-        """!
-        Mouse wheel moved
+        """!Mouse wheel moved
         """
         self.processMouse = False
         current  = event.GetPositionTuple()[:]
@@ -1183,22 +1057,19 @@
             zoomtype = 1
         else:
             zoomtype = -1
-
+        
         # zoom
         self.Zoom(begin, end, zoomtype)
-
+        
         # redraw map
         self.UpdateMap()
-
-        ### self.OnPaint(None)
-
+        
         # update statusbar
         self.parent.StatusbarUpdate()
-
+        
         self.Refresh()
         self.processMouse = True
-#        event.Skip()
-
+        
     def OnDragging(self, event):
         """!Mouse dragging
         """
@@ -1208,7 +1079,10 @@
         move = (current[0] - previous[0],
                 current[1] - previous[1])
         
-        digitToolbar = self.parent.toolbars['vdigit']
+        if hasattr(self, "digit"):
+            digitToolbar = self.toolbar
+        else:
+            digitToolbar = None
         
         # dragging or drawing box with left button
         if self.mouse['use'] == 'pan' or \
@@ -1224,326 +1098,16 @@
         # dragging anything else - rubber band box or line
         else:
             if (self.mouse['use'] == 'pointer' and 
-                not digitToolbar): return
+                not digitToolbar):
+                return
             self.mouse['end'] = event.GetPositionTuple()[:]
-            digitClass = self.parent.digit
             if (event.LeftIsDown() and 
                 not (digitToolbar and 
                     digitToolbar.GetAction() in ("moveLine",) and 
-                    digitClass.GetDisplay().GetSelected() > 0)):
+                    self.display.GetSelected() > 0)):
                 # draw box only when left mouse button is pressed
                 self.MouseDraw(pdc = self.pdcTmp)
         
-        # 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 / centroiud
-            east, north = self.Pixel2Cell(self.mouse['begin'])
-            nfeat, fids = digitClass.AddFeature(digitToolbar.GetAction('type'), [(east, north)])
-            if nfeat < 1:
-                return
-            
-            self.UpdateMap(render = False) # redraw map
-            
-            # add new record into atribute table
-            if UserSettings.Get(group = 'vdigit', key = "addRecord", subkey = 'enabled'):
-                # select attributes based on layer and category
-                cats = { fids[0] : {
-                        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 digitToolbar.GetAction('type') == 'centroid':
-                    for fid in fids:
-                        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", "area"]:
-            # 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'] = []
-                
-        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.GetDisplay().SetSelected([])
-        
-        # select feature by point
-        cats = {}
-        if digitClass.GetDisplay().SelectLineByPoint(coords) is None:
-            return
-        
-        if UserSettings.Get(group = 'vdigit', key = 'checkForDupl',
-                            subkey = 'enabled'):
-            lines = digitClass.GetDisplay().GetSelected()
-        else:
-            lines = (digitClass.GetDisplay().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, renderVector = True)
- 
-    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
         """
@@ -1566,11 +1130,11 @@
         
         # vector digizer
         elif self.mouse["use"] == "pointer" and \
-                self.parent.toolbars['vdigit']:
+                hasattr(self, "digit"):
             if event.ControlDown():
-                self.OnLeftDownVDigitUndo(event)
+                self.OnLeftDownUndo(event)
             else:
-                self.OnLeftDownVDigit(event)
+                self._onLeftDown(event)
         
         elif self.mouse['use'] == 'pointer':
             # get decoration or text id
@@ -1585,375 +1149,9 @@
                 self.dragid = idlist[0] #drag whatever is on top
         else:
             pass
-
+        
         event.Skip()
-
-    def OnLeftDownVDigitUndo(self, event):
-        """!Left mouse button down with control key pressed - vector
-        digitizer undo functionality
-        """
-        digitToolbar = self.parent.toolbars['vdigit']
-        if self.mouse["use"] != "pointer" or not digitToolbar:
-            return
         
-        digitClass = self.parent.digit
-        if (digitToolbar.GetAction() == "addLine" and \
-                digitToolbar.GetAction('type') in ["line", "boundary", "area"]) or \
-                digitToolbar.GetAction() == "editLine":
-            # add line or boundary -> remove last point from the line
-            try:
-                removed = self.polycoords.pop()
-                Debug.msg(4, "BufferedWindow.OnMiddleDown(): polycoords_poped=%s" % \
-                              [removed,])
-                # self.mouse['begin'] = self.Cell2Pixel(self.polycoords[-1])
-            except:
-                pass
-            
-        if digitToolbar.GetAction() == "editLine":
-            # remove last vertex & line
-            if len(self.vdigitMove['id']) > 1:
-                self.vdigitMove['id'].pop()
-                
-            self.UpdateMap(render = False, renderVector = False)
-            
-        elif digitToolbar.GetAction() in ["deleteLine", "moveLine", "splitLine",
-                                          "addVertex", "removeVertex", "moveVertex",
-                                          "copyCats", "flipLine", "mergeLine",
-                                          "snapLine", "connectLine", "copyLine",
-                                          "queryLine", "breakLine", "typeConv"]:
-            # varios tools -> unselected selected features
-            digitClass.GetDisplay().SetSelected([])
-            if digitToolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] and \
-                    hasattr(self, "vdigitMove"):
-                del self.vdigitMove
-                
-            elif digitToolbar.GetAction() == "copyCats":
-                try:
-                    del self.copyCatsList
-                    del self.copyCatsIds
-                except AttributeError:
-                    pass
-                
-            elif digitToolbar.GetAction() == "copyLine":
-                del self.copyIds
-                if self.layerTmp:
-                    self.Map.DeleteLayer(self.layerTmp)
-                    self.UpdateMap(render = True, renderVector = False)
-                del self.layerTmp
-
-            self.polycoords = []
-            self.UpdateMap(render = False) # render vector
-        
-        elif digitToolbar.GetAction() == "zbulkLine":
-            # reset polyline
-            self.polycoords = []
-            digitClass.GetDisplay().SetSelected([])
-            self.UpdateMap(render = False)
-        
-        self.redrawAll = True
-        self.UpdateMap(render = False, renderVector = False)
-
-    def OnLeftDownVDigit(self, event):
-        """!Left mouse button donw - vector digitizer various actions
-        """
-        digitToolbar = self.parent.toolbars['vdigit']
-        digitClass   = self.parent.digit
-        
-        try:
-            mapLayer = digitToolbar.GetLayer().GetName()
-        except:
-            wx.MessageBox(parent = self,
-                          message = _("No vector map selected for editing."),
-                          caption = _("Vector digitizer"),
-                          style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
-            event.Skip()
-            return
-    
-        if digitToolbar.GetAction() not in ("moveVertex",
-                                            "addVertex",
-                                            "removeVertex",
-                                            "editLine"):
-            # set pen
-            self.pen = wx.Pen(colour = 'Red', width = 2, style = wx.SHORT_DASH)
-            self.polypen = wx.Pen(colour = 'dark green', width = 2, style = wx.SOLID)
-            
-        if digitToolbar.GetAction() in ("addVertex",
-                                        "removeVertex",
-                                        "splitLines"):
-            # unselect
-            digitClass.GetDisplay().SetSelected([])
-
-        if digitToolbar.GetAction() == "addLine":
-            self.OnLeftDownVDigitAddLine(event)
-            
-        elif digitToolbar.GetAction() == "editLine" and \
-                hasattr(self, "vdigitMove"):
-            self.OnLeftDownVDigitEditLine(event)
-
-        elif digitToolbar.GetAction() in ("moveLine", 
-                                          "moveVertex",
-                                          "editLine") and \
-                                          not hasattr(self, "vdigitMove"):
-                                          self.OnLeftDownVDigitMoveLine(event)
-
-        elif digitToolbar.GetAction() in ("displayAttrs"
-                                          "displayCats"):
-            self.OnLeftDownVDigitDisplayCA(event)
-            
-        elif digitToolbar.GetAction() in ("copyCats",
-                                          "copyAttrs"):
-            self.OnLeftDownVDigitCopyCA(event)
-            
-        elif digitToolbar.GetAction() == "copyLine":
-            self.OnLeftDownVDigitCopyLine(event)
-            
-        elif digitToolbar.GetAction() == "zbulkLine":
-            self.OnLeftDownVDigitBulkLine(event)
-    
-    def OnLeftUpVDigit(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.GetDisplay().GetSelected()) == 0:
-                nselected = digitClass.GetDisplay().SelectLineByPoint(pos1)['point']
-                
-                if digitToolbar.GetAction() == "editLine":
-                    try:
-                        selVertex = digitClass.GetDisplay().GetSelectedVertex(pos1)[0]
-                    except IndexError:
-                        selVertex = None
-                        
-                    if selVertex:
-                        # self.UpdateMap(render=False)
-                        ids = digitClass.GetDisplay().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.GetDisplay().DrawSelected(False) 
-                                
-                        if selVertex < ids[-1] / 2:
-                            # choose first or last node of line
-                            self.vdigitMove['id'].reverse()
-                            self.polycoords.reverse()
-                    else:
-                        # unselect
-                        digitClass.GetDisplay().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.GetDisplay().SelectLineByPoint(pos1)['point']
-                if nselected:
-                    self.copyCatsList = digitClass.GetDisplay().GetSelected()
-            else:
-                # -> 'to' -> select by bbox
-                digitClass.GetDisplay().SetSelected([])
-                # return number of selected features (by box/point)
-                nselected = digitClass.GetDisplay().SelectLinesByBox((pos1, pos2))
-                if nselected == 0:
-                    if digitClass.GetDisplay().SelectLineByPoint(pos1) is not None:
-                        nselected = 1
-                        
-                if nselected > 0:
-                    self.copyCatsIds = digitClass.GetDisplay().GetSelected()
-
-        elif digitToolbar.GetAction() == "queryLine":
-            selected = digitClass.SelectLinesByQuery(bbox = (pos1, pos2))
-            nselected = len(selected)
-            if nselected > 0:
-                digitClass.GetDisplay().SetSelected(selected)
-        
-        else:
-            # -> moveLine || deleteLine, etc. (select by point/box)
-            if digitToolbar.GetAction() == 'moveLine' and \
-                    len(digitClass.GetDisplay().GetSelected()) > 0:
-                nselected = 0
-            else:
-                if digitToolbar.GetAction() == 'moveLine':
-                    drawSeg = True
-                else:
-                    drawSeg = False
-                
-                nselected = digitClass.GetDisplay().SelectLinesByBox(bbox = (pos1, pos2),
-                                                                     drawSeg = drawSeg)
-                if nselected == 0:
-                    if digitClass.GetDisplay().SelectLineByPoint(pos1) 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.GetDisplay().GetSelected(grassId = False)
-                else: # moveVertex
-                    self.vdigitMove['id'] = digitClass.GetDisplay().GetSelectedVertex(pos1)
-                    if len(self.vdigitMove['id']) == 0: # no vertex found
-                        digitClass.GetDisplay().SetSelected([])
-            
-            #
-            # check for duplicates
-            #
-            if UserSettings.Get(group = 'vdigit', key = 'checkForDupl', subkey = 'enabled'):
-                dupl = digitClass.GetDisplay().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.GetDisplay().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 \
-                        hasattr(self, "vdigitMove") 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.GetDisplay().SelectLineByPoint(pos1)['point']
-        if not pointOnLine:
-            return
-
-        if digitToolbar.GetAction() in ["splitLine", "addVertex"]:
-            self.UpdateMap(render = False) # highlight object
-            self.DrawCross(pdc = self.pdcTmp, coords = self.Cell2Pixel((pointOnLine[0], pointOnLine[1])),
-                           size = 5)
-        else: # removeVertex
-            # get only id of vertex
-            try:
-                id = digitClass.GetDisplay().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.GetDisplay().SetSelected([])
-                self.UpdateMap(render = False)
-
-    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.GetDisplay().SelectLinesByBox((pos1, pos2))
-
-            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(bbox = (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:
-                    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.GetDisplay().SelectLinesByBox((pos1, pos2))
-        
-        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)
-
-    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.GetDisplay().GetSelected()) > 0:
-            self.UpdateMap(render = False)
-        
     def OnLeftUp(self, event):
         """!Left mouse button released
         """
@@ -1981,26 +1179,26 @@
 
             # redraw map
             self.UpdateMap(render = True)
-
+            
             # update statusbar
             self.parent.StatusbarUpdate()
-
+            
         elif self.mouse["use"] == "query":
             # querying
             self.parent.QueryMap(self.mouse['begin'][0],self.mouse['begin'][1])
-
+        
         elif self.mouse["use"] == "queryVector":
             # editable mode for vector map layers
             self.parent.QueryVector(self.mouse['begin'][0], self.mouse['begin'][1])
-
+            
             # clear temp canvas
             self.UpdateMap(render = False, renderVector = False)
-            
+        
         elif self.mouse["use"] in ["measure", "profile"]:
             # measure or profile
             if self.mouse["use"] == "measure":
                 self.parent.MeasureDist(self.mouse['begin'], self.mouse['end'])
-
+            
             self.polycoords.append(self.Pixel2Cell(self.mouse['end']))
             self.ClearLines(pdc = self.pdcTmp)
             self.DrawLines(pdc = self.pdcTmp)
@@ -2014,10 +1212,10 @@
                     coordtype = 'source'
                 else:
                     coordtype = 'target'
-
+                
                 self.parent.GetLayerManager().gcpmanagement.SetGCPData(coordtype, coord, self, confirm = True)
                 self.UpdateMap(render = False, renderVector = False)
-
+        
         elif self.mouse["use"] == "pointer" and \
                 self.parent.GetLayerManager().georectifying:
             # -> georectifying
@@ -2026,55 +1224,14 @@
                 coordtype = 'gcpcoord'
             else:
                 coordtype = 'mapcoord'
-
+            
             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
             
-            if hasattr(self, "vdigitMove"):
-                if len(digitClass.GetDisplay().GetSelected()) == 0:
-                    self.vdigitMove['begin'] = self.Pixel2Cell(self.mouse['begin']) # left down
-                
-                # eliminate initial mouse moving efect
-                self.mouse['begin'] = self.mouse['end'] 
-
-            if digitToolbar.GetAction() in ("deleteLine",
-                                            "moveLine",
-                                            "moveVertex",
-                                            "copyCats",
-                                            "copyAttrs",
-                                            "editLine",
-                                            "flipLine",
-                                            "mergeLine",
-                                            "snapLine",
-                                            "queryLine",
-                                            "breakLine",
-                                            "typeConv",
-                                            "connectLine"):
-                self.OnLeftUpVDigit(event)
-
-            elif digitToolbar.GetAction() in ("splitLine",
-                                              "addVertex",
-                                              "removeVertex"):
-                self.OnLeftUpVDigitModifyLine(event)
-
-            elif digitToolbar.GetAction() == "copyLine":
-                self.OnLeftUpVDigitCopyLine(event)
+        elif self.mouse["use"] == "pointer" and \
+                hasattr(self, "digit"):
+            self._onLeftUp(event)
             
-            elif digitToolbar.GetAction() == "zbulkLine" and \
-                    len(self.polycoords) == 2:
-                self.OnLeftUpVDigitBulkLine(event)
-            
-            elif digitToolbar.GetAction() == "connectLine":
-                self.OnLeftUpConnectLine(event)
-            
-            if len(digitClass.GetDisplay().GetSelected()) > 0:
-                self.redrawAll = None
-            
         elif (self.mouse['use'] == 'pointer' and 
                 self.dragid >= 0):
             # end drag of overlay decoration
@@ -2089,12 +1246,11 @@
             self.currtxtid = None
         
     def OnButtonDClick(self, event):
-        """!
-        Mouse button double click
+        """!Mouse button double click
         """
         Debug.msg (5, "BufferedWindow.OnButtonDClick(): use=%s" % \
                    self.mouse["use"])
-
+        
         if self.mouse["use"] == "measure":
             # measure
             self.ClearLines(pdc=self.pdcTmp)
@@ -2104,17 +1260,11 @@
             self.mouse['end'] = [0, 0]
             self.Refresh()
             self.SetCursor(self.parent.cursors["default"])
-
-        elif self.mouse["use"] == "profile":
-            pass
-
-        elif self.mouse['use'] == 'pointer' and \
-                self.parent.toolbars['vdigit']:
-            # vector digitizer
-            pass
-
-        else:
-            # select overlay decoration options dialog
+        
+        elif self.mouse["use"] != "profile" or \
+                (self.mouse['use'] != 'pointer' and \
+                     hasattr(self, "digit")):
+               # select overlay decoration options dialog
             clickposition = event.GetPositionTuple()[:]
             idlist  = self.pdc.FindObjects(clickposition[0], clickposition[1], self.hitradius)
             if idlist == []:
@@ -2135,238 +1285,37 @@
         """
         Debug.msg (5, "BufferedWindow.OnRightDown(): use=%s" % \
                    self.mouse["use"])
-                   
-        digitToolbar = self.parent.toolbars['vdigit']
-        if digitToolbar:
-            digitClass = self.parent.digit
-            # digitization tool (confirm action)
-            if digitToolbar.GetAction() in ("moveLine",
-                                            "moveVertex") and \
-                    hasattr(self, "vdigitMove"):
-
-                pFrom = self.vdigitMove['begin']
-                pTo = self.Pixel2Cell(event.GetPositionTuple())
-                
-                move = (pTo[0] - pFrom[0],
-                        pTo[1] - pFrom[1])
-                
-                if digitToolbar.GetAction() == "moveLine":
-                    # move line
-                    if digitClass.MoveSelectedLines(move) < 0:
-                        return
-                elif digitToolbar.GetAction() == "moveVertex":
-                    # move vertex
-                    fid = digitClass.MoveSelectedVertex(pFrom, move)
-                    if fid < 0:
-                        return
-
-                    self._geomAttrbUpdate([fid,])
-                
-                del self.vdigitMove
-                
+        
+        if hasattr(self, "digit"):
+            self._onRightDown(event)
+        
         event.Skip()
-
+        
     def OnRightUp(self, event):
         """!Right mouse button released
         """
         Debug.msg (5, "BufferedWindow.OnRightUp(): use=%s" % \
                    self.mouse["use"])
         
-        self.OnRightUpVDigit(event)
+        if hasattr(self, "digit"):
+            self._onRightUp(event)
         
         self.redrawAll = True
         self.Refresh()
-            
+        
         event.Skip()
-    
-    def OnRightUpVDigit(self, event):
-        """!Right mouse button release (vector digitizer)
-        """
-        digitToolbar = self.parent.toolbars['vdigit']
-        if not digitToolbar:
-            return
         
-        digitClass = self.parent.digit
-        # digitization tool (confirm action)
-        if digitToolbar.GetAction() == "addLine" and \
-                digitToolbar.GetAction('type') in ["line", "boundary", "area"]:
-            # -> add new line / boundary
-            try:
-                mapName = digitToolbar.GetLayer().GetName()
-            except:
-                mapName = None
-                gcmd.GError(parent = self,
-                            message = _("No vector map selected for editing."))
-                    
-            if mapName:
-                if digitToolbar.GetAction('type') == 'line':
-                    line = True
-                else:
-                    line = False
-                    
-                if len(self.polycoords) < 2: # ignore 'one-point' lines
-                    return
-                    
-                nfeat, fids = digitClass.AddFeature(digitToolbar.GetAction('type'), self.polycoords)
-                if nfeat < 0:
-                    return
-                    
-                position = self.Cell2Pixel(self.polycoords[-1])
-                self.polycoords = []
-                self.UpdateMap(render = False)
-                self.redrawAll = True
-                self.Refresh()
-                
-            # add new record into atribute table
-                if UserSettings.Get(group = 'vdigit', key = "addRecord", subkey = 'enabled') and \
-                        (line is True or \
-                             (not line and nfeat > 0)):
-                    posWindow = self.ClientToScreen((position[0] + self.dialogOffset,
-                                                     position[1] + self.dialogOffset))
-                        
-                    # select attributes based on layer and category
-                    cats = { fids[0] : {
-                            UserSettings.Get(group = 'vdigit', key = "layer", subkey = 'value') :
-                                (UserSettings.Get(group = 'vdigit', key = "category", subkey = 'value'), )
-                            }}
-                    
-                    addRecordDlg = dbm_dialogs.DisplayAttributesDialog(parent = self, map = mapName,
-                                                                       cats = cats,
-                                                                       pos = posWindow,
-                                                                       action = "add")
-                    
-                    for fid in fids:
-                        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()
-                        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
-            fid = digitClass.AddVertex(self.Pixel2Cell(self.mouse['begin']))
-            if fid < 0:
-                return
-        elif digitToolbar.GetAction() == "removeVertex":
-            # remove vertex
-            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':
-                    if digitClass.CopyCats(self.copyCatsList,
-                                           self.copyCatsIds, copyAttrb = False) < 0:
-                        return
-                else:
-                    if digitClass.CopyCats(self.copyCatsList,
-                                           self.copyCatsIds, copyAttrb = True) < 0:
-                        return
-                
-                del self.copyCatsList
-                del self.copyCatsIds
-            except AttributeError:
-                pass
-            
-            self.__updateATM()
-                
-        elif digitToolbar.GetAction() == "editLine" and \
-                hasattr(self, "vdigitMove"):
-            line = digitClass.GetDisplay().GetSelected()
-            if digitClass.EditLine(line, self.polycoords) < 0:
-                return
-                
-            del self.vdigitMove
-                
-        elif digitToolbar.GetAction() == "flipLine":
-            if digitClass.FlipLine() < 0:
-                return
-        elif digitToolbar.GetAction() == "mergeLine":
-            if digitClass.MergeLine() < 0:
-                return
-        elif digitToolbar.GetAction() == "breakLine":
-            if digitClass.BreakLine() < 0:
-                return
-        elif digitToolbar.GetAction() == "snapLine":
-            if digitClass.SnapLine() < 0:
-                return
-        elif digitToolbar.GetAction() == "connectLine":
-            if len(digitClass.GetDisplay().GetSelected()) > 1:
-                if digitClass.ConnectLine() < 0:
-                    return
-        elif digitToolbar.GetAction() == "copyLine":
-            if digitClass.CopyLine(self.copyIds) < 0:
-                return
-            del self.copyIds
-            if self.layerTmp:
-                self.Map.DeleteLayer(self.layerTmp)
-                self.UpdateMap(render = True, renderVector = False)
-            del self.layerTmp
-        
-        elif digitToolbar.GetAction() == "zbulkLine" and len(self.polycoords) == 2:
-            pos1 = self.polycoords[0]
-            pos2 = self.polycoords[1]
-            
-            selected = digitClass.GetDisplay().GetSelected()
-            dlg = VDigitZBulkDialog(parent = self, title = _("Z bulk-labeling dialog"),
-                                    nselected = len(selected))
-            if dlg.ShowModal() == wx.ID_OK:
-                if digitClass.ZBulkLines(pos1, pos2, dlg.value.GetValue(),
-                                         dlg.step.GetValue()) < 0:
-                    return
-            self.UpdateMap(render = False, renderVector = True)
-        elif digitToolbar.GetAction() == "typeConv":
-            # -> feature type conversion
-            # - point <-> centroid
-            # - line <-> boundary
-            if digitClass.TypeConvForSelectedLines() < 0:
-                return
-
-        if digitToolbar.GetAction() != "addLine":
-            # unselect and re-render
-            digitClass.GetDisplay().SetSelected([])
-            self.polycoords = []
-            self.UpdateMap(render = False)
-        
     def OnMiddleDown(self, event):
         """!Middle mouse button pressed
         """
-        if event:
-            self.mouse['begin'] = event.GetPositionTuple()[:]
-    
+        if not event:
+            return
+        
+        self.mouse['begin'] = event.GetPositionTuple()[:]
+        
     def OnMiddleUp(self, event):
         """!Middle mouse button released
         """
-        # if self.parent.toolbars['vdigit']:
-        #     event.Skip()
-        #     return
-        
         self.mouse['end'] = event.GetPositionTuple()[:]
         
         # set region in zoom or pan
@@ -2394,74 +1343,16 @@
                     self.SetFocus()
         else:
             event.Skip()
-
+        
     def OnMouseMoving(self, event):
         """!Motion event and no mouse buttons were pressed
         """
-        digitToolbar = self.parent.toolbars['vdigit']
-        if self.mouse["use"] == "pointer" and digitToolbar:
-            digitClass = self.parent.digit
-            self.mouse['end'] = event.GetPositionTuple()[:]
-            Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \
-                           (self.mouse['end'][0], self.mouse['end'][1]))
-            if digitToolbar.GetAction() == "addLine" and \
-                    digitToolbar.GetAction('type') in ["line", "boundary", "area"]:
-                if len(self.polycoords) > 0:
-                    self.MouseDraw(pdc = self.pdcTmp, begin = self.Cell2Pixel(self.polycoords[-1]))
-            elif digitToolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] \
-                    and hasattr(self, "vdigitMove"):
-                dx = self.mouse['end'][0] - self.mouse['begin'][0]
-                dy = self.mouse['end'][1] - self.mouse['begin'][1]
-                
-                if len(self.vdigitMove['id']) > 0:
-                    # draw lines on new position
-                    if digitToolbar.GetAction() == "moveLine":
-                        # move line
-                        for id in self.vdigitMove['id']:
-                            self.pdcTmp.TranslateId(id, dx, dy)
-                    elif digitToolbar.GetAction() in ["moveVertex", "editLine"]:
-                        # move vertex ->
-                        # (vertex, left vertex, left line,
-                        # right vertex, right line)
-                        
-                        # do not draw static lines
-                        if digitToolbar.GetAction() == "moveVertex":
-                            self.polycoords = []
-                            ### self.pdcTmp.TranslateId(self.vdigitMove['id'][0], dx, dy)
-                            self.pdcTmp.RemoveId(self.vdigitMove['id'][0])
-                            if self.vdigitMove['id'][1] > 0: # previous vertex
-                                x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.vdigitMove['id'][1])[0:2])
-                                self.pdcTmp.RemoveId(self.vdigitMove['id'][1] + 1)
-                                self.polycoords.append((x, y))
-                            ### x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.vdigitMove['id'][0])[0:2])
-                            self.polycoords.append(self.Pixel2Cell(self.mouse['end']))
-                            if self.vdigitMove['id'][2] > 0: # next vertex
-                                x, y = self.Pixel2Cell(self.pdcTmp.GetIdBounds(self.vdigitMove['id'][2])[0:2])
-                                self.pdcTmp.RemoveId(self.vdigitMove['id'][2]-1)
-                                self.polycoords.append((x, y))
-                            
-                            self.ClearLines(pdc = self.pdcTmp)
-                            self.DrawLines(pdc = self.pdcTmp)
-
-                        else: # edit line
-                            try:
-                                if self.vdigitMove['id'][-1] > 0: # previous vertex
-                                    self.MouseDraw(pdc = self.pdcTmp,
-                                                   begin = self.Cell2Pixel(self.polycoords[-1]))
-                            except: # no line
-                                self.vdigitMove['id'] = []
-                                self.polycoords = []
-
-                self.Refresh() # TODO: use RefreshRect()
-                self.mouse['begin'] = self.mouse['end']
-
-            elif digitToolbar.GetAction() == "zbulkLine":
-                if len(self.polycoords) == 1:
-                    # draw mouse moving
-                    self.MouseDraw(self.pdcTmp)
-
+        if self.mouse["use"] == "pointer" and \
+                hasattr(self, "digit"):
+            self._onMouseMoving(event)
+        
         event.Skip()
-
+        
     def ClearLines(self, pdc = None):
         """!Clears temporary drawn lines from PseudoDC
         """
@@ -2472,23 +1363,21 @@
             pdc.RemoveId(self.lineid)
         except:
             pass
-
+        
         try:
             pdc.ClearId(self.plineid)
             pdc.RemoveId(self.plineid)
         except:
             pass
-
+        
         Debug.msg(4, "BufferedWindow.ClearLines(): lineid=%s, plineid=%s" %
                   (self.lineid, self.plineid))
-
-        ### self.Refresh()
-
+        
         return True
 
     def Pixel2Cell(self, (x, y)):
         """!Convert image coordinates to real word coordinates
-
+        
         @param x, y image coordinates
         
         @return easting, northing
@@ -2512,7 +1401,7 @@
         north = n - y * res
         
         return (east, north)
-
+    
     def Cell2Pixel(self, (east, north)):
         """!Convert real word coordinates to image coordinates
         """
@@ -2534,7 +1423,7 @@
         y = (n - north) / res
         
         return (x, y)
-
+    
     def Zoom(self, begin, end, zoomtype):
         """!
         Calculates new region while (un)zoom/pan-ing
@@ -2542,21 +1431,20 @@
         x1, y1 = begin
         x2, y2 = end
         newreg = {}
-
+        
         # threshold - too small squares do not make sense
         # can only zoom to windows of > 5x5 screen pixels
         if abs(x2-x1) > 5 and abs(y2-y1) > 5 and zoomtype != 0:
-
             if x1 > x2:
                 x1, x2 = x2, x1
             if y1 > y2:
                 y1, y2 = y2, y1
-
+            
             # zoom in
             if zoomtype > 0:
                 newreg['w'], newreg['n'] = self.Pixel2Cell((x1, y1))
                 newreg['e'], newreg['s'] = self.Pixel2Cell((x2, y2))
-
+            
             # zoom out
             elif zoomtype < 0:
                 newreg['w'], newreg['n'] = self.Pixel2Cell((-x1 * 2, -y1 * 2))
@@ -2574,7 +1462,7 @@
             newreg['w'], newreg['n'] = self.Pixel2Cell((dx, dy))
             newreg['e'], newreg['s'] = self.Pixel2Cell((self.Map.width  + dx,
                                                         self.Map.height + dy))
-
+        
         # if new region has been calculated, set the values
         if newreg != {}:
             # LL locations
@@ -2587,33 +1475,23 @@
             ce = newreg['w'] + (newreg['e'] - newreg['w']) / 2
             cn = newreg['s'] + (newreg['n'] - newreg['s']) / 2
             
-            if hasattr(self, "vdigitMove"):
-                # xo = self.Cell2Pixel((self.Map.region['center_easting'], self.Map.region['center_northing']))
-                # xn = self.Cell2Pixel(ce, cn))
-                tmp = self.Pixel2Cell(self.mouse['end'])
-            
             # calculate new center point and display resolution
             self.Map.region['center_easting'] = ce
             self.Map.region['center_northing'] = cn
             self.Map.region["ewres"] = (newreg['e'] - newreg['w']) / self.Map.width
             self.Map.region["nsres"] = (newreg['n'] - newreg['s']) / self.Map.height
             self.Map.AlignExtentFromDisplay()
-
-            if hasattr(self, "vdigitMove"):
-                tmp1 = self.mouse['end']
-                tmp2 = self.Cell2Pixel(self.vdigitMove['begin'])
-                dx = tmp1[0] - tmp2[0]
-                dy = tmp1[1] - tmp2[1]
-                self.vdigitMove['beginDiff'] = (dx, dy)
-                for id in self.vdigitMove['id']:
-                    self.pdcTmp.RemoveId(id)
             
+            if hasattr(self, "digit") and \
+                    hasattr(self, "moveInfo"):
+                self._zoom(event)
+            
             self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
                              self.Map.region['e'], self.Map.region['w'])
-
+        
         if self.redrawAll is False:
             self.redrawAll = True
-
+        
     def ZoomBack(self):
         """!Zoom to previous extents in zoomhistory list
         """
@@ -2645,8 +1523,7 @@
         self.parent.StatusbarUpdate()
 
     def ZoomHistory(self, n, s, e, w):
-        """!
-        Manages a list of last 10 zoom extents
+        """!Manages a list of last 10 zoom extents
 
         @param n,s,e,w north, south, east, west
 
@@ -2685,8 +1562,7 @@
     def ResetZoomHistory(self):
         """!Reset zoom history"""
         self.zoomhistory = list()
-        
-        
+                
     def ZoomToMap(self, layers = None, ignoreNulls = False, render = True):
         """!Set display extents to match selected raster
         or vector map(s).
@@ -2711,9 +1587,9 @@
             if l.type == 'raster':
                 rast.append(l.GetName())
             elif l.type == 'vector':
-                digitToolbar = self.parent.toolbars['vdigit']
-                if digitToolbar and digitToolbar.GetLayer() == l:
-                    w, s, b, e, n, t = self.parent.digit.GetDisplay().GetMapBoundingBox()
+                if hasattr(self, "digit") and \
+                        self.toolbar.GetLayer() == l:
+                    w, s, b, e, n, t = self.display.GetMapBoundingBox()
                     self.Map.GetRegion(n = n, s = s, w = w, e = e,
                                        update = True)
                     updated = True
@@ -2733,7 +1609,7 @@
         
         if render:
             self.UpdateMap()
-
+        
         self.parent.StatusbarUpdate()
         
     def ZoomToWind(self):
@@ -2741,13 +1617,12 @@
         settings (set with g.region)
         """
         self.Map.region = self.Map.GetRegion()
-        ### self.Map.SetRegion(windres=True)
-
+        
         self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
                          self.Map.region['e'], self.Map.region['w'])
-
+        
         self.UpdateMap()
-
+        
         self.parent.StatusbarUpdate()
 
     def ZoomToDefault(self):
@@ -2758,9 +1633,9 @@
 
         self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
                          self.Map.region['e'], self.Map.region['w'])
-
+        
         self.UpdateMap()
-
+        
         self.parent.StatusbarUpdate()
         
     def DisplayToWind(self):
@@ -2770,7 +1645,7 @@
         tmpreg = os.getenv("GRASS_REGION")
         if tmpreg:
             del os.environ["GRASS_REGION"]
-
+        
         # We ONLY want to set extents here. Don't mess with resolution. Leave that
         # for user to set explicitly with g.region
         new = self.Map.AlignResolution()
@@ -2786,7 +1661,7 @@
         
         if tmpreg:
             os.environ["GRASS_REGION"] = tmpreg
-
+        
     def ZoomToSaved(self):
         """!Set display geometry to match extents in
         saved region file
@@ -2828,7 +1703,7 @@
         if dlg.ShowModal() == wx.ID_CANCEL or not dlg.wind:
             dlg.Destroy()
             return
-
+        
         # test to see if it already exists and ask permission to overwrite
         if grass.find_file(name = dlg.wind, element = 'windows')['name']:
             overwrite = wx.MessageBox(parent = self,
@@ -2841,14 +1716,14 @@
             self.SaveRegion(dlg.wind)
         
         dlg.Destroy()
-
+        
     def SaveRegion(self, wind):
         """!Save region settings
-
+        
         @param wind region name
         """
         new = self.Map.GetCurrentRegion()
-
+        
         tmpreg = os.getenv("GRASS_REGION")
         if tmpreg:
             del os.environ["GRASS_REGION"]
@@ -2867,14 +1742,14 @@
         
         if tmpreg:
             os.environ["GRASS_REGION"] = tmpreg
-
+        
     def Distance(self, beginpt, endpt, screen=True):
         """!Calculete distance
-
+        
         LL-locations not supported
-
+        
         @todo Use m.distance
-
+        
         @param beginpt first point
         @param endpt second point
         @param screen True for screen coordinates otherwise EN

Modified: grass/trunk/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/toolbars.py	2011-02-12 09:54:41 UTC (rev 45384)
+++ grass/trunk/gui/wxpython/gui_modules/toolbars.py	2011-02-12 09:59:05 UTC (rev 45385)
@@ -633,7 +633,8 @@
         self.layerTree     = layerTree  # reference to layer tree associated to map display
         self.log           = log        # log area
         AbstractToolbar.__init__(self, parent)
-        
+        self.digit         = self.parent.MapWindow.digit
+
         # 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)
@@ -790,8 +791,8 @@
         # clear tmp canvas
         if self.action['id'] != id:
             self.parent.MapWindow.ClearLines(pdc = self.parent.MapWindow.pdcTmp)
-            if self.parent.digit and \
-                    len(self.parent.digit.GetDisplay().GetSelected()) > 0:
+            if self.parent.MapWindow.digit and \
+                    len(self.parent.MapWindow.digit.GetDisplay().GetSelected()) > 0:
                 # cancel action
                 self.parent.MapWindow.OnMiddleDown(None)
         
@@ -979,7 +980,7 @@
         
     def OnUndo(self, event):
         """!Undo previous changes"""
-        self.parent.digit.Undo()
+        self.digit.Undo()
         
         event.Skip()
 
@@ -997,11 +998,11 @@
         
     def OnSettings(self, event):
         """!Show settings dialog"""
-        if self.parent.digit is None:
+        if self.digit is None:
             try:
-                self.parent.digit = VDigit(mapwindow = self.parent.MapWindow)
+                self.digit = self.parent.MapWindow.digit = VDigit(mapwindow = self.parent.MapWindow)
             except SystemExit:
-                self.parent.digit = None
+                self.digit = self.parent.MapWindow.digit = None
         
         if not self.settingsDialog:
             self.settingsDialog = VDigitSettingsDialog(parent = self.parent, title = _("Digitization settings"),
@@ -1187,7 +1188,7 @@
 
     def OnZBulk(self, event):
         """!Z bulk-labeling selected lines/boundaries"""
-        if not self.parent.digit.IsVector3D():
+        if not self.digit.IsVector3D():
             gcmd.GError(parent = self.parent,
                         message = _("Vector map is not 3D. Operation canceled."))
             return
@@ -1297,12 +1298,12 @@
                                                 0)
         
         self.parent.MapWindow.pdcVector = wx.PseudoDC()
-        self.parent.digit = VDigit(mapwindow = self.parent.MapWindow)
+        self.digit = self.parent.MapWindow.digit = VDigit(mapwindow = self.parent.MapWindow)
         
         self.mapLayer = mapLayer
         
         # open vector map
-        if self.parent.digit.OpenMap(mapLayer.GetName()) is None:
+        if self.digit.OpenMap(mapLayer.GetName()) is None:
             self.mapLayer = None
             self.StopEditing()
             return False
@@ -1326,7 +1327,7 @@
         opacity = mapLayer.GetOpacity(float = True)
         if opacity < 1.0:
             alpha = int(opacity * 255)
-            self.parent.digit.driver.UpdateSettings(alpha)
+            self.digit.UpdateSettings(alpha)
         
         return True
 
@@ -1342,7 +1343,7 @@
         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:
+                if self.digit.GetUndoLevel() > -1:
                     dlg = wx.MessageDialog(parent = self.parent,
                                            message = _("Do you want to save changes "
                                                      "in vector map <%s>?") % self.mapLayer.GetName(),
@@ -1350,7 +1351,7 @@
                                            style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
                     if dlg.ShowModal() == wx.ID_NO:
                         # revert changes
-                        self.parent.digit.Undo(0)
+                        self.digit.Undo(0)
                     dlg.Destroy()
             
             self.parent.statusbar.SetStatusText(_("Please wait, "
@@ -1361,7 +1362,7 @@
             if lmgr:
                 lmgr.toolbar.Enable('vdigit', enable = True)
                 lmgr.notebook.SetSelection(1)
-            self.parent.digit.CloseMap()
+            self.digit.CloseMap()
             if lmgr:
                 lmgr.GetLogWindow().GetProgressBar().SetValue(0)
                 lmgr.GetLogWindow().WriteCmdLog(_("Editing of vector map <%s> successfully finished") % \
@@ -1381,8 +1382,8 @@
                 self.parent.dialogs[dialog].Close()
                 self.parent.dialogs[dialog] = None
         
-        self.parent.digit.__del__() # FIXME: destructor is not called here (del)
-        self.parent.digit = None
+        self.digit.__del__() # FIXME: destructor is not called here (del)
+        self.digit = self.parent.MapWindow.digit = None
         
         self.mapLayer = None
         

Modified: grass/trunk/gui/wxpython/gui_modules/wxvdigit.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxvdigit.py	2011-02-12 09:54:41 UTC (rev 45384)
+++ grass/trunk/gui/wxpython/gui_modules/wxvdigit.py	2011-02-12 09:59:05 UTC (rev 45385)
@@ -1075,7 +1075,7 @@
         area = Vect_get_centroid_area(self.poMapInfo, centroid)
         perimeter = -1
         if area > 0:
-            if not Vect_area_alive(self,poMapInfo, area):
+            if not Vect_area_alive(self.poMapInfo, area):
                 return -1
             
             Vect_get_area_points(self.poMapInfo, area, self.poPoints)



More information about the grass-commit mailing list