[GRASS-SVN] r45292 - in grass/branches/develbranch_6: gui/icons/grass2 gui/wxpython gui/wxpython/docs gui/wxpython/gui_modules gui/wxpython/icons include lib/vector/vedit

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Feb 3 09:53:02 EST 2011


Author: martinl
Date: 2011-02-03 06:53:02 -0800 (Thu, 03 Feb 2011)
New Revision: 45292

Added:
   grass/branches/develbranch_6/gui/icons/grass2/boundary-create.png
   grass/branches/develbranch_6/gui/icons/grass2/edit.png
   grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdigit.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdriver.py
   grass/branches/develbranch_6/lib/vector/vedit/render.c
Removed:
   grass/branches/develbranch_6/gui/wxpython/vdigit/
Modified:
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Attribute_Table_Manager.html
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.GCP_Manager.html
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Modeler.html
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Vector_Digitizer.html
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_layer_manager.jpg
   grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm_dialogs.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
   grass/branches/develbranch_6/gui/wxpython/icons/grass2_icons.py
   grass/branches/develbranch_6/gui/wxpython/icons/grass_icons.py
   grass/branches/develbranch_6/gui/wxpython/icons/icon.py
   grass/branches/develbranch_6/gui/wxpython/icons/silk_icons.py
   grass/branches/develbranch_6/gui/wxpython/wxgui.py
   grass/branches/develbranch_6/gui/wxpython/wxpythonlib.dox
   grass/branches/develbranch_6/include/vedit.h
   grass/branches/develbranch_6/lib/vector/vedit/
   grass/branches/develbranch_6/lib/vector/vedit/Makefile
   grass/branches/develbranch_6/lib/vector/vedit/break.c
   grass/branches/develbranch_6/lib/vector/vedit/cats.c
   grass/branches/develbranch_6/lib/vector/vedit/chtype.c
   grass/branches/develbranch_6/lib/vector/vedit/copy.c
   grass/branches/develbranch_6/lib/vector/vedit/delete.c
   grass/branches/develbranch_6/lib/vector/vedit/distance.c
   grass/branches/develbranch_6/lib/vector/vedit/flip.c
   grass/branches/develbranch_6/lib/vector/vedit/merge.c
   grass/branches/develbranch_6/lib/vector/vedit/move.c
   grass/branches/develbranch_6/lib/vector/vedit/select.c
   grass/branches/develbranch_6/lib/vector/vedit/snap.c
   grass/branches/develbranch_6/lib/vector/vedit/veditlib.dox
   grass/branches/develbranch_6/lib/vector/vedit/vertex.c
   grass/branches/develbranch_6/lib/vector/vedit/zbulk.c
Log:
wxGUI/vdigit: pythonized
(merge r44823, r44824, r44893, r44903, r44907, r44908, r44909, r44910, r44911, r44912, r44913, r44943, r44947, r44951, r44985, r44986, r45266, r45268, r45287, r45288, r45289 from trunk)


Copied: grass/branches/develbranch_6/gui/icons/grass2/boundary-create.png (from rev 44985, grass/trunk/gui/icons/grass2/boundary-create.png)
===================================================================
(Binary files differ)

Copied: grass/branches/develbranch_6/gui/icons/grass2/edit.png (from rev 44947, grass/trunk/gui/icons/grass2/edit.png)
===================================================================
(Binary files differ)

Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Attribute_Table_Manager.html
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Attribute_Table_Manager.html	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Attribute_Table_Manager.html	2011-02-03 14:53:02 UTC (rev 45292)
@@ -22,7 +22,7 @@
 
 <p>
 Other wxGUI components:<br>
-<em>
+<em
   <a href="wxGUI.Vector_Digitizer.html">Vector Digitizer</a><br>
   <a href="wxGUI.Nviz.html">3D Viewer</a><br>
   <a href="wxGUI.Modeler.html">Graphical Modeler</a><br>

Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.GCP_Manager.html
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.GCP_Manager.html	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.GCP_Manager.html	2011-02-03 14:53:02 UTC (rev 45292)
@@ -297,7 +297,7 @@
 
 <p>
 Other wxGUI components:<br>
-<em>
+<em
   <a href="wxGUI.Vector_Digitizer.html">Vector Digitizer</a><br>
   <a href="wxGUI.Attribute_Table_Manager.html">Attribute Table Manager</a><br>
   <a href="wxGUI.Nviz.html">3D Viewer</a><br>

Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Modeler.html
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Modeler.html	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Modeler.html	2011-02-03 14:53:02 UTC (rev 45292)
@@ -29,7 +29,7 @@
 
 <p>
 Other wxGUI components:<br>
-<em>
+<em
   <a href="wxGUI.Vector_Digitizer.html">Vector Digitizer</a><br>
   <a href="wxGUI.Attribute_Table_Manager.html">Attribute Table Manager</a><br>
   <a href="wxGUI.Nviz.html">3D Viewer</a><br>

Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html	2011-02-03 14:53:02 UTC (rev 45292)
@@ -300,7 +300,7 @@
 
 <p>
 Other wxGUI components:<br>
-<em>
+<em
   <a href="wxGUI.Vector_Digitizer.html">Vector Digitizer</a><br>
   <a href="wxGUI.Attribute_Table_Manager.html">Attribute Table Manager</a><br>
   <a href="wxGUI.Modeler.html">Graphical Modeler</a><br>

Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Vector_Digitizer.html
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Vector_Digitizer.html	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Vector_Digitizer.html	2011-02-03 14:53:02 UTC (rev 45292)
@@ -194,8 +194,8 @@
 <h2>NOTES</h2>
 
 <dl><dt><b>Mouse button Functions:</b><dd>
-	<dt><i>Left</i>    - select/deselect features</dt>
-	<dt><i>Middle</i> - cancel action</dt>
+	<dt><i>Left</i>   - select/deselect features</dt>
+	<dt><i>Control+Left</i> - cancel action/undo vertex</dt>
 	<dt><i>Right</i>  - confirm action</dt>
 </dl>
 

Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_layer_manager.jpg
===================================================================
(Binary files differ)

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -40,4 +40,6 @@
     "vdigit.py",
     "workspace.py",
     "wxnviz.py",
+    "wxvdriver.py",
+    "wxvdigit.py",
 ]

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -2568,10 +2568,10 @@
     def __createDeletePage(self):
         """!Delete layer"""
         self.deletePanel = wx.Panel(parent=self, id=wx.ID_ANY)
-        self.AddPage(page=self.deletePanel, text=_("Delete layer"))
+        self.AddPage(page=self.deletePanel, text=_("Remove layer"))
 
         label = wx.StaticText(parent=self.deletePanel, id=wx.ID_ANY,
-                              label='%s:' % _("Layer to detele"))
+                              label='%s:' % _("Layer to remove"))
 
         self.deleteLayer = wx.ComboBox(parent=self.deletePanel, id=wx.ID_ANY, size=(100, -1),
                                        style=wx.CB_SIMPLE | wx.CB_READONLY,
@@ -2592,7 +2592,7 @@
             self.deleteLayer.Enable(False)
             self.deleteTable.Enable(False)
             
-        btnDelete   = wx.Button(self.deletePanel, wx.ID_DELETE, _("&Delete layer"),
+        btnDelete   = wx.Button(self.deletePanel, wx.ID_DELETE, _("&Remove layer"),
                                 size=(125,-1))
         btnDelete.Bind(wx.EVT_BUTTON, self.OnDeleteLayer)
 

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm_dialogs.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm_dialogs.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm_dialogs.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -271,8 +271,8 @@
         """!Cancel button pressed"""
         self.parent.parent.dialogs['attributes'] = None
         if self.parent.parent.digit:
-            self.parent.parent.digit.driver.SetSelected([])
-            self.parent.UpdateMap(render=False)
+            self.parent.parent.digit.GetDisplay().SetSelected([])
+            self.parent.UpdateMap(render = False)
         else:
             self.parent.parent.OnRender(None)
 

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -15,7 +15,7 @@
 Functions:
  - RunCommand
 
-(C) 2007-2008, 2010 by the GRASS Development Team
+(C) 2007-2008, 2010-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.
@@ -58,8 +58,9 @@
 from debug import Debug as Debug
 
 class GError:
-    def __init__(self, message, parent = None):
-        caption = _('Error')
+    def __init__(self, message, parent = None, caption = None):
+        if not caption:
+            caption = _('Error')
         style = wx.OK | wx.ICON_ERROR | wx.CENTRE
         exc_type, exc_value, exc_traceback = sys.exc_info()
         if exc_traceback:

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -567,6 +567,20 @@
         self.cmd_output.SetReadOnly(True)
         self.console_progressbar.SetValue(0)
 
+    def GetProgressBar(self):
+        """!Return progress bar widget"""
+        return self.console_progressbar
+    
+    def GetLog(self, err = False):
+        """!Get widget used for logging
+
+        @param err True to get stderr widget
+        """
+        if err:
+            return self.cmd_stderr
+        
+        return self.cmd_stdout
+    
     def SaveHistory(self, event):
         """!Save history of commands"""
         self.history = self.cmd_output.GetSelectedText()

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -8,7 +8,7 @@
  - Layer
  - LayerTree
 
-(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
 for details.
@@ -64,7 +64,7 @@
     """!Creates layer tree structure
     """
     def __init__(self, parent,
-                 id = wx.ID_ANY, style=wx.SUNKEN_BORDER,
+                 id = wx.ID_ANY, style = wx.SUNKEN_BORDER,
                  ctstyle = CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
                  CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT |
                  CT.TR_MULTIPLE, **kwargs):
@@ -105,18 +105,17 @@
         # self.SetAutoLayout(True)
         self.SetGradientStyle(1)
         self.EnableSelectionGradient(True)
-        self.SetFirstGradientColour(wx.Colour(100, 100, 100))
-        self.SetSecondGradientColour(wx.Colour(150, 150, 150))
+        self._setGradient()
         
         # init associated map display
         pos = wx.Point((self.disp_idx + 1) * 25, (self.disp_idx + 1) * 25)
         self.mapdisplay = mapdisp.MapFrame(self,
-                                           id=wx.ID_ANY, pos=pos,
-                                           size=globalvar.MAP_WINDOW_SIZE,
-                                           style=wx.DEFAULT_FRAME_STYLE,
-                                           tree=self, notebook=self.notebook,
-                                           lmgr=self.lmgr, page=self.treepg,
-                                           Map=self.Map, auimgr=self.auimgr)
+                                           id = wx.ID_ANY, pos = pos,
+                                           size = globalvar.MAP_WINDOW_SIZE,
+                                           style = wx.DEFAULT_FRAME_STYLE,
+                                           tree = self, notebook = self.notebook,
+                                           lmgr = self.lmgr, page = self.treepg,
+                                           Map = self.Map, auimgr = self.auimgr)
         
         # title
         self.mapdisplay.SetTitle(_("GRASS GIS Map Display: %(id)d  - Location: %(loc)s") % \
@@ -133,7 +132,7 @@
         self.SetPyData(self.root, (None, None))
         
         #create image list to use with layer tree
-        il = wx.ImageList(16, 16, mask=False)
+        il = wx.ImageList(16, 16, mask = False)
         
         trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, (16, 16))
         self.folder_open = il.Add(trart)
@@ -199,6 +198,21 @@
         self.Bind(wx.EVT_TREE_END_LABEL_EDIT,   self.OnRenamed)
         self.Bind(wx.EVT_KEY_UP,                self.OnKeyUp)
         self.Bind(wx.EVT_IDLE,                  self.OnIdle)
+
+    def _setGradient(self, iType = None):
+        """!Set gradient for items
+
+        @param iType bgmap, vdigit or None
+        """
+        if iType == 'bgmap':
+            self.SetFirstGradientColour(wx.Colour(0, 100, 0))
+            self.SetSecondGradientColour(wx.Colour(0, 150, 0))
+        elif iType == 'vdigit':
+            self.SetFirstGradientColour(wx.Colour(100, 0, 0))
+            self.SetSecondGradientColour(wx.Colour(150, 0, 0))
+        else:
+            self.SetFirstGradientColour(wx.Colour(100, 100, 100))
+            self.SetSecondGradientColour(wx.Colour(150, 150, 150))
         
     def GetMap(self):
         """!Get map instace"""
@@ -215,7 +229,7 @@
         """
         if self.rerender:
             if self.mapdisplay.statusbarWin['render'].GetValue():
-                self.mapdisplay.MapWindow.UpdateMap(render=True)
+                self.mapdisplay.MapWindow.UpdateMap(render = True)
 
         event.Skip()
         
@@ -290,9 +304,7 @@
         except:
             mltype = None
         
-        #
         # vector layers (specific items)
-        #
         if mltype and mltype == "vector":
             self.popupMenu.AppendSeparator()
             self.popupMenu.Append(self.popupID['export'], text = _("Export"))
@@ -303,7 +315,7 @@
             self.popupMenu.AppendSeparator()
             self.popupMenu.Append(self.popupID['attr'], text = _("Show attribute data"))
             self.Bind(wx.EVT_MENU, self.lmgr.OnShowAttributeTable, id = self.popupID['attr'])
-            
+
             self.popupMenu.Append(self.popupID['edit0'], text = _("Start editing"))
             self.popupMenu.Append(self.popupID['edit1'], text = _("Stop editing"))
             self.popupMenu.Enable(self.popupID['edit1'], False)
@@ -356,9 +368,7 @@
                 self.popupMenu.Enable(self.popupID['topo'],   False)
                 self.popupMenu.Enable(self.popupID['export'], False)
         
-        #
         # raster layers (specific items)
-        #
         elif mltype and mltype == "raster":
             self.popupMenu.Append(self.popupID['zoom1'], text = _("Zoom to selected map(s) (ignore NULLs)"))
             self.Bind(wx.EVT_MENU, self.mapdisplay.OnZoomToRaster, id = self.popupID['zoom1'])
@@ -390,7 +400,7 @@
                 self.popupMenu.Enable(self.popupID['meta'],    False)
                 self.popupMenu.Enable(self.popupID['nviz'],    False)
                 self.popupMenu.Enable(self.popupID['export'],  False)
-        
+
         self.PopupMenu(self.popupMenu)
         self.popupMenu.Destroy()
         
@@ -415,7 +425,7 @@
         cmd.append('map=%s' % mapLayer.GetName())
 
         # print output to command log area
-        self.lmgr.goutput.RunCmd(cmd, switchPage=True)
+        self.lmgr.goutput.RunCmd(cmd, switchPage = True)
 
     def OnSetCompRegFromRaster(self, event):
         """!Set computational region from selected raster map (ignore NULLs)"""
@@ -465,10 +475,10 @@
         """!Plot profile of given raster map layer"""
         mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
         if not mapLayer.GetName():
-            wx.MessageBox(parent=self,
-                          message=_("Unable to create profile of "
+            wx.MessageBox(parent = self,
+                          message = _("Unable to create profile of "
                                     "raster map."),
-                          caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+                          caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
             return False
 
         if not hasattr (self, "profileFrame"):
@@ -479,8 +489,8 @@
 
         if not self.profileFrame:
             self.profileFrame = profile.ProfileFrame(self.mapdisplay,
-                                                     id=wx.ID_ANY, pos=wx.DefaultPosition, size=(700,300),
-                                                     style=wx.DEFAULT_FRAME_STYLE, rasterList=[mapLayer.GetName()])
+                                                     id = wx.ID_ANY, pos = wx.DefaultPosition, size = (700,300),
+                                                     style = wx.DEFAULT_FRAME_STYLE, rasterList = [mapLayer.GetName()])
             # show new display
             self.profileFrame.Show()
         
@@ -497,10 +507,10 @@
         """
         mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
         if not mapLayer.GetName():
-            wx.MessageBox(parent=self,
-                          message=_("Unable to display histogram of "
+            wx.MessageBox(parent = self,
+                          message = _("Unable to display histogram of "
                                     "raster map."),
-                          caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
+                          caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
             return False
 
         if not hasattr (self, "histogramFrame"):
@@ -511,9 +521,9 @@
 
         if not self.histogramFrame:
             self.histogramFrame = histogram.HistFrame(self,
-                                                      id=wx.ID_ANY,
-                                                      pos=wx.DefaultPosition, size=globalvar.HIST_WINDOW_SIZE,
-                                                      style=wx.DEFAULT_FRAME_STYLE)
+                                                      id = wx.ID_ANY,
+                                                      pos = wx.DefaultPosition, size = globalvar.HIST_WINDOW_SIZE,
+                                                      style = wx.DEFAULT_FRAME_STYLE)
             # show new display
             self.histogramFrame.Show()
 
@@ -533,20 +543,8 @@
             event.Skip()
             return
         
-        if not self.mapdisplay.toolbars['vdigit']: # enable tool
-            self.mapdisplay.AddToolbar('vdigit')
-        else: # tool already enabled
-            pass
-        
-        # mark layer as 'edited'
-                
-        if not self.mapdisplay.toolbars['vdigit'].StartEditing(maplayer) or \
-                not haveVDigit:
-            if not haveVDigit:
-                from vdigit import errorMsg
-            else:
-                errorMsg = _("Unable to initialize display driver of vector "
-                             "digitizer")
+        if not haveVDigit:
+            from vdigit import errorMsg
             msg = _("Unable to start wxGUI vector digitizer.\nDo you want to start "
                     "TCL/TK digitizer (v.digit) instead?\n\n"
                     "Details: %s" % errorMsg)
@@ -558,29 +556,50 @@
                                    style = wx.YES_NO | wx.CENTRE)
             if dlg.ShowModal() == wx.ID_YES:
                 self.lmgr.goutput.RunCmd(['v.digit', 'map=%s' % maplayer.GetName()],
-                                         switchPage=False)
+                                         switchPage = False)
             
             dlg.Destroy()
+            return
         
+        if not self.mapdisplay.toolbars['vdigit']: # enable tool
+            self.mapdisplay.AddToolbar('vdigit')
+        else: # tool already enabled
+            pass
+        
+        # mark layer as 'edited'
+        self.mapdisplay.toolbars['vdigit'].StartEditing(maplayer)
+        
+        self._setGradient('vdigit')
+        self.RefreshLine(self.layer_selected)
+        
     def OnStopEditing(self, event):
+        """!Stop editing the current vector map layer
         """
-        Stop editing the current vector map layer
-        """
         maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
         
         self.mapdisplay.toolbars['vdigit'].OnExit()
-        self.mapdisplay.imgVectorMap = None
+        if self.lmgr:
+            self.lmgr.toolbar.Enable('vdigit', enable = True)
         
+        self._setGradient()
+        self.RefreshLine(self.layer_selected)
+        
     def OnSetBgMap(self, event):
         """!Set background vector map for editing sesstion"""
         if event.IsChecked():
             mapName = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
-            UserSettings.Set(group='vdigit', key='bgmap', subkey='value',
-                             value=str(mapName), internal=True)
+            UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
+                             value = str(mapName), internal = True)
+            self.mapdisplay.digit.OpenBackgroundMap(mapName)
+            self._setGradient('bgmap')
         else:
-            UserSettings.Set(group='vdigit', key='bgmap', subkey='value',
-                             value='', internal=True)
+            UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
+                             value = '', internal = True)
+            self.mapdisplay.digit.CloseBackgroundMap()
+            self._setGradient()
         
+        self.RefreshLine(self.layer_selected)
+
     def OnPopupProperties (self, event):
         """!Popup properties dialog"""
         self.PropertiesDialog(self.layer_selected)
@@ -593,8 +612,8 @@
         maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
         current_opacity = maplayer.GetOpacity()
         
-        dlg = gdialogs.SetOpacityDialog(self, opacity=current_opacity,
-                                        title=_("Set opacity <%s>") % maplayer.GetName())
+        dlg = gdialogs.SetOpacityDialog(self, opacity = current_opacity,
+                                        title = _("Set opacity <%s>") % maplayer.GetName())
         dlg.CentreOnParent()
 
         if dlg.ShowModal() == wx.ID_OK:
@@ -641,8 +660,8 @@
         
         event.Skip()
 
-    def AddLayer(self, ltype, lname=None, lchecked=None,
-                 lopacity=1.0, lcmd=None, lgroup=None, lvdigit=None, lnviz=None, multiple = True):
+    def AddLayer(self, ltype, lname = None, lchecked = None,
+                 lopacity = 1.0, lcmd = None, lgroup = None, lvdigit = None, lnviz = None, multiple = True):
         """!Add new item to the layer tree, create corresponding MapLayer instance.
         Launch property dialog if needed (raster, vector, etc.)
 
@@ -671,16 +690,16 @@
 
         # deselect active item
         if self.layer_selected:
-            self.SelectItem(self.layer_selected, select=False)
+            self.SelectItem(self.layer_selected, select = False)
         
         Debug.msg (3, "LayerTree().AddLayer(): ltype=%s" % (ltype))
         
         if ltype == 'command':
             # generic command item
-            ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
-                               pos=wx.DefaultPosition, size=(self.GetSize()[0]-100,25),
-                               # style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
-                               style=wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
+            ctrl = wx.TextCtrl(self, id = wx.ID_ANY, value = '',
+                               pos = wx.DefaultPosition, size = (self.GetSize()[0]-100,25),
+                               # style = wx.TE_MULTILINE|wx.TE_WORDWRAP)
+                               style = wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
             ctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
             # ctrl.Bind(wx.EVT_TEXT,       self.OnCmdChanged)
         elif ltype == 'group':
@@ -690,7 +709,7 @@
             self.groupnode += 1
         else:
             btnbmp = Icons["layeropts"].GetBitmap((16,16))
-            ctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp, size=(24,24))
+            ctrl = buttons.GenBitmapButton(self, id = wx.ID_ANY, bitmap = btnbmp, size = (24,24))
             ctrl.SetToolTipString(_("Click to edit layer settings"))
             self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, ctrl)
         # add layer to the layer tree
@@ -698,29 +717,29 @@
             if self.GetPyData(self.layer_selected)[0]['type'] == 'group' \
                 and self.IsExpanded(self.layer_selected):
                 # add to group (first child of self.layer_selected) if group expanded
-                layer = self.PrependItem(parent=self.layer_selected,
-                                         text='', ct_type=1, wnd=ctrl)
+                layer = self.PrependItem(parent = self.layer_selected,
+                                         text = '', ct_type = 1, wnd = ctrl)
             else:
                 # prepend to individual layer or non-expanded group
                 if lgroup == -1:
                     # -> last child of root (loading from workspace)
-                    layer = self.AppendItem(parentId=self.root,
-                                            text='', ct_type=1, wnd=ctrl)
+                    layer = self.AppendItem(parentId = self.root,
+                                            text = '', ct_type = 1, wnd = ctrl)
                 elif lgroup > -1:
                     # -> last child of group (loading from workspace)
                     parent = self.FindItemByIndex(index = lgroup)
                     if not parent:
                         parent = self.root
-                    layer = self.AppendItem(parentId=parent,
-                                            text='', ct_type=1, wnd=ctrl)
+                    layer = self.AppendItem(parentId = parent,
+                                            text = '', ct_type = 1, wnd = ctrl)
                 elif lgroup is None:
                     # -> previous sibling of selected layer
                     parent = self.GetItemParent(self.layer_selected)
-                    layer = self.InsertItem(parentId=parent,
-                                            input=self.GetPrevSibling(self.layer_selected),
-                                            text='', ct_type=1, wnd=ctrl)
+                    layer = self.InsertItem(parentId = parent,
+                                            input = self.GetPrevSibling(self.layer_selected),
+                                            text = '', ct_type = 1, wnd = ctrl)
         else: # add first layer to the layer tree (first child of root)
-            layer = self.PrependItem(parent=self.root, text='', ct_type=1, wnd=ctrl)
+            layer = self.PrependItem(parent = self.root, text = '', ct_type = 1, wnd = ctrl)
 
         # layer is initially unchecked as inactive (beside 'command')
         # use predefined value if given
@@ -729,10 +748,10 @@
         else:
             checked = True
 
-        self.CheckItem(layer, checked=checked)
+        self.CheckItem(layer, checked = checked)
 
         # select new item
-        self.SelectItem(layer, select=True)
+        self.SelectItem(layer, select = True)
         self.layer_selected = layer
         
         # add text and icons for each layer ltype
@@ -831,15 +850,15 @@
                 else: 
                     pos = -1
             
-            maplayer = self.Map.AddLayer(pos=pos,
-                                         type=ltype, command=self.GetPyData(layer)[0]['cmd'], name=name,
-                                         l_active=checked, l_hidden=False,
-                                         l_opacity=lopacity, l_render=render)
+            maplayer = self.Map.AddLayer(pos = pos,
+                                         type = ltype, command = self.GetPyData(layer)[0]['cmd'], name = name,
+                                         l_active = checked, l_hidden = False,
+                                         l_opacity = lopacity, l_render = render)
             self.GetPyData(layer)[0]['maplayer'] = maplayer
 
             # run properties dialog if no properties given
             if len(cmd) == 0:
-                self.PropertiesDialog(layer, show=True)
+                self.PropertiesDialog(layer, show = True)
         
         else: # group
             self.SetPyData(layer, ({'cmd'      : None,
@@ -861,11 +880,11 @@
         
         # updated progress bar range (mapwindow statusbar)
         if checked is True:
-            self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+            self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active = True)))
             
         return layer
 
-    def PropertiesDialog (self, layer, show=True):
+    def PropertiesDialog (self, layer, show = True):
         """!Launch the properties dialog"""
         if self.GetPyData(layer)[0].has_key('propwin') and \
                 self.GetPyData(layer)[0]['propwin'] is not None:
@@ -890,8 +909,8 @@
         if self.GetPyData(layer)[0]['cmd']:
             module = menuform.GUI()
             module.ParseCommand(self.GetPyData(layer)[0]['cmd'],
-                                completed=(self.GetOptData,layer,params),
-                                parentframe=self, show=show)
+                                completed = (self.GetOptData,layer,params),
+                                parentframe = self, show = show, centreOnParent = False)
             
             self.GetPyData(layer)[0]['cmd'] = module.GetCmd()
         elif ltype == 'raster':
@@ -899,59 +918,59 @@
             
             if UserSettings.Get(group='cmd', key='rasterOverlay', subkey='enabled'):
                 cmd.append('-o')
-            menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            
+            menuform.GUI().ParseCommand(cmd, completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == '3d-raster':
             cmd = ['d.rast3d']
-            menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(cmd, completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'rgb':
-            menuform.GUI().ParseCommand(['d.rgb'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.rgb'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'his':
-            menuform.GUI().ParseCommand(['d.his'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.his'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'shaded':
-            menuform.GUI().ParseCommand(['d.shadedmap'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.shadedmap'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'rastarrow':
-            menuform.GUI().ParseCommand(['d.rast.arrow'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.rast.arrow'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'rastnum':
-            menuform.GUI().ParseCommand(['d.rast.num'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.rast.num'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'vector':
-            types = ''
-            for type in UserSettings.Get(group='cmd', key='showType').keys():
-                if UserSettings.Get(group='cmd', key='showType', subkey=[type, 'enabled']):
-                    types += type + ','
-            types = types.rstrip(',')
+            types = list()
+            for ftype in ['point', 'line', 'boundary', 'centroid', 'area', 'face']:
+                if UserSettings.Get(group = 'cmd', key = 'showType', subkey = [ftype, 'enabled']):
+                    types.append(ftype)
             
-            menuform.GUI().ParseCommand(['d.vect', 'type=%s' % types],
-                                         completed=(self.GetOptData,layer,params),
-                                         parentframe=self)
+            menuform.GUI().ParseCommand(['d.vect', 'type=%s' % ','.join(types)],
+                                         completed = (self.GetOptData,layer,params),
+                                         parentframe = self, centreOnParent = False)
         elif ltype == 'thememap':
             # -s flag requested, otherwise only first thematic category is displayed
             # should be fixed by C-based d.thematic.* modules
             menuform.GUI().ParseCommand(['d.vect.thematic', '-s'], 
-                                        completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+                                        completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'themechart':
             menuform.GUI().ParseCommand(['d.vect.chart'],
-                                        completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+                                        completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'grid':
-            menuform.GUI().ParseCommand(['d.grid'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.grid'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'geodesic':
-            menuform.GUI().ParseCommand(['d.geodesic'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.geodesic'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'rhumb':
-            menuform.GUI().ParseCommand(['d.rhumbline'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.rhumbline'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'labels':
-            menuform.GUI().ParseCommand(['d.labels'], completed=(self.GetOptData,layer,params),
-                                        parentframe=self)
+            menuform.GUI().ParseCommand(['d.labels'], completed = (self.GetOptData,layer,params),
+                                        parentframe = self, centreOnParent = False)
         elif ltype == 'cmdlayer':
             pass
         elif ltype == 'group':
@@ -1004,10 +1023,10 @@
         self.reorder = True
         
         if self.mapdisplay.toolbars['vdigit']:
-            self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers (updateTool=True)
+            self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers (updateTool = True)
 
         # update progress bar range (mapwindow statusbar)
-        self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+        self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active = True)))
 
         event.Skip()
 
@@ -1041,7 +1060,7 @@
         #
         # update progress bar range (mapwindow statusbar)
         #
-        self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+        self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active = True)))
 
         #
         # nviz
@@ -1103,6 +1122,22 @@
             event.Veto()
             return
         
+        digitToolbar = self.mapdisplay.toolbars['vdigit']
+        if digitToolbar:
+            mapLayer = self.GetPyData(layer)[0]['maplayer']
+            bgmap = UserSettings.Get(group = 'vdigit', key = 'bgmap', subkey = 'value',
+                                     internal = True)
+            
+        if digitToolbar:
+            if digitToolbar.GetLayer() == mapLayer:
+                self._setGradient('vdigit')
+            elif bgmap == mapLayer.GetName():
+                self._setGradient('bgmap')
+            else:
+                self._setGradient()
+        else:
+            self._setGradient()
+        
         self.layer_selected = layer
         
         try:
@@ -1117,21 +1152,19 @@
                 self.SetItemWindowEnabled(layer, False)
         except:
             pass
-
+        
         try:
             self.RefreshLine(oldlayer)
             self.RefreshLine(layer)
         except:
             pass
-
-        #
+        
         # update statusbar -> show command string
-        #
         if self.GetPyData(layer) and self.GetPyData(layer)[0]['maplayer']:
-            cmd = self.GetPyData(layer)[0]['maplayer'].GetCmd(string=True)
+            cmd = self.GetPyData(layer)[0]['maplayer'].GetCmd(string = True)
             if len(cmd) > 0:
                 self.lmgr.SetStatusText(cmd)
-
+        
         # set region if auto-zooming is enabled
         if self.GetPyData(layer) and self.GetPyData(layer)[0]['cmd'] and \
                UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
@@ -1141,9 +1174,7 @@
                 self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
                                                     render = render)
         
-        #
         # update nviz tools
-        #
         if self.mapdisplay.toolbars['nviz'] and \
                 self.GetPyData(self.layer_selected) is not None:
             if self.layer_selected.IsChecked():
@@ -1203,21 +1234,16 @@
             (child, cookie) = self.GetFirstChild(dragItem)
             if child:
                 while child:
-                    self.RecreateItem(child, dropTarget, parent=newItem)
+                    self.RecreateItem(child, dropTarget, parent = newItem)
                     self.Delete(child)
                     child = self.GetNextChild(old, cookie)[0]
-            #self.Expand(newItem)
-
+        
         # delete layer at original position
         try:
             self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
         except AttributeError:
-            # FIXME being ugly (item.SetWindow(None))
             pass
 
-        # reorder layers in render.Map to match new order after drag and drop
-        #self.ReorderLayers()
-
         # redraw map if auto-rendering is enabled
         self.rerender = True
         self.reorder = True
@@ -1225,7 +1251,7 @@
         # select new item
         self.SelectItem(newItem)
         
-    def RecreateItem (self, dragItem, dropTarget, parent=None):
+    def RecreateItem (self, dragItem, dropTarget, parent = None):
         """!Recreate item (needed for OnEndDrag())
         """
         Debug.msg (4, "LayerTree.RecreateItem(): layer=%s" % \
@@ -1238,7 +1264,7 @@
         if self.GetPyData(dragItem)[0]['ctrl']:
             # recreate data layer
             btnbmp = Icons["layeropts"].GetBitmap((16,16))
-            newctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp, size=(24, 24))
+            newctrl = buttons.GenBitmapButton(self, id = wx.ID_ANY, bitmap = btnbmp, size = (24, 24))
             newctrl.SetToolTipString(_("Click to edit layer settings"))
             self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, newctrl)
             data    = self.GetPyData(dragItem)
@@ -1246,11 +1272,11 @@
         elif self.GetPyData(dragItem)[0]['type'] == 'command':
             # recreate command layer
             oldctrl = None
-            newctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
-                                  pos=wx.DefaultPosition, size=(250,25),
-                                  style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
+            newctrl = wx.TextCtrl(self, id = wx.ID_ANY, value = '',
+                                  pos = wx.DefaultPosition, size = (250,25),
+                                  style = wx.TE_MULTILINE|wx.TE_WORDWRAP)
             try:
-                newctrl.SetValue(self.GetPyData(dragItem)[0]['maplayer'].GetCmd(string=True))
+                newctrl.SetValue(self.GetPyData(dragItem)[0]['maplayer'].GetCmd(string = True))
             except:
                 pass
             newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
@@ -1273,27 +1299,27 @@
 
             # dragItem dropped on group
             if  self.GetPyData(afteritem)[0]['type'] == 'group':
-                newItem = self.PrependItem(afteritem, text=text, \
-                                      ct_type=1, wnd=newctrl, image=image, \
-                                      data=data)
+                newItem = self.PrependItem(afteritem, text = text, \
+                                      ct_type = 1, wnd = newctrl, image = image, \
+                                      data = data)
                 self.Expand(afteritem)
             else:
                 #dragItem dropped on single layer
                 newparent = self.GetItemParent(afteritem)
                 newItem = self.InsertItem(newparent, self.GetPrevSibling(afteritem), \
-                                       text=text, ct_type=1, wnd=newctrl, \
-                                       image=image, data=data)
+                                       text = text, ct_type = 1, wnd = newctrl, \
+                                       image = image, data = data)
         else:
             # if dragItem not dropped on a layer or group, append or prepend it to the layer tree
             if self.flag & wx.TREE_HITTEST_ABOVE:
-                newItem = self.PrependItem(self.root, text=text, \
-                                      ct_type=1, wnd=newctrl, image=image, \
-                                      data=data)
+                newItem = self.PrependItem(self.root, text = text, \
+                                      ct_type = 1, wnd = newctrl, image = image, \
+                                      data = data)
             elif (self.flag &  wx.TREE_HITTEST_BELOW) or (self.flag & wx.TREE_HITTEST_NOWHERE) \
                      or (self.flag & wx.TREE_HITTEST_TOLEFT) or (self.flag & wx.TREE_HITTEST_TORIGHT):
-                newItem = self.AppendItem(self.root, text=text, \
-                                      ct_type=1, wnd=newctrl, image=image, \
-                                      data=data)
+                newItem = self.AppendItem(self.root, text = text, \
+                                      ct_type = 1, wnd = newctrl, image = image, \
+                                      data = data)
 
         #update new layer 
         self.SetPyData(newItem, self.GetPyData(dragItem))
@@ -1302,10 +1328,8 @@
         else:
             self.GetPyData(newItem)[0]['ctrl'] = None
             
-        self.CheckItem(newItem, checked=checked) # causes a new render
-
-        # newItem.SetHeight(TREE_ITEM_HEIGHT)
-
+        self.CheckItem(newItem, checked = checked) # causes a new render
+        
         return newItem
 
     def _getLayerName(self, item):
@@ -1380,8 +1404,8 @@
                     mapWin.LoadVector(layer)
 
                 # reset view when first layer loaded
-                nlayers = len(mapWin.Map.GetListOfLayers(l_type=('raster', 'vector'),
-                                                         l_active=True))
+                nlayers = len(mapWin.Map.GetListOfLayers(l_type = ('raster', 'vector'),
+                                                         l_active = True))
                 if nlayers < 2:
                     mapWin.ResetView()
         
@@ -1436,7 +1460,7 @@
         elif type != 'group':
             if self.GetPyData(item)[0] is not None:
                 cmdlist = self.GetPyData(item)[0]['cmd']
-                opac = self.GetPyData(item)[0]['maplayer'].GetOpacity(float=True)
+                opac = self.GetPyData(item)[0]['maplayer'].GetOpacity(float = True)
                 chk = self.IsItemChecked(item)
                 hidden = not self.IsVisible(item)
                 # determine layer name
@@ -1444,15 +1468,15 @@
                 if not found:
                     layerName = self.GetItemText(item)
         
-        maplayer = self.Map.ChangeLayer(layer=self.GetPyData(item)[0]['maplayer'], type=type,
-                                        command=cmdlist, name=layerName,
-                                        l_active=chk, l_hidden=hidden, l_opacity=opac, l_render=False)
+        maplayer = self.Map.ChangeLayer(layer = self.GetPyData(item)[0]['maplayer'], type = type,
+                                        command = cmdlist, name = layerName,
+                                        l_active = chk, l_hidden = hidden, l_opacity = opac, l_render = False)
         
         self.GetPyData(item)[0]['maplayer'] = maplayer
         
         # if digitization tool enabled -> update list of available vector map layers
         if self.mapdisplay.toolbars['vdigit']:
-            self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers(updateTool=True)
+            self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers(updateTool = True)
         
         # redraw map if auto-rendering is enabled
         self.rerender = True
@@ -1488,7 +1512,7 @@
         
         return None
     
-    def EnableItemType(self, type, enable=True):
+    def EnableItemType(self, type, enable = True):
         """!Enable/disable items in layer tree"""
         item = self.GetFirstChild(self.root)[0]
         while item and item.IsOk():

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -14,7 +14,7 @@
 Usage:
 python mapdisp.py monitor-identifier /path/to/command/file
 
-(C) 2006-2010 by the GRASS Development Team
+(C) 2006-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.
@@ -330,8 +330,8 @@
                         "TCL/TK digitizer (v.digit) instead?\n\n"
                         "Details: %s" % errorMsg)
                 
-                self.mapdisplay.toolbars['map'].combo.SetValue (_("2D view"))
-                dlg = wx.MessageDialog(parent = self.mapdisplay,
+                self.toolbars['map'].combo.SetValue(_("2D view"))
+                dlg = wx.MessageDialog(parent = self,
                                        message = msg,
                                        caption=_("Vector digitizer failed"),
                                        style = wx.YES_NO | wx.CENTRE)
@@ -542,7 +542,7 @@
         
         # deselect features in vdigit
         if self.toolbars['vdigit'] and self.digit:
-            self.digit.driver.SetSelected([])
+            self.digit.GetDisplay().SetSelected([])
             self.MapWindow.UpdateMap(render = True, renderVector = True)
         else:
             self.MapWindow.UpdateMap(render = True)
@@ -1168,8 +1168,7 @@
             maplayer = self.toolbars['vdigit'].GetLayer()
             if maplayer:
                 self.toolbars['vdigit'].OnExit()
-                self.imgVectorMap = None
-
+        
         if self.toolbars['nviz']:
             self.toolbars['nviz'].OnExit()
         

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,13 +1,13 @@
 """!
 @package mapdisp_window.py
 
- at brief GIS map display canvas, buffered window.
+ at brief Map display canvas - buffered window.
 
 Classes:
  - MapWindow
  - BufferedWindow
 
-(C) 2006-2010 by the GRASS Development Team
+(C) 2006-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.
@@ -42,7 +42,6 @@
 from vdigit import VDigitCategoryDialog
 from vdigit import VDigitZBulkDialog
 from vdigit import VDigitDuplicatesDialog
-from vdigit import PseudoDC as VDigitPseudoDC
 
 class MapWindow(object):
     """!Abstract map window class
@@ -267,8 +266,6 @@
         # render output objects
         self.mapfile = None   # image file to be rendered
         self.img     = None   # wx.Image object (self.mapfile)
-        # used in digitization tool (do not redraw vector map)
-        self.imgVectorMap = None
         # decoration overlays
         self.overlays = {}
         # images and their PseudoDC ID's for painting and dragging
@@ -303,45 +300,18 @@
         self.dragid   = -1
         self.lastpos  = (0, 0)
 
-    def DefinePseudoDC(self, vdigit = False):
-        """!Define PseudoDC class to use
-
-        @vdigit True to use PseudoDC from vdigit
+    def DefinePseudoDC(self):
+        """!Define PseudoDC objects to use
         """
         # create PseudoDC used for background map, map decorations like scales and legends
-        self.pdc = self.PseudoDC(vdigit)
+        self.pdc = wx.PseudoDC()
         # used for digitization tool
         self.pdcVector = None
         # decorations (region box, etc.)
-        self.pdcDec = self.PseudoDC(vdigit)
+        self.pdcDec = wx.PseudoDC()
         # pseudoDC for temporal objects (select box, measurement tool, etc.)
-        self.pdcTmp = self.PseudoDC(vdigit)
-        
-    def PseudoDC(self, vdigit = False):
-        """!Create PseudoDC instance"""
-        if vdigit:
-            PseudoDC = VDigitPseudoDC
-        else:
-            PseudoDC = wx.PseudoDC
-        
-        return PseudoDC()
+        self.pdcTmp = wx.PseudoDC()
     
-    def CheckPseudoDC(self):
-        """!Try to draw background
-        
-        @return True on success
-        @return False on failure
-        """
-        try:
-            self.pdc.BeginDrawing()
-            self.pdc.SetBackground(wx.Brush(self.GetBackgroundColour()))
-            self.pdc.BeginDrawing()
-        except StandardError, e:
-            traceback.print_exc(file = sys.stderr)
-            return False
-        
-        return True
-    
     def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0, 0, 0, 0]):
         """!Draws map and overlay decorations
         """
@@ -531,8 +501,7 @@
                 tool(event)
         
     def OnPaint(self, event):
-        """!
-        Draw PseudoDC's to buffered paint DC
+        """!Draw PseudoDC's to buffered paint DC
 
         self.pdc for background and decorations
         self.pdcVector for vector map which is edited
@@ -593,9 +562,8 @@
                 # self.bufferLast = wx.BitmapFromImage(self.buffer.ConvertToImage())
                 self.bufferLast = dc.GetAsBitmap(wx.Rect(0, 0, self.Map.width, self.Map.height))
             
-            pdcLast = self.PseudoDC(vdigit = False)
-            pdcLast.DrawBitmap(self.bufferLast, 0, 0, False)
-            pdcLast.DrawToDC(dc)
+            self.pdc.DrawBitmap(self.bufferLast, 0, 0, False)
+            self.pdc.DrawToDC(dc)
         
         # draw decorations (e.g. region box)
         try:
@@ -743,7 +711,7 @@
         #
         # initialize process bar (only on 'render')
         #
-        if render is True or renderVector is True:
+        if render or renderVector:
             self.parent.statusbarWin['progress'].Show()
             if self.parent.statusbarWin['progress'].GetRange() > 0:
                 self.parent.statusbarWin['progress'].SetValue(1)
@@ -751,9 +719,8 @@
         #
         # render background image if needed
         #
-        
         # update layer dictionary if there has been a change in layers
-        if self.tree and self.tree.reorder == True:
+        if self.tree and self.tree.reorder:
             self.tree.ReorderLayers()
         
         # reset flag for auto-rendering
@@ -778,7 +745,7 @@
             self.mapfile = None
         
         self.img = self.GetImage() # id=99
-            
+        
         #
         # clear pseudoDcs
         #
@@ -798,7 +765,7 @@
                 id = self.imagedict[self.img]['id']
             except:
                 return False
-
+            
             self.Draw(self.pdc, self.img, drawid = id)
         
         #
@@ -808,21 +775,23 @@
         if renderVector and digitToolbar and \
                 digitToolbar.GetLayer():
             # set region
-            self.parent.digit.driver.UpdateRegion()
+            self.parent.digit.GetDisplay().UpdateRegion()
             # re-calculate threshold for digitization tool
-            self.parent.digit.driver.GetThreshold()
+            # self.parent.digit.GetDisplay().GetThreshold()
             # draw map
             if self.pdcVector:
-                self.pdcVector.Clear()
+                # self.pdcVector.Clear()
                 self.pdcVector.RemoveAll()
+            
             try:
                 item = self.tree.FindItemByData('maplayer', digitToolbar.GetLayer())
             except TypeError:
                 item = None
             
             if item and self.tree.IsItemChecked(item):
-                self.parent.digit.driver.DrawMap()
-
+                self.redrawAll = True
+                self.parent.digit.GetDisplay().DrawMap()
+            
             # translate tmp objects (pointer position)
             if digitToolbar.GetAction() == 'moveLine':
                 if  hasattr(self, "vdigitMove") and \
@@ -843,7 +812,7 @@
                 id = self.imagedict[img]['id']
                 self.Draw(self.pdc, img = img, drawid = id,
                           pdctype = self.overlays[id]['pdcType'], coords = self.overlays[id]['coords'])
-
+        
         for id in self.textdict.keys():
             self.Draw(self.pdc, img = self.textdict[id], drawid = id,
                       pdctype = 'text', coords = [10, 10, 10, 10])
@@ -906,7 +875,7 @@
         else:
             self.parent.statusbarWin['mask'].SetLabel('')
         
-        Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s -> time=%g" % \
+        Debug.msg (1, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s -> time=%g" % \
                    (render, renderVector, (stop-start)))
         
         return True
@@ -1231,8 +1200,7 @@
 #        event.Skip()
 
     def OnDragging(self, event):
-        """!
-        Mouse dragging with left button down
+        """!Mouse dragging
         """
         Debug.msg (5, "BufferedWindow.MouseAction(): Dragging")
         current  = event.GetPositionTuple()[:]
@@ -1262,7 +1230,7 @@
             if (event.LeftIsDown() and 
                 not (digitToolbar and 
                     digitToolbar.GetAction() in ("moveLine",) and 
-                    digitClass.driver.GetSelected() > 0)):
+                    digitClass.GetDisplay().GetSelected() > 0)):
                 # draw box only when left mouse button is pressed
                 self.MouseDraw(pdc = self.pdcTmp)
         
@@ -1280,24 +1248,19 @@
         except:
             return
         
-        if digitToolbar.GetAction('type') in ["point", "centroid"]:
-            # add new point
-            if digitToolbar.GetAction('type') == 'point':
-                point = True
-            else:
-                point = False
-
+        if digitToolbar.GetAction('type') in ['point', 'centroid']:
+            # add new point / centroiud
             east, north = self.Pixel2Cell(self.mouse['begin'])
-            fid = digitClass.AddPoint(mapLayer, point, east, north)
-            if fid < 0:
+            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')  is True:
+            if UserSettings.Get(group = 'vdigit', key = "addRecord", subkey = 'enabled'):
                 # select attributes based on layer and category
-                cats = { fid : {
+                cats = { fids[0] : {
                         UserSettings.Get(group = 'vdigit', key = "layer", subkey = 'value') :
                             (UserSettings.Get(group = 'vdigit', key = "category", subkey = 'value'), )
                         }}
@@ -1310,12 +1273,13 @@
                                                                    pos = posWindow,
                                                                    action = "add")
 
-                if not point:
-                    self.__geomAttrb(fid, addRecordDlg, 'area', digitClass,
-                                     digitToolbar.GetLayer())
-                    self.__geomAttrb(fid, addRecordDlg, 'perimeter', digitClass,
-                                     digitToolbar.GetLayer())
-
+                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")
@@ -1331,12 +1295,12 @@
                 if addRecordDlg.mapDBInfo:
                     self.__updateATM()
         
-        elif digitToolbar.GetAction('type') in ["line", "boundary"]:
+        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):
+    def _geomAttrb(self, fid, dialog, attrb, digit, mapLayer):
         """!Trac geometry attributes?"""
         item = self.tree.FindItemByData('maplayer', mapLayer)
         vdigit = self.tree.GetPyData(item)[0]['vdigit']
@@ -1361,7 +1325,7 @@
                 dialog.SetColumnValue(layer, column, val)
                 dialog.OnReset()
         
-    def __geomAttrbUpdate(self, fids):
+    def _geomAttrbUpdate(self, fids):
         """!Update geometry atrributes of currently selected features
 
         @param fid list feature id
@@ -1447,8 +1411,6 @@
         self.vdigitMove['begin'] = None
         # list of ids to modify    
         self.vdigitMove['id'] = []
-        # ids geographic coordinates
-        self.vdigitMove['coord'] = {}
                 
         if digitToolbar.GetAction() in ["moveVertex", "editLine"]:
             # set pen
@@ -1459,8 +1421,7 @@
             self.pdcTmp.SetPen(self.polypen)
 
     def OnLeftDownVDigitDisplayCA(self, event):
-        """!
-        Left mouse button down - vector digitizer display categories
+        """!Left mouse button down - vector digitizer display categories
         or attributes action
         """
         digitToolbar = self.parent.toolbars['vdigit']
@@ -1474,19 +1435,18 @@
         coords = self.Pixel2Cell(self.mouse['begin'])
         
         # unselect
-        digitClass.driver.SetSelected([])
+        digitClass.GetDisplay().SetSelected([])
         
         # select feature by point
         cats = {}
-        if digitClass.driver.SelectLineByPoint(coords,
-                                               digitClass.GetSelectType()) is None:
+        if digitClass.GetDisplay().SelectLineByPoint(coords) is None:
             return
-
+        
         if UserSettings.Get(group = 'vdigit', key = 'checkForDupl',
                             subkey = 'enabled'):
-            lines = digitClass.driver.GetSelected()
+            lines = digitClass.GetDisplay().GetSelected()
         else:
-            lines = (digitClass.driver.GetSelected()[0],) # only first found
+            lines = (digitClass.GetDisplay().GetSelected()[0],) # only first found
                         
         for line in lines:
             cats[line] = digitClass.GetLineCats(line)
@@ -1504,7 +1464,7 @@
             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
@@ -1527,7 +1487,7 @@
             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
@@ -1536,8 +1496,8 @@
                 else:
                     if self.parent.dialogs['category'].IsShown():
                         self.parent.dialogs['category'].Hide()
-                
-        self.UpdateMap(render = False)
+        
+        self.UpdateMap(render = False, renderVector = True)
  
     def OnLeftDownVDigitCopyCA(self, event):
         """!
@@ -1585,12 +1545,11 @@
             self.DrawLines(self.pdcTmp, polycoords = (begin, end))
         
     def OnLeftDown(self, event):
-        """!
-        Left mouse button pressed
+        """!Left mouse button pressed
         """
         Debug.msg (5, "BufferedWindow.OnLeftDown(): use=%s" % \
                    self.mouse["use"])
-
+        
         self.mouse['begin'] = event.GetPositionTuple()[:]
         
         if self.mouse["use"] in ["measure", "profile"]:
@@ -1601,68 +1560,18 @@
                 self.ClearLines(pdc=self.pdcTmp)
             else:
                 self.mouse['begin'] = self.mouse['end']
+        
         elif self.mouse['use'] == 'zoom':
             pass
-
-        #
+        
         # vector digizer
-        #
         elif self.mouse["use"] == "pointer" and \
                 self.parent.toolbars['vdigit']:
-            digitToolbar = self.parent.toolbars['vdigit']
-            digitClass   = self.parent.digit
-            
-            try:
-                mapLayer = digitToolbar.GetLayer().GetName()
-            except:
-                wx.MessageBox(parent = self,
-                              message = _("No vector map selected for editing."),
-                              caption = _("Vector digitizer"),
-                              style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
-                event.Skip()
-                return
-            
-            if digitToolbar.GetAction() not in ("moveVertex",
-                                                "addVertex",
-                                                "removeVertex",
-                                                "editLine"):
-                # set pen
-                self.pen = wx.Pen(colour = 'Red', width = 2, style = wx.SHORT_DASH)
-                self.polypen = wx.Pen(colour = 'dark green', width = 2, style = wx.SOLID)
-
-            if digitToolbar.GetAction() in ("addVertex",
-                                            "removeVertex",
-                                            "splitLines"):
-                # unselect
-                digitClass.driver.SetSelected([])
-
-            if digitToolbar.GetAction() == "addLine":
-                self.OnLeftDownVDigitAddLine(event)
-            
-            elif digitToolbar.GetAction() == "editLine" and \
-                    hasattr(self, "vdigitMove"):
-                self.OnLeftDownVDigitEditLine(event)
-
-            elif digitToolbar.GetAction() in ("moveLine", 
-                                              "moveVertex",
-                                              "editLine") and \
-                    not hasattr(self, "vdigitMove"):
-                self.OnLeftDownVDigitMoveLine(event)
-
-            elif digitToolbar.GetAction() in ("displayAttrs"
-                                              "displayCats"):
-                self.OnLeftDownVDigitDisplayCA(event)
-            
-            elif digitToolbar.GetAction() in ("copyCats",
-                                              "copyAttrs"):
-                self.OnLeftDownVDigitCopyCA(event)
-            
-            elif digitToolbar.GetAction() == "copyLine":
-                self.OnLeftDownVDigitCopyLine(event)
-            
-            elif digitToolbar.GetAction() == "zbulkLine":
-                self.OnLeftDownVDigitBulkLine(event)
-            
+            if event.ControlDown():
+                self.OnLeftDownVDigitUndo(event)
+            else:
+                self.OnLeftDownVDigit(event)
+        
         elif self.mouse['use'] == 'pointer':
             # get decoration or text id
             self.idlist = []
@@ -1679,13 +1588,134 @@
 
         event.Skip()
 
-    def OnLeftUpVDigitVarious(self, event):
-        """!
-        Left mouse button up - vector digitizer various actions
+    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'])
         
@@ -1693,25 +1723,25 @@
         # -> delete line || move line || move vertex
         if digitToolbar.GetAction() in ("moveVertex",
                                         "editLine"):
-            if len(digitClass.driver.GetSelected()) == 0:
-                nselected = digitClass.driver.SelectLineByPoint(pos1, type = VDigit_Lines_Type)
+            if len(digitClass.GetDisplay().GetSelected()) == 0:
+                nselected = digitClass.GetDisplay().SelectLineByPoint(pos1)['point']
                 
                 if digitToolbar.GetAction() == "editLine":
                     try:
-                        selVertex = digitClass.driver.GetSelectedVertex(pos1)[0]
+                        selVertex = digitClass.GetDisplay().GetSelectedVertex(pos1)[0]
                     except IndexError:
                         selVertex = None
                         
                     if selVertex:
                         # self.UpdateMap(render=False)
-                        ids = digitClass.driver.GetSelected(grassId = 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.driver.DrawSelected(False) 
+                        digitClass.GetDisplay().DrawSelected(False) 
                                 
                         if selVertex < ids[-1] / 2:
                             # choose first or last node of line
@@ -1719,7 +1749,7 @@
                             self.polycoords.reverse()
                     else:
                         # unselect
-                        digitClass.driver.SetSelected([])
+                        digitClass.GetDisplay().SetSelected([])
                         del self.vdigitMove
                 
                     self.UpdateMap(render = False)
@@ -1728,47 +1758,42 @@
                                           "copyAttrs"):
             if not hasattr(self, "copyCatsIds"):
                 # 'from' -> select by point
-                nselected = digitClass.driver.SelectLineByPoint(pos1, digitClass.GetSelectType())
+                nselected = digitClass.GetDisplay().SelectLineByPoint(pos1)['point']
                 if nselected:
-                    self.copyCatsList = digitClass.driver.GetSelected()
+                    self.copyCatsList = digitClass.GetDisplay().GetSelected()
             else:
                 # -> 'to' -> select by bbox
-                digitClass.driver.SetSelected([])
+                digitClass.GetDisplay().SetSelected([])
                 # return number of selected features (by box/point)
-                nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                               digitClass.GetSelectType())
+                nselected = digitClass.GetDisplay().SelectLinesByBox((pos1, pos2))
                 if nselected == 0:
-                    if digitClass.driver.SelectLineByPoint(pos1,
-                                                           digitClass.GetSelectType()) is not None:
+                    if digitClass.GetDisplay().SelectLineByPoint(pos1) is not None:
                         nselected = 1
                         
                 if nselected > 0:
-                    self.copyCatsIds = digitClass.driver.GetSelected()
+                    self.copyCatsIds = digitClass.GetDisplay().GetSelected()
 
         elif digitToolbar.GetAction() == "queryLine":
-            selected = digitClass.SelectLinesByQuery(pos1, pos2)
+            selected = digitClass.SelectLinesByQuery(bbox = (pos1, pos2))
             nselected = len(selected)
             if nselected > 0:
-                digitClass.driver.SetSelected(selected)
-
+                digitClass.GetDisplay().SetSelected(selected)
+        
         else:
             # -> moveLine || deleteLine, etc. (select by point/box)
             if digitToolbar.GetAction() == 'moveLine' and \
-                    len(digitClass.driver.GetSelected()) > 0:
+                    len(digitClass.GetDisplay().GetSelected()) > 0:
                 nselected = 0
             else:
                 if digitToolbar.GetAction() == 'moveLine':
                     drawSeg = True
                 else:
                     drawSeg = False
-
-                nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                               digitClass.GetSelectType(),
-                                                               drawSeg)
-                    
+                
+                nselected = digitClass.GetDisplay().SelectLinesByBox(bbox = (pos1, pos2),
+                                                                     drawSeg = drawSeg)
                 if nselected == 0:
-                    if digitClass.driver.SelectLineByPoint(pos1,
-                                                           digitClass.GetSelectType()) is not None:
+                    if digitClass.GetDisplay().SelectLineByPoint(pos1) is not None:
                         nselected = 1
         
         if nselected > 0:
@@ -1777,18 +1802,17 @@
                 # get pseudoDC id of objects which should be redrawn
                 if digitToolbar.GetAction() == "moveLine":
                     # -> move line
-                    self.vdigitMove['id'] = digitClass.driver.GetSelected(grassId = False)
-                    self.vdigitMove['coord'] = digitClass.driver.GetSelectedCoord()
+                    self.vdigitMove['id']    = digitClass.GetDisplay().GetSelected(grassId = False)
                 else: # moveVertex
-                    self.vdigitMove['id'] = digitClass.driver.GetSelectedVertex(pos1)
+                    self.vdigitMove['id'] = digitClass.GetDisplay().GetSelectedVertex(pos1)
                     if len(self.vdigitMove['id']) == 0: # no vertex found
-                        digitClass.driver.SetSelected([])
-                
+                        digitClass.GetDisplay().SetSelected([])
+            
             #
             # check for duplicates
             #
-            if UserSettings.Get(group = 'vdigit', key = 'checkForDupl', subkey = 'enabled') is True:
-                dupl = digitClass.driver.GetDuplicates()
+            if UserSettings.Get(group = 'vdigit', key = 'checkForDupl', subkey = 'enabled'):
+                dupl = digitClass.GetDisplay().GetDuplicates()
                 self.UpdateMap(render = False)
                     
                 if dupl:
@@ -1798,7 +1822,7 @@
                     dlg = VDigitDuplicatesDialog(parent = self, data = dupl, pos = posWindow)
                     
                     if dlg.ShowModal() == wx.ID_OK:
-                        digitClass.driver.UnSelect(dlg.GetUnSelected())
+                        digitClass.GetDisplay().UnSelect(dlg.GetUnSelected())
                         # update selected
                         self.UpdateMap(render = False)
                 
@@ -1814,8 +1838,7 @@
                 self.UpdateMap(render = False, renderVector = False)
         
     def OnLeftUpVDigitModifyLine(self, event):
-        """!
-        Left mouse button up - vector digitizer split line, add/remove
+        """!Left mouse button up - vector digitizer split line, add/remove
         vertex action
         """
         digitToolbar = self.parent.toolbars['vdigit']
@@ -1823,20 +1846,18 @@
         
         pos1 = self.Pixel2Cell(self.mouse['begin'])
         
-        pointOnLine = digitClass.driver.SelectLineByPoint(pos1,
-                                                          type = VDigit_Lines_Type)
-
+        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),
+            self.DrawCross(pdc = self.pdcTmp, coords = self.Cell2Pixel((pointOnLine[0], pointOnLine[1])),
                            size = 5)
         else: # removeVertex
             # get only id of vertex
             try:
-                id = digitClass.driver.GetSelectedVertex(pos1)[0]
+                id = digitClass.GetDisplay().GetSelectedVertex(pos1)[0]
             except IndexError:
                 id = None
 
@@ -1848,7 +1869,7 @@
                                size = 5)
             else:
                 # unselect
-                digitClass.driver.SetSelected([])
+                digitClass.GetDisplay().SetSelected([])
                 self.UpdateMap(render = False)
 
     def OnLeftUpVDigitCopyLine(self, event):
@@ -1864,8 +1885,7 @@
         if UserSettings.Get(group = 'vdigit', key = 'bgmap',
                             subkey = 'value', internal = True) == '':
             # no background map -> copy from current vector map layer
-            nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                           digitClass.GetSelectType())
+            nselected = digitClass.GetDisplay().SelectLinesByBox((pos1, pos2))
 
             if nselected > 0:
                 # highlight selected features
@@ -1874,7 +1894,7 @@
                 self.UpdateMap(render = False, renderVector = False)
         else:
             # copy features from background map
-            self.copyIds += digitClass.SelectLinesFromBackgroundMap(pos1, pos2)
+            self.copyIds += digitClass.SelectLinesFromBackgroundMap(bbox = (pos1, pos2))
             if len(self.copyIds) > 0:
                 color = UserSettings.Get(group = 'vdigit', key = 'symbol',
                                          subkey = ['highlight', 'color'])
@@ -1914,9 +1934,8 @@
         # select lines to be labeled
         pos1 = self.polycoords[0]
         pos2 = self.polycoords[1]
-        nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                       digitClass.GetSelectType())
-
+        nselected = digitClass.GetDisplay().SelectLinesByBox((pos1, pos2))
+        
         if nselected > 0:
             # highlight selected features
             self.UpdateMap(render = False)
@@ -1931,7 +1950,7 @@
         digitToolbar = self.parent.toolbars['vdigit']
         digitClass   = self.parent.digit
         
-        if len(digitClass.driver.GetSelected()) > 0:
+        if len(digitClass.GetDisplay().GetSelected()) > 0:
             self.UpdateMap(render = False)
         
     def OnLeftUp(self, event):
@@ -2016,7 +2035,7 @@
             digitClass   = self.parent.digit
             
             if hasattr(self, "vdigitMove"):
-                if len(digitClass.driver.GetSelected()) == 0:
+                if len(digitClass.GetDisplay().GetSelected()) == 0:
                     self.vdigitMove['begin'] = self.Pixel2Cell(self.mouse['begin']) # left down
                 
                 # eliminate initial mouse moving efect
@@ -2035,7 +2054,7 @@
                                             "breakLine",
                                             "typeConv",
                                             "connectLine"):
-                self.OnLeftUpVDigitVarious(event)
+                self.OnLeftUpVDigit(event)
 
             elif digitToolbar.GetAction() in ("splitLine",
                                               "addVertex",
@@ -2052,7 +2071,7 @@
             elif digitToolbar.GetAction() == "connectLine":
                 self.OnLeftUpConnectLine(event)
             
-            if len(digitClass.driver.GetSelected()) > 0:
+            if len(digitClass.GetDisplay().GetSelected()) > 0:
                 self.redrawAll = None
             
         elif (self.mouse['use'] == 'pointer' and 
@@ -2111,8 +2130,7 @@
                 self.parent.OnAddLegend(None)
         
     def OnRightDown(self, event):
-        """!
-        Right mouse button pressed
+        """!Right mouse button pressed
         """
         Debug.msg (5, "BufferedWindow.OnRightDown(): use=%s" % \
                    self.mouse["use"])
@@ -2141,15 +2159,14 @@
                     if fid < 0:
                         return
 
-                    self.__geomAttrbUpdate([fid,])
+                    self._geomAttrbUpdate([fid,])
                 
                 del self.vdigitMove
                 
         event.Skip()
 
     def OnRightUp(self, event):
-        """!
-        Right mouse button released
+        """!Right mouse button released
         """
         Debug.msg (5, "BufferedWindow.OnRightUp(): use=%s" % \
                    self.mouse["use"])
@@ -2159,31 +2176,27 @@
             digitClass = self.parent.digit
             # digitization tool (confirm action)
             if digitToolbar.GetAction() == "addLine" and \
-                    digitToolbar.GetAction('type') in ["line", "boundary"]:
+                    digitToolbar.GetAction('type') in ["line", "boundary", "area"]:
                 # -> add new line / boundary
                 try:
-                    map = digitToolbar.GetLayer().GetName()
+                    mapName = digitToolbar.GetLayer().GetName()
                 except:
-                    map = None
+                    mapName = None
                     wx.MessageBox(parent = self,
                                   message = _("No vector map selected for editing."),
                                   caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
                     
-                if map:
-                    # mapcoords = []
-                    # xy -> EN
-                    # for coord in self.polycoords:
-                    #    mapcoords.append(self.Pixel2Cell(coord))
+                if mapName:
                     if digitToolbar.GetAction('type') == 'line':
                         line = True
                     else:
                         line = False
-
+                    
                     if len(self.polycoords) < 2: # ignore 'one-point' lines
                         return
                     
-                    fid = digitClass.AddLine(map, line, self.polycoords)
-                    if fid < 0:
+                    nfeat, fids = digitClass.AddFeature(digitToolbar.GetAction('type'), self.polycoords)
+                    if nfeat < 0:
                         return
                     
                     position = self.Cell2Pixel(self.polycoords[-1])
@@ -2195,29 +2208,30 @@
                     # add new record into atribute table
                     if UserSettings.Get(group = 'vdigit', key = "addRecord", subkey = 'enabled') and \
                             (line is True or \
-                                 (not line and fid > 0)):
+                                 (not line and nfeat > 0)):
                         posWindow = self.ClientToScreen((position[0] + self.dialogOffset,
                                                          position[1] + self.dialogOffset))
-
+                        
                         # select attributes based on layer and category
-                        cats = { fid : {
+                        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 = map,
+                        addRecordDlg = dbm_dialogs.DisplayAttributesDialog(parent = self, map = mapName,
                                                                            cats = cats,
                                                                            pos = posWindow,
                                                                            action = "add")
 
-                        self.__geomAttrb(fid, addRecordDlg, 'length', digitClass,
-                                         digitToolbar.GetLayer())
-                        # auto-placing centroid
-                        self.__geomAttrb(fid, addRecordDlg, 'area', digitClass,
-                                         digitToolbar.GetLayer())
-                        self.__geomAttrb(fid, addRecordDlg, 'perimeter', digitClass,
-                                         digitToolbar.GetLayer())
-
+                        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")
@@ -2251,7 +2265,7 @@
                 fid = digitClass.RemoveVertex(self.Pixel2Cell(self.mouse['begin']))
                 if fid < 0:
                     return
-                self.__geomAttrbUpdate([fid,])
+                self._geomAttrbUpdate([fid,])
             elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
                 try:
                     if digitToolbar.GetAction() == 'copyCats':
@@ -2272,7 +2286,7 @@
                 
             elif digitToolbar.GetAction() == "editLine" and \
                     hasattr(self, "vdigitMove"):
-                line = digitClass.driver.GetSelected()
+                line = digitClass.GetDisplay().GetSelected()
                 if digitClass.EditLine(line, self.polycoords) < 0:
                     return
                 
@@ -2291,7 +2305,7 @@
                 if digitClass.SnapLine() < 0:
                     return
             elif digitToolbar.GetAction() == "connectLine":
-                if len(digitClass.driver.GetSelected()) > 1:
+                if len(digitClass.GetDisplay().GetSelected()) > 1:
                     if digitClass.ConnectLine() < 0:
                         return
             elif digitToolbar.GetAction() == "copyLine":
@@ -2307,7 +2321,7 @@
                 pos1 = self.polycoords[0]
                 pos2 = self.polycoords[1]
 
-                selected = digitClass.driver.GetSelected()
+                selected = digitClass.GetDisplay().GetSelected()
                 dlg = VDigitZBulkDialog(parent = self, title = _("Z bulk-labeling dialog"),
                                         nselected = len(selected))
                 if dlg.ShowModal() == wx.ID_OK:
@@ -2324,7 +2338,7 @@
 
             if digitToolbar.GetAction() != "addLine":
                 # unselect and re-render
-                digitClass.driver.SetSelected([])
+                digitClass.GetDisplay().SetSelected([])
                 self.polycoords = []
                 self.UpdateMap(render = False)
 
@@ -2334,81 +2348,23 @@
         event.Skip()
 
     def OnMiddleDown(self, event):
-        """!
-        Middle mouse button pressed
+        """!Middle mouse button pressed
         """
-        self.mouse['begin'] = event.GetPositionTuple()[:]
-        
-        digitToolbar = self.parent.toolbars['vdigit']
-        # digitization tool
-        if self.mouse["use"] == "pointer" and digitToolbar:
-            digitClass = self.parent.digit
-            if (digitToolbar.GetAction() == "addLine" and \
-                    digitToolbar.GetAction('type') in ["line", "boundary"]) or \
-                    digitToolbar.GetAction() == "editLine":
-                # add line or boundary -> remove last point from the line
-                try:
-                    removed = self.polycoords.pop()
-                    Debug.msg(4, "BufferedWindow.OnMiddleDown(): polycoords_poped=%s" % \
-                                  [removed,])
-
-                    self.mouse['begin'] = self.Cell2Pixel(self.polycoords[-1])
-                except:
-                    pass
-
-                if digitToolbar.GetAction() == "editLine":
-                    # remove last vertex & line
-                    if len(self.vdigitMove['id']) > 1:
-                        self.vdigitMove['id'].pop()
-
-                self.UpdateMap(render = False, renderVector = False)
-
-            elif digitToolbar.GetAction() in ["deleteLine", "moveLine", "splitLine",
-                                              "addVertex", "removeVertex", "moveVertex",
-                                              "copyCats", "flipLine", "mergeLine",
-                                              "snapLine", "connectLine", "copyLine",
-                                              "queryLine", "breakLine", "typeConv"]:
-                # varios tools -> unselected selected features
-                digitClass.driver.SetSelected([])
-                if digitToolbar.GetAction() in ["moveLine", "moveVertex", "editLine"] and \
-                        hasattr(self, "vdigitMove"):
-
-                    del self.vdigitMove
-                    
-                elif digitToolbar.GetAction() == "copyCats":
-                    try:
-                        del self.copyCatsList
-                        del self.copyCatsIds
-                    except AttributeError:
-                        pass
-                
-                elif digitToolbar.GetAction() == "copyLine":
-                    del self.copyIds
-                    if self.layerTmp:
-                        self.Map.DeleteLayer(self.layerTmp)
-                        self.UpdateMap(render = True, renderVector = False)
-                    del self.layerTmp
-
-                self.polycoords = []
-                self.UpdateMap(render = False) # render vector
-
-            elif digitToolbar.GetAction() == "zbulkLine":
-                # reset polyline
-                self.polycoords = []
-                digitClass.driver.SetSelected([])
-                self.UpdateMap(render = False)
-            
-            self.redrawAll = True
-
+        if event:
+            self.mouse['begin'] = event.GetPositionTuple()[:]
+    
     def OnMiddleUp(self, event):
-        """!
-        Middle mouse button released
+        """!Middle mouse button released
         """
+        # if self.parent.toolbars['vdigit']:
+        #     event.Skip()
+        #     return
+        
         self.mouse['end'] = event.GetPositionTuple()[:]
         
         # set region in zoom or pan
         begin = self.mouse['begin']
-        end = self.mouse['end']
+        end   = self.mouse['end']
         
         self.Zoom(begin, end, 0) # no zoom
         
@@ -2419,8 +2375,7 @@
         self.parent.StatusbarUpdate()
         
     def OnMouseEnter(self, event):
-        """!
-        Mouse entered window and no mouse buttons were pressed
+        """!Mouse entered window and no mouse buttons were pressed
         """
         if self.parent.GetLayerManager().gcpmanagement:
             if self.parent.toolbars['gcpdisp']:
@@ -2434,8 +2389,7 @@
             event.Skip()
 
     def OnMouseMoving(self, event):
-        """!
-        Motion event and no mouse buttons were pressed
+        """!Motion event and no mouse buttons were pressed
         """
         digitToolbar = self.parent.toolbars['vdigit']
         if self.mouse["use"] == "pointer" and digitToolbar:
@@ -2443,7 +2397,8 @@
             self.mouse['end'] = event.GetPositionTuple()[:]
             Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \
                            (self.mouse['end'][0], self.mouse['end'][1]))
-            if digitToolbar.GetAction() == "addLine" and digitToolbar.GetAction('type') in ["line", "boundary"]:
+            if 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"] \
@@ -2461,7 +2416,7 @@
                         # move vertex ->
                         # (vertex, left vertex, left line,
                         # right vertex, right line)
-
+                        
                         # do not draw static lines
                         if digitToolbar.GetAction() == "moveVertex":
                             self.polycoords = []
@@ -2469,7 +2424,7 @@
                             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.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']))
@@ -2751,7 +2706,7 @@
             elif l.type == 'vector':
                 digitToolbar = self.parent.toolbars['vdigit']
                 if digitToolbar and digitToolbar.GetLayer() == l:
-                    w, s, b, e, n, t = self.parent.digit.driver.GetMapBoundingBox()
+                    w, s, b, e, n, t = self.parent.digit.GetDisplay().GetMapBoundingBox()
                     self.Map.GetRegion(n = n, s = s, w = w, e = e,
                                        update = True)
                     updated = True

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -2115,8 +2115,10 @@
         if show is not None:
             self.mf.notebookpanel.OnUpdateSelection(None)
             if show is True:
-                if self.parent:
+                if self.parent and centreOnParent:
                     self.mf.CentreOnParent()
+                else:
+                    self.mf.CenterOnScreen()
                 self.mf.Show(show)
                 self.mf.MakeModal(modal)
             else:

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -339,14 +339,6 @@
                 'delRecord' : {
                     'enabled' : True
                     },
-                # add centroid to left/right area
-                'addCentroid' : {
-                    'enabled' : False
-                    },
-                # do not attach category to boundary
-                'catBoundary' : {
-                    'enabled' : False
-                    },
                 # query tool
                 'query' : {
                     'selection' : 0,

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -199,7 +199,7 @@
                 self.maskfile = None
         
         except gcmd.GException, e:
-            sys.stderr.write(e.value)
+            # sys.stderr.write(e.value)
             # clean up after problems
             try:
                 os.remove(self.mapfile)

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -15,7 +15,7 @@
  - HistogramToolbar
  - LayerManagerToolbar
 
-(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 for details.
 
@@ -35,8 +35,7 @@
 import globalvar
 import gcmd
 import gdialogs
-import vdigit
-from vdigit import VDigitSettingsDialog, haveVDigit
+from vdigit import VDigitSettingsDialog, haveVDigit, VDigit
 from debug import Debug
 from preferences import globalSettings as UserSettings
 from nviz import haveNviz
@@ -51,7 +50,7 @@
     def __init__(self, parent):
         self.parent = parent
         wx.ToolBar.__init__(self, parent = self.parent, id = wx.ID_ANY)
-    
+        
         self.action = dict()
         
         self.Bind(wx.EVT_TOOL, self.OnTool)
@@ -66,7 +65,7 @@
         
         self._data = toolData
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data (virtual)"""
         return None
     
@@ -79,8 +78,8 @@
         bmpDisabled = wx.NullBitmap
         
         if label:
-            Debug.msg(3, "CreateTool(): tool=%d, label=%s bitmap=%s" % \
-                  (tool, label, bitmap))
+            Debug.msg(3, "CreateTool(): tool=%d, label=%s bitmap=%d" % \
+                  (tool, label, bitmap.GetWidth()))
             toolWin = self.AddLabelTool(tool, label, bitmap,
                                         bmpDisabled, kind,
                                         shortHelp, longHelp)
@@ -105,7 +104,8 @@
                 self.SetToolLongHelp(tool[0], "")
         
     def OnTool(self, event):
-        """!Tool selected"""
+        """!Tool selected
+        """
         if self.parent.GetName() == "GCPFrame":
             return
         
@@ -175,7 +175,7 @@
         self.mapcontent = mapcontent # render.Map
         AbstractToolbar.__init__(self, parent = parent) # MapFrame
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # optional tools
         choices = [ _('2D view'), ]
@@ -194,6 +194,7 @@
                            'In the meantime you can use "NVIZ" from the File menu.'), wrap = 60)
             
             self.toolId['3d'] = -1
+
         if haveVDigit:
             choices.append(_('Digitize'))
             if self.toolId['3d'] > -1:
@@ -236,7 +237,7 @@
         
         self.FixSize(width = 90)
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data"""
         self.displaymap = wx.NewId()
         self.rendermap = wx.NewId()
@@ -355,12 +356,12 @@
     def __init__(self, parent):
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
 
-    def ToolbarData(self):
+    def _toolbarData(self):
         self.gcpSave = wx.NewId()
         self.gcpReload = wx.NewId()
         self.gcpAdd = wx.NewId()
@@ -405,7 +406,7 @@
         """
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # add tool to toggle active map window
         self.togglemapid = wx.NewId()
@@ -430,7 +431,7 @@
         
         self.EnableTool(self.zoomback, False)
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data"""
         self.displaymap = wx.NewId()
         self.rendermap = wx.NewId()
@@ -507,7 +508,7 @@
         self.mapcontent = mapcontent
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
@@ -520,7 +521,7 @@
         
         self.EnableTool(self.zoomback, False)
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data"""
         self.displaymap = wx.NewId()
         self.rendermap = wx.NewId()
@@ -579,12 +580,12 @@
     def __init__(self, parent):
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
 
-    def ToolbarData(self):
+    def _toolbarData(self):
         self.gcpSave = wx.NewId()
         self.gcpAdd = wx.NewId()
         self.gcpDelete = wx.NewId()
@@ -629,9 +630,8 @@
             )
     
 class VDigitToolbar(AbstractToolbar):
+    """!Toolbar for digitization
     """
-    Toolbar for digitization
-    """
     def __init__(self, parent, mapcontent, layerTree = None, log = None):
         self.mapcontent    = mapcontent # Map class instance
         self.layerTree     = layerTree  # reference to layer tree associated to map display
@@ -649,7 +649,7 @@
         self.settingsDialog   = None
         
         # create toolbars (two rows optionally)
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         self.Bind(wx.EVT_TOOL, self.OnTool)
         
         # default action (digitize new point, line, etc.)
@@ -674,9 +674,8 @@
         
         self.FixSize(width = 105)
         
-    def ToolbarData(self):
-        """!
-        Toolbar data
+    def _toolbarData(self):
+        """!Toolbar data
         """
         data = []
         
@@ -684,6 +683,7 @@
         self.addLine = wx.NewId()
         self.addBoundary = wx.NewId()
         self.addCentroid = wx.NewId()
+        self.addArea = wx.NewId()
         self.moveVertex = wx.NewId()
         self.addVertex = wx.NewId()
         self.removeVertex = wx.NewId()
@@ -712,6 +712,9 @@
                 (self.addCentroid, "digAddCentroid", Icons["digAddCentroid"].GetBitmap(),
                  wx.ITEM_CHECK, Icons["digAddCentroid"].GetLabel(), Icons["digAddCentroid"].GetDesc(),
                  self.OnAddCentroid),
+                (self.addArea, "digAddArea", Icons["digAddArea"].GetBitmap(),
+                 wx.ITEM_CHECK, Icons["digAddArea"].GetLabel(), Icons["digAddArea"].GetDesc(),
+                 self.OnAddArea),
                 (self.moveVertex, "digMoveVertex", Icons["digMoveVertex"].GetBitmap(),
                  wx.ITEM_CHECK, Icons["digMoveVertex"].GetLabel(), Icons["digMoveVertex"].GetDesc(),
                  self.OnMoveVertex),
@@ -792,7 +795,7 @@
         if self.action['id'] != id:
             self.parent.MapWindow.ClearLines(pdc = self.parent.MapWindow.pdcTmp)
             if self.parent.digit and \
-                    len(self.parent.digit.driver.GetSelected()) > 0:
+                    len(self.parent.digit.GetDisplay().GetSelected()) > 0:
                 # cancel action
                 self.parent.MapWindow.OnMiddleDown(None)
         
@@ -835,6 +838,14 @@
                         'id'   : self.addCentroid }
         self.parent.MapWindow.mouse['box'] = 'point'
 
+    def OnAddArea(self, event):
+        """!Add area to the vector map layer"""
+        Debug.msg (2, "VDigitToolbar.OnAddCentroid()")
+        self.action = { 'desc' : "addLine",
+                        'type' : "area",
+                        'id'   : self.addArea }
+        self.parent.MapWindow.mouse['box'] = 'line'
+
     def OnExit (self, event=None):
         """!Quit digitization tool"""
         # stop editing of the currently selected map layer
@@ -991,10 +1002,8 @@
     def OnSettings(self, event):
         """!Show settings dialog"""
         if self.parent.digit is None:
-            reload(vdigit)
-            from vdigit import VDigit as VDigit
             try:
-                self.parent.digit = VDigit(mapwindow=self.parent.MapWindow)
+                self.parent.digit = VDigit(mapwindow = self.parent.MapWindow)
             except SystemExit:
                 self.parent.digit = None
         
@@ -1182,10 +1191,9 @@
 
     def OnZBulk(self, event):
         """!Z bulk-labeling selected lines/boundaries"""
-        if not self.parent.digit.driver.Is3D():
-            wx.MessageBox(parent = self.parent,
-                          message = _("Vector map is not 3D. Operation canceled."),
-                          caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
+        if not self.parent.digit.IsVector3D():
+            gcmd.GError(parent = self.parent,
+                        message = _("Vector map is not 3D. Operation canceled."))
             return
         
         if self.action['desc'] == 'zbulkLine': # select previous action
@@ -1273,11 +1281,14 @@
     def StartEditing (self, mapLayer):
         """!Start editing selected vector map layer.
         
-        @param mapLayer reference to MapLayer instance
+        @param mapLayer MapLayer to be edited
         """
         # deactive layer
         self.mapcontent.ChangeLayerActive(mapLayer, False)
         
+        # clean map canvas
+        self.parent.MapWindow.EraseMap()
+        
         # unset background map if needed
         if mapLayer:
             if UserSettings.Get(group = 'vdigit', key = 'bgmap',
@@ -1286,35 +1297,26 @@
                                  subkey = 'value', value = '', internal = True)
             
             self.parent.statusbar.SetStatusText(_("Please wait, "
-                                                  "opening vector map <%s> for editing...") % \
-                                                    mapLayer.GetName(),
+                                                  "opening vector map <%s> for editing...") % mapLayer.GetName(),
                                                 0)
         
-        # reload vdigit module
-        reload(vdigit)
-        from vdigit import VDigit as VDigit
-        # use vdigit's PseudoDC
-        self.parent.MapWindow.DefinePseudoDC(vdigit = True)
+        self.parent.MapWindow.pdcVector = wx.PseudoDC()
         self.parent.digit = VDigit(mapwindow = self.parent.MapWindow)
         
         self.mapLayer = mapLayer
         
         # open vector map
-        try:
-            if not self.parent.MapWindow.CheckPseudoDC():
-                raise gcmd.GException(_("Unable to initialize display driver of vector "
-                                        "digitizer. See 'Command output' for details."))
-            self.parent.digit.SetMapName(mapLayer.GetName())
-        except gcmd.GException, e:
+        if self.parent.digit.OpenMap(mapLayer.GetName()) is None:
             self.mapLayer = None
             self.StopEditing()
-            gcmd.GError(parent = self.parent,
-                        message = str(e))
             return False
         
         # update toolbar
         self.combo.SetValue(mapLayer.GetName())
         self.parent.toolbars['map'].combo.SetValue (_('Digitize'))
+        lmgr = self.parent.GetLayerManager()
+        if lmgr:
+            lmgr.toolbar.Enable('vdigit', enable = False)
         
         Debug.msg (4, "VDigitToolbar.StartEditing(): layer=%s" % mapLayer.GetName())
         
@@ -1322,10 +1324,6 @@
         if self.parent.MapWindow.mouse['use'] == 'pointer':
             self.parent.MapWindow.SetCursor(self.parent.cursors["cross"])
         
-        # create pseudoDC for drawing the map
-        self.parent.MapWindow.pdcVector = vdigit.PseudoDC()
-        self.parent.digit.driver.SetDevice(self.parent.MapWindow.pdcVector)
-        
         if not self.parent.MapWindow.resize:
             self.parent.MapWindow.UpdateMap(render = True)
         
@@ -1342,9 +1340,6 @@
         @return True on success
         @return False on failure
         """
-        # use wx's PseudoDC
-        self.parent.MapWindow.DefinePseudoDC(vdigit = False)
-        
         self.combo.SetValue (_('Select vector map'))
         
         # save changes
@@ -1366,9 +1361,15 @@
                                                   "closing and rebuilding topology of "
                                                   "vector map <%s>...") % self.mapLayer.GetName(),
                                                 0)
-        
-            self.parent.digit.SetMapName(None) # -> close map
-        
+            lmgr = self.parent.GetLayerManager()
+            if lmgr:
+                lmgr.toolbar.Enable('vdigit', enable = True)
+                lmgr.notebook.SetSelection(1)
+            self.parent.digit.CloseMap()
+            if lmgr:
+                lmgr.GetLogWindow().GetProgressBar().SetValue(0)
+                lmgr.GetLogWindow().WriteCmdLog(_("Editing of vector map <%s> successfully finished") % \
+                                                    self.mapLayer.GetName())
             # re-active layer 
             item = self.parent.tree.FindItemByData('maplayer', self.mapLayer)
             if item and self.parent.tree.IsItemChecked(item):
@@ -1376,10 +1377,7 @@
         
         # change cursor
         self.parent.MapWindow.SetCursor(self.parent.cursors["default"])
-        
-        # disable pseudodc for vector map layer
         self.parent.MapWindow.pdcVector = None
-        self.parent.digit.driver.SetDevice(None)
         
         # close dialogs
         for dialog in ('attributes', 'category'):
@@ -1448,12 +1446,12 @@
     def __init__(self, parent):
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data"""
         self.transect = wx.NewId()
         self.addraster = wx.NewId()
@@ -1523,12 +1521,12 @@
         # only one dialog can be open
         self.settingsDialog   = None
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data"""
         self.view = wx.NewId()
         self.surface = wx.NewId()
@@ -1635,12 +1633,12 @@
     def __init__(self, parent):
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data"""
         self.new = wx.NewId()
         self.open = wx.NewId()
@@ -1717,12 +1715,12 @@
     def __init__(self, parent):
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
         
-    def ToolbarData(self):
+    def _toolbarData(self):
         """!Toolbar data"""
         self.histogram = wx.NewId()
         self.rendermap = wx.NewId()
@@ -1765,13 +1763,14 @@
     def __init__(self, parent):
         AbstractToolbar.__init__(self, parent)
         
-        self.InitToolbar(self.ToolbarData())
+        self.InitToolbar(self._toolbarData())
         
         # realize the toolbar
         self.Realize()
 
-    def ToolbarData(self):
-        """!Toolbar data"""
+    def _toolbarData(self):
+        """!Toolbar data
+        """
         self.newdisplay = wx.NewId()
         self.workspaceLoad = wx.NewId()
         self.workspaceOpen = wx.NewId()
@@ -1784,18 +1783,19 @@
         self.addovl = wx.NewId()
         self.delcmd = wx.NewId()
         self.attribute = wx.NewId()
+        self.vdigit = wx.NewId()
         self.preferences = wx.NewId()
         self.modeler = wx.NewId() 
         
         # tool, label, bitmap, kind, shortHelp, longHelp, handler
         return (
             (self.newdisplay, 'newdisplay', Icons["newdisplay"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["newdisplay"].GetLabel(), Icons["newdisplay"].GetDesc(),
-             self.parent.OnNewDisplay),
+             wx.ITEM_NORMAL, _("Start new display / create new workspace"), '',
+             self.parent.OnNewMenu),
             ('', '', '', '', '', '', ''),
             (self.workspaceLoad, 'workspaceLoad', Icons["workspaceLoad"].GetBitmap(),
-             wx.ITEM_NORMAL, Icons["workspaceLoad"].GetLabel(), Icons["workspaceLoad"].GetDesc(),
-             self.parent.OnWorkspace),
+             wx.ITEM_NORMAL, _("Load / import map layers into workspace"), '',
+             self.parent.OnLoadMenu),
             (self.workspaceOpen, 'workspaceOpen', Icons["workspaceOpen"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["workspaceOpen"].GetLabel(), Icons["workspaceOpen"].GetDesc(),
              self.parent.OnWorkspaceOpen),
@@ -1825,6 +1825,9 @@
              wx.ITEM_NORMAL, Icons["delcmd"].GetLabel(), Icons["delcmd"].GetDesc(),
              self.parent.OnDeleteLayer),
             ('', '', '', '', '', '', ''),
+            (self.vdigit, 'vdigit', Icons["vdigit"].GetBitmap(),
+             wx.ITEM_NORMAL, Icons["vdigit"].GetLabel(), Icons["vdigit"].GetDesc(),
+             self.parent.OnVDigit),
             (self.attribute, 'attrtable', Icons["attrtable"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["attrtable"].GetLabel(), Icons["attrtable"].GetDesc(),
              self.parent.OnShowAttributeTable),
@@ -1836,4 +1839,3 @@
              wx.ITEM_NORMAL, Icons["settings"].GetLabel(), Icons["settings"].GetDesc(),
              self.parent.OnPreferences)
             )
-    

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,21 +1,18 @@
 """!
 @package vdigit
 
- at brief wxGUI vector digitizer user interface
+ at brief Dialogs for wxGUI vector digitizer
 
 Classes:
- - AbstractDigit 
  - VDigit
- - AbstractDisplayDriver
- - CDisplayDriver
  - VDigitSettingsDialog
  - VDigitCategoryDialog
  - CategoryListCtrl
  - VDigitZBulkDialog
  - VDigitDuplicatesDialog
- - VDigitVBuildDialog
+ - CheckListFeature
 
-(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 for details.
 
@@ -43,1103 +40,40 @@
 from units import Units
 from preferences import globalSettings as UserSettings
 try:
-    digitPath = os.path.join(globalvar.ETCWXDIR, "vdigit")
-    sys.path.append(digitPath)
-    import grass6_wxvdigit as wxvdigit
-    GV_LINES = wxvdigit.GV_LINES
-    PseudoDC = wxvdigit.PseudoDC
+    from wxvdigit  import IVDigit, GV_LINES
     haveVDigit = True
     errorMsg = ''
 except ImportError, err:
     haveVDigit = False
-    GV_LINES = None
-    PseudoDC = wx.PseudoDC
     errorMsg = err
-    
-class AbstractDigit:
-    """!Abstract digitization class
-    """
-    def __init__(self, mapwindow):
-        """!Initialization
+    GV_LINES = -1
+    class IVDigit:
+        def __init__(self):
+            pass
 
-        @param mapwindow reference to mapwindow (MapFrame) instance
-        @param settings  initial settings of digitization tool
-        """
-        self.map       = None
-        self.mapWindow = mapwindow
-        
-        Debug.msg (3, "AbstractDigit.__init__(): map=%s" % \
-                   self.map)
-
-        #self.SetCategory()
-
-        self.driver = CDisplayDriver(self, mapwindow)
-
-    def __del__(self):
-        pass
-    
-    def SetCategoryNextToUse(self):
-        """!Find maximum category number in the map layer
-        and update Digit.settings['category']
-
-        @return 'True' on success, 'False' on failure
-        """
-        # vector map layer without categories, reset to '1'
-        UserSettings.Set(group='vdigit', key='category', subkey='value', value=1)
-
-        if self.map:
-            cat = self.digit.GetCategory(UserSettings.Get(group='vdigit', key='layer', subkey='value'))
-            cat += 1
-            UserSettings.Set(group='vdigit', key='category', subkey='value',
-                             value=cat)
-        
-    def SetCategory(self):
-        """!Return category number to use (according Settings)"""
-        if UserSettings.Get(group='vdigit', key="categoryMode", subkey='selection') == 0:
-            self.SetCategoryNextToUse()
-
-        return UserSettings.Get(group='vdigit', key="category", subkey='value')
-
-    def SetMapName(self, map):
-        """!Set map name
-
-        @param map map name to be set up or None (will close currently edited map)
-        """
-        Debug.msg (3, "AbstractDigit.SetMapName map=%s" % map)
-        self.map = map
-
-        try:
-            ret = self.driver.Reset(self.map)
-        except StandardError, e:
-            raise gcmd.GException(_("Unable to initialize display driver of vector "
-                              "digitizer. See 'Command output' for details.\n\n"
-                              "Details: ") + e)
-        
-        if map and ret == -1:
-            raise gcmd.GException(_('Unable to open vector map <%s> for editing.\n\n'
-                                    'Data are probably corrupted, '
-                                    'try to run v.build to rebuild '
-                                    'the topology (Vector->Develop vector map->'
-                                    'Create/rebuild topology).') % map)
-        if not map and ret != 0:
-            raise gcmd.GException(_('Unable to open vector map <%s> for editing.\n\n'
-                                    'Data are probably corrupted, '
-                                    'try to run v.build to rebuild '
-                                    'the topology (Vector->Develop vector map->'
-                                    'Create/rebuild topology).') % map)
-        
-        if self.digit:
-            self.digit.InitCats()
-        
-    def SelectLinesByQueryThresh(self):
-        """!Generic method used for SelectLinesByQuery()
-        -- to get threshold value"""
-        thresh = 0.0
-        if UserSettings.Get(group='vdigit', key='query', subkey='selection') == 0:
-            thresh = UserSettings.Get(group='vdigit', key='queryLength', subkey='thresh')
-            if UserSettings.Get(group='vdigit', key="queryLength", subkey='than-selection') == 0:
-                thresh = -1 * thresh
-        else:
-            thresh = UserSettings.Get(group='vdigit', key='queryDangle', subkey='thresh')
-            if UserSettings.Get(group='vdigit', key="queryDangle", subkey='than-selection') == 0:
-                thresh = -1 * thresh
-
-        return thresh
-
-    def GetSelectType(self):
-        """!Get type(s) to be selected
-
-        Used by SelectLinesByBox() and SelectLinesByPoint()"""
-
-        type = 0
-        for feature in (('point', wxvdigit.GV_POINT),
-                        ('line', wxvdigit.GV_LINE),
-                        ('centroid', wxvdigit.GV_CENTROID),
-                        ('boundary', wxvdigit.GV_BOUNDARY)):
-            if UserSettings.Get(group='vdigit', key='selectType',
-                                subkey=[feature[0], 'enabled']) is True:
-                type |= feature[1]
-
-        return type
-
-    def SelectLinesFromBackgroundMap(self, pos1, pos2):
-        """!Select features from background map
-
-        @param pos1,pos2 bounding box
-        """
-        bgmap = str(UserSettings.Get(group='vdigit', key='bgmap', subkey='value',
-                                     internal=True))
-        
-        if bgmap == '':
-            Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): []")
-            return []
-
-        x1, y1 = pos1
-        x2, y2 = pos2
-        ret = gcmd.RunCommand('v.edit',
-                              parent = self,
-                              quiet = True,
-                              read = True,
-                              map = bgmap,
-                              tool = 'select',
-                              bbox = '%f,%f,%f,%f' % (x1, y1, x2, y2))
-
-        if not ret:
-            x, y = pos1
-            ret = gcmd.RunCommand('v.edit',
-                                  parent = self,
-                                  quiet = True,
-                                  read = True,
-                                  map = bgmap,
-                                  tool = 'select',
-                                  coords = '%f,%f' % (x, y),
-                                  thresh = self.driver.GetThreshold(type='selectThresh'))
-        
-        if not ret:
-            return []
-        
-        output = ret.splitlines()[0] # first line
-        ids = output.split(',') 
-        ids = map(int, ids) # str -> int
-        
-        Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): %s" % \
-                      ",".join(["%d" % v for v in ids]))
-        
-        return ids
-
-class VDigit(AbstractDigit):
-    """!Prototype of digitization class based on v.digit
-    reimplementation (wxWidgets C/C++)
-    """
+class VDigit(IVDigit):
     def __init__(self, mapwindow):
-        """!VDigit constructor
+        """!Base class of vector digitizer
         
-        @param mapwindow reference to mapwindow (MapFrame) instance
+        @param mapwindow reference to mapwindow (mapdisp_window.BufferedWindow) instance
         """
-        AbstractDigit.__init__(self, mapwindow)
+        IVDigit.__init__(self, mapwindow)
         
-        if not mapwindow.parent.IsStandalone():
-            self.log = mapwindow.parent.GetLayerManager().goutput.cmd_stderr
-        else:
-            self.log = sys.stderr
-        
-        self.toolbar = mapwindow.parent.toolbars['vdigit']
-        
-        try:
-            self.digit = wxvdigit.Digit(self.driver.GetDevice(),
-                                        mapwindow)
-        except (ImportError, NameError, TypeError), e:
-            # print traceback
-            traceback.print_exc(file = self.log)
-            self.digit = None
-        self.UpdateSettings()
-        
-    def __del__(self):
-        del self.digit
-        
-    def AddPoint (self, map, point, x, y, z=None):
-        """!Add new point/centroid
-
-        @param map   map name (unused, for compatability with VEdit)
-        @param point feature type (if true point otherwise centroid)
-        @param x,y,z coordinates
+class VDigitSettingsDialog(wx.Dialog):
+    def __init__(self, parent, title, style = wx.DEFAULT_DIALOG_STYLE):
+        """!Standard settings dialog for digitization purposes
         """
-        if UserSettings.Get(group='vdigit', key="categoryMode", subkey='selection') == 2:
-            layer = -1 # -> no category
-            cat   = -1
-        else:
-            layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
-            cat   = self.SetCategory()
-            
-        if point:
-            type = wxvdigit.GV_POINT 
-        else:
-            type = wxvdigit.GV_CENTROID 
-
-        snap, thresh = self.__getSnapThreshold()
-
-        bgmap = str(UserSettings.Get(group='vdigit', key="bgmap",
-                                     subkey='value', internal=True))
-        if z:
-            ret = self.digit.AddLine(type, [x, y, z], layer, cat,
-                                     bgmap, snap, thresh)
-        else:
-            ret = self.digit.AddLine(type, [x, y], layer, cat,
-                                     bgmap, snap, thresh)
-        self.toolbar.EnableUndo()
-
-        return ret
+        wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, title = title, style = style)
         
-    def AddLine (self, map, line, coords):
-        """!Add line/boundary
-
-        @param map    map name (unused, for compatability with VEdit)
-        @param line   feature type (if True line, otherwise boundary)
-        @param coords list of coordinates
-        """
-        if len(coords) < 2:
-            return
-        
-        if UserSettings.Get(group='vdigit', key="categoryMode", subkey='selection') == 2:
-            layer = -1 # -> no category
-            cat   = -1
-        else:
-            layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
-            cat   = self.SetCategory()
-        
-        if line:
-            type = wxvdigit.GV_LINE
-        else:
-            type = wxvdigit.GV_BOUNDARY
-        
-        listCoords = []
-        for c in coords:
-            for x in c:
-                listCoords.append(x)
-        
-        snap, thresh = self.__getSnapThreshold()
-        
-        bgmap = str(UserSettings.Get(group='vdigit', key="bgmap",
-                                     subkey='value', internal=True))
-        
-        ret = self.digit.AddLine(type, listCoords, layer, cat,
-                                 bgmap, snap, thresh)
-
-        self.toolbar.EnableUndo()
-        
-        return ret
-    
-    def DeleteSelectedLines(self):
-        """!Delete selected features
-
-        @return number of deleted lines
-        """
-        nlines = self.digit.DeleteLines(UserSettings.Get(group='vdigit', key='delRecord', subkey='enabled'))
-        
-        if nlines > 0:
-            self.toolbar.EnableUndo()
-            
-        return nlines
-
-    def MoveSelectedLines(self, move):
-        """!Move selected features
-
-        @param move direction (x, y)
-        """
-        snap, thresh = self.__getSnapThreshold()
-        
-        bgmap = str(UserSettings.Get(group='vdigit', key="bgmap",
-                                     subkey='value', internal=True))
-        
-        try:
-            nlines = self.digit.MoveLines(move[0], move[1], 0.0, # TODO 3D
-                                          bgmap, snap, thresh)
-        except SystemExit:
-            pass
-        
-        if nlines > 0:
-            self.toolbar.EnableUndo()
-        
-        return nlines
-
-    def MoveSelectedVertex(self, coords, move):
-        """!Move selected vertex of the line
-
-        @param coords click coordinates
-        @param move   X,Y direction
-
-        @return id of new feature
-        @return 0 vertex not moved (not found, line is not selected)
-        """
-        snap, thresh = self.__getSnapThreshold()
-
-        bgmap = str(UserSettings.Get(group='vdigit', key="bgmap",
-                                     subkey='value', internal=True))
-        
-        moved = self.digit.MoveVertex(coords[0], coords[1], 0.0, # TODO 3D
-                                      move[0], move[1], 0.0,
-                                      bgmap, snap,
-                                      self.driver.GetThreshold(type='selectThresh'), thresh)
-
-        if moved:
-            self.toolbar.EnableUndo()
-
-        return moved
-
-    def AddVertex(self, coords):
-        """!Add new vertex to the selected line/boundary on position 'coords'
-
-        @param coords coordinates to add vertex
-
-        @return id of new feature
-        @return 0 nothing changed
-        @return -1 on failure
-        """
-        added = self.digit.ModifyLineVertex(1, coords[0], coords[1], 0.0, # TODO 3D
-                                            self.driver.GetThreshold(type='selectThresh'))
-
-        if added > 0:
-            self.toolbar.EnableUndo()
-
-        return added
-
-    def RemoveVertex(self, coords):
-        """!Remove vertex from the selected line/boundary on position 'coords'
-
-        @param coords coordinates to remove vertex
-
-        @return id of new feature
-        @return 0 nothing changed
-        @return -1 on failure
-        """
-        deleted = self.digit.ModifyLineVertex(0, coords[0], coords[1], 0.0, # TODO 3D
-                                              self.driver.GetThreshold(type='selectThresh'))
-
-        if deleted > 0:
-            self.toolbar.EnableUndo()
-
-        return deleted
-
-
-    def SplitLine(self, coords):
-        """!Split selected line/boundary on position 'coords'
-
-        @param coords coordinates to split line
-
-        @return 1 line modified
-        @return 0 nothing changed
-        @return -1 error
-        """
-        ret = self.digit.SplitLine(coords[0], coords[1], 0.0, # TODO 3D
-                                   self.driver.GetThreshold('selectThresh'))
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def EditLine(self, line, coords):
-        """!Edit existing line/boundary
-
-        @param line id of line to be modified
-        @param coords list of coordinates of modified line
-
-        @return feature id of new line
-        @return -1 on error
-        """
-        try:
-            lineid = line[0]
-        except:
-            lineid = -1
-
-        if len(coords) < 2:
-            self.DeleteSelectedLines()
-            return 0
-            
-        listCoords = []
-        for c in coords:
-            for x in c:
-                listCoords.append(x)
-
-        snap, thresh = self.__getSnapThreshold()
-        
-        bgmap = str(UserSettings.Get(group='vdigit', key="bgmap",
-                                     subkey='value', internal=True))
-        
-        try:
-            ret = self.digit.RewriteLine(lineid, listCoords,
-                                         bgmap, snap, thresh)
-        except SystemExit:
-            pass
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def FlipLine(self):
-        """!Flip selected lines/boundaries
-
-        @return number of modified lines
-        @return -1 on error
-        """
-        ret = self.digit.FlipLines()
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def MergeLine(self):
-        """!Merge selected lines/boundaries
-
-        @return number of modified lines
-        @return -1 on error
-        """
-        ret = self.digit.MergeLines()
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def BreakLine(self):
-        """!Break selected lines/boundaries
-
-        @return number of modified lines
-        @return -1 on error
-        """
-        ret = self.digit.BreakLines()
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def SnapLine(self):
-        """!Snap selected lines/boundaries
-
-        @return on success
-        @return -1 on error
-        """
-        snap, thresh = self.__getSnapThreshold()
-        ret = self.digit.SnapLines(thresh)
-        
-        if ret == 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def ConnectLine(self):
-        """!Connect selected lines/boundaries
-
-        @return 1 lines connected
-        @return 0 lines not connected
-        @return -1 on error
-        """
-        snap, thresh = self.__getSnapThreshold()
-        ret = self.digit.ConnectLines(thresh)
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-        
-    def CopyLine(self, ids=[]):
-        """!Copy features from (background) vector map
-
-        @param ids list of line ids to be copied
-
-        @return number of copied features
-        @return -1 on error
-        """
-        bgmap = str(UserSettings.Get(group='vdigit', key='bgmap',
-                                     subkey='value', internal=True))
-        
-        if len(bgmap) > 0:
-            ret = self.digit.CopyLines(ids, bgmap)
-        else:
-            ret = self.digit.CopyLines(ids, None)
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def CopyCats(self, fromId, toId, copyAttrb=False):
-        """!Copy given categories to objects with id listed in ids
-
-        @param cats ids of 'from' feature
-        @param ids  ids of 'to' feature(s)
-
-        @return number of modified features
-        @return -1 on error
-        """
-        if len(fromId) == 0 or len(toId) == 0:
-            return 0
-        
-        ret = self.digit.CopyCats(fromId, toId, copyAttrb)
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def SelectLinesByQuery(self, pos1, pos2):
-        """!Select features by query
-
-        @param pos1, pos2 bounding box definition
-        """
-        thresh = self.SelectLinesByQueryThresh()
-        
-        w, n = pos1
-        e, s = pos2
-
-        query = wxvdigit.QUERY_UNKNOWN
-        if UserSettings.Get(group='vdigit', key='query', subkey='selection') == 0:
-            query = wxvdigit.QUERY_LENGTH
-        else:
-            query = wxvdigit.QUERY_DANGLE
-
-        type = wxvdigit.GV_POINTS | wxvdigit.GV_LINES # TODO: 3D
-        
-        ids = self.digit.SelectLinesByQuery(w, n, 0.0, e, s, 1000.0,
-                                            UserSettings.Get(group='vdigit', key='query', subkey='box'),
-                                            query, type, thresh)
-
-        Debug.msg(4, "VDigit.SelectLinesByQuery(): %s" % \
-                      ",".join(["%d" % v for v in ids]))
-        
-        return ids
-
-    def GetLineCats(self, line=-1):
-        """!Get layer/category pairs from given (selected) line
-        
-        @param line feature id (-1 for first selected line)
-        """
-        return dict(self.digit.GetLineCats(line))
-
-    def GetLineLength(self, line):
-        """!Get line length
-
-        @param line feature id
-
-        @return line length
-        @return -1 on error
-        """
-        return self.digit.GetLineLength(line)
-
-    def GetAreaSize(self, centroid):
-        """!Get area size
-
-        @param centroid centroid id
-
-        @return area size
-        @return -1 on error
-        """
-        return self.digit.GetAreaSize(centroid)
-        
-    def GetAreaPerimeter(self, centroid):
-        """!Get area perimeter
-
-        @param centroid centroid id
-
-        @return area size
-        @return -1 on error
-        """
-        return self.digit.GetAreaPerimeter(centroid)
-
-    def SetLineCats(self, line, layer, cats, add=True):
-        """!Set categories for given line and layer
-
-        @param line feature id
-        @param layer layer number (-1 for first selected line)
-        @param cats list of categories
-        @param add if True to add, otherwise do delete categories
-
-        @return new feature id (feature need to be rewritten)
-        @return -1 on error
-        """
-        ret = self.digit.SetLineCats(line, layer, cats, add)
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def GetLayers(self):
-        """!Get list of layers"""
-        return self.digit.GetLayers()
-
-    def TypeConvForSelectedLines(self):
-        """!Feature type conversion for selected objects.
-
-        Supported conversions:
-         - point <-> centroid
-         - line <-> boundary
-
-        @return number of modified features
-        @return -1 on error
-        """
-        ret = self.digit.TypeConvLines()
-
-        if ret > 0:
-            self.toolbar.EnableUndo()
-
-        return ret
-
-    def Undo(self, level=-1):
-        """!Undo action
-
-        @param level levels to undo (0 to revert all)
-
-        @return id of current changeset
-        """
-        try:
-            ret = self.digit.Undo(level)
-        except SystemExit:
-            ret = -2
-
-        if ret == -2:
-            raise gcmd.GException(_("Undo failed, data corrupted."))
-
-        self.mapWindow.UpdateMap(render=False)
-        
-        if ret < 0: # disable undo tool
-            self.toolbar.EnableUndo(False)
-
-    def GetUndoLevel(self):
-        """!Get undo level (number of active changesets)
-        
-        Note: Changesets starts wiht 0
-        """
-        if not self.digit:
-            return -1
-        
-        return self.digit.GetUndoLevel()
-
-    def UpdateSettings(self):
-        """!Update digit settigs"""
-        if not self.digit:
-            return
-        
-        self.digit.UpdateSettings(UserSettings.Get(group='vdigit', key='breakLines',
-                                                   subkey='enabled'),
-                                  UserSettings.Get(group='vdigit', key='addCentroid',
-                                                   subkey='enabled'),
-                                  UserSettings.Get(group='vdigit', key='catBoundary',
-                                                   subkey='enabled'))
-        
-    def ZBulkLines(self, pos1, pos2, start, step):
-        """!Z-bulk labeling
-
-        @param pos1 reference line (start point)
-        @param pos1 reference line (end point)
-        @param start starting value
-        @param step step value
-
-        @return number of modified lines
-        @return -1 on error
-        """
-        ret = self.digit.ZBulkLabeling(pos1[0], pos1[1], pos2[0], pos2[1],
-                                       start, step)
-        
-        if ret > 0:
-            self.toolbar.EnableUndo()
-        
-        return ret
-    
-    def __getSnapThreshold(self):
-        """!Get snap mode and threshold value
-
-        @return (snap, thresh)
-        """
-        thresh = self.driver.GetThreshold()
-
-        if thresh > 0.0:
-            if UserSettings.Get(group='vdigit', key='snapToVertex', subkey='enabled') is True:
-                snap = wxvdigit.SNAPVERTEX
-            else:
-                snap = wxvdigit.SNAP
-        else:
-            snap = wxvdigit.NO_SNAP
-
-        return (snap, thresh)
-
-class AbstractDisplayDriver:
-    """!Abstract classs for display driver"""
-    def __init__(self, parent, mapwindow):
-        """!Initialization
-
-        @param parent
-        @param mapwindow reference to mapwindow (MFrame)
-        """
-        self.parent      = parent
-        self.mapwindow   = mapwindow
-        
-        self.ids         = {}   # dict[g6id] = [pdcId]
-        self.selected    = []   # list of selected objects (grassId!)
-
-    def GetThreshold(self, type='snapping', value=None, units=None):
-        """!Return threshold in map units
-
-        @param value threshold to be set up
-        @param units units (map, screen)
-        """
-        if value is None:
-            value = UserSettings.Get(group='vdigit', key=type, subkey='value')
-
-        if units is None:
-            units = UserSettings.Get(group='vdigit', key=type, subkey='units')
-
-        reg = self.mapwindow.Map.region
-        if value < 0:
-            value = (reg['nsres'] + reg['ewres']) / 2.
-        
-        if units == "screen pixels":
-            # pixel -> cell
-            if reg['nsres'] > reg['ewres']:
-                res = reg['nsres']
-            else:
-                res = reg['ewres']
-
-            threshold = value * res
-        else:
-            threshold = value
-
-        Debug.msg(4, "AbstractDisplayDriver.GetThreshold(): type=%s, thresh=%f" % (type, threshold))
-        
-        return threshold
-
-class CDisplayDriver(AbstractDisplayDriver):
-    """
-    Display driver using grass6_wxdriver module
-    """
-    def __init__(self, parent, mapwindow):
-        """!Initialization
-
-        @param parent
-        @param mapwindow reference to mapwindow (MFrame)
-        """
-        AbstractDisplayDriver.__init__(self, parent, mapwindow)
-
-        self.mapWindow = mapwindow
-
-        if not self.mapwindow.parent.IsStandalone():
-            logerr = self.mapwindow.parent.GetLayerManager().goutput.cmd_stderr
-        else:
-            logerr = None
-
-        # initialize wx display driver
-        try:
-            self.__display = wxvdigit.DisplayDriver(mapwindow.pdcVector,
-                                                    mapwindow.pdcTmp,
-                                                    logerr)
-        except:
-            self.__display = None
-            
-        self.UpdateSettings()
-
-    def GetDevice(self):
-        """!Get device"""
-        return self.__display
-    
-    def SetDevice(self, pdc):
-        """!Set device for driver
-
-        @param pdc wx.PseudoDC instance
-        """
-        if self.__display:
-            self.__display.SetDevice(pdc)
-            
-    def Reset(self, map):
-        """!Reset map
-
-        Open or close the vector map by driver.
-
-        @param map map name or None to close the map
-
-        @return 0 on success (close map)
-        @return topo level on success (open map)
-        @return non-zero (close map)
-        @return -1 on error (open map)
-        """
-        if map:
-            name, mapset = map.split('@')
-            try:
-                ret = self.__display.OpenMap(str(name), str(mapset), True)
-            except SystemExit:
-                ret = -1
-        else:
-            ret = self.__display.CloseMap()
-
-        return ret
-    
-    def ReloadMap(self):
-        """!Reload map (close and re-open).
-
-        Needed for v.edit, TODO: get rid of that..."""
-        
-        Debug.msg(4, "CDisplayDriver.ReloadMap():")
-        self.__display.ReloadMap()
-
-    def DrawMap(self):
-        """!Draw vector map layer content
-
-        @return wx.Image instance
-        """
-        if not self.__display:
-            return 0
-        
-        nlines = self.__display.DrawMap(True) # force
-        Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d" % nlines)
-
-        return nlines
-
-    def SelectLinesByBox(self, begin, end, type=0, drawSeg=False):
-        """!Select vector features by given bounding box.
-
-        If type is given, only vector features of given type are selected.
-
-        @param begin,end bounding box definition
-        @param type      select only objects of given type
-        """
-        x1, y1 = begin
-        x2, y2 = end
-
-        inBox = UserSettings.Get(group='vdigit', key='selectInside', subkey='enabled')
-        
-        nselected = self.__display.SelectLinesByBox(x1, y1, -1.0 * wxvdigit.PORT_DOUBLE_MAX,
-                                                    x2, y2, wxvdigit.PORT_DOUBLE_MAX,
-                                                    type, inBox, drawSeg)
-        
-        Debug.msg(4, "CDisplayDriver.SelectLinesByBox(): selected=%d" % \
-                      nselected)
-        
-        return nselected
-
-    def SelectLineByPoint(self, point, type=0):
-        """!Select vector feature by coordinates of click point (in given threshold).
-
-        If type is given, only vector features of given type are selected.
-
-        @param point click coordinates (bounding box given by threshold)
-        @param type  select only objects of given type
-        """
-        pointOnLine = self.__display.SelectLineByPoint(point[0], point[1], 0.0,
-                                                       self.GetThreshold(type='selectThresh'),
-                                                       type, 0); # without_z
-
-        if len(pointOnLine) > 0:
-            Debug.msg(4, "CDisplayDriver.SelectLineByPoint(): pointOnLine=%f,%f" % \
-                          (pointOnLine[0], pointOnLine[1]))
-            return pointOnLine
-        else:
-            Debug.msg(4, "CDisplayDriver.SelectLineByPoint(): no line found")
-            return None
-        
-    def GetSelected(self, grassId=True):
-        """!Return ids of selected vector features
-        
-        @param grassId if grassId is True returns GRASS ids, otherwise
-        internal ids of objects drawn in PseudoDC"""
-        if not self.__display:
-            return list()
-        
-        if grassId:
-            selected = self.__display.GetSelected(True)
-        else:
-            selected = self.__display.GetSelected(False)
-            
-        Debug.msg(4, "CDisplayDriver.GetSelected(): grassId=%d, ids=%s" % \
-                      (grassId, (",".join(["%d" % v for v in selected]))))
-            
-        return selected
-
-    def GetSelectedCoord(self):
-        """!Return ids of selected vector features and their coordinates"""
-        return dict(self.__display.GetSelectedCoord())
-        
-    def GetRegionSelected(self):
-        """!Get minimal region extent of selected features (ids/cats)"""
-        return self.__display.GetRegionSelected()
-    
-    def GetDuplicates(self):
-        """!Return ids of (selected) duplicated vector features
-        """
-        # -> id : (list of ids)
-        dupl = dict(self.__display.GetDuplicates())
-
-        # -> id : ((id, cat), ...)
-        dupl_full = {}
-        for key in dupl.keys():
-            dupl_full[key] = []
-            for id in dupl[key]:
-                catStr = ''
-                
-                cats = self.parent.GetLineCats(line=id)
-                
-                for layer in cats.keys():
-                    if len(cats[layer]) > 0:
-                        catStr = "%d: (" % layer
-                        for cat in cats[layer]:
-                            catStr += "%d," % cat
-                        catStr = catStr.rstrip(',')
-                        catStr += ')'
-                
-                dupl_full[key].append([id, catStr])
-
-        return dupl_full
-
-    def GetSelectedVertex(self, coords):
-        """!Get PseudoDC id(s) of vertex (of selected line)
-        on position 'coords'
-
-        @param coords click position
-        """
-        x, y = coords
-
-        id = self.__display.GetSelectedVertex(x, y, self.GetThreshold(type='selectThresh'))
-
-        Debug.msg(4, "CDisplayDriver.GetSelectedVertex(): id=%s" % \
-                      (",".join(["%d" % v for v in id])))
-
-        return id 
-
-    def SetSelected(self, id, field=-1):
-        """!Set selected vector features
-
-        @param id list of feature ids/categories to be selected
-        @param field field(layer) number, -1 for ids instead of cats
-        """
-        Debug.msg(4, "CDisplayDriver.SetSelected(): id=%s" % \
-                      id)
-
-        self.__display.SetSelected(id, field)
-
-    def UnSelect(self, id):
-        """!Unselect vector features
-
-        @param id list of feature id(s)
-        """
-
-        Debug.msg(4, "CDisplayDriver.UnSelect(): id=%s" % \
-                      ",".join(["%d" % v for v in id]))
-        
-        self.__display.UnSelect(id)
-
-    def UpdateRegion(self):
-        """!Set geographical region
-        
-        Needed for 'cell2pixel' conversion"""
-        if not self.__display:
-            return
-        
-        map = self.mapwindow.Map
-        reg = map.region
-        
-        self.__display.SetRegion(reg['n'],
-                                 reg['s'],
-                                 reg['e'],
-                                 reg['w'],
-                                 reg['nsres'],
-                                 reg['ewres'],
-                                 reg['center_easting'],
-                                 reg['center_northing'],
-                                 map.width, map.height)
-
-    def GetMapBoundingBox(self):
-        """!Return bounding box of given vector map layer
-
-        @return (w,s,b,e,n,t)
-        """
-
-        return self.__display.GetMapBoundingBox()
-
-    def Is3D(self):
-        """!Check if open vector map is 3D
-
-        @return True if 3D
-        @return False if not 3D"""
-        return self.__display.Is3D()
-    
-    def DrawSelected(self, draw=True):
-        """!Show/hide selected features"""
-        self.__display.DrawSelected(draw)
-        
-    def UpdateSettings(self, alpha=255):
-        """!Update display driver settings"""
-        # TODO map units
-
-        if not self.__display:
-            return
-        
-        color = {}
-        for symbol in ("highlight",
-                       "highlightDupl",
-                       "point",
-                       "line",
-                       "boundaryNo",
-                       "boundaryOne",
-                       "boundaryTwo",
-                       "centroidIn",
-                       "centroidOut",
-                       "centroidDup",
-                       "nodeOne",
-                       "nodeTwo",
-                       "vertex",
-                       "area",
-                       "direction"):
-            color[symbol] = wx.Color(UserSettings.Get(group='vdigit', key='symbol',
-                                                      subkey=[symbol, 'color'])[0],
-                                     UserSettings.Get(group='vdigit', key='symbol',
-                                                      subkey=[symbol, 'color'])[1],
-                                     UserSettings.Get(group='vdigit', key='symbol',
-                                                      subkey=[symbol, 'color'])[2]).GetRGB()
-
-        self.__display.UpdateSettings (color['highlight'],
-                                       UserSettings.Get(group='vdigit', key='checkForDupl',
-                                                        subkey='enabled'),
-                                       color['highlightDupl'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['point', 'enabled']),
-                                       color['point'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['line', 'enabled']),
-                                       color['line'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['boundaryNo', 'enabled']),
-                                       color['boundaryNo'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['boundaryOne', 'enabled']),
-                                       color['boundaryOne'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['boundaryTwo', 'enabled']),
-                                       color['boundaryTwo'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['centroidIn', 'enabled']),
-                                       color['centroidIn'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['centroidOut', 'enabled']),
-                                       color['centroidOut'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['centroidDup', 'enabled']),
-                                       color['centroidDup'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['nodeOne', 'enabled']),
-                                       color['nodeOne'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['nodeTwo', 'enabled']),
-                                       color['nodeTwo'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['vertex', 'enabled']),
-                                       color['vertex'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['area', 'enabled']),
-                                       color['area'],
-                                       UserSettings.Get(group='vdigit', key='symbol',
-                                                        subkey=['direction', 'enabled']),
-                                       color['direction'],
-                                       UserSettings.Get(group='vdigit', key='lineWidth',
-                                                        subkey='value'),
-                                       alpha)
-
-class VDigitSettingsDialog(wx.Dialog):
-    """
-    Standard settings dialog for digitization purposes
-    """
-    def __init__(self, parent, title, style=wx.DEFAULT_DIALOG_STYLE):
-        wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style)
-
         self.parent = parent # mapdisplay.BufferedWindow class instance
 
         # notebook
-        notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
-        self.__CreateSymbologyPage(notebook)
-        parent.digit.SetCategory() # update category number (next to use)
-        self.__CreateGeneralPage(notebook)
-        self.__CreateAttributesPage(notebook)
-        self.__CreateQueryPage(notebook)
+        notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
+        self._createSymbologyPage(notebook)
+        self.parent.digit.SetCategory()
+        self._createGeneralPage(notebook)
+        self._createAttributesPage(notebook)
+        self._createQueryPage(notebook)
 
         # buttons
         btnApply = wx.Button(self, wx.ID_APPLY)
@@ -1164,268 +98,265 @@
         btnSizer.Realize()
         
         mainSizer = wx.BoxSizer(wx.VERTICAL)
-        mainSizer.Add(item=notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
-        mainSizer.Add(item=btnSizer, proportion=0,
-                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+        mainSizer.Add(item = notebook, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
+        mainSizer.Add(item = btnSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
         
         self.Bind(wx.EVT_CLOSE, self.OnCancel)
         
         self.SetSizer(mainSizer)
         mainSizer.Fit(self)
 
-    def __CreateSymbologyPage(self, notebook):
-        """!Create notebook page concerning with symbology settings"""
+    def _createSymbologyPage(self, notebook):
+        """!Create notebook page concerning symbology settings"""
+        panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+        notebook.AddPage(page = panel, text = _("Symbology"))
 
-        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
-        notebook.AddPage(page=panel, text=_("Symbology"))
-
         sizer = wx.BoxSizer(wx.VERTICAL)
         
-        flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5)
+        flexSizer = wx.FlexGridSizer (cols = 3, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(0)
 
         self.symbology = {}
-        for label, key in self.__SymbologyData():
+        for label, key in self._symbologyData():
             textLabel = wx.StaticText(panel, wx.ID_ANY, label)
-            color = csel.ColourSelect(panel, id=wx.ID_ANY,
-                                      colour=UserSettings.Get(group='vdigit', key='symbol',
-                                                              subkey=[key, 'color']), size=globalvar.DIALOG_COLOR_SIZE)
-            isEnabled = UserSettings.Get(group='vdigit', key='symbol',
-                                         subkey=[key, 'enabled'])
+            color = csel.ColourSelect(panel, id = wx.ID_ANY,
+                                      colour = UserSettings.Get(group = 'vdigit', key = 'symbol',
+                                                              subkey = [key, 'color']), size = globalvar.DIALOG_COLOR_SIZE)
+            isEnabled = UserSettings.Get(group = 'vdigit', key = 'symbol',
+                                         subkey = [key, 'enabled'])
             if isEnabled is not None:
-                enabled = wx.CheckBox(panel, id=wx.ID_ANY, label="")
+                enabled = wx.CheckBox(panel, id = wx.ID_ANY, label = "")
                 enabled.SetValue(isEnabled)
                 self.symbology[key] = (enabled, color)
             else:
                 enabled = (1, 1)
                 self.symbology[key] = (None, color)
             
-            flexSizer.Add(textLabel, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-            flexSizer.Add(enabled, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-            flexSizer.Add(color, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
+            flexSizer.Add(textLabel, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+            flexSizer.Add(enabled, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+            flexSizer.Add(color, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
             color.SetName("GetColour")
         
-        sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=10)
+        sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 10)
         
         panel.SetSizer(sizer)
         
         return panel
 
-    def __CreateGeneralPage(self, notebook):
-        """!Create notebook page concerning with symbology settings"""
+    def _createGeneralPage(self, notebook):
+        """!Create notebook page concerning general settings"""
+        panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+        notebook.AddPage(page = panel, text = _("General"))
 
-        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
-        notebook.AddPage(page=panel, text=_("General"))
-
         border = wx.BoxSizer(wx.VERTICAL)
         
         #
         # display section
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Display"))
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Display"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5)
+        flexSizer = wx.FlexGridSizer (cols = 3, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(0)
         # line width
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Line width"))
-        self.lineWidthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(75, -1),
-                                          initial=UserSettings.Get(group='vdigit', key="lineWidth", subkey='value'),
-                                          min=1, max=1e6)
-        units = wx.StaticText(parent=panel, id=wx.ID_ANY, size=(115, -1),
-                              label=UserSettings.Get(group='vdigit', key="lineWidth", subkey='units'),
-                              style=wx.ALIGN_LEFT)
-        flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.lineWidthValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(units, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
-                      border=10)
+        text = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Line width"))
+        self.lineWidthValue = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (75, -1),
+                                          initial = UserSettings.Get(group = 'vdigit', key = "lineWidth", subkey = 'value'),
+                                          min = 1, max = 1e6)
+        units = wx.StaticText(parent = panel, id = wx.ID_ANY, size = (115, -1),
+                              label = UserSettings.Get(group = 'vdigit', key = "lineWidth", subkey = 'units'),
+                              style = wx.ALIGN_LEFT)
+        flexSizer.Add(text, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.lineWidthValue, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(units, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
+                      border = 10)
 
-        sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
+        sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+        border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
 
         #
         # snapping section
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Snapping"))
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Snapping"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5)
+        flexSizer = wx.FlexGridSizer(cols = 3, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(0)
 
         # snapping
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Snapping threshold"))
-        self.snappingValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(75, -1),
-                                         initial=UserSettings.Get(group='vdigit', key="snapping", subkey='value'),
-                                         min=-1, max=1e6)
+        text = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Snapping threshold"))
+        self.snappingValue = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (75, -1),
+                                         initial = UserSettings.Get(group = 'vdigit', key = "snapping", subkey = 'value'),
+                                         min = -1, max = 1e6)
         self.snappingValue.Bind(wx.EVT_SPINCTRL, self.OnChangeSnappingValue)
         self.snappingValue.Bind(wx.EVT_TEXT, self.OnChangeSnappingValue)
-        self.snappingUnit = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                      choices=["screen pixels", "map units"])
-        self.snappingUnit.SetStringSelection(UserSettings.Get(group='vdigit', key="snapping", subkey='units'))
+        self.snappingUnit = wx.Choice(parent = panel, id = wx.ID_ANY, size = (125, -1),
+                                      choices = ["screen pixels", "map units"])
+        self.snappingUnit.SetStringSelection(UserSettings.Get(group = 'vdigit', key = "snapping", subkey = 'units'))
         self.snappingUnit.Bind(wx.EVT_CHOICE, self.OnChangeSnappingUnits)
-        flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.snappingValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(self.snappingUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
+        flexSizer.Add(text, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.snappingValue, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(self.snappingUnit, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
 
         vertexSizer = wx.BoxSizer(wx.VERTICAL)
-        self.snapVertex = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                      label=_("Snap also to vertex"))
-        self.snapVertex.SetValue(UserSettings.Get(group='vdigit', key="snapToVertex", subkey='enabled'))
-        vertexSizer.Add(item=self.snapVertex, proportion=0, flag=wx.EXPAND)
+        self.snapVertex = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                      label = _("Snap also to vertex"))
+        self.snapVertex.SetValue(UserSettings.Get(group = 'vdigit', key = "snapToVertex", subkey = 'enabled'))
+        vertexSizer.Add(item = self.snapVertex, proportion = 0, flag = wx.EXPAND)
         self.mapUnits = self.parent.MapWindow.Map.GetProjInfo()['units']
-        self.snappingInfo = wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                          label=_("Snapping threshold is %(value).1f %(units)s") % \
-                                              {'value' : self.parent.digit.driver.GetThreshold(),
+        self.snappingInfo = wx.StaticText(parent = panel, id = wx.ID_ANY,
+                                          label = _("Snapping threshold is %(value).1f %(units)s") % \
+                                              {'value' : self.parent.digit.GetDisplay().GetThreshold(),
                                                'units' : self.mapUnits})
-        vertexSizer.Add(item=self.snappingInfo, proportion=0,
-                        flag=wx.ALL | wx.EXPAND, border=1)
+        vertexSizer.Add(item = self.snappingInfo, proportion = 0,
+                        flag = wx.ALL | wx.EXPAND, border = 1)
 
-        sizer.Add(item=flexSizer, proportion=1, flag=wx.EXPAND)
-        sizer.Add(item=vertexSizer, proportion=1, flag=wx.EXPAND)
-        border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
+        sizer.Add(item = flexSizer, proportion = 1, flag = wx.EXPAND)
+        sizer.Add(item = vertexSizer, proportion = 1, flag = wx.EXPAND)
+        border.Add(item = sizer, proportion = 0, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
 
         #
         # select box
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Select vector features"))
+        box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Select vector features"))
         # feature type
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
         inSizer = wx.BoxSizer(wx.HORIZONTAL)
         self.selectFeature = {}
         for feature in ('point', 'line',
                         'centroid', 'boundary'):
-            chkbox = wx.CheckBox(parent=panel, label=feature)
+            chkbox = wx.CheckBox(parent = panel, label = feature)
             self.selectFeature[feature] = chkbox.GetId()
-            chkbox.SetValue(UserSettings.Get(group='vdigit', key='selectType',
-                                             subkey=[feature, 'enabled']))
-            inSizer.Add(item=chkbox, proportion=0,
-                        flag=wx.EXPAND | wx.ALL, border=5)
-        sizer.Add(item=inSizer, proportion=0, flag=wx.EXPAND)
+            chkbox.SetValue(UserSettings.Get(group = 'vdigit', key = 'selectType',
+                                             subkey = [feature, 'enabled']))
+            inSizer.Add(item = chkbox, proportion = 0,
+                        flag = wx.EXPAND | wx.ALL, border = 5)
+        sizer.Add(item = inSizer, proportion = 0, flag = wx.EXPAND)
         # threshold
-        flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5)
+        flexSizer = wx.FlexGridSizer (cols = 3, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(0)
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select threshold"))
-        self.selectThreshValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(75, -1),
-                                             initial=UserSettings.Get(group='vdigit', key="selectThresh", subkey='value'),
-                                             min=1, max=1e6)
-        units = wx.StaticText(parent=panel, id=wx.ID_ANY, size=(115, -1),
-                              label=UserSettings.Get(group='vdigit', key="lineWidth", subkey='units'),
-                              style=wx.ALIGN_LEFT)
-        flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.selectThreshValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(units, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
-                      border=10)
+        text = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Select threshold"))
+        self.selectThreshValue = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (75, -1),
+                                             initial = UserSettings.Get(group = 'vdigit', key = "selectThresh", subkey = 'value'),
+                                             min = 1, max = 1e6)
+        units = wx.StaticText(parent = panel, id = wx.ID_ANY, size = (115, -1),
+                              label = UserSettings.Get(group = 'vdigit', key = "lineWidth", subkey = 'units'),
+                              style = wx.ALIGN_LEFT)
+        flexSizer.Add(text, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.selectThreshValue, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(units, proportion = 0, flag = wx.ALIGN_RIGHT | wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
+                      border = 10)
 
-        self.selectIn = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                    label=_("Select only features inside of selection bounding box"))
-        self.selectIn.SetValue(UserSettings.Get(group='vdigit', key="selectInside", subkey='enabled'))
+        self.selectIn = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                    label = _("Select only features inside of selection bounding box"))
+        self.selectIn.SetValue(UserSettings.Get(group = 'vdigit', key = "selectInside", subkey = 'enabled'))
         self.selectIn.SetToolTipString(_("By default are selected all features overlapping selection bounding box "))
         
-        self.checkForDupl = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                        label=_("Check for duplicates"))
-        self.checkForDupl.SetValue(UserSettings.Get(group='vdigit', key="checkForDupl", subkey='enabled'))
+        self.checkForDupl = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                        label = _("Check for duplicates"))
+        self.checkForDupl.SetValue(UserSettings.Get(group = 'vdigit', key = "checkForDupl", subkey = 'enabled'))
 
 
-        sizer.Add(item=flexSizer, proportion=0, flag=wx.EXPAND)
-        sizer.Add(item=self.selectIn, proportion=0, flag=wx.EXPAND | wx.ALL, border=1)
-        sizer.Add(item=self.checkForDupl, proportion=0, flag=wx.EXPAND | wx.ALL, border=1)        
-        border.Add(item=sizer, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
+        sizer.Add(item = flexSizer, proportion = 0, flag = wx.EXPAND)
+        sizer.Add(item = self.selectIn, proportion = 0, flag = wx.EXPAND | wx.ALL, border = 1)
+        sizer.Add(item = self.checkForDupl, proportion = 0, flag = wx.EXPAND | wx.ALL, border = 1)        
+        border.Add(item = sizer, proportion = 0, flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
 
         #
         # digitize lines box
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Digitize line features"))
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Digitize line features"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
 
-        self.intersect = wx.CheckBox(parent=panel, label=_("Break lines at intersection"))
-        self.intersect.SetValue(UserSettings.Get(group='vdigit', key='breakLines', subkey='enabled'))
+        self.intersect = wx.CheckBox(parent = panel, label = _("Break lines at intersection"))
+        self.intersect.SetValue(UserSettings.Get(group = 'vdigit', key = 'breakLines', subkey = 'enabled'))
         
-        sizer.Add(item=self.intersect, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+        sizer.Add(item = self.intersect, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
 
-        border.Add(item=sizer, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
+        border.Add(item = sizer, proportion = 0, flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
 
         #
         # save-on-exit box
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Save changes"))
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Save changes"))
         # save changes on exit?
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        self.save = wx.CheckBox(parent=panel, label=_("Save changes on exit"))
-        self.save.SetValue(UserSettings.Get(group='vdigit', key='saveOnExit', subkey='enabled'))
-        sizer.Add(item=self.save, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
+        self.save = wx.CheckBox(parent = panel, label = _("Save changes on exit"))
+        self.save.SetValue(UserSettings.Get(group = 'vdigit', key = 'saveOnExit', subkey = 'enabled'))
+        sizer.Add(item = self.save, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
+        border.Add(item = sizer, proportion = 0, flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
 
         panel.SetSizer(border)
         
         return panel
 
-    def __CreateQueryPage(self, notebook):
+    def _createQueryPage(self, notebook):
         """!Create notebook page for query tool"""
+        panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+        notebook.AddPage(page = panel, text = _("Query tool"))
 
-        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
-        notebook.AddPage(page=panel, text=_("Query tool"))
-
         border = wx.BoxSizer(wx.VERTICAL)
 
         #
         # query tool box
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Choose query tool"))
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Choose query tool"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
 
         LocUnits = self.parent.MapWindow.Map.GetProjInfo()['units']
 
-        self.queryBox = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_("Select by box"))
-        self.queryBox.SetValue(UserSettings.Get(group='vdigit', key="query", subkey='box'))
+        self.queryBox = wx.CheckBox(parent = panel, id = wx.ID_ANY, label = _("Select by box"))
+        self.queryBox.SetValue(UserSettings.Get(group = 'vdigit', key = "query", subkey = 'box'))
 
-        sizer.Add(item=self.queryBox, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+        sizer.Add(item = self.queryBox, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
         sizer.Add((0, 5))
 
         #
         # length
         #
-        self.queryLength = wx.RadioButton(parent=panel, id=wx.ID_ANY, label=_("length"))
+        self.queryLength = wx.RadioButton(parent = panel, id = wx.ID_ANY, label = _("length"))
         self.queryLength.Bind(wx.EVT_RADIOBUTTON, self.OnChangeQuery)
-        sizer.Add(item=self.queryLength, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        flexSizer = wx.FlexGridSizer (cols=4, hgap=5, vgap=5)
+        sizer.Add(item = self.queryLength, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
+        flexSizer = wx.FlexGridSizer (cols = 4, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(0)
-        txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select lines"))
-        self.queryLengthSL = wx.Choice (parent=panel, id=wx.ID_ANY, 
-                                        choices = [_("shorter than"), _("longer than")])
-        self.queryLengthSL.SetSelection(UserSettings.Get(group='vdigit', key="queryLength", subkey='than-selection'))
-        self.queryLengthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(100, -1),
-                                            initial=1,
-                                            min=0, max=1e6)
-        self.queryLengthValue.SetValue(UserSettings.Get(group='vdigit', key="queryLength", subkey='thresh'))
-        units = wx.StaticText(parent=panel, id=wx.ID_ANY, label="%s" % LocUnits)
-        flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.queryLengthSL, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(self.queryLengthValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(units, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        sizer.Add(item=flexSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+        txt = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Select lines"))
+        self.queryLengthSL = wx.Choice (parent = panel, id = wx.ID_ANY, 
+                                        choices  =  [_("shorter than"), _("longer than")])
+        self.queryLengthSL.SetSelection(UserSettings.Get(group = 'vdigit', key = "queryLength", subkey = 'than-selection'))
+        self.queryLengthValue = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (100, -1),
+                                            initial = 1,
+                                            min = 0, max = 1e6)
+        self.queryLengthValue.SetValue(UserSettings.Get(group = 'vdigit', key = "queryLength", subkey = 'thresh'))
+        units = wx.StaticText(parent = panel, id = wx.ID_ANY, label = "%s" % LocUnits)
+        flexSizer.Add(txt, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.queryLengthSL, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(self.queryLengthValue, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(units, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        sizer.Add(item = flexSizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
 
         #
         # dangle
         #
-        self.queryDangle = wx.RadioButton(parent=panel, id=wx.ID_ANY, label=_("dangle"))
+        self.queryDangle = wx.RadioButton(parent = panel, id = wx.ID_ANY, label = _("dangle"))
         self.queryDangle.Bind(wx.EVT_RADIOBUTTON, self.OnChangeQuery)
-        sizer.Add(item=self.queryDangle, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        flexSizer = wx.FlexGridSizer (cols=4, hgap=5, vgap=5)
+        sizer.Add(item = self.queryDangle, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
+        flexSizer = wx.FlexGridSizer (cols = 4, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(0)
-        txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select dangles"))
-        self.queryDangleSL = wx.Choice (parent=panel, id=wx.ID_ANY, 
+        txt = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Select dangles"))
+        self.queryDangleSL = wx.Choice (parent = panel, id = wx.ID_ANY, 
                                         choices = [_("shorter than"), _("longer than")])
-        self.queryDangleSL.SetSelection(UserSettings.Get(group='vdigit', key="queryDangle", subkey='than-selection'))
-        self.queryDangleValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(100, -1),
-                                       initial=1,
-                                       min=0, max=1e6)
-        self.queryDangleValue.SetValue(UserSettings.Get(group='vdigit', key="queryDangle", subkey='thresh'))
-        units = wx.StaticText(parent=panel, id=wx.ID_ANY, label="%s" % LocUnits)
-        flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.queryDangleSL, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(self.queryDangleValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(units, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        sizer.Add(item=flexSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+        self.queryDangleSL.SetSelection(UserSettings.Get(group = 'vdigit', key = "queryDangle", subkey = 'than-selection'))
+        self.queryDangleValue = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (100, -1),
+                                       initial = 1,
+                                       min = 0, max = 1e6)
+        self.queryDangleValue.SetValue(UserSettings.Get(group = 'vdigit', key = "queryDangle", subkey = 'thresh'))
+        units = wx.StaticText(parent = panel, id = wx.ID_ANY, label = "%s" % LocUnits)
+        flexSizer.Add(txt, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.queryDangleSL, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(self.queryDangleValue, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(units, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        sizer.Add(item = flexSizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
 
-        if UserSettings.Get(group='vdigit', key="query", subkey='selection') == 0:
+        if UserSettings.Get(group = 'vdigit', key = "query", subkey = 'selection') == 0:
             self.queryLength.SetValue(True)
         else:
             self.queryDangle.SetValue(True)
@@ -1433,99 +364,78 @@
         # enable & disable items
         self.OnChangeQuery(None)
 
-        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
+        border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
 
         panel.SetSizer(border)
         
         return panel
 
-    def __CreateAttributesPage(self, notebook):
-        """!Create notebook page for query tool"""
+    def _createAttributesPage(self, notebook):
+        """!Create notebook page for attributes"""
+        panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+        notebook.AddPage(page = panel, text = _("Attributes"))
 
-        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
-        notebook.AddPage(page=panel, text=_("Attributes"))
-
         border = wx.BoxSizer(wx.VERTICAL)
 
         #
         # add new record
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Digitize new feature"))
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Digitize new feature"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
 
         # checkbox
-        self.addRecord = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                     label=_("Add new record into table"))
-        self.addRecord.SetValue(UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled'))
-        sizer.Add(item=self.addRecord, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+        self.addRecord = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                     label = _("Add new record into table"))
+        self.addRecord.SetValue(UserSettings.Get(group = 'vdigit', key = "addRecord", subkey = 'enabled'))
+        sizer.Add(item = self.addRecord, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
         # settings
-        flexSizer = wx.FlexGridSizer(cols=2, hgap=3, vgap=3)
+        flexSizer = wx.FlexGridSizer(cols = 2, hgap = 3, vgap = 3)
         flexSizer.AddGrowableCol(0)
         settings = ((_("Layer"), 1), (_("Category"), 1), (_("Mode"), _("Next to use")))
         # layer
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Layer"))
-        self.layer = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1),
+        text = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Layer"))
+        self.layer = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (125, -1),
                                  min = 1, max = 1e3)
-        self.layer.SetValue(int(UserSettings.Get(group='vdigit', key="layer", subkey='value')))
-        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=self.layer, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        self.layer.SetValue(int(UserSettings.Get(group = 'vdigit', key = "layer", subkey = 'value')))
+        flexSizer.Add(item = text, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item = self.layer, proportion = 0,
+                      flag = wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
         # category number
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category number"))
-        self.category = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                    initial=UserSettings.Get(group='vdigit', key="category", subkey='value'),
-                                    min=-1e9, max=1e9) 
-        if UserSettings.Get(group='vdigit', key="categoryMode", subkey='selection') != 1:
+        text = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Category number"))
+        self.category = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (125, -1),
+                                    initial = UserSettings.Get(group = 'vdigit', key = "category", subkey = 'value'),
+                                    min = -1e9, max = 1e9) 
+        if UserSettings.Get(group = 'vdigit', key = "categoryMode", subkey = 'selection') != 1:
             self.category.Enable(False)
-        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=self.category, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item = text, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item = self.category, proportion = 0,
+                      flag = wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
         # category mode
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category mode"))
-        self.categoryMode = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                      choices=[_("Next to use"), _("Manual entry"), _("No category")])
-        self.categoryMode.SetSelection(UserSettings.Get(group='vdigit', key="categoryMode", subkey='selection'))
-        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=self.categoryMode, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        text = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Category mode"))
+        self.categoryMode = wx.Choice(parent = panel, id = wx.ID_ANY, size = (125, -1),
+                                      choices = [_("Next to use"), _("Manual entry"), _("No category")])
+        self.categoryMode.SetSelection(UserSettings.Get(group = 'vdigit', key = "categoryMode", subkey = 'selection'))
+        flexSizer.Add(item = text, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item = self.categoryMode, proportion = 0,
+                      flag = wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
 
-        sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0,
-                   flag=wx.ALL | wx.EXPAND, border=5)
+        sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+        border.Add(item = sizer, proportion = 0,
+                   flag = wx.ALL | wx.EXPAND, border = 5)
 
         #
-        # digitize new area
-        #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Digitize new area"))
-        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        
-        # add centroid
-        self.addCentroid = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                       label=_("Add centroid to left/right area"))
-        self.addCentroid.SetValue(UserSettings.Get(group='vdigit', key="addCentroid", subkey='enabled'))
-        sizer.Add(item=self.addCentroid, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        
-        # attach category to boundary
-        self.catBoundary = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                       label=_("Do not attach category to boundaries"))
-        self.catBoundary.SetValue(UserSettings.Get(group='vdigit', key="catBoundary", subkey='enabled'))
-        sizer.Add(item=self.catBoundary, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0,
-                   flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
-        
-        #
         # delete existing record
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Delete existing feature(s)"))
+        box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Delete existing feature(s)"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
         
         # checkbox
-        self.deleteRecord = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                        label=_("Delete record from table"))
-        self.deleteRecord.SetValue(UserSettings.Get(group='vdigit', key="delRecord", subkey='enabled'))
-        sizer.Add(item=self.deleteRecord, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0,
-                   flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
+        self.deleteRecord = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                        label = _("Delete record from table"))
+        self.deleteRecord.SetValue(UserSettings.Get(group = 'vdigit', key = "delRecord", subkey = 'enabled'))
+        sizer.Add(item = self.deleteRecord, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 1)
+        border.Add(item = sizer, proportion = 0,
+                   flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
 
         #
         # geometry attributes (currently only length and area are supported)
@@ -1533,7 +443,7 @@
         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY,
                               label = " %s " % _("Geometry attributes"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        gridSizer = wx.GridBagSizer(hgap=3, vgap=3)
+        gridSizer = wx.GridBagSizer(hgap = 3, vgap = 3)
         gridSizer.AddGrowableCol(0)
         self.geomAttrb = { 'length' : { 'label' : _('length') },
                            'area' : { 'label' : _('area') },
@@ -1544,7 +454,7 @@
             vectorName = digitToolbar.GetLayer().GetName()
         except AttributeError:
             vectorName = None # no vector selected for editing
-        layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
+        layer = UserSettings.Get(group = 'vdigit', key = "layer", subkey = 'value')
         mapLayer = self.parent.toolbars['vdigit'].GetLayer()
         tree = self.parent.tree
         item = tree.FindItemByData('maplayer', mapLayer)
@@ -1556,7 +466,7 @@
             ### self.deleteRecord.SetValue(UserSettings.Get(group='vdigit', key="delRecord", subkey='enabled'))
             check.Bind(wx.EVT_CHECKBOX, self.OnGeomAttrb)
             # column (only numeric)
-            column = gselect.ColumnSelect(parent = panel, size=(200, -1))
+            column = gselect.ColumnSelect(parent = panel, size = (200, -1))
             column.InsertColumns(vector = vectorName,
                                  layer = layer, excludeKey = True,
                                  type = ['integer', 'double precision'])
@@ -1566,7 +476,7 @@
             else:
                 choices = Units.GetUnitsList('length')
             win_units = wx.Choice(parent = panel, id = wx.ID_ANY,
-                                  choices = choices, size=(120, -1))
+                                  choices = choices, size = (120, -1))
             
             # default values
             check.SetValue(False)
@@ -1604,16 +514,16 @@
             row += 1
         
         note = '\n'.join(textwrap.wrap(_("Note: These settings are stored "
-                                         " in the workspace not in the vector digitizer "
+                                         "in the workspace not in the vector digitizer "
                                          "preferences."), 55))
         gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
                                            label = note),
-                      pos = (3, 0), span=(1, 3))
+                      pos = (3, 0), span = (1, 3))
                       
-        sizer.Add(item=gridSizer, proportion=1,
-                  flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0,
-                   flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
+        sizer.Add(item = gridSizer, proportion = 1,
+                  flag = wx.ALL | wx.EXPAND, border = 1)
+        border.Add(item = sizer, proportion = 0,
+                   flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
 
         # bindings
         self.Bind(wx.EVT_CHECKBOX, self.OnChangeAddRecord, self.addRecord)
@@ -1624,9 +534,8 @@
         
         return panel
 
-    def __SymbologyData(self):
-        """
-        Data for __CreateSymbologyPage()
+    def _symbologyData(self):
+        """!Data for _createSymbologyPage()
 
         label | checkbox | color
         """
@@ -1650,7 +559,8 @@
             (_("Direction"), "direction"),)
 
     def OnGeomAttrb(self, event):
-        """!Register geometry attributes (enable/disable)"""
+        """!Register geometry attributes (enable/disable)
+        """
         checked = event.IsChecked()
         id = event.GetId()
         key = None
@@ -1666,48 +576,51 @@
             column.Enable(False)
         
     def OnChangeCategoryMode(self, event):
-        """!Change category mode"""
-
+        """!Change category mode
+        """
         mode = event.GetSelection()
-        UserSettings.Set(group='vdigit', key="categoryMode", subkey='selection', value=mode)
+        UserSettings.Set(group = 'vdigit', key = "categoryMode", subkey = 'selection', value = mode)
         if mode == 1: # manual entry
             self.category.Enable(True)
         elif self.category.IsEnabled(): # disable
             self.category.Enable(False)
-
+        
         if mode == 2 and self.addRecord.IsChecked(): # no category
             self.addRecord.SetValue(False)
-
+        
         self.parent.digit.SetCategory()
-        self.category.SetValue(UserSettings.Get(group='vdigit', key='category', subkey='value'))
+        self.category.SetValue(UserSettings.Get(group = 'vdigit', key = 'category', subkey = 'value'))
 
     def OnChangeLayer(self, event):
-        """!Layer changed"""
+        """!Layer changed
+        """
         layer = event.GetInt()
         if layer > 0:
-            UserSettings.Set(group='vdigit', key='layer', subkey='value', value=layer)
+            UserSettings.Set(group = 'vdigit', key = 'layer', subkey = 'value', value = layer)
             self.parent.digit.SetCategory()
-            self.category.SetValue(UserSettings.Get(group='vdigit', key='category', subkey='value'))
+            self.category.SetValue(UserSettings.Get(group = 'vdigit', key = 'category', subkey = 'value'))
             
         event.Skip()
 
     def OnChangeAddRecord(self, event):
-        """!Checkbox 'Add new record' status changed"""
+        """!Checkbox 'Add new record' status changed
+        """
         self.category.SetValue(self.parent.digit.SetCategory())
             
     def OnChangeSnappingValue(self, event):
-        """!Change snapping value - update static text"""
+        """!Change snapping value - update static text
+        """
         value = self.snappingValue.GetValue()
         
         if value < 0:
             region = self.parent.MapWindow.Map.GetRegion()
             res = (region['nsres'] + region['ewres']) / 2.
-            threshold = self.parent.digit.driver.GetThreshold(value=res)
+            threshold = self.parent.digit.GetDisplay().GetThreshold(value = res)
         else:
             if self.snappingUnit.GetStringSelection() == "map units":
                 threshold = value
             else:
-                threshold = self.parent.digit.driver.GetThreshold(value=value)
+                threshold = self.parent.digit.GetDisplay().GetThreshold(value = value)
             
         if value == 0:
             self.snappingInfo.SetLabel(_("Snapping disabled"))
@@ -1724,10 +637,11 @@
         event.Skip()
 
     def OnChangeSnappingUnits(self, event):
-        """!Snapping units change -> update static text"""
+        """!Snapping units change -> update static text
+        """
         value = self.snappingValue.GetValue()
         units = self.snappingUnit.GetStringSelection()
-        threshold = self.parent.digit.driver.GetThreshold(value=value, units=units)
+        threshold = self.parent.digit.GetDisplay().GetThreshold(value = value, units = units)
 
         if units == "map units":
             self.snappingInfo.SetLabel(_("Snapping threshold is %(value).1f %(units)s") % 
@@ -1741,7 +655,8 @@
         event.Skip()
 
     def OnChangeQuery(self, event):
-        """!Change query"""
+        """!Change query
+        """
         if self.queryLength.GetValue():
             # length
             self.queryLengthSL.Enable(True)
@@ -1756,13 +671,14 @@
             self.queryDangleValue.Enable(True)
 
     def OnSave(self, event):
-        """!Button 'Save' clicked"""
+        """!Button 'Save' pressed
+        """
         self.UpdateSettings()
         self.parent.toolbars['vdigit'].settingsDialog = None
 
         fileSettings = {}
-        UserSettings.ReadSettingsFile(settings=fileSettings)
-        fileSettings['vdigit'] = UserSettings.Get(group='vdigit')
+        UserSettings.ReadSettingsFile(settings = fileSettings)
+        fileSettings['vdigit'] = UserSettings.Get(group = 'vdigit')
         
         file = UserSettings.SaveToFile(fileSettings)
         self.parent.GetLayerManager().goutput.WriteLog(_('Vector digitizer settings saved to file <%s>.') % file)
@@ -1772,11 +688,13 @@
         event.Skip()
         
     def OnApply(self, event):
-        """!Button 'Apply' clicked"""
+        """!Button 'Apply' pressed
+        """
         self.UpdateSettings()
 
     def OnCancel(self, event):
-        """!Button 'Cancel' clicked"""
+        """!Button 'Cancel' pressed
+        """
         self.parent.toolbars['vdigit'].settingsDialog = None
         self.Destroy()
 
@@ -1784,52 +702,47 @@
             event.Skip()
         
     def UpdateSettings(self):
-        """!Update UserSettings"""
-
+        """!Update digitizer settings
+        """
+        self.parent.GetLayerManager().WorkspaceChanged() # geometry attributes
         # symbology
         for key, (enabled, color) in self.symbology.iteritems():
             if enabled:
-                UserSettings.Set(group='vdigit', key='symbol',
-                                 subkey=[key, 'enabled'],
-                                 value=enabled.IsChecked())
-                UserSettings.Set(group='vdigit', key='symbol',
-                                 subkey=[key, 'color'],
-                                 value=tuple(color.GetColour()))
+                UserSettings.Set(group = 'vdigit', key = 'symbol',
+                                 subkey = [key, 'enabled'],
+                                 value = enabled.IsChecked())
+                UserSettings.Set(group = 'vdigit', key = 'symbol',
+                                 subkey = [key, 'color'],
+                                 value = tuple(color.GetColour()))
             else:
-                UserSettings.Set(group='vdigit', key='symbol',
-                                 subkey=[key, 'color'],
-                                 value=tuple(color.GetColour()))
+                UserSettings.Set(group = 'vdigit', key = 'symbol',
+                                 subkey = [key, 'color'],
+                                 value = tuple(color.GetColour()))
         # display
-        UserSettings.Set(group='vdigit', key="lineWidth", subkey='value',
-                         value=int(self.lineWidthValue.GetValue()))
+        UserSettings.Set(group = 'vdigit', key = "lineWidth", subkey = 'value',
+                         value = int(self.lineWidthValue.GetValue()))
 
         # snapping
-        UserSettings.Set(group='vdigit', key="snapping", subkey='value',
-                         value=int(self.snappingValue.GetValue()))
-        UserSettings.Set(group='vdigit', key="snapping", subkey='units',
-                         value=self.snappingUnit.GetStringSelection())
-        UserSettings.Set(group='vdigit', key="snapToVertex", subkey='enabled',
-                         value=self.snapVertex.IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "snapping", subkey = 'value',
+                         value = int(self.snappingValue.GetValue()))
+        UserSettings.Set(group = 'vdigit', key = "snapping", subkey = 'units',
+                         value = self.snappingUnit.GetStringSelection())
+        UserSettings.Set(group = 'vdigit', key = "snapToVertex", subkey = 'enabled',
+                         value = self.snapVertex.IsChecked())
         
         # digitize new feature
-        UserSettings.Set(group='vdigit', key="addRecord", subkey='enabled',
-                         value=self.addRecord.IsChecked())
-        UserSettings.Set(group='vdigit', key="layer", subkey='value',
-                         value=int(self.layer.GetValue()))
-        UserSettings.Set(group='vdigit', key="category", subkey='value',
-                         value=int(self.category.GetValue()))
-        UserSettings.Set(group='vdigit', key="categoryMode", subkey='selection',
-                         value=self.categoryMode.GetSelection())
+        UserSettings.Set(group = 'vdigit', key = "addRecord", subkey = 'enabled',
+                         value = self.addRecord.IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "layer", subkey = 'value',
+                         value = int(self.layer.GetValue()))
+        UserSettings.Set(group = 'vdigit', key = "category", subkey = 'value',
+                         value = int(self.category.GetValue()))
+        UserSettings.Set(group = 'vdigit', key = "categoryMode", subkey = 'selection',
+                         value = self.categoryMode.GetSelection())
 
-        # digitize new area
-        UserSettings.Set(group='vdigit', key="addCentroid", subkey='enabled',
-                         value=self.addCentroid.IsChecked())
-        UserSettings.Set(group='vdigit', key="catBoundary", subkey='enabled',
-                         value=self.catBoundary.IsChecked())
-        
         # delete existing feature
-        UserSettings.Set(group='vdigit', key="delRecord", subkey='enabled',
-                         value=self.deleteRecord.IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "delRecord", subkey = 'enabled',
+                         value = self.deleteRecord.IsChecked())
 
         # geometry attributes (workspace)
         mapLayer = self.parent.toolbars['vdigit'].GetLayer()
@@ -1855,52 +768,45 @@
                         tree.GetPyData(item)[0]['vdigit']['geomAttr'].has_key(key):
                     del tree.GetPyData(item)[0]['vdigit']['geomAttr'][key]
         
-        # snapping threshold
-        self.parent.digit.threshold = self.parent.digit.driver.GetThreshold()
-
         # query tool
         if self.queryLength.GetValue():
-            UserSettings.Set(group='vdigit', key="query", subkey='selection',
-                             value=0)
+            UserSettings.Set(group = 'vdigit', key = "query", subkey = 'selection',
+                             value = 0)
         else:
-            UserSettings.Set(group='vdigit', key="query", subkey='type',
-                             value=1)
-        UserSettings.Set(group='vdigit', key="query", subkey='box',
-                         value=self.queryBox.IsChecked())
-        UserSettings.Set(group='vdigit', key="queryLength", subkey='than-selection',
-                         value=self.queryLengthSL.GetSelection())
-        UserSettings.Set(group='vdigit', key="queryLength", subkey='thresh',
-                         value=int(self.queryLengthValue.GetValue()))
-        UserSettings.Set(group='vdigit', key="queryDangle", subkey='than-selection',
-                         value=self.queryDangleSL.GetSelection())
-        UserSettings.Set(group='vdigit', key="queryDangle", subkey='thresh',
-                         value=int(self.queryDangleValue.GetValue()))
+            UserSettings.Set(group = 'vdigit', key = "query", subkey = 'type',
+                             value = 1)
+        UserSettings.Set(group = 'vdigit', key = "query", subkey = 'box',
+                         value = self.queryBox.IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "queryLength", subkey = 'than-selection',
+                         value = self.queryLengthSL.GetSelection())
+        UserSettings.Set(group = 'vdigit', key = "queryLength", subkey = 'thresh',
+                         value = int(self.queryLengthValue.GetValue()))
+        UserSettings.Set(group = 'vdigit', key = "queryDangle", subkey = 'than-selection',
+                         value = self.queryDangleSL.GetSelection())
+        UserSettings.Set(group = 'vdigit', key = "queryDangle", subkey = 'thresh',
+                         value = int(self.queryDangleValue.GetValue()))
 
         # select features
         for feature in ('point', 'line',
                         'centroid', 'boundary'):
-            UserSettings.Set(group='vdigit', key='selectType',
-                             subkey=[feature, 'enabled'],
-                             value=self.FindWindowById(self.selectFeature[feature]).IsChecked())
-        UserSettings.Set(group='vdigit', key="selectThresh", subkey='value',
-                         value=int(self.selectThreshValue.GetValue()))
-        UserSettings.Set(group='vdigit', key="checkForDupl", subkey='enabled',
-                         value=self.checkForDupl.IsChecked())
-        UserSettings.Set(group='vdigit', key="selectInside", subkey='enabled',
-                         value=self.selectIn.IsChecked())
+            UserSettings.Set(group = 'vdigit', key = 'selectType',
+                             subkey = [feature, 'enabled'],
+                             value = self.FindWindowById(self.selectFeature[feature]).IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "selectThresh", subkey = 'value',
+                         value = int(self.selectThreshValue.GetValue()))
+        UserSettings.Set(group = 'vdigit', key = "checkForDupl", subkey = 'enabled',
+                         value = self.checkForDupl.IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "selectInside", subkey = 'enabled',
+                         value = self.selectIn.IsChecked())
 
         # on-exit
-        UserSettings.Set(group='vdigit', key="saveOnExit", subkey='enabled',
-                         value=self.save.IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "saveOnExit", subkey = 'enabled',
+                         value = self.save.IsChecked())
 
         # break lines
-        UserSettings.Set(group='vdigit', key="breakLines", subkey='enabled',
-                         value=self.intersect.IsChecked())
+        UserSettings.Set(group = 'vdigit', key = "breakLines", subkey = 'enabled',
+                         value = self.intersect.IsChecked())
         
-        # update driver settings
-        self.parent.digit.driver.UpdateSettings()
-
-        # update digit settings
         self.parent.digit.UpdateSettings()
         
         # redraw map if auto-rendering is enabled
@@ -1908,21 +814,19 @@
             self.parent.OnRender(None)
 
 class VDigitCategoryDialog(wx.Dialog, listmix.ColumnSorterMixin):
-    """
-    Dialog used to display/modify categories of vector objects
-    
-    @param parent
-    @param title dialog title
-    @param query {coordinates, qdist} - used by v.edit/v.what
-    @param cats  directory of lines (layer/categories) - used by vdigit
-    @param pos
-    @param style
-    """
     def __init__(self, parent, title,
-                 map, query=None, cats=None,
-                 pos=wx.DefaultPosition,
-                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
-
+                 map, query = None, cats = None,
+                 pos = wx.DefaultPosition,
+                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
+        """!Dialog used to display/modify categories of vector objects
+        
+        @param parent
+        @param title dialog title
+        @param query {coordinates, qdist} - used by v.edit/v.what
+        @param cats  directory of lines (layer/categories) - used by vdigit
+        @param pos
+        @param style
+        """
         # parent
         self.parent = parent # mapdisplay.BufferedWindow class instance
 
@@ -1934,7 +838,7 @@
         
         # do not display dialog if no line is found (-> self.cats)
         if cats is None:
-            if self.__GetCategories(query[0], query[1]) == 0 or not self.line:
+            if self._getCategories(query[0], query[1]) == 0 or not self.line:
                 Debug.msg(3, "VDigitCategoryDialog(): nothing found!")
         else:
             self.cats = cats
@@ -1949,15 +853,15 @@
         # make copy of cats (used for 'reload')
         self.cats_orig = copy.deepcopy(self.cats)
         
-        wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY, title=title,
-                          style=style, pos=pos)
+        wx.Dialog.__init__(self, parent = self.parent, id = wx.ID_ANY, title = title,
+                          style = style, pos = pos)
         
         # list of categories
-        box = wx.StaticBox(parent=self, id=wx.ID_ANY,
-                           label=" %s " % _("List of categories - right-click to delete"))
+        box = wx.StaticBox(parent = self, id = wx.ID_ANY,
+                           label = " %s " % _("List of categories - right-click to delete"))
         listSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        self.list = CategoryListCtrl(parent=self, id=wx.ID_ANY,
-                                     style=wx.LC_REPORT |
+        self.list = CategoryListCtrl(parent = self, id = wx.ID_ANY,
+                                     style = wx.LC_REPORT |
                                      wx.BORDER_NONE |
                                      wx.LC_SORT_ASCENDING |
                                      wx.LC_HRULES |
@@ -1966,10 +870,10 @@
         self.fid = self.cats.keys()[0]
         self.itemDataMap = self.list.Populate(self.cats[self.fid])
         listmix.ColumnSorterMixin.__init__(self, 2)
-        self.fidMulti = wx.Choice(parent=self, id=wx.ID_ANY,
-                                  size=(150, -1))
+        self.fidMulti = wx.Choice(parent = self, id = wx.ID_ANY,
+                                  size = (150, -1))
         self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
-        self.fidText = wx.StaticText(parent=self, id=wx.ID_ANY)
+        self.fidText = wx.StaticText(parent = self, id = wx.ID_ANY)
         if len(self.cats.keys()) == 1:
             self.fidMulti.Show(False)
             self.fidText.SetLabel(str(self.fid))
@@ -1981,44 +885,44 @@
             self.fidMulti.SetItems(choices)
             self.fidMulti.SetSelection(0)
         
-        listSizer.Add(item=self.list, proportion=1, flag=wx.EXPAND)
+        listSizer.Add(item = self.list, proportion = 1, flag = wx.EXPAND)
 
         # add new category
-        box = wx.StaticBox(parent=self, id=wx.ID_ANY,
-                           label=" %s " % _("Add new category"))
+        box = wx.StaticBox(parent = self, id = wx.ID_ANY,
+                           label = " %s " % _("Add new category"))
         addSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        flexSizer = wx.FlexGridSizer (cols=5, hgap=5, vgap=5)
+        flexSizer = wx.FlexGridSizer (cols = 5, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(3)
 
-        layerNewTxt = wx.StaticText(parent=self, id=wx.ID_ANY,
-                                 label="%s:" % _("Layer"))
-        self.layerNew = wx.Choice(parent=self, id=wx.ID_ANY, size=(75, -1),
-                                  choices=layers)
+        layerNewTxt = wx.StaticText(parent = self, id = wx.ID_ANY,
+                                 label = "%s:" % _("Layer"))
+        self.layerNew = wx.Choice(parent = self, id = wx.ID_ANY, size = (75, -1),
+                                  choices = layers)
         if len(layers) > 0:
             self.layerNew.SetSelection(0)
         
-        catNewTxt = wx.StaticText(parent=self, id=wx.ID_ANY,
-                               label="%s:" % _("Category"))
+        catNewTxt = wx.StaticText(parent = self, id = wx.ID_ANY,
+                               label = "%s:" % _("Category"))
 
         try:
             newCat = max(self.cats[self.fid][1]) + 1
         except KeyError:
             newCat = 1
-        self.catNew = wx.SpinCtrl(parent=self, id=wx.ID_ANY, size=(75, -1),
-                                  initial=newCat, min=0, max=1e9)
+        self.catNew = wx.SpinCtrl(parent = self, id = wx.ID_ANY, size = (75, -1),
+                                  initial = newCat, min = 0, max = 1e9)
         btnAddCat = wx.Button(self, wx.ID_ADD)
-        flexSizer.Add(item=layerNewTxt, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=self.layerNew, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=catNewTxt, proportion=0,
-                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
-                      border=10)
-        flexSizer.Add(item=self.catNew, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=btnAddCat, proportion=0,
-                      flag=wx.EXPAND | wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
-        addSizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
+        flexSizer.Add(item = layerNewTxt, proportion = 0,
+                      flag = wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item = self.layerNew, proportion = 0,
+                      flag = wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item = catNewTxt, proportion = 0,
+                      flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
+                      border = 10)
+        flexSizer.Add(item = self.catNew, proportion = 0,
+                      flag = wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item = btnAddCat, proportion = 0,
+                      flag = wx.EXPAND | wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
+        addSizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
 
         # buttons
         btnApply = wx.Button(self, wx.ID_APPLY)
@@ -2039,24 +943,24 @@
         btnSizer.Realize()
         
         mainSizer = wx.BoxSizer(wx.VERTICAL)
-        mainSizer.Add(item=listSizer, proportion=1,
-                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
-        mainSizer.Add(item=addSizer, proportion=0,
-                      flag=wx.EXPAND | wx.ALIGN_CENTER |
-                      wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
+        mainSizer.Add(item = listSizer, proportion = 1,
+                      flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
+        mainSizer.Add(item = addSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALIGN_CENTER |
+                      wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
         fidSizer = wx.BoxSizer(wx.HORIZONTAL)
-        fidSizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY,
-                                        label=_("Feature id:")),
-                     proportion=0, border=5,
-                     flag=wx.ALIGN_CENTER_VERTICAL)
-        fidSizer.Add(item=self.fidMulti, proportion=0,
-                     flag=wx.EXPAND | wx.ALL,  border=5)
-        fidSizer.Add(item=self.fidText, proportion=0,
-                     flag=wx.EXPAND | wx.ALL,  border=5)
-        mainSizer.Add(item=fidSizer, proportion=0,
-                      flag=wx.EXPAND | wx.ALL, border=5)
-        mainSizer.Add(item=btnSizer, proportion=0,
-                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+        fidSizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
+                                        label = _("Feature id:")),
+                     proportion = 0, border = 5,
+                     flag = wx.ALIGN_CENTER_VERTICAL)
+        fidSizer.Add(item = self.fidMulti, proportion = 0,
+                     flag = wx.EXPAND | wx.ALL,  border = 5)
+        fidSizer.Add(item = self.fidText, proportion = 0,
+                     flag = wx.EXPAND | wx.ALL,  border = 5)
+        mainSizer.Add(item = fidSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALL, border = 5)
+        mainSizer.Add(item = btnSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
         
         self.SetSizer(mainSizer)
         mainSizer.Fit(self)
@@ -2066,16 +970,12 @@
         self.SetMinSize(self.GetBestSize())
 
         # bindings
-        # buttons
-        #btnReload.Bind(wx.EVT_BUTTON, self.OnReload)
         btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
         btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
         btnAddCat.Bind(wx.EVT_BUTTON, self.OnAddCat)
         btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
                                      
         # list
-        # self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
-        # self.list.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
         self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightUp) #wxMSW
         self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) #wxGTK
         self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list)
@@ -2083,19 +983,23 @@
         self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
 
     def GetListCtrl(self):
-        """!Used by ColumnSorterMixin"""
+        """!Used by ColumnSorterMixin
+        """
         return self.list
 
     def OnColClick(self, event):
-        """!Click on column header (order by)"""
+        """!Click on column header (order by)
+        """
         event.Skip()
         
     def OnBeginEdit(self, event):
-        """!Editing of item started"""
+        """!Editing of item started
+        """
         event.Allow()
 
     def OnEndEdit(self, event):
-        """!Finish editing of item"""
+        """!Finish editing of item
+        """
         itemIndex = event.GetIndex()
         layerOld = int (self.list.GetItem(itemIndex, 0).GetText())
         catOld = int (self.list.GetItem(itemIndex, 1).GetText())
@@ -2127,7 +1031,8 @@
             return False
 
     def OnRightDown(self, event):
-        """!Mouse right button down"""
+        """!Mouse right button down
+        """
         x = event.GetX()
         y = event.GetY()
         item, flags = self.list.HitTest((x, y))
@@ -2139,14 +1044,15 @@
         event.Skip()
 
     def OnRightUp(self, event):
-        """!Mouse right button up"""
+        """!Mouse right button up
+        """
         if not hasattr(self, "popupID1"):
             self.popupID1 = wx.NewId()
             self.popupID2 = wx.NewId()
             self.popupID3 = wx.NewId()
-            self.Bind(wx.EVT_MENU, self.OnItemDelete,    id=self.popupID1)
-            self.Bind(wx.EVT_MENU, self.OnItemDeleteAll, id=self.popupID2)
-            self.Bind(wx.EVT_MENU, self.OnReload, id=self.popupID3)
+            self.Bind(wx.EVT_MENU, self.OnItemDelete,    id = self.popupID1)
+            self.Bind(wx.EVT_MENU, self.OnItemDeleteAll, id = self.popupID2)
+            self.Bind(wx.EVT_MENU, self.OnReload, id = self.popupID3)
 
         # generate popup-menu
         menu = wx.Menu()
@@ -2162,11 +1068,13 @@
         menu.Destroy()
 
     def OnItemSelected(self, event):
-        """!Item selected"""
+        """!Item selected
+        """
         event.Skip()
 
     def OnItemDelete(self, event):
-        """!Delete selected item(s) from the list (layer/category pair)"""
+        """!Delete selected item(s) from the list (layer/category pair)
+        """
         item = self.list.GetFirstSelected()
         while item != -1:
             layer = int (self.list.GetItem(item, 0).GetText())
@@ -2179,18 +1087,20 @@
         event.Skip()
         
     def OnItemDeleteAll(self, event):
-        """!Delete all items from the list"""
+        """!Delete all items from the list
+        """
         self.list.DeleteAllItems()
         self.cats[self.fid] = {}
 
         event.Skip()
 
     def OnFeature(self, event):
-        """!Feature id changed (on duplicates)"""
+        """!Feature id changed (on duplicates)
+        """
         self.fid = int(event.GetString())
         
         self.itemDataMap = self.list.Populate(self.cats[self.fid],
-                                              update=True)
+                                              update = True)
 
         try:
             newCat = max(self.cats[self.fid][1]) + 1
@@ -2201,12 +1111,12 @@
         
         event.Skip()
         
-    def __GetCategories(self, coords, qdist):
+    def _getCategories(self, coords, qdist):
         """!Get layer/category pairs for all available
         layers
 
-        Return True line found or False if not found"""
-        
+        Return True line found or False if not found
+        """
         ret = gcmd.RunCommand('v.what',
                               parent = self,
                               quiet = True,
@@ -2232,35 +1142,42 @@
         return True
 
     def OnReload(self, event):
-        """!Reload button pressed"""
+        """!Reload button pressed
+        """
         # restore original list
         self.cats = copy.deepcopy(self.cats_orig)
 
         # polulate list
         self.itemDataMap = self.list.Populate(self.cats[self.fid],
-                                              update=True)
+                                              update = True)
 
         event.Skip()
 
     def OnCancel(self, event):
-        """!Cancel button pressed"""
+        """!Cancel button pressed
+        """
         self.parent.parent.dialogs['category'] = None
         if self.parent.parent.digit:
-            self.parent.parent.digit.driver.SetSelected([])
-            self.parent.UpdateMap(render=False)
+            self.parent.parent.digit.GetDisplay().SetSelected([])
+            self.parent.UpdateMap(render = False)
         else:
             self.parent.parent.OnRender(None)
             
         self.Close()
 
     def OnApply(self, event):
-        """!Apply button pressed"""
+        """!Apply button pressed
+        """
         for fid in self.cats.keys():
             newfid = self.ApplyChanges(fid)
             if fid == self.fid:
                 self.fid = newfid
             
     def ApplyChanges(self, fid):
+        """!Apply changes 
+
+        @param fid feature id
+        """
         cats = self.cats[fid]
         cats_orig = self.cats_orig[fid]
 
@@ -2299,20 +1216,22 @@
                     
                     fid = newfid
                     if self.fid < 0:
-                        wx.MessageBox(parent=self, message=_("Unable to update vector map."),
-                                      caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
+                        wx.MessageBox(parent = self, message = _("Unable to update vector map."),
+                                      caption = _("Error"), style = wx.OK | wx.ICON_ERROR)
         
         self.cats_orig[fid] = copy.deepcopy(cats)
         
         return newfid
 
     def OnOK(self, event):
-        """!OK button pressed"""
+        """!OK button pressed
+        """
         self.OnApply(event)
         self.OnCancel(event)
 
     def OnAddCat(self, event):
-        """!Button 'Add' new category pressed"""
+        """!Button 'Add' new category pressed
+        """
         try:
             layer = int(self.layerNew.GetStringSelection())
             cat   = int(self.catNew.GetValue())
@@ -2336,7 +1255,7 @@
 
         # reload list
         self.itemDataMap = self.list.Populate(self.cats[self.fid],
-                                              update=True)
+                                              update = True)
 
         # update category number for add
         self.catNew.SetValue(cat + 1)
@@ -2346,13 +1265,14 @@
         return True
 
     def GetLine(self):
-        """!Get id of selected line of 'None' if no line is selected"""
+        """!Get id of selected line of 'None' if no line is selected
+        """
         return self.cats.keys()
 
-    def UpdateDialog(self, query=None, cats=None):
+    def UpdateDialog(self, query = None, cats = None):
         """!Update dialog
         
-        @param query {coordinates, distance} - v.edit/v.what
+        @param query {coordinates, distance} - v.what
         @param cats  directory layer/cats    - vdigit
         Return True if updated otherwise False
         """
@@ -2360,7 +1280,7 @@
         self.cats = {}
         # do not display dialog if no line is found (-> self.cats)
         if cats is None:
-            ret = self.__GetCategories(query[0], query[1])
+            ret = self._getCategories(query[0], query[1])
         else:
             self.cats = cats
             for line in cats.keys():
@@ -2377,7 +1297,7 @@
         # polulate list
         self.fid = self.cats.keys()[0]
         self.itemDataMap = self.list.Populate(self.cats[self.fid],
-                                              update=True)
+                                              update = True)
 
         try:
             newCat = max(self.cats[self.fid][1]) + 1
@@ -2405,11 +1325,9 @@
 class CategoryListCtrl(wx.ListCtrl,
                        listmix.ListCtrlAutoWidthMixin,
                        listmix.TextEditMixin):
-    """!List of layers/categories"""
-
-    def __init__(self, parent, id, pos=wx.DefaultPosition,
-                 size=wx.DefaultSize, style=0):
-        
+    def __init__(self, parent, id, pos = wx.DefaultPosition,
+                 size = wx.DefaultSize, style = 0):
+        """!List of layers/categories"""
         self.parent = parent
         
         wx.ListCtrl.__init__(self, parent, id, pos, size, style)
@@ -2417,9 +1335,9 @@
         listmix.ListCtrlAutoWidthMixin.__init__(self)
         listmix.TextEditMixin.__init__(self)
 
-    def Populate(self, cats, update=False):
-        """!Populate the list"""
-
+    def Populate(self, cats, update = False):
+        """!Populate the list
+        """
         itemData = {} # requested by sorter
 
         if not update:
@@ -2448,11 +1366,10 @@
         return itemData
 
 class VDigitZBulkDialog(wx.Dialog):
-    """
-    Dialog used for Z bulk-labeling tool
-    """
-    def __init__(self, parent, title, nselected, style=wx.DEFAULT_DIALOG_STYLE):
-        wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style)
+    def __init__(self, parent, title, nselected, style = wx.DEFAULT_DIALOG_STYLE):
+        """!Dialog used for Z bulk-labeling tool
+        """
+        wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, title = title, style = style)
 
         self.parent = parent # mapdisplay.BufferedWindow class instance
 
@@ -2460,35 +1377,35 @@
 
         border = wx.BoxSizer(wx.VERTICAL)
         
-        txt = wx.StaticText(parent=self,
-                            label=_("%d lines selected for z bulk-labeling") % nselected);
-        border.Add(item=txt, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
+        txt = wx.StaticText(parent = self,
+                            label = _("%d lines selected for z bulk-labeling") % nselected);
+        border.Add(item = txt, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
 
-        box   = wx.StaticBox (parent=self, id=wx.ID_ANY, label=" %s " % _("Set value"))
+        box   = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Set value"))
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
+        flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
         flexSizer.AddGrowableCol(0)
 
         # starting value
-        txt = wx.StaticText(parent=self,
-                            label=_("Starting value"));
-        self.value = wx.SpinCtrl(parent=self, id=wx.ID_ANY, size=(150, -1),
-                                 initial=0,
-                                 min=-1e6, max=1e6)
-        flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.value, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        txt = wx.StaticText(parent = self,
+                            label = _("Starting value"));
+        self.value = wx.SpinCtrl(parent = self, id = wx.ID_ANY, size = (150, -1),
+                                 initial = 0,
+                                 min = -1e6, max = 1e6)
+        flexSizer.Add(txt, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.value, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
 
         # step
-        txt = wx.StaticText(parent=self,
-                            label=_("Step"))
-        self.step  = wx.SpinCtrl(parent=self, id=wx.ID_ANY, size=(150, -1),
-                                 initial=0,
-                                 min=0, max=1e6)
-        flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.step, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        txt = wx.StaticText(parent = self,
+                            label = _("Step"))
+        self.step  = wx.SpinCtrl(parent = self, id = wx.ID_ANY, size = (150, -1),
+                                 initial = 0,
+                                 min = 0, max = 1e6)
+        flexSizer.Add(txt, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.step, proportion = 0, flag = wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
 
-        sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=0)
+        sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+        border.Add(item = sizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 0)
 
         # buttons
         btnCancel = wx.Button(self, wx.ID_CANCEL)
@@ -2502,23 +1419,21 @@
         btnSizer.Realize()
         
         mainSizer = wx.BoxSizer(wx.VERTICAL)
-        mainSizer.Add(item=border, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
-        mainSizer.Add(item=btnSizer, proportion=0,
-                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+        mainSizer.Add(item = border, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
+        mainSizer.Add(item = btnSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
 
         self.SetSizer(mainSizer)
         mainSizer.Fit(self)
 
 class VDigitDuplicatesDialog(wx.Dialog):
-    """
-    Show duplicated feature ids
-    """
-    def __init__(self, parent, data, title=_("List of duplicates"),
-                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
-                 pos=wx.DefaultPosition):
-
-        wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style,
-                           pos=pos)
+    def __init__(self, parent, data, title = _("List of duplicates"),
+                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+                 pos = wx.DefaultPosition):
+        """!Show duplicated feature ids
+        """
+        wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, title = title, style = style,
+                           pos = pos)
         
         self.parent = parent # BufferedWindow
         self.data = data
@@ -2527,21 +1442,21 @@
         # panel  = wx.Panel(parent=self, id=wx.ID_ANY)
 
         # notebook
-        self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
+        self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
 
         id = 1
         for key in self.data.keys():
-            panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
-            self.notebook.AddPage(page=panel, text=" %d " % (id))
+            panel = wx.Panel(parent = self.notebook, id = wx.ID_ANY)
+            self.notebook.AddPage(page = panel, text = " %d " % (id))
             
             # notebook body
             border = wx.BoxSizer(wx.VERTICAL)
 
-            win = CheckListFeature(parent=panel, data=list(self.data[key]))
+            win = CheckListFeature(parent = panel, data = list(self.data[key]))
             self.winList.append(win.GetId())
 
-            border.Add(item=win, proportion=1,
-                       flag=wx.ALL | wx.EXPAND, border=5)
+            border.Add(item = win, proportion = 1,
+                       flag = wx.ALL | wx.EXPAND, border = 5)
 
             panel.SetSizer(border)
 
@@ -2559,9 +1474,9 @@
         btnSizer.Realize()
         
         mainSizer = wx.BoxSizer(wx.VERTICAL)
-        mainSizer.Add(item=self.notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
-        mainSizer.Add(item=btnSizer, proportion=0,
-                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+        mainSizer.Add(item = self.notebook, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
+        mainSizer.Add(item = btnSizer, proportion = 0,
+                      flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
 
         self.SetSizer(mainSizer)
         mainSizer.Fit(self)
@@ -2586,14 +1501,15 @@
         return ids
 
 class CheckListFeature(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin):
-    """!List of mapset/owner/group"""
     def __init__(self, parent, data,
-                 pos=wx.DefaultPosition, log=None):
+                 pos = wx.DefaultPosition, log = None):
+        """!List of mapset/owner/group
+        """
         self.parent = parent
         self.data = data
 
         wx.ListCtrl.__init__(self, parent, wx.ID_ANY,
-                             style=wx.LC_REPORT)
+                             style = wx.LC_REPORT)
 
         listmix.CheckListCtrlMixin.__init__(self)
 
@@ -2605,7 +1521,8 @@
         self.LoadData(self.data)
 
     def LoadData(self, data):
-        """!Load data into list"""
+        """!Load data into list
+        """
         self.InsertColumn(0, _('Feature id'))
         self.InsertColumn(1, _('Layer (Categories)'))
 
@@ -2617,9 +1534,10 @@
         for item in range(self.GetItemCount()):
             self.CheckItem(item, True)
 
-        self.SetColumnWidth(col=0, width=wx.LIST_AUTOSIZE_USEHEADER)
-        self.SetColumnWidth(col=1, width=wx.LIST_AUTOSIZE_USEHEADER)
+        self.SetColumnWidth(col = 0, width = wx.LIST_AUTOSIZE_USEHEADER)
+        self.SetColumnWidth(col = 1, width = wx.LIST_AUTOSIZE_USEHEADER)
                 
     def OnCheckItem(self, index, flag):
-        """!Mapset checked/unchecked"""
+        """!Mapset checked/unchecked
+        """
         pass

Copied: grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdigit.py (from rev 44823, grass/trunk/gui/wxpython/gui_modules/wxvdigit.py)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdigit.py	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdigit.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -0,0 +1,1578 @@
+"""!
+ at package wxvdigit.py
+
+ at brief wxGUI vector digitizer (base class)
+
+Code based on wxVdigit C++ component from GRASS 6.4.0
+(gui/wxpython/vdigit). Converted to Python in 2010/12-2011/01.
+
+List of classes:
+ - VDigitError
+ - IVDigit
+
+(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 for details.
+
+ at author Martin Landa <landa.martin gmail.com>
+"""
+
+from gcmd        import GError
+from debug       import Debug
+from preferences import globalSettings as UserSettings
+
+from wxvdriver   import DisplayDriver
+
+from grass.lib.grass  import *
+from grass.lib.vector import *
+from grass.lib.vedit  import *
+from grass.lib.dbmi   import *
+
+class VDigitError:
+    def __init__(self, parent):
+        """!Class for managing error messages of vector digitizer
+
+        @param parent parent window for dialogs
+        """
+        self.parent  = parent
+        self.caption = _('Digitization Error')
+    
+    def NoMap(self, name = None):
+        """!No map for editing"""
+        if name:
+            message = _('Unable to open vector map <%s>.') % name
+        else:
+            message =  _('No vector map open for editing.')
+        GError(message + ' ' + _('Operation cancelled.'),
+               parent  = self.parent,
+               caption = self.caption)
+
+    def WriteLine(self):
+        """!Writing line failed
+        """
+        GError(message = _('Writing new feature failed. '
+                           'Operation cancelled.'),
+               parent  = self.parent,
+               caption = self.caption)
+
+    def ReadLine(self, line):
+        """!Reading line failed
+        """
+        GError(message = _('Reading feature id %d failed. '
+                           'Operation cancelled.') % line,
+               parent  = self.parent,
+               caption = self.caption)
+
+    def DbLink(self, dblink):
+        """!No dblink available
+        """
+        GError(message = _('Database link %d not available. '
+                           'Operation cancelled.') % dblink,
+               parent  = self.parent,
+               caption = self.caption)
+
+    def Driver(self, driver):
+        """!Staring driver failed
+        """
+        GError(message = _('Unable to start database driver <%s>. '
+                           'Operation cancelled.') % driver,
+               parent  = self.parent,
+               caption = self.caption)
+
+    def Database(self, driver, database):
+        """!Opening database failed
+        """
+        GError(message = _('Unable to open database <%s> by driver <%s>. '
+                           'Operation cancelled.') % (database, driver),
+               parent  = self.parent,
+               caption = self.caption)
+
+    def DbExecute(self, sql):
+        """!Sql query failed
+        """
+        GError(message = _("Unable to execute SQL query '%s'. "
+                           "Operation cancelled.") % sql,
+               parent  = self.parent,
+               caption = self.caption)
+
+    def DeadLine(self, line):
+        """!Dead line
+        """
+        GError(message = _("Feature id %d is marked as dead. "
+                           "Operation cancelled.") % line,
+               parent  = self.parent,
+               caption = self.caption)
+
+    def FeatureType(self, ftype):
+        """!Unknown feature type
+        """
+        GError(message = _("Unsupported feature type %d. "
+                           "Operation cancelled.") % ftype,
+               parent  = self.parent,
+               caption = self.caption)
+        
+class IVDigit:
+    def __init__(self, mapwindow):
+        """!Base class for vector digitizer (ctypes interface)
+        
+        @parem mapwindow reference for map window (BufferedWindow)
+        """
+        self.poMapInfo   = None      # pointer to Map_info
+        self.mapWindow = mapwindow
+
+        # background map
+        self.bgMapInfo   = Map_info()
+        self.poBgMapInfo = self.popoBgMapInfo = None
+        
+        if not mapwindow.parent.IsStandalone():
+            goutput = mapwindow.parent.GetLayerManager().GetLogWindow()
+            log = goutput.GetLog(err = True)
+            progress = goutput.GetProgressBar()
+        else:
+            log = sys.stderr
+            progress = None
+        
+        self.toolbar = mapwindow.parent.toolbars['vdigit']
+        
+        self._error   = VDigitError(parent = self.mapWindow)
+        
+        self._display = DisplayDriver(device    = mapwindow.pdcVector,
+                                      deviceTmp = mapwindow.pdcTmp,
+                                      mapObj    = mapwindow.Map,
+                                      window    = mapwindow,
+                                      glog      = log,
+                                      gprogress = progress)
+        
+        # GRASS lib
+        self.poPoints = Vect_new_line_struct()
+        self.poCats   = Vect_new_cats_struct()
+        
+        # self.SetCategory()
+        
+        # layer / max category
+        self.cats = dict()
+        
+        self._settings = dict()
+        self.UpdateSettings() # -> self._settings
+        
+        # undo/redo
+        self.changesets = dict()
+        self.changesetCurrent = -1 # first changeset to apply
+        self.changesetEnd     = -1 # last changeset to be applied
+        
+        if self.poMapInfo:
+            self.InitCats()
+        
+    def __del__(self):
+        Vect_destroy_line_struct(self.poPoints)
+        self.poPoints = None
+        Vect_destroy_cats_struct(self.poCats)
+        self.poCats = None
+        
+        if self.poBgMapInfo:
+            Vect_close(self.poBgMapInfo)
+            self.poBgMapInfo = self.popoBgMapInfo = None
+            del self.bgMapInfo
+        
+    def CloseBackgroundMap(self):
+        """!Close background vector map"""
+        if not self.poBgMapInfo:
+            return
+        
+        Vect_close(self.poBgMapInfo)
+        self.poBgMapInfo = self.popoBgMapInfo = None
+        
+    def OpenBackgroundMap(self, bgmap):
+        """!Open background vector map
+
+        @todo support more background maps then only one
+        
+        @param bgmap name of vector map to be opened
+
+        @return pointer to map_info
+        @return None on error
+        """
+        name   = create_string_buffer(GNAME_MAX)
+        mapset = create_string_buffer(GMAPSET_MAX)
+        if not G_name_is_fully_qualified(bgmap, name, mapset):
+            name   = str(bgmap)
+            mapset = str(G_find_vector2(bgmap, ''))
+        else:
+            name   = str(name.value)
+            mapset = str(mapset.value)
+        
+        if (name == Vect_get_name(self.poMapInfo) and \
+                mapset == Vect_get_mapset(self.poMapInfo)):
+            self.poBgMapInfo = self.popoBgMapInfo = None
+            self._error.NoMap(bgmap)
+            return
+        
+        self.poBgMapInfo = pointer(self.bgMapInfo)
+        self.popoBgMapInfo = pointer(self.poBgMapInfo)
+	if Vect_open_old(self.poBgMapInfo, name, mapset) == -1:
+            self.poBgMapInfo = self.popoBgMapInfo = None
+            self._error.NoMap(bgmap)
+            return
+        
+    def _getSnapMode(self):
+        """!Get snapping mode
+
+         - snap to vertex
+         - snap to nodes
+         - no snapping
+        
+        @return snap mode
+        """
+        threshold = self._display.GetThreshold()
+        if threshold > 0.0:
+            if UserSettings.Get(group = 'vdigit', key = 'snapToVertex', subkey = 'enabled'):
+                return SNAPVERTEX
+            else:
+                return SNAP
+        else:
+            return NO_SNAP
+    
+    def _breakLineAtIntersection(self, line, pointsLine, changeset):
+        """!Break given line at intersection
+
+        \param line line id
+        \param pointsLine line geometry
+        \param changeset id
+  
+        \return number of modified lines
+        """
+        if not self._checkMap():
+            return -1
+        
+        if not Vect_line_alive(self.poMapInfo, line):
+            return 0
+        
+        if not pointsLine:
+            if Vect_read_line(self.poMapInfo, self.poPoints, None, line) < 0:
+                self._error.ReadLine(line)
+                return -1
+            points = self.poPoints
+        else:
+            points = pointsLine
+        
+        listLine  = Vect_new_list()
+        listRef   = Vect_new_list()
+        listBreak = Vect_new_list()
+    
+        pointsCheck = Vect_new_line_struct()
+    
+        lineBox = bound_box()
+        # find all relevant lines
+        Vect_get_line_box(self.poMapInfo, line, byref(lineBox))
+        Vect_select_lines_by_box(self.poMapInfo, byref(lineBox),
+                                 GV_LINES, listLine)
+    
+        # check for intersection
+        Vect_list_append(listBreak, line)
+        Vect_list_append(listRef, line)
+        for i in range(listLine.contents.n_values):
+            lineBreak = listLine.contents.value[i]
+            if lineBreak == line:
+		continue
+            
+            ltype = Vect_read_line(self.poMapInfo, pointsCheck, None, lineBreak)
+            if not (ltype & GV_LINES):
+                continue
+            
+            if Vect_line_check_intersection(self.poPoints, pointsCheck,
+                                            WITHOUT_Z):
+                Vect_list_append(listBreak, lineBreak)
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        for i in range(listBreak.contents.n_values):
+            self._addActionToChangeset(changeset, listBreak.contents.value[i], add = False)
+        
+        ret = Vect_break_lines_list(self.poMapInfo, listBreak, listRef,
+                                    GV_LINES, None)
+        
+        for i in range(listBreak.contents.n_values):
+            if Vect_line_alive(self.poMapInfo, listBreak.contents.value[i]):
+                self._removeActionFromChangeset(changeset, listBreak.contents.value[i],
+                                                add = False)
+        
+        for line in range(nlines + 1, Vect_get_num_lines(self.poMapInfo) + 1):
+            self._addActionToChangeset(changeset, line, add = True)
+        
+        Vect_destroy_line_struct(pointsCheck)
+
+        Vect_destroy_list(listLine)
+        Vect_destroy_list(listBreak)
+        Vect_destroy_list(listRef)
+        
+        return ret
+    
+    def _addActionsBefore(self):
+        """!Register action before operation
+  
+        @return changeset id
+        """
+        changeset = len(self.changesets)
+        for line in self._display.selected['ids']:
+            if Vect_line_alive(self.poMapInfo, line):
+                self._addActionToChangeset(changeset, line, add = False)
+        
+        return changeset
+
+    def _applyChangeset(self, changeset, undo):
+        """!Apply changeset (undo/redo changeset)
+        
+        @param changeset changeset id
+        @param undo True for undo otherwise redo
+
+        @return 1 changeset applied
+        @return 0 changeset not applied
+        @return -1 on error
+        """
+        if changeset < 0 or changeset > len(self.changesets.keys()):
+            return -1
+        
+        if self.changesetEnd < 0:
+            self.changesetEnd = changeset
+            
+        ret = 0
+        actions = self.changesets[changeset]
+        for action in actions: 
+            add = action['add']
+            line = action['line']
+            if (undo and add) or \
+                    (not undo and not add):
+                if Vect_line_alive(self.poMapInfo, line):
+                    Debug.msg(3, "IVDigit._applyChangeset(): changeset=%d, action=add, line=%d -> deleted",
+                              changeset, line)
+                    Vect_delete_line(self.poMapInfo, line)
+                    ret = 1
+                else:
+                    Debug.msg(3, "Digit.ApplyChangeset(): changeset=%d, action=add, line=%d dead",
+                              changeset, line)
+            else: # delete
+                offset = action['offset']
+                if not Vect_line_alive(self.poMapInfo, line):
+                    Debug.msg(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d -> added",
+                              changeset, line)
+                    if Vect_restore_line(self.poMapInfo, line, offset) < 0:
+                        return -1
+                    ret = 1
+                else:
+                    Debug.msg(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d alive",
+                              changeset, line)
+        
+        return ret
+    
+    def _addActionsAfter(self, changeset, nlines):
+        """!Register action after operation
+
+        @param changeset changeset id
+        @param nline number of lines
+        """
+        for line in self._display.selected['ids']:
+            if Vect_line_alive(self.poMapInfo, line):
+                self._removeActionFromChangeset(changeset, line, add = False)
+        
+        for line in range(nlines + 1, Vect_get_num_lines(self.poMapInfo)):
+            if Vect_line_alive(self.poMapInfo, line):
+                self._addActionToChangeset(changeset, line, add = True)
+        
+    def _addActionToChangeset(self, changeset, line, add):
+        """!Add action to changeset
+        
+        @param changeset id of changeset
+        @param line feature id
+        @param add True to add, otherwise delete
+        """
+        if not self._checkMap():
+            return 
+        
+        if not Vect_line_alive(self.poMapInfo, line):
+            return
+        
+        offset = Vect_get_line_offset(self.poMapInfo, line)
+        
+        if not self.changesets.has_key(changeset):
+            self.changesets[changeset] = list()
+            self.changesetCurrent = changeset
+        
+        self.changesets[changeset].append({ 'add'    : add,
+                                            'line'   : line,
+                                            'offset' : offset })
+        
+        Debug.msg(3, "IVDigit._addActionToChangeset(): changeset=%d, type=%d, line=%d, offset=%d",
+                  changeset, type, line, offset)
+        
+    def _removeActionFromChangeset(self, changeset, line, add):
+        """!Remove action from changeset
+        
+        @param changeset changeset id
+        @param line line id
+        @param add True for add, False for delete
+        
+        @return number of actions in changeset
+        @return -1 on error
+        """
+        if changeset not in self.changesets.keys():
+            return -1
+        
+        alist = self.changesets[changeset] 
+        for action in alist:
+            if action['add'] == add and action['line'] == line:
+                alist.remove(action)
+        
+        return len(alist)
+
+    def AddFeature(self, ftype, points):
+        """!Add new feature
+        
+        @param ftype feature type (point, line, centroid, boundary)
+        @param points tuple of points ((x, y), (x, y), ...)
+        
+        @return tuple (number of added features, feature ids)
+        """
+        if UserSettings.Get(group = 'vdigit', key = "categoryMode", subkey = 'selection') == 2:
+            layer = -1 # -> no category
+            cat   = -1
+        else:
+            layer = UserSettings.Get(group = 'vdigit', key = "layer", subkey = 'value')
+            cat   = self.SetCategory()
+        
+        if ftype == 'point':
+            vtype = GV_POINT
+        elif ftype == 'line':
+            vtype = GV_LINE
+        elif ftype == 'centroid':
+            vtype = GV_CENTROID
+        elif ftype == 'boundary':
+            vtype = GV_BOUNDARY
+        elif ftype == 'area':
+            vtype = GV_AREA
+        else:
+            GError(parent = self.mapWindow,
+                   message = _("Unknown feature type '%s'") % ftype)
+            return (-1, None)
+        
+        if vtype & GV_LINES and len(points) < 2:
+            GError(parent = self.mapWindow,
+                   message = _("Not enough points for line"))
+            return (-1, None)
+        
+        self.toolbar.EnableUndo()
+        
+        return self._addFeature(vtype, points, layer, cat,
+                                self._getSnapMode(), self._display.GetThreshold())
+    
+    def DeleteSelectedLines(self):
+        """!Delete selected features
+
+        @return number of deleted features
+        """
+        deleteRec = UserSettings.Get(group = 'vdigit', key = 'delRecord', subkey = 'enabled')
+        if not self._checkMap():
+            return -1
+        
+        n_dblinks = Vect_get_num_dblinks(self.poMapInfo)
+        Cats_del = None
+        
+        # collect categories for delete if requested
+        if deleteRec:
+            poCats    = Vect_new_cats_struct()
+            poCatsDel = Vect_new_cats_struct()
+            for i in self._display.selected['ids']:
+                if Vect_read_line(self.poMapInfo, None, poCats, i) < 0:
+                    Vect_destroy_cats_struct(poCatsDel)
+                    self._error.ReadLine(i)
+                    return -1
+                
+                cats = poCats.contents
+                for j in range(cats.n_cats):
+                    Vect_cat_set(poCatsDel, cats.field[j], cats.cat[j])
+            
+            Vect_destroy_cats_struct(poCats)
+        
+        # register changeset
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        nlines = Vedit_delete_lines(self.poMapInfo, poList)
+        Vect_destroy_list(poList)
+        self._display.selected['ids'] = list()
+        
+        if nlines > 0 and deleteRec:
+            handle  = dbHandle()
+            poHandle = pointer(handle)
+            stmt    = dbString()
+            poStmt   = pointer(stmt)
+            
+            for dblink in range(n_dblinks):
+                poFi = Vect_get_dblink(self.poMapInfo, dblink)
+                if poFi is None:
+                    self._error.DbLink(dblink)
+                    return -1
+                
+                Fi = poFi.contents
+                poDriver = db_start_driver(Fi.driver)
+                if poDriver is None:
+                    self._error.Driver(Fi.driver)
+                    return -1
+                
+                db_init_handle(poHandle)
+                db_set_handle(poHandle, Fi.database, None)
+                if db_open_database(poDriver, poHandle) != DB_OK:
+                    self._error.Database(Fi.driver, Fi.database)
+                    return -1
+                
+                db_init_string(poStmt)
+                db_set_string(poStmt, "DELETE FROM %s WHERE" % Fi.table)
+                n_cats = 0;
+                catsDel = poCatsDel.contents
+                for c in range(catsDel.n_cats):
+                    if catsDel.field[c] == Fi.number:
+                        if n_cats > 0:
+                            db_append_string(poStmt, " or")
+                    
+		    db_append_string(poStmt, " %s = %d" % (Fi.key, catsDel.cat[c]))
+		    n_cats += 1
+                
+                Vect_cat_del(poCatsDel, Fi.number)
+                
+                if n_cats and \
+                        db_execute_immediate(poDriver, poStmt) != DB_OK:
+                    self._error.DbExecute(db_get_string(poStmt))
+                    return -1
+                
+                db_close_database(poDriver)
+                db_shutdown_driver(poDriver)
+        
+        if poCatsDel:
+            Vect_destroy_cats_struct(poCatsDel)
+        
+        if nlines > 0:
+            self.toolbar.EnableUndo()
+        
+        return nlines
+
+    def MoveSelectedLines(self, move):
+        """!Move selected features
+
+        @param move direction (x, y)
+        """
+        if not self._checkMap():
+            return -1
+        
+        thresh = self._display.GetThreshold()
+        snap   = self._getSnapMode()
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        # register changeset
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        nlines = Vedit_move_lines(self.poMapInfo, self.popoBgMapInfo, int(self.poBgMapInfo is not None),
+                                  poList,
+                                  move[0], move[1], 0,
+                                  snap, thresh)
+        Vect_destroy_list(poList)
+        
+        if nlines > 0:
+            self._addActionsAfter(changeset, nlines)
+        else:
+            del self.changesets[changeset]
+        
+        if nlines > 0 and self._settings['breakLines']:
+            for i in range(1, nlines):
+                self._breakLineAtIntersection(nlines + i, None, changeset)
+        
+        if nlines > 0:
+            self.toolbar.EnableUndo()
+        
+        return nlines
+
+    def MoveSelectedVertex(self, point, move):
+        """!Move selected vertex of the line
+
+        @param point location point
+        @param move  x,y direction
+        
+        @return id of new feature
+        @return 0 vertex not moved (not found, line is not selected)
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        if len(self._display.selected['ids']) != 1:
+            return -1
+        
+        Vect_reset_line(self.poPoints)
+        Vect_append_point(self.poPoints, point[0], point[1], 0.0)
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        changeset = self._addActionsBefore()
+        
+        # move only first found vertex in bbox 
+        poList = self._display.GetSelectedIList()
+        moved = Vedit_move_vertex(self.poMapInfo, self.popoBgMapInfo, int(self.poBgMapInfo is not None),
+                                  poList, self.poPoints,
+                                  self._display.GetThreshold(type = 'selectThresh'),
+                                  self._display.GetThreshold(),
+                                  move[0], move[1], 0.0,
+                                  1, self._getSnapMode())
+        Vect_destroy_list(poList)
+        
+        if moved > 0:
+            self._addActionsAfter(changeset, nlines)
+        else:
+            del self.changesets[changeset]
+        
+        if moved > 0 and self._settings['breakLines']:
+            self._breakLineAtIntersection(Vect_get_num_lines(self.poMapInfo),
+                                          None, changeset)
+        
+        if moved > 0:
+            self.toolbar.EnableUndo()
+        
+        return moved
+
+    def AddVertex(self, coords):
+        """!Add new vertex to the selected line/boundary on position 'coords'
+
+        @param coords coordinates to add vertex
+
+        @return id of new feature
+        @return 0 nothing changed
+        @return -1 on failure
+        """
+        added = self._ModifyLineVertex(coords, add = True)
+        
+        if added > 0:
+            self.toolbar.EnableUndo()
+
+        return added
+
+    def RemoveVertex(self, coords):
+        """!Remove vertex from the selected line/boundary on position 'coords'
+
+        @param coords coordinates to remove vertex
+
+        @return id of new feature
+        @return 0 nothing changed
+        @return -1 on failure
+        """
+        deleted = self._ModifyLineVertex(coords, add = False)
+        
+        if deleted > 0:
+            self.toolbar.EnableUndo()
+
+        return deleted
+
+
+    def SplitLine(self, point):
+        """!Split/break selected line/boundary on given position
+
+        @param point point where to split line
+        
+        @return 1 line modified
+        @return 0 nothing changed
+        @return -1 error
+        """
+        thresh = self._display.GetThreshold('selectThresh')
+        if not self._checkMap():
+            return -1
+        
+        poList  = self._display.GetSelectedIList()
+        Vect_reset_line(self.poPoints)
+        Vect_append_point(self.poPoints, point[0], point[1], 0.0)
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        changeset = self._addActionsBefore()
+        
+        ret = Vedit_split_lines(self.poMapInfo, poList,
+                                self.poPoints, thresh, poList)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+        
+        return ret
+
+    def EditLine(self, line, coords):
+        """!Edit existing line/boundary
+
+        @param line id of line to be modified
+        @param coords list of coordinates of modified line
+
+        @return feature id of new line
+        @return -1 on error
+        """
+        if self._checkMap():
+            return -1
+        
+        try:
+            lineid = line[0]
+        except:
+            lineid = -1
+        
+        if len(coords) < 2:
+            self.DeleteSelectedLines()
+            return 0
+        
+        ret = self.digit.RewriteLine(lineid, listCoords,
+                                     bgmap, self._getSnapMode(),
+                                     self._display.GetThreshold())
+        
+        if ret > 0:
+            self.toolbar.EnableUndo()
+        
+        return ret
+
+    def FlipLine(self):
+        """!Flip selected lines/boundaries
+
+        @return number of modified lines
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        # register changeset
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        ret = Vedit_flip_lines(self.poMapInfo, poList)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+        
+        return ret
+
+    def MergeLine(self):
+        """!Merge selected lines/boundaries
+
+        @return number of modified lines
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        ret = Vedit_merge_lines(self.poMapInfo, poList)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+                
+        return ret
+
+    def BreakLine(self):
+        """!Break selected lines/boundaries
+
+        @return number of modified lines
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        ret = Vect_break_lines_list(self.poMapInfo, poList, None,
+                                    GV_LINES, None)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+                
+        return ret
+
+    def SnapLine(self):
+        """!Snap selected lines/boundaries
+
+        @return on success
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        Vect_snap_lines_list(self.poMapInfo, poList,
+                             self._display.GetThreshold(), None)
+        Vect_destroy_list(poList)
+        
+        if nlines < Vect_get_num_lines(self.poMapInfo):
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+        
+    def ConnectLine(self):
+        """!Connect selected lines/boundaries
+
+        @return 1 lines connected
+        @return 0 lines not connected
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        # register changeset
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        ret = Vedit_connect_lines(self.poMapInfo, poList,
+                                  self._display.GetThreshold())
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+        
+        return ret
+        
+    def CopyLine(self, ids = []):
+        """!Copy features from (background) vector map
+
+        @param ids list of line ids to be copied
+
+        @return number of copied features
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        poList = self._display.GetSelectedIList(ids)
+        ret = Vedit_copy_lines(self.poMapInfo, self.poBgMapInfo,
+                               poList)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            changeset = len(self.changesets)
+            for line in (range(nlines + 1, Vect_get_num_lines(self.poMapInfo))):
+                self._addActionToChangeset(changeset, line, add = True)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+
+        if ret > 0 and self.poBgMapInfo and self._settings['breakLines']:
+            for i in range(1, ret):
+                self._breakLineAtIntersection(nlines + i, None, changeset)
+        
+        return ret
+
+    def CopyCats(self, fromId, toId, copyAttrb=False):
+        """!Copy given categories to objects with id listed in ids
+
+        @param cats ids of 'from' feature
+        @param ids  ids of 'to' feature(s)
+
+        @return number of modified features
+        @return -1 on error
+        """
+        if len(fromId) == 0 or len(toId) == 0:
+            return 0
+        
+        ret = self.digit.CopyCats(fromId, toId, copyAttrb)
+
+        if ret > 0:
+            self.toolbar.EnableUndo()
+
+        return ret
+
+    def _selectLinesByQueryThresh(self):
+        """!Generic method used for SelectLinesByQuery() -- to get
+        threshold value"""
+        thresh = 0.0
+        if UserSettings.Get(group = 'vdigit', key = 'query', subkey = 'selection') == 0:
+            thresh = UserSettings.Get(group = 'vdigit', key = 'queryLength', subkey = 'thresh')
+            if UserSettings.Get(group = 'vdigit', key = "queryLength", subkey = 'than-selection') == 0:
+                thresh = -1 * thresh
+        else:
+            thresh = UserSettings.Get(group = 'vdigit', key = 'queryDangle', subkey = 'thresh')
+            if UserSettings.Get(group = 'vdigit', key = "queryDangle", subkey = 'than-selection') == 0:
+                thresh = -1 * thresh
+        
+        return thresh
+
+    def SelectLinesByQuery(self, bbox):
+        """!Select features by query
+        
+        @todo layer / 3D
+        
+        @param bbox bounding box definition
+        """
+        if not self._checkMap():
+            return -1
+        
+        thresh = self._selectLinesByQueryThresh()
+        
+        query = QUERY_UNKNOWN
+        if UserSettings.Get(group = 'vdigit', key = 'query', subkey = 'selection') == 0:
+            query = QUERY_LENGTH
+        else:
+            query = QUERY_DANGLE
+        
+        ftype = GV_POINTS | GV_LINES # TODO: 3D
+        layer = 1 # TODO
+        
+        ids = list()
+        poList = Vect_new_list()
+        coList = poList.contents
+        if UserSettings.Get(group = 'vdigit', key = 'query', subkey = 'box'):
+            Vect_reset_line(self.poPoints)
+            x1, y1 = bbox[0]
+            x2, y2 = bbox[1]
+            z1 = z2 = 0.0
+            
+            Vect_append_point(self.poPoints, x1, y1, z1)
+            Vect_append_point(self.poPoints, x2, y1, z2)
+            Vect_append_point(self.poPoints, x2, y2, z1)
+            Vect_append_point(self.poPoints, x1, y2, z2)
+            Vect_append_point(self.poPoints, x1, y1, z1)
+	
+            Vect_select_lines_by_polygon(self.poMapInfo, self.poPoints, 0, None,
+                                         ftype, poList)
+            
+            if coList.n_values == 0:
+                return ids
+        
+        Vedit_select_by_query(self.poMapInfo,
+                              ftype, layer, thresh, query,
+                              poList)
+        
+        for i in range(coList.n_values):
+            ids.append(int(coList.value[i]))
+            
+        Debug.msg(3, "IVDigit.SelectLinesByQuery(): lines=%d", coList.n_values)    
+        Vect_destroy_list(poList)
+        
+        return ids
+
+    def IsVector3D(self):
+        """!Check if open vector map is 3D
+        """
+        if not self._checkMap():
+            return False
+        
+        return Vect_is_3d(self.poMapInfo)
+    
+    def GetLineCats(self, line=-1):
+        """!Get layer/category pairs from given (selected) line
+        
+        @param line feature id (-1 for first selected line)
+        """
+        return dict(self.digit.GetLineCats(line))
+
+    def GetLineLength(self, line):
+        """!Get line length
+
+        @param line feature id
+
+        @return line length
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        if not Vect_line_alive(self.poMapInfo, line):
+            return -1
+    
+        ltype = Vect_read_line(self.poMapInfo, self.poPoints, None, line)
+        if ltype < 0:
+            self._error.ReadLine(line)
+            return ret
+        
+        length = -1
+        if ltype & GV_LINES: # lines & boundaries
+            length = Vect_line_length(self.poPoints)
+        
+        return length
+
+    def GetAreaSize(self, centroid):
+        """!Get area size
+
+        @param centroid centroid id
+
+        @return area size
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        ltype = Vect_read_line(self.poMapInfo, None, None, centroid)
+        if ltype < 0:
+            self._error.ReadLine(line)
+            return ret
+        
+        if ltype != GV_CENTROID:
+            return -1
+        
+        area = Vect_get_centroid_area(self.poMapInfo, centroid)
+        size = -1
+        if area > 0:
+            if not Vect_area_alive(self.poMapInfo, area):
+                return size
+            
+            size = Vect_get_area_area(self.poMapInfo, area)
+        
+        return size
+        
+    def GetAreaPerimeter(self, centroid):
+        """!Get area perimeter
+        
+        @param centroid centroid id
+        
+        @return area size
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        ltype = Vect_read_line(self.poMapInfo, None, None, centroid)
+        if ltype < 0:
+            self._error.ReadLine(line)
+            return ret
+        
+        if ltype != GV_CENTROID:
+            return -1
+        
+        area = Vect_get_centroid_area(self.poMapInfo, centroid)
+        perimeter = -1
+        if area > 0:
+            if not Vect_area_alive(self,poMapInfo, area):
+                return -1
+            
+            Vect_get_area_points(self.poMapInfo, area, self.poPoints)
+            perimeter = Vect_area_perimeter(self.poPoints)
+        
+        return perimeter
+    
+    def SetLineCats(self, line, layer, cats, add=True):
+        """!Set categories for given line and layer
+
+        @param line feature id
+        @param layer layer number (-1 for first selected line)
+        @param cats list of categories
+        @param add if True to add, otherwise do delete categories
+
+        @return new feature id (feature need to be rewritten)
+        @return -1 on error
+        """
+        ret = self.digit.SetLineCats(line, layer, cats, add)
+
+        if ret > 0:
+            self.toolbar.EnableUndo()
+
+        return ret
+
+    def GetLayers(self):
+        """!Get list of layers"""
+        return self.digit.GetLayers()
+
+    def TypeConvForSelectedLines(self):
+        """!Feature type conversion for selected objects.
+
+        Supported conversions:
+         - point <-> centroid
+         - line <-> boundary
+
+        @return number of modified features
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        # register changeset
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        ret = Vedit_chtype_lines(self.poMapInfo, poList)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+        
+        return ret
+
+    def Undo(self, level = -1):
+        """!Undo action
+
+        @param level levels to undo (0 to revert all)
+
+        @return id of current changeset
+        """
+        changesetLast = len(self.changesets.keys()) - 1
+
+        if changesetLast < 0:
+            return changesetLast
+        
+        if self.changesetCurrent == -2: # value uninitialized 
+            self.changesetCurrent = changesetLast
+            
+        if level > 0 and self.changesetCurrent < 0:
+            self.changesetCurrent = 0
+        
+        if level == 0:
+            # 0 -> undo all
+            level = -1 * changesetLast + 1
+
+        Debug.msg(2, "Digit.Undo(): changeset_last=%d, changeset_current=%d, level=%d",
+                  changesetLast, self.changesetCurrent, level)
+    
+        if level < 0: # undo
+            if self.changesetCurrent + level < -1:
+                return changesetCurrent;
+            for changeset in range(self.changesetCurrent, self.changesetCurrent + level, -1):
+                self._applyChangeset(changeset, undo = True)
+        elif level > 0: # redo 
+            if self.changesetCurrent + level > len(self.changesets.keys()):
+                return self.changesetCurrent
+            for changeset in range(self.changesetCurrent, self.changesetCurrent + level):
+                self._applyChangeset(changeset, undo = False)
+        
+        self.changesetCurrent += level
+
+        Debug.msg(2, "Digit.Undo(): changeset_current=%d, changeset_last=%d, changeset_end=%d",
+                  self.changesetCurrent, changesetLast, self.changesetEnd)
+        
+        if self.changesetCurrent == self.changesetEnd:
+            self.changesetEnd = changesetLast
+            return -1
+        
+        self.mapWindow.UpdateMap(render = False)
+        
+        if self.changesetCurrent < 0: # disable undo tool
+            self.toolbar.EnableUndo(False)
+
+    def ZBulkLines(self, pos1, pos2, start, step):
+        """!Z-bulk labeling
+
+        @param pos1 reference line (start point)
+        @param pos1 reference line (end point)
+        @param start starting value
+        @param step step value
+
+        @return number of modified lines
+        @return -1 on error
+        """
+        if not self._checkMap():
+            return -1
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        
+        # register changeset
+        changeset = self._addActionsBefore()
+        
+        poList = self._display.GetSelectedIList()
+        ret = Vedit_bulk_labeling(self.poMapInfo, poList,
+                                  pos1[0], pos1[1], pos2[0], pos2[1],
+                                  start, step)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+            self.toolbar.EnableUndo()
+        else:
+            del self.changesets[changeset]
+        
+        return ret
+    
+    def GetDisplay(self):
+        """!Get display driver instance"""
+        return self._display
+    
+    def OpenMap(self, name):
+        """!Open vector map for editing
+        
+        @param map name of vector map to be set up
+        """
+        Debug.msg (3, "AbstractDigit.SetMapName map=%s" % name)
+        
+        name, mapset = name.split('@')
+        
+        self.poMapInfo = self._display.OpenMap(str(name), str(mapset), True)
+        
+        if self.poMapInfo:
+            self.InitCats()
+        
+        return self.poMapInfo
+    
+    def CloseMap(self):
+        """!Close currently open vector map
+        """
+        if not self._checkMap():
+            return
+        
+        self._display.CloseMap()
+
+    def InitCats(self):
+        """!Initialize categories information
+        
+        @return 0 on success
+        @return -1 on error
+        """
+        self.cats.clear()
+        if not self._checkMap():
+            return -1
+        
+        ndblinks = Vect_get_num_dblinks(self.poMapInfo)
+        for i in range(ndblinks):
+            fi = Vect_get_dblink(self.poMapInfo, i).contents
+            if fi:
+                self.cats[fi.number] = None
+        
+        # find max category
+        nfields = Vect_cidx_get_num_fields(self.poMapInfo)
+        Debug.msg(2, "wxDigit.InitCats(): nfields=%d", nfields)
+        
+        for i in range(nfields):
+            field = Vect_cidx_get_field_number(self.poMapInfo, i)
+            ncats = Vect_cidx_get_num_cats_by_index(self.poMapInfo, i)
+            if field <= 0:
+                continue
+            for j in range(ncats):
+                cat = c_int()
+                type = c_int()
+                id = c_int()
+                Vect_cidx_get_cat_by_index(self.poMapInfo, i, j,
+                                           byref(cat), byref(type), byref(id))
+                if self.cats.has_key(field):
+                    if cat > self.cats[field]:
+                        self.cats[field] = cat.value
+                else:
+                    self.cats[field] = cat.value
+            Debug.msg(3, "wxDigit.InitCats(): layer=%d, cat=%d", field, self.cats[field])
+            
+        # set default values
+        for field, cat in self.cats.iteritems():
+            if cat == None:
+                self.cats[field] = 0 # first category 1
+	    Debug.msg(3, "wxDigit.InitCats(): layer=%d, cat=%d", field, self.cats[field])
+        
+    def _checkMap(self):
+        """!Check if map is open
+        """
+        if not self.poMapInfo:
+            self._error.NoMap()
+            return False
+        
+        return True
+
+    def _addFeature(self, ftype, coords, layer, cat, snap, threshold):
+        """!Add new feature(s) to the vector map
+
+        @param ftype feature type (GV_POINT, GV_LINE, GV_BOUNDARY, ...)
+        @coords tuple of coordinates ((x, y), (x, y), ...)
+        @param layer layer number (-1 for no cat)
+        @param cat category number
+        @param snap snap to node/vertex
+        @param threshold threshold for snapping
+        
+        @return tuple (number of added features, list of fids)
+        @return number of features -1 on error
+        """
+        fids = list()
+        if not self._checkMap():
+            return (-1, None)
+        
+        is3D = bool(Vect_is_3d(self.poMapInfo))
+        
+        Debug.msg(2, "IVDigit._addFeature(): npoints=%d, layer=%d, cat=%d, snap=%d",
+                  len(coords), layer, cat, snap)
+        
+        if not (ftype & (GV_POINTS | GV_LINES | GV_AREA)): # TODO: 3D
+            self._error.FeatureType(ftype)
+            return (-1, None)
+        
+        # set category
+        Vect_reset_cats(self.poCats)
+        if layer > 0 and ftype != GV_AREA:
+            Vect_cat_set(self.poCats, layer, cat)
+            self.cats[layer] = max(cat, self.cats.get(layer, 1))
+        
+        # append points
+        Vect_reset_line(self.poPoints)
+        for c in coords:
+            Vect_append_point(self.poPoints, c[0], c[1], 0.0)
+        
+        if ftype & (GV_BOUNDARY | GV_AREA):
+            # close boundary
+            points = self.poPoints.contents
+            last = points.n_points - 1
+            if Vect_points_distance(points.x[0], points.x[0], points.z[0],
+                                    points.x[last], points.x[last], points.z[last],
+                                    is3D) <= threshold:
+                points.x[last] = points.x[0]
+                points.y[last] = points.y[0]
+                points.z[last] = points.z[0]
+        
+        if snap != NO_SNAP:
+            # apply snapping (node or vertex)
+            modeSnap = not (snap == SNAP)
+            Vedit_snap_line(self.poMapInfo, self.popoBgMapInfo, int(self.poBgMapInfo is not None),
+                            -1, self.poPoints, threshold, modeSnap)
+        
+        if ftype == GV_AREA:
+            ltype = GV_BOUNDARY
+        else:
+            ltype = ftype
+        newline = Vect_write_line(self.poMapInfo, ltype, self.poPoints, self.poCats)
+        if newline < 0:
+            self._error.WriteLine()
+            return (-1, None)
+        else:
+            fids.append(newline)
+        
+        left = right = -1
+        if ftype & GV_AREA:
+            # add centroids for left/right area
+            bpoints = Vect_new_line_struct()
+            cleft = c_int()
+            cright = c_int()
+            
+            Vect_get_line_areas(self.poMapInfo, newline,
+                                byref(cleft), byref(cright))
+            left = cleft.value
+            right = cright.value
+            
+            # check if area exists and has no centroid inside
+            if layer > 0 and (left > 0 or right > 0):
+                Vect_cat_set(self.poCats, layer, cat)
+                self.cats[layer] = max(cat, self.cats.get(layer, 0))
+            
+            x = c_double()
+            y = c_double()
+            if left > 0 and \
+                    Vect_get_area_centroid(self.poMapInfo, left) == 0:
+                # if Vect_get_area_points(self.poMapInfo, left, bpoints) > 0 and
+                # Vect_find_poly_centroid(bpoints, byref(x), byref(y)) == 0:
+                if Vect_get_point_in_area(self.poMapInfo, left, byref(x), byref(y)) == 0:
+                    Vect_reset_line(bpoints)
+                    Vect_append_point(bpoints, x.value, y.value, 0.0)
+                    newline = Vect_write_line(self.poMapInfo, GV_CENTROID,
+                                              bpoints, self.poCats)
+                    if newline < 0:
+                        self._error.WriteLine()
+                        return (len(fids), fids)
+                    else:
+                        fids.append(newline)
+                    
+            if right > 0 and \
+                    Vect_get_area_centroid(self.poMapInfo, right) == 0:
+                # if Vect_get_area_points(byref(self.poMapInfo), right, bpoints) > 0 and 
+                # Vect_find_poly_centroid(bpoints, byref(x), byref(y)) == 0:
+                if Vect_get_point_in_area(self.poMapInfo, left, byref(x), byref(y)) == 0:
+                    Vect_reset_line(bpoints)
+                    Vect_append_point(bpoints, x.value, y.value, 0.0)
+                    newline =  Vect_write_line(byref(self.poMapInfo), GV_CENTROID,
+                                               bpoints, self.poCats)
+                    if newline < 0:
+                        self._error.WriteLine()
+                        return (len(fids, fids))
+                    else:
+                        fids.append(newline)
+                    
+            Vect_destroy_line_struct(bpoints)
+        
+        # register changeset
+        changeset = len(self.changesets)
+        self._addActionToChangeset(changeset, newline, add = True)
+        
+        # break at intersection
+        if self._settings['breakLines']:
+            self._breakLineAtIntersection(newline, self.poPoints, changeset)
+        
+        return (len(fids), fids)
+    
+    def _ModifyLineVertex(self, coords, add = True):
+        """!Add or remove vertex
+        
+        Shape of line/boundary is not changed when adding new vertex.
+        
+        @param coords coordinates of point
+        @param add True to add, False to remove
+        
+        @return id id of the new feature
+        @return 0 nothing changed
+        @return -1 error
+        """
+        if not self._checkMap():
+            return -1
+        
+        selected = self._display.selected
+        if len(selected['ids']) != 1:
+            return 0
+        
+        poList  = self._display.GetSelectedIList()
+        Vect_reset_line(self.poPoints)
+        Vect_append_point(self.poPoints, coords[0], coords[1], 0.0)
+        
+        nlines = Vect_get_num_lines(self.poMapInfo)
+        thresh = self._display.GetThreshold(type = 'selectThresh')
+        
+        changeset = self._addActionsBefore()
+        
+        if add:
+            ret = Vedit_add_vertex(self.poMapInfo, poList,
+                                   self.poPoints, thresh)
+        else:
+            ret = Vedit_remove_vertex(self.poMapInfo, poList,
+                                      self.poPoints, thresh)
+        Vect_destroy_list(poList)
+        
+        if ret > 0:
+            self._addActionsAfter(changeset, nlines)
+        else:
+            del self.changesets[changeset]
+        
+        if not add and ret > 0 and self._settings['breakLines']:
+            self._breakLineAtIntersection(Vect_get_num_lines(self.poMapInfo),
+                                          None, changeset)
+                
+        return nlines + 1 # feature is write at the end of the file
+    
+    def GetLineCats(self, line):
+        """!Get list of layer/category(ies) for selected feature.
+
+        @param line feature id (-1 for first selected feature)
+
+        @return list of layer/cats
+        """
+        ret = dict()
+        if not self._checkMap():
+            return ret
+        
+        if line == -1 and len(self._display.selected['ids']) < 1:
+            return ret
+        
+        if line == -1:
+            line = self._display.selected['ids'][0]
+            
+        if not Vect_line_alive(self.poMapInfo, line):
+            self._error.DeadLine(line)
+            return ret
+        
+        if Vect_read_line(self.poMapInfo, None, self.poCats, line) < 0:
+            self._error.ReadLine(line)
+            return ret
+        
+        cats = self.poCats.contents
+        for i in range(cats.n_cats):
+            field = cats.field[i]
+            if field not in ret:
+                ret[field] = list()
+            ret[field].append(cats.cat[i])
+        
+        return ret
+
+    def GetLayers(self):
+        """!Get list of layers
+        
+        Requires self.InitCats() to be called.
+
+        @return list of layers
+        """
+        return self.cats.keys()
+    
+    def UpdateSettings(self):
+        """!Update digit (and display) settings
+        """
+        self._display.UpdateSettings()
+        
+        self._settings['breakLines']  = bool(UserSettings.Get(group = 'vdigit', key = "breakLines",
+                                                              subkey = 'enabled'))
+        
+    def SetCategory(self):
+        """!Update self.cats based on settings"""
+        sel = UserSettings.Get(group = 'vdigit', key = 'categoryMode', subkey = 'selection')
+        cat = None
+        if sel == 0: # next to usep
+            cat = self._setCategoryNextToUse()
+        elif sel == 1:
+            cat = UserSettings.Get(group = 'vdigit', key = 'category', subkey = 'value')
+        
+        if cat:
+            layer = UserSettings.Get(group = 'vdigit', key = 'layer', subkey = 'value')
+            self.cats[layer] = cat
+        
+        return cat
+    
+    def _setCategoryNextToUse(self):
+        """!Find maximum category number for the given layer and
+        update the settings
+
+        @return category to be used
+        """
+        # get max category number for given layer and update the settings
+        layer = UserSettings.Get(group = 'vdigit', key = 'layer', subkey = 'value')
+        cat = self.cats.get(layer, 0) + 1
+        UserSettings.Set(group = 'vdigit', key = 'category', subkey = 'value',
+                         value = cat)
+        Debug.msg(1, "IVDigit._setCategoryNextToUse(): cat=%d", cat)
+        
+        return cat
+
+    def SelectLinesFromBackgroundMap(self, bbox):
+        """!Select features from background map
+
+        @param bbox bounding box definition
+        
+        @return list of selected feature ids
+        """
+        ret = list()
+        
+        # try select features by Box
+        ids = self._display.SelectLinesByBox(bbox, poMapInfo = self.poBgMapInfo)
+        if not ids:
+            ids = [self._display.SelectLineByPoint(bbox[0], poMapInfo = self.poBgMapInfo)['line'], ]
+        
+        return ids
+
+    def GetUndoLevel(self):
+        """!Get undo level (number of active changesets)
+        
+        Note: Changesets starts wiht 0
+        """
+        return self.changesetCurrent
+    

Copied: grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdriver.py (from rev 44823, grass/trunk/gui/wxpython/gui_modules/wxvdriver.py)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdriver.py	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/wxvdriver.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -0,0 +1,985 @@
+"""!
+ at package wxvdriver.py
+
+ at brief wxGUI vector digitizer (display driver)
+
+Code based on wxVdigit C++ component from GRASS 6.4.0
+(gui/wxpython/vdigit). Converted to Python in 2010/12-2011/01.
+
+List of classes:
+ - DisplayDriver
+
+(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 for details.
+
+ at author Martin Landa <landa.martin gmail.com>
+"""
+
+import math
+
+import wx
+
+from debug import Debug
+from preferences import globalSettings as UserSettings
+
+from grass.lib.grass  import *
+from grass.lib.vector import *
+from grass.lib.vedit  import *
+
+log      = None
+progress = None
+
+def print_error(msg, type):
+    """!Redirect stderr"""
+    global log
+    if log:
+        log.write(msg)
+    else:
+        print msg
+    
+    return 0
+
+def print_progress(value):
+    """!Redirect progress info"""
+    global progress
+    if progress:
+        progress.SetValue(value)
+    else:
+        print value
+    
+    return 0
+
+errtype = CFUNCTYPE(UNCHECKED(c_int), String, c_int)
+errfunc = errtype(print_error)
+pertype = CFUNCTYPE(UNCHECKED(c_int), c_int)
+perfunc = pertype(print_progress)
+
+class DisplayDriver:
+    def __init__(self, device, deviceTmp, mapObj, window, glog, gprogress):
+        """!Display driver used by vector digitizer
+        
+        @param device    wx.PseudoDC device where to draw vector objects
+        @param deviceTmp wx.PseudoDC device where to draw temporary vector objects
+        @param mapOng    Map Object (render.Map)
+        @param windiow   parent window for dialogs
+        @param glog      logging device (None to discard messages)
+        @param gprogress progress bar device (None to discard message)
+        """
+        global errfunc, perfunc, log, progress
+        log = glog
+        progress = gprogress
+        
+        G_gisinit('')             # initialize GRASS libs
+        G_set_error_routine(errfunc) 
+        G_set_percent_routine(perfunc)
+        
+        self.mapInfo   = None     # open vector map (Map_Info structure)
+        self.poMapInfo = None     # pointer to self.mapInfo
+        self.is3D      = False    # is open vector map 3D
+        
+        self.dc      = device     # PseudoDC devices
+        self.dcTmp   = deviceTmp
+        self.mapObj  = mapObj
+        self.region  = mapObj.GetCurrentRegion()
+        self.window  = window
+        self.log     = log        # log device
+
+        # GRASS lib
+        self.poPoints = Vect_new_line_struct()
+        self.poCats   = Vect_new_cats_struct()
+        
+        # selected objects
+        self.selected = {
+            'field'   : -1,      # field number
+            'cats'    : list(),  # list of cats
+            'ids'     : list(),  # list of ids
+            'idsDupl' : list(),  # list of duplicated features
+            }
+        
+        # digitizer settings
+        self.settings = {
+            'highlight'     : None,
+            'highlightDupl' : { 'enabled' : False,
+                                'color'   : None },
+            'point'         : { 'enabled' : False,
+                                'color'   : None },
+            'line'          : { 'enabled' : False,
+                                'color'   : None },
+            'boundaryNo'    : { 'enabled' : False,
+                                'color'   : None },
+            'boundaryOne'   : { 'enabled' : False,
+                                'color'   : None },
+            'boundaryTwo'   : { 'enabled' : False,
+                                'color'   : None },
+            'centroidIn'    : { 'enabled' : False,
+                                'color'   : None },
+            'centroidOut'   : { 'enabled' : False,
+                                'color'   : None },
+            'centroidDup'   : { 'enabled' : False,
+                                'color'   : None },
+            'nodeOne'       : { 'enabled' : False,
+                                'color'   : None },
+            'nodeTwo'       : { 'enabled' : False,
+                                'color'   : None },
+            'vertex'        : { 'enabled' : False,
+                                'color'   : None },
+            'area'          : { 'enabled' : False,
+                                'color'   : None },
+            'direction'     : { 'enabled' : False,
+                                'color'   : None },
+            'lineWidth'     : -1,    # screen units 
+            }
+        
+        # topology
+        self._resetTopology()
+        
+        self._drawSelected = False
+        self._drawSegments = False
+        
+        self.UpdateSettings()
+        
+    def __del__(self):
+        """!Close currently open vector map"""
+        G_unset_error_routine()
+        G_unset_percent_routine()
+        
+        if self.poMapInfo:
+            self.CloseMap()
+        
+        Vect_destroy_line_struct(self.poPoints)
+        Vect_destroy_cats_struct(self.poCats)
+
+    def _resetTopology(self):
+        """!Reset topology dict
+        """
+        self.topology = {
+            'highlight'   : 0,
+            'point'       : 0,
+            'line'        : 0,
+            'boundaryNo'  : 0,
+            'boundaryOne' : 0,
+            'boundaryTwo' : 0,
+            'centroidIn'  : 0,
+            'centroidOut' : 0,
+            'centroidDup' : 0,
+            'nodeOne'     : 0,
+            'nodeTwo'     : 0,
+            'vertex'      : 0,
+            }
+        
+    def _cell2Pixel(self, east, north, elev):
+        """!Conversion from geographic coordinates (east, north)
+        to screen (x, y)
+  
+        @todo 3D stuff...
+
+        @param east, north, elev geographical coordinates
+
+        @return x, y screen coordinates (integer)
+        """
+        map_res = max(self.region['ewres'], self.region['nsres'])
+        w = self.region['center_easting']  - (self.mapObj.width  / 2) * map_res
+        n = self.region['center_northing'] + (self.mapObj.height / 2) * map_res
+        
+        return int((east - w) / map_res), int((n - north) / map_res)
+    
+    def _drawCross(self, pdc, point, size = 5):
+        """!Draw cross symbol of given size to device content
+   
+        Used for points, nodes, vertices
+
+        @param[in,out] PseudoDC where to draw
+        @param point coordinates of center
+        @param size size of the cross symbol
+   
+        @return 0 on success
+        @return -1 on failure
+        """
+        if not pdc or not point:
+            return -1
+        
+        pdc.DrawLine(point.x - size, point.y, point.x + size, point.y)
+        pdc.DrawLine(point.x, point.y - size, point.x, point.y + size)
+        
+        return 0
+    
+    def _drawObject(self, robj):
+        """!Draw given object to the device
+        
+        The object is defined as robject() from vedit.h.
+        
+        @param robj object to be rendered
+        
+        @return  1 on success
+        @return -1 on failure (vector feature marked as dead, etc.)
+        """
+        if not self.dc or not self.dcTmp:
+            return -1
+        
+        Debug.msg(3, "_drawObject(): type=%d npoints=%d", robj.type, robj.npoints)
+        brush = None
+        if self._isSelected(robj.fid):
+            pdc = self.dcTmp
+            if self.settings['highlightDupl']['enabled'] and self._isDuplicated(robj.fid):
+                pen = wx.Pen(self.settings['highlightDupl']['color'], self.settings['lineWidth'], wx.SOLID)
+            else:            
+                pen = wx.Pen(self.settings['highlight'], self.settings['lineWidth'], wx.SOLID)
+            
+            dcId = 1
+            self.topology['highlight'] += 1
+            if not self._drawSelected:
+                return
+        else:
+            pdc = self.dc
+            pen, brush = self._definePen(robj.type)
+            dcId = 0
+        
+        pdc.SetPen(pen)        
+        if brush:
+            pdc.SetBrush(brush)
+        
+        if robj.type & (TYPE_POINT | TYPE_CENTROIDIN | TYPE_CENTROIDOUT | TYPE_CENTROIDDUP |
+                        TYPE_NODEONE | TYPE_NODETWO | TYPE_VERTEX): # -> point
+            for i in range(robj.npoints):
+                p = robj.point[i]
+                self._drawCross(pdc, p)
+        else:
+            if dcId > 0 and self._drawSegments:
+                dcId = 2 # first segment
+                i = 0
+                while i < robj.npoints - 1:
+                    point_beg = wx.Point(robj.point[i].x, robj.point[i].y)
+                    point_end = wx.Point(robj.point[i+1].x, robj.point[i+1].y)
+                    pdc.SetId(dcId) # set unique id & set bbox for each segment
+                    pdc.SetPen(pen)
+                    pdc.SetIdBounds(dcId - 1, wx.Rect(point_beg.x, point_beg.y, 0, 0))
+                    pdc.SetIdBounds(dcId, wx.RectPP(point_beg, point_end))
+                    pdc.DrawLine(point_beg.x, point_beg.y,
+                                 point_end.x, point_end.y)
+                    i    += 1
+                    dcId += 2
+                pdc.SetIdBounds(dcId - 1, wx.Rect(robj.point[robj.npoints - 1].x,
+                                                  robj.point[robj.npoints - 1].y,
+                                                  0, 0))
+            else:
+                points = list()
+                for i in range(robj.npoints):
+                    p = robj.point[i]
+                    points.append(wx.Point(p.x, p.y))
+                    
+                if robj.type == TYPE_AREA:
+                    pdc.DrawPolygon(points)
+                else:
+                    pdc.DrawLines(points)
+        
+    def _definePen(self, rtype):
+        """!Define pen/brush based on rendered object)
+        
+        Updates also self.topology dict
+
+        @return pen, brush
+        """
+        if rtype == TYPE_POINT:
+            key = 'point'
+        elif rtype == TYPE_LINE:
+            key = 'line'
+        elif rtype == TYPE_BOUNDARYNO:
+            key = 'boundaryNo'
+        elif rtype == TYPE_BOUNDARYTWO:
+            key = 'boundaryTwo'
+        elif rtype == TYPE_BOUNDARYONE:
+            key = 'boundaryOne'
+        elif rtype == TYPE_CENTROIDIN:
+            key = 'centroidIn'
+        elif rtype == TYPE_CENTROIDOUT:
+            key = 'centroidOut'
+        elif rtype == TYPE_CENTROIDDUP:
+            key = 'centroidDup'
+        elif rtype == TYPE_NODEONE:
+            key = 'nodeOne'
+        elif rtype == TYPE_NODETWO:
+            key = 'nodeTwo'
+        elif rtype == TYPE_VERTEX:
+            key = 'vertex'
+        elif rtype == TYPE_AREA:
+            key = 'area' 
+        elif rtype == TYPE_ISLE:
+            key = 'isle'
+        elif rtype == TYPE_DIRECTION:
+            key = 'direction'
+        
+        if key not in ('direction', 'area', 'isle'):
+            self.topology[key] += 1
+        
+        if key in ('area', 'isle'):
+            pen = wx.TRANSPARENT_PEN
+            if key == 'area':
+                brush = wx.Brush(self.settings[key]['color'], wx.SOLID)
+            else:
+                brush = wx.TRANSPARENT_BRUSH
+        else:
+            pen = wx.Pen(self.settings[key]['color'], self.settings['lineWidth'], wx.SOLID)
+            brush = None
+        
+        return pen, brush
+        
+    def _getDrawFlag(self):
+        """!Get draw flag from the settings
+        
+        See vedit.h for list of draw flags.
+        
+        @return draw flag (int)
+        """
+        ret = 0
+        if self.settings['point']['enabled']:
+            ret |= DRAW_POINT
+        if self.settings['line']['enabled']:
+            ret |= DRAW_LINE
+        if self.settings['boundaryNo']['enabled']:
+            ret |= DRAW_BOUNDARYNO
+        if self.settings['boundaryTwo']['enabled']:
+            ret |= DRAW_BOUNDARYTWO
+        if self.settings['boundaryOne']['enabled']:
+            ret |= DRAW_BOUNDARYONE
+        if self.settings['centroidIn']['enabled']:
+            ret |= DRAW_CENTROIDIN
+        if self.settings['centroidOut']['enabled']:
+            ret |= DRAW_CENTROIDOUT
+        if self.settings['centroidDup']['enabled']:
+            ret |= DRAW_CENTROIDDUP
+        if self.settings['nodeOne']['enabled']:
+            ret |= DRAW_NODEONE
+        if self.settings['nodeTwo']['enabled']:
+            ret |= DRAW_NODETWO
+        if self.settings['vertex']['enabled']:
+            ret |= DRAW_VERTEX
+        if self.settings['area']['enabled']:
+            ret |= DRAW_AREA
+        if self.settings['direction']['enabled']:
+            ret |= DRAW_DIRECTION
+        
+        return ret
+        
+    def _isSelected(self, line, force = False):
+        """!Check if vector object selected?
+   
+        @param line feature id
+
+        @return True if vector object is selected
+        @return False if vector object is not selected
+        """
+        if len(self.selected['cats']) < 1 or force:
+            # select by id
+            if line in self.selected['ids']:
+                return True
+        else: 
+            # select by cat
+            cats = self.poCats.contents
+            for i in range(cats.n_cats):
+                if cats.field[i] == self.selected['field'] and \
+                        cats.cat[i] in self.selected['cats']:
+                    # remember id
+                    # -> after drawing all features selected.cats is reseted */
+                    self.selected['ids'].append(line)
+                    return True
+        
+        return False
+
+    def _isDuplicated(self, line):
+        """!Check for already marked duplicates
+        
+        @param line feature id
+
+        @return True line already marked as duplicated
+        @return False not duplicated
+        """
+        return line in self.selected['idsDupl']
+    
+    def _getRegionBox(self):
+        """!Get bound_box() from current region
+
+        @return bound_box
+        """
+        box = bound_box()
+        
+        box.N = self.region['n']
+        box.S = self.region['s']
+        box.E = self.region['e']
+        box.W = self.region['w']
+        box.T = PORT_DOUBLE_MAX
+        box.B = -PORT_DOUBLE_MAX
+        
+        return box
+
+    def DrawMap(self, force = False):
+        """!Draw content of the vector map to the device
+        
+        @param force force drawing
+        @return number of drawn features
+        @return -1 on error
+        """
+        Debug.msg(1, "DisplayDriver.DrawMap(): force=%d", force)
+        
+        if not self.poMapInfo or not self.dc or not self.dcTmp:
+            return -1
+        
+        rlist = Vedit_render_map(self.poMapInfo, byref(self._getRegionBox()), self._getDrawFlag(),
+                                 self.region['center_easting'], self.region['center_northing'],
+                                 self.mapObj.width, self.mapObj.height,
+                                 max(self.region['nsres'], self.region['ewres'])).contents
+        
+        self._resetTopology()
+        
+        self.dc.BeginDrawing()
+        self.dcTmp.BeginDrawing()
+        
+        # draw objects
+        for i in range(rlist.nitems):
+            robj = rlist.item[i].contents
+            self._drawObject(robj)
+        
+        self.dc.EndDrawing()
+        self.dcTmp.EndDrawing()
+        
+        # reset list of selected features by cat 
+        # list of ids - see IsSelected()
+        self.selected['field'] = -1
+        self.selected['cats'] = list()
+        
+    def _getSelectType(self):
+        """!Get type(s) to be selected
+
+        Used by SelectLinesByBox() and SelectLineByPoint()
+        """
+        ftype = 0
+        for feature in (('point',    GV_POINT),
+                        ('line',     GV_LINE),
+                        ('centroid', GV_CENTROID),
+                        ('boundary', GV_BOUNDARY)):
+            if UserSettings.Get(group = 'vdigit', key = 'selectType',
+                                subkey = [feature[0], 'enabled']):
+                ftype |= feature[1]
+        
+        return ftype
+
+    def _validLine(self, line):
+        """!Check if feature id is valid
+
+        @param line feature id
+
+        @return True valid feature id
+        @return False invalid
+        """
+        if line > 0 and line <= Vect_get_num_lines(self.poMapInfo):
+            return True
+        
+        return False
+    
+    def SelectLinesByBox(self, bbox, drawSeg = False, poMapInfo = None):
+        """!Select vector objects by given bounding box
+        
+        If line id is already in the list of selected lines, then it will
+        be excluded from this list.
+        
+        @param bbox bounding box definition
+        @param drawSeg True to draw segments of line
+        @param poMapInfo use external Map_info, None for self.poMapInfo
+
+        @return number of selected features
+        @return None on error
+        """
+        thisMapInfo = poMapInfo is None
+        if not poMapInfo:
+            poMapInfo = self.poMapInfo
+        
+        if not poMapInfo:
+            return None
+        
+        if thisMapInfo:
+            self._drawSegments = drawSeg
+            self._drawSelected = True
+        
+            # select by ids
+            self.selected['cats'] = list()
+        
+        if thisMapInfo:
+            selected = self.selected['ids']
+        else:
+            selected = list()
+        
+        poList = Vect_new_list()
+        x1, y1 = bbox[0]
+        x2, y2 = bbox[1]
+        poBbox = Vect_new_line_struct()
+        Vect_append_point(poBbox, x1, y1, 0.0)
+        Vect_append_point(poBbox, x2, y1, 0.0)
+        Vect_append_point(poBbox, x2, y2, 0.0)
+        Vect_append_point(poBbox, x1, y2, 0.0)
+        Vect_append_point(poBbox, x1, y1, 0.0)
+        
+        Vect_select_lines_by_polygon(poMapInfo, poBbox,
+                                     0, None, # isles
+                                     self._getSelectType(), poList)
+        
+        flist = poList.contents
+        nlines = flist.n_values
+        Debug.msg(1, "DisplayDriver.SelectLinesByBox() num = %d", nlines)
+        for i in range(nlines):
+            line = flist.value[i]
+            if UserSettings.Get(group = 'vdigit', key = 'selectInside',
+                                subkey = 'enabled'):
+                inside = True
+                if not self._validLine(line):
+                    return None
+                Vect_read_line(poMapInfo, self.poPoints, None, line)
+                points = self.poPoints.contents
+                for p in range(points.n_points):
+                    if not Vect_point_in_poly(points.x[p], points.y[p],
+                                              poBbox):
+                        inside = False
+                        break
+                    
+                if not inside:
+                    continue # skip lines just overlapping bbox
+            
+            if not self._isSelected(line):
+                selected.append(line)
+            else:
+                selected.remove(line)
+        
+        Vect_destroy_line_struct(poBbox)
+        Vect_destroy_list(poList)
+        
+        return nlines
+
+    def SelectLineByPoint(self, point, poMapInfo = None):
+        """!Select vector feature by given point in given
+        threshold
+   
+        Only one vector object can be selected. Bounding boxes of
+        all segments are stores.
+        
+        @param point points coordinates (x, y)
+        @param poMapInfo use external Map_info, None for self.poMapInfo
+
+        @return dict {'line' : feature id, 'point' : point on line}
+        @return None nothing found
+        """
+        thisMapInfo = poMapInfo is None
+        if not poMapInfo:
+            poMapInfo = self.poMapInfo
+        
+        if not poMapInfo:
+            return None
+        
+        if thisMapInfo:
+            self._drawSelected = True
+            # select by ids 
+            self.selected['cats'] = list()
+        
+        if thisMapInfo:
+            selected = self.selected['ids']
+        else:
+            selected = list()
+        
+        poFound = Vect_new_list()
+        
+        lineNearest = Vect_find_line_list(poMapInfo, point[0], point[1], 0,
+                                           self._getSelectType(), self.GetThreshold(), self.is3D,
+                                           None, poFound)
+        Debug.msg(1, "DisplayDriver.SelectLineByPoint() found = %d", lineNearest)
+        
+        if lineNearest > 0:
+            if not self._isSelected(lineNearest):
+                selected.append(lineNearest)
+            else:
+                selected.remove(lineNearest)
+        
+        px = c_double()
+        py = c_double()
+        pz = c_double()
+        if not self._validLine(lineNearest):
+            return None
+	ftype = Vect_read_line(poMapInfo, self.poPoints, self.poCats, lineNearest)
+	Vect_line_distance (self.poPoints, point[0], point[1], 0.0, self.is3D,
+			    byref(px), byref(py), byref(pz),
+			    None, None, None)
+        
+	# check for duplicates 
+	if self.settings['highlightDupl']['enabled']:
+            found = poFound.contents
+	    for i in range(found.n_values):
+		line = found.value[i]
+		if line != lineNearest:
+                    selected.append(line)
+	    
+            self.GetDuplicates()
+	    
+	    for i in range(found.n_values):
+		line = found.value[i]
+		if line != lineNearest and not self._isDuplicated(line):
+                    selected.remove(line)
+        
+        Vect_destroy_list(poFound)
+        
+        if thisMapInfo:
+            # drawing segments can be very expensive
+            # only one features selected
+            self._drawSegments = True
+        
+        return { 'line'  : lineNearest,
+                 'point' : (px.value, py.value, pz.value) }
+    
+    def _listToIList(self, plist):
+        """!Generate from list struct_ilist
+        """
+        ilist = Vect_new_list()
+        for val in plist:
+            Vect_list_append(ilist, val)
+        
+        return ilist
+        
+    def GetSelectedIList(self, ilist = None):
+        """!Get list of selected objects as struct_ilist
+
+        Returned IList must be freed by Vect_destroy_list().
+        
+        @return struct_ilist
+        """
+        if ilist:
+            return self._listToIList(ilist)
+        
+        return self._listToIList(self.selected['ids'])
+        
+    def GetSelected(self, grassId = True):
+        """!Get ids of selected objects
+        
+        @param grassId True for feature id, False for PseudoDC id
+        
+        @return list of ids of selected vector objects
+        """
+        if grassId:
+            return self.selected['ids']
+        
+        dc_ids = list()
+        
+        if not self._drawSegments:
+            dc_ids.append(1)
+        elif len(self.selected['ids']) > 0:
+            # only first selected feature
+            Vect_read_line(self.poMapInfo, self.poPoints, None,
+                           self.selected['ids'][0])
+            points = self.poPoints.contents
+            # node - segment - vertex - segment - node
+            for i in range(1, 2 * points.n_points):
+                dc_ids.append(i)
+        
+        return dc_ids
+        
+    def SetSelected(self, ids, layer = -1):
+        """!Set selected vector objects
+
+        @param list of ids (None to unselect features)
+        @param layer layer number for features selected based on category number
+        """
+        if ids:
+            self._drawSelected = True
+        else:
+            self._drawSelected = False
+        
+        if layer > 0:
+            selected.field = layer
+            self.selected['cats'] = ids
+        else:
+            field = -1
+            self.selected['ids'] = ids
+        
+    def GetSelectedVertex(self, pos):
+        """!Get PseudoDC vertex id of selected line
+
+        Set bounding box for vertices of line.
+        
+        @param pos position
+        
+        @return id of center, left and right vertex
+        @return 0 no line found
+        @return -1 on error
+        """
+        returnId = list()
+        # only one object can be selected
+        if len(self.selected['ids']) != 1 or not self._drawSegments:
+            return returnId
+        
+        startId = 1
+        line = self.selected['ids'][0]
+        
+        if not self._validLine(line):
+            return -1
+        ftype = Vect_read_line(self.poMapInfo, self.poPoints, self.poCats, line)
+        
+        minDist = 0.0
+        Gid = -1
+        # find the closest vertex (x, y)
+        DCid = 1
+        points = self.poPoints.contents
+        for idx in range(points.n_points):
+            dist = Vect_points_distance(pos[0], pos[1], 0.0,
+                                        points.x[idx], points.y[idx], points.z[idx], 0)
+            
+            if idx == 0:
+                minDist = dist
+                Gid     = idx
+            else:
+                if minDist > dist:
+                    minDist = dist
+                    Gid = idx
+            
+            vx, vy = self._cell2Pixel(points.x[idx], points.y[idx], points.z[idx])
+            rect = wx.Rect(vx, vy, 0, 0)
+            self.dc.SetIdBounds(DCid, rect)
+            DCid += 2
+        
+        if minDist > self.GetThreshold():
+            return returnId
+        
+        # translate id
+        DCid = Gid * 2 + 1
+        
+        # add selected vertex
+        returnId.append(DCid)
+        # left vertex
+        if DCid == startId:
+            returnId.append(-1)
+        else:
+            returnId.append(DCid - 2)
+        # right vertex
+        if DCid == (points.n_points - 1) * 2 + startId:
+            returnId.append(-1)
+        else:
+            returnId.append(DCid + 2)
+        
+        return returnId
+
+    def DrawSelected(self, flag):
+        """!Draw selected features
+        
+        @param flag True to draw selected features
+        """
+        self._drawSelected = bool(flag)
+        
+    def CloseMap(self):
+        """!Close vector map
+        
+        @return 0 on success
+        @return non-zero on error
+        """
+        ret = 0
+        if self.poMapInfo:
+            # rebuild topology
+            Vect_build_partial(self.poMapInfo, GV_BUILD_NONE)
+            Vect_build(self.poMapInfo)
+
+            # close map and store topo/cidx
+            ret = Vect_close(self.poMapInfo)
+            del self.mapInfo
+            self.poMapInfo = self.mapInfo = None
+        
+        return ret
+    
+    def OpenMap(self, name, mapset, update = True):
+        """!Open vector map by the driver
+        
+        @param name name of vector map to be open
+        @param mapset name of mapset where the vector map lives
+   
+        @return map_info
+        @return None on error
+        """
+        Debug.msg("DisplayDriver.OpenMap(): name=%s mapset=%s updated=%d",
+                  name, mapset, update)
+        if not self.mapInfo:
+            self.mapInfo = Map_info()
+            self.poMapInfo = pointer(self.mapInfo)
+        
+        # open existing map
+        if update:
+            ret = Vect_open_update(self.poMapInfo, name, mapset)
+        else:
+            ret = Vect_open_old(self.poMapInfo, name, mapset)
+        self.is3D = Vect_is_3d(self.poMapInfo)
+        
+        if ret == -1: # error
+            del self.mapInfo
+            self.poMapInfo = self.mapInfo = None
+        elif ret < 2:
+            dlg = wx.MessageDialog(parent = self.window,
+                                   message = _("Topology for vector map <%s> is not available. "
+                                               "Topology is required by digitizer. Do you want to "
+                                               "rebuild topology (takes some time) and open the vector map "
+                                               "for editing?") % name,
+                                   caption=_("Topology missing"),
+                                   style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION | wx.CENTRE)
+            ret = dlg.ShowModal()
+            if ret != wx.ID_YES:
+                del self.mapInfo
+                self.poMapInfo = self.mapInfo = None
+            else:
+                Vect_build(self.poMapInfo)
+        
+        return self.poMapInfo
+    
+    def GetMapBoundingBox(self):
+        """!Get bounding box of (opened) vector map layer
+
+        @return (w,s,b,e,n,t)
+        """
+        if not self.poMapInfo:
+            return None
+        
+        bbox = bound_box()
+        Vect_get_map_box(self.poMapInfo, byref(bbox))
+
+        return bbox.W, bbox.S, bbox.B, \
+            bbox.E, bbox.N, bbox.T
+    
+    def UpdateSettings(self, alpha = 255):
+        """!Update display driver settings
+
+        @todo map units
+        
+        @alpha color value for aplha channel
+        """
+        color = dict()
+        for key in self.settings.keys():
+            if key == 'lineWidth':
+                self.settings[key] = int(UserSettings.Get(group = 'vdigit', key = 'lineWidth',
+                                                          subkey = 'value'))
+                continue
+            
+            color = wx.Color(UserSettings.Get(group = 'vdigit', key = 'symbol',
+                                              subkey = [key, 'color'])[0],
+                             UserSettings.Get(group = 'vdigit', key = 'symbol',
+                                              subkey = [key, 'color'])[1],
+                             UserSettings.Get(group = 'vdigit', key = 'symbol',
+                                              subkey = [key, 'color'])[2])
+            
+            if key == 'highlight':
+                self.settings[key] = color
+                continue
+            
+            if key == 'highlightDupl':
+                self.settings[key]['enabled'] = bool(UserSettings.Get(group = 'vdigit', key = 'checkForDupl',
+                                                                      subkey = 'enabled'))
+            else:
+                self.settings[key]['enabled'] = bool(UserSettings.Get(group = 'vdigit', key = 'symbol',
+                                                                      subkey = [key, 'enabled']))
+            
+            self.settings[key]['color'] = color
+        
+    def UpdateRegion(self):
+        """!Update geographical region used by display driver
+        """
+        self.region = self.mapObj.GetCurrentRegion()
+        
+    def GetThreshold(self, type = 'snapping', value = None, units = None):
+        """!Return threshold value in map units
+        
+        @param type snapping mode (node, vertex)
+        @param value threshold to be set up
+        @param units units (map, screen)
+
+        @return threshold value
+        """
+        if value is None:
+            value = UserSettings.Get(group = 'vdigit', key = type, subkey = 'value')
+        
+        if units is None:
+            units = UserSettings.Get(group = 'vdigit', key = type, subkey = 'units')
+        
+        if value < 0:
+            value = (self.region['nsres'] + self.region['ewres']) / 2.0
+        
+        if units == "screen pixels":
+            # pixel -> cell
+            res = max(self.region['nsres'], self.region['ewres'])
+            return value * res
+        
+        return value
+    
+    def GetDuplicates(self):
+        """!Return ids of (selected) duplicated vector features
+        """
+        if not self.poMapInfo:
+            return
+        
+        ids = dict()
+        APoints = Vect_new_line_struct()
+        BPoints = Vect_new_line_struct()
+        
+        self.selected['idsDupl'] = list()
+        
+        for i in range(len(self.selected['ids'])):
+            line1 = self.selected['ids'][i]
+            if self._isDuplicated(line1):
+                continue
+            
+            Vect_read_line(self.poMapInfo, APoints, None, line1)
+            
+            for line2 in self.selected['ids']:
+                if line1 == line2 or self._isDuplicated(line2):
+                    continue
+                
+                Vect_read_line(self.poMapInfo, BPoints, None, line2)
+	    
+                if Vect_line_check_duplicate(APoints, BPoints, WITHOUT_Z):
+                    if not ids.has_key(i):
+                        ids[i] = list()
+                        ids[i].append((line1, self._getCatString(line1)))
+                        self.selected['idsDupl'].append(line1)
+                    
+                    ids[i].append((line2, self._getCatString(line2)))
+                    self.selected['idsDupl'].append(line2)
+        
+        Vect_destroy_line_struct(APoints)
+        Vect_destroy_line_struct(BPoints)
+
+        return ids
+    
+    def _getCatString(self, line):
+        Vect_read_line(self.poMapInfo, None, self.poCats, line)
+        
+        cats = self.poCats.contents
+        catsDict = dict()
+        for i in range(cats.n_cats):
+            layer = cats.field[i]
+            if not catsDict.has_key(layer):
+                catsDict[layer] = list()
+            catsDict[layer].append(cats.cat[i])
+        
+        catsStr = ''
+        for l, c in catsDict.iteritems():
+            catsStr = '%d: (%s)' % (l, ','.join(map(str, c)))
+        
+        return catsStr
+
+    def UnSelect(self, lines):
+        """!Unselect vector features
+
+        @param lines list of feature id(s)
+        """
+        checkForDupl = False
+
+        for line in lines:
+            if self._isSelected(line):
+                self.selected['ids'].remove(line)
+            if self.settings['highlightDupl']['enabled'] and self._isDuplicated(line):
+                checkForDupl = True
+
+        if checkForDupl:
+            self.GetDuplicates()
+        
+        return len(self.selected['ids'])
+    
+

Modified: grass/branches/develbranch_6/gui/wxpython/icons/grass2_icons.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/icons/grass2_icons.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/icons/grass2_icons.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -43,8 +43,9 @@
     ## add feature
     "digAddPoint": 'point-create.png',
     "digAddLine" : 'line-create.png',
-    "digAddBoundary": 'polygon-create.png',
+    "digAddBoundary": 'boundary-create.png',
     "digAddCentroid": 'centroid-create.png',
+    "digAddArea": 'polygon-create.png',
     ## vertex
     "digAddVertex" : 'vertex-create.png',
     "digMoveVertex" : 'vertex-move.png',
@@ -84,6 +85,7 @@
     "addlabels"  : 'layer-label-add.png',
     "delcmd"     : 'layer-remove.png',
     "attrtable"  : 'table.png',
+    "vdigit"     : 'edit.png',
     "addrgb"     : 'layer-rgb-add.png',
     "addhis"     : 'layer-his-add.png',
     "addthematic": 'layer-vector-thematic-add.png',

Modified: grass/branches/develbranch_6/gui/wxpython/icons/grass_icons.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/icons/grass_icons.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/icons/grass_icons.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -33,6 +33,7 @@
     "digAddLine" : 'new.line.gif',
     "digAddBoundary": 'new.boundary.gif',
     "digAddCentroid": 'new.centroid.gif',
+    "digAddArea": wx.ART_ERROR,
     ## vertex
     "digAddVertex" : 'add.vertex.gif',
     "digMoveVertex" : 'move.vertex.gif',
@@ -67,6 +68,7 @@
     "addovl"     : 'module-d.grid.gif',
     "delcmd"     : 'edit-cut.gif',
     "attrtable"  : 'db-values.gif',
+    "vdigit"     :  wx.ART_ERROR,
     "addrgb"     : 'module-d.rgb.gif',
     "addhis"     : 'channel-his.gif',
     "addshaded"  : 'module-d.shadedmap.gif',

Modified: grass/branches/develbranch_6/gui/wxpython/icons/icon.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/icons/icon.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/icons/icon.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -10,7 +10,7 @@
 Classes:
  - MetaIcon
 
-(C) 2007-2008, 2010 by the GRASS Development Team
+(C) 2007-2008, 2010-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.
@@ -177,9 +177,9 @@
                              label=_("Print display")),
     # layer manager
     "newdisplay" : MetaIcon (img=Icons["newdisplay"],
-                             label=_("Start new display")),
+                             label=_("Start new map display")),
     "workspaceNew" : MetaIcon (img=Icons["fileNew"],
-                               label=_("Create new workspace file (Ctrl+N)")),
+                               label=_("Create new workspace (Ctrl+N)")),
     "workspaceLoad" : MetaIcon (img=Icons["fileLoad"],
                                 label=_("Load map layers into workspace (Ctrl+L)")),
     "workspaceOpen" : MetaIcon (img=Icons["fileOpen"],
@@ -210,6 +210,8 @@
                              label=_("Quit")),
     "attrtable"  : MetaIcon (img=Icons["attrtable"],
                              label=_("Show attribute table")),
+    "vdigit"     : MetaIcon (img=Icons["vdigit"],
+                             label=_("Edit vector maps")),
     "addrgb"     : MetaIcon (img=Icons["addrgb"],
                              label=_("Add RGB map layer")),
     "addhis"     : MetaIcon (img=Icons["addhis"],
@@ -252,6 +254,9 @@
     "digAddCentroid": MetaIcon (img=Icons["digAddCentroid"],
                                 label=_("Digitize new centroid"),
                              desc=_("Left: new point")),
+    "digAddArea": MetaIcon (img=Icons["digAddArea"],
+                                label=_("Digitize new area (composition of bondaries without category and one centroid with category)"),
+                             desc=_("Left: new point")),
     "digAddVertex": MetaIcon (img=Icons["digAddVertex"],
                               label=_("Add new vertex"),
                               desc=_("Left: Select; Middle: Unselect; Right: Confirm")),

Modified: grass/branches/develbranch_6/gui/wxpython/icons/silk_icons.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/icons/silk_icons.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/icons/silk_icons.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -48,6 +48,7 @@
     "digAddLine" : 'vector_add.png',
     "digAddBoundary": 'shape_handles.png',
     "digAddCentroid": 'shape_square_add.png',
+    "digAddArea": wx.ART_ERROR,
     ## vertex
     "digAddVertex" : 'chart_line_add.png',
     "digMoveVertex" : 'chart_line.png',
@@ -87,6 +88,7 @@
     "addlabels"  : 'tag_blue_add.png',
     "delcmd"     : 'bin_closed.png',
     "attrtable"  : 'application_view_columns.png',
+    "vdigit"     : wx.ART_ERROR,
     "addrgb"     : 'rgb.png',
     "addhis"     : 'his.png',
     "addthematic": 'thematic.png',

Modified: grass/branches/develbranch_6/gui/wxpython/wxgui.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/wxgui.py	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/wxgui.py	2011-02-03 14:53:02 UTC (rev 45292)
@@ -113,8 +113,8 @@
 
         # initialize variables
         self.disp_idx      = 0            # index value for map displays and layer trees
-        self.curr_page     = ''           # currently selected page for layer tree notebook
-        self.curr_pagenum  = ''           # currently selected page number for layer tree notebook
+        self.curr_page     = None         # currently selected page for layer tree notebook
+        self.curr_pagenum  = None         # currently selected page number for layer tree notebook
         self.workspaceFile = workspace    # workspace file
         self.workspaceChanged = False     # track changes in workspace
         self.georectifying = None         # reference to GCP class or None
@@ -429,6 +429,45 @@
             cmd = self.GetMenuCmd(event)
         menuform.GUI().ParseCommand(cmd, parentframe = self)
 
+    def OnVDigit(self, event):
+        """!Start vector digitizer
+        """
+        if not self.curr_page:
+            self.MsgNoLayerSelected()
+            return
+        
+        tree = self.GetLayerTree()
+        layer = tree.layer_selected
+        # no map layer selected
+        if not layer:
+            self.MsgNoLayerSelected()
+            return
+        
+        # available only for vector map layers
+        try:
+            mapLayer = tree.GetPyData(layer)[0]['maplayer']
+        except:
+            mapLayer = None
+        
+        if not mapLayer or mapLayer.GetType() != 'vector':
+            gcmd.GMessage(parent = self,
+                          message = _("Selected map layer is not vector."))
+            return
+        
+        if mapLayer.GetMapset() != grass.gisenv()['MAPSET']:
+            gcmd.GMessage(parent = self,
+                          message = _("Editing is allowed only for vector maps from the "
+                                      "current mapset."))
+            return
+        
+        if not tree.GetPyData(layer)[0]:
+            return
+        dcmd = tree.GetPyData(layer)[0]['cmd']
+        if not dcmd:
+            return
+        
+        tree.OnStartEditing(None)
+        
     def OnRunScript(self, event):
         """!Run script"""
         # open dialog and choose script file
@@ -514,16 +553,13 @@
         win.CentreOnScreen()
         win.Show(True)  
         
-    def OnWorkspace(self, event):
-        """!Workspace menu (new, load, import)"""
+    def _popupMenu(self, data):
+        """!Create popup menu
+        """
         point = wx.GetMousePosition()
         menu = wx.Menu()
-
-        for key, handler in (('workspaceNew',  self.OnWorkspaceNew),
-                             ('workspaceLoad', self.OnWorkspaceLoad),
-                             (None, None),
-                             ('rastImport',    self.OnImportGdalLayers),
-                             ('vectImport',    self.OnImportOgrLayers)):
+        
+        for key, handler in data:
             if key is None:
                 menu.AppendSeparator()
                 continue
@@ -536,6 +572,23 @@
         self.PopupMenu(menu)
         menu.Destroy()
 
+    def OnNewMenu(self, event):
+        """!New display/workspace menu
+        """
+        self._popupMenu((('newdisplay', self.OnNewDisplay),
+                         ('workspaceNew',  self.OnWorkspaceNew)))
+
+    def OnLoadMenu(self, event):
+        """!Load maps menu (new, load, import, link)
+        """
+        self._popupMenu((('workspaceLoad', self.OnWorkspaceLoad),
+                         (None, None),
+                         ('rastImport',    self.OnImportGdalLayers),
+                         ('rastLink',      self.OnLinkGdalLayers),
+                         (None, None),
+                         ('vectImport',    self.OnImportOgrLayers),
+                         ('vectLink',      self.OnLinkOgrLayers)))
+        
     def OnWorkspaceNew(self, event = None):
         """!Create new workspace file
 
@@ -1077,7 +1130,8 @@
             self.MsgNoLayerSelected()
             return
         
-        layer = self.curr_page.maptree.layer_selected
+        tree = self.GetLayerTree()
+        layer = tree.layer_selected
         # no map layer selected
         if not layer:
             self.MsgNoLayerSelected()
@@ -1085,21 +1139,18 @@
         
         # available only for vector map layers
         try:
-            maptype = self.curr_page.maptree.GetPyData(layer)[0]['maplayer'].type
+            maptype = tree.GetPyData(layer)[0]['maplayer'].type
         except:
             maptype = None
         
         if not maptype or maptype != 'vector':
-            wx.MessageBox(parent = self,
-                          message = _("Attribute management is available only "
-                                    "for vector maps."),
-                          caption = _("Message"),
-                          style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
+            gcmd.GMessage(parent = self,
+                          message = _("Selected map layer is not vector."))
             return
         
-        if not self.curr_page.maptree.GetPyData(layer)[0]:
+        if not tree.GetPyData(layer)[0]:
             return
-        dcmd = self.curr_page.maptree.GetPyData(layer)[0]['cmd']
+        dcmd = tree.GetPyData(layer)[0]['cmd']
         if not dcmd:
             return
         
@@ -1193,32 +1244,16 @@
         if not self.curr_page:
             self.NewDisplay(show = True)
         
-        point = wx.GetMousePosition()
-        rastmenu = wx.Menu()
+        self._popupMenu((('addrast3d', self.OnAddRaster3D),
+                         (None, None),
+                         ('addrgb',    self.OnAddRasterRGB),
+                         ('addhis',    self.OnAddRasterHIS),
+                         (None, None),
+                         ('addshaded', self.OnAddRasterShaded),
+                         (None, None),
+                         ('addrarrow', self.OnAddRasterArrow),
+                         ('addrnum',   self.OnAddRasterNum)))
         
-        for key, handler in (('addrast3d', self.OnAddRaster3D),
-                             (None, None),
-                             ('addrgb',    self.OnAddRasterRGB),
-                             ('addhis',    self.OnAddRasterHIS),
-                             (None, None),
-                             ('addshaded', self.OnAddRasterShaded),
-                             (None, None),
-                             ('addrarrow', self.OnAddRasterArrow),
-                             ('addrnum',   self.OnAddRasterNum)):
-            if key is None:
-                rastmenu.AppendSeparator()
-                continue
-            
-            item = wx.MenuItem(rastmenu, wx.ID_ANY, Icons[key].GetLabel())
-            item.SetBitmap(Icons[key].GetBitmap(self.iconsize))
-            rastmenu.AppendItem(item)
-            self.Bind(wx.EVT_MENU, handler, item)
-            
-        # Popup the menu. If an item is selected then its handler
-        # will be called before PopupMenu returns.
-        self.PopupMenu(rastmenu)
-        rastmenu.Destroy()
-        
         # show map display
         self.curr_page.maptree.mapdisplay.Show()
         
@@ -1237,25 +1272,9 @@
         if not self.curr_page:
             self.NewDisplay(show = True)
 
-        point = wx.GetMousePosition()
-        vectmenu = wx.Menu()
+        self._popupMenu((('addthematic', self.OnAddVectorTheme),
+                         ('addchart',    self.OnAddVectorChart)))
         
-        for key, handler in (('addthematic', self.OnAddVectorTheme),
-                             ('addchart',    self.OnAddVectorChart)):
-            if key is None:
-                rastmenu.AppendSeparator()
-                continue
-            
-            item = wx.MenuItem(vectmenu, wx.ID_ANY, Icons[key].GetLabel())
-            item.SetBitmap(Icons[key].GetBitmap(self.iconsize))
-            vectmenu.AppendItem(item)
-            self.Bind(wx.EVT_MENU, handler, item)
-        
-        # Popup the menu.  If an item is selected then its handler
-        # will be called before PopupMenu returns.
-        self.PopupMenu(vectmenu)
-        vectmenu.Destroy()
-
         # show map display
         self.curr_page.maptree.mapdisplay.Show()
 
@@ -1275,29 +1294,13 @@
         if not self.curr_page:
             self.NewDisplay(show = True)
 
-        point = wx.GetMousePosition()
-        ovlmenu = wx.Menu()
-
-        for key, handler in (('addgrid',     self.OnAddGrid),
-                             ('addlabels',   self.OnAddLabels),
-                             ('addgeodesic', self.OnAddGeodesic),
-                             ('addrhumb',    self.OnAddRhumb),
-                             (None, None),
-                             ('addcmd',      self.OnAddCommand)):
-            if key is None:
-                ovlmenu.AppendSeparator()
-                continue
-            
-            item = wx.MenuItem(ovlmenu, wx.ID_ANY, Icons[key].GetLabel())
-            item.SetBitmap(Icons[key].GetBitmap(self.iconsize))
-            ovlmenu.AppendItem(item)
-            self.Bind(wx.EVT_MENU, handler, item)
+        self._popupMenu((('addgrid',     self.OnAddGrid),
+                         ('addlabels',   self.OnAddLabels),
+                         ('addgeodesic', self.OnAddGeodesic),
+                         ('addrhumb',    self.OnAddRhumb),
+                         (None, None),
+                         ('addcmd',      self.OnAddCommand)))
         
-        # Popup the menu.  If an item is selected then its handler
-        # will be called before PopupMenu returns.
-        self.PopupMenu(ovlmenu)
-        ovlmenu.Destroy()
-
         # show map display
         self.curr_page.maptree.mapdisplay.Show()
         

Modified: grass/branches/develbranch_6/gui/wxpython/wxpythonlib.dox
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/wxpythonlib.dox	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/gui/wxpython/wxpythonlib.dox	2011-02-03 14:53:02 UTC (rev 45292)
@@ -266,10 +266,7 @@
 \subsection vdigit Vector digitizer
 
 - gui_modules/vdigit.py
- - gui_modules::vdigit::AbstractDigit
  - gui_modules::vdigit::VDigit
- - gui_modules::vdigit::AbstractDisplayDriver
- - gui_modules::vdigit::CDisplayDriver
  - gui_modules::vdigit::VDigitSettingsDialog
  - gui_modules::vdigit::VDigitCategoryDialog
  - gui_modules::vdigit::CategoryListCtrl
@@ -277,6 +274,13 @@
  - gui_modules::vdigit::VDigitDuplicatesDialog
  - gui_modules::vdigit::CheckListFeature
 
+- gui_modules/wxvdriver.py
+ - gui_modules::wxvdriver::DisplayDriver
+ 
+- gui_modules/wxvdigit.py
+ - gui_modules::wxvdigit::VDigitError
+ - gui_modules::wxvdigit::IVDigit
+
 \subsection wxnviz 3D view mode (wxNviz)
 
 - gui_modules/nviz_mapdisp.py

Modified: grass/branches/develbranch_6/include/vedit.h
===================================================================
--- grass/branches/develbranch_6/include/vedit.h	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/include/vedit.h	2011-02-03 14:53:02 UTC (rev 45292)
@@ -12,6 +12,55 @@
 #define QUERY_LENGTH   0	/* select by line length */
 #define QUERY_DANGLE   1	/* select dangles */
 
+/* used by Vedit_render_map() */
+#define TYPE_POINT           0x01
+#define TYPE_LINE	     0x02
+#define TYPE_BOUNDARYNO      0x04
+#define TYPE_BOUNDARYTWO     0x08
+#define TYPE_BOUNDARYONE     0x10
+#define TYPE_CENTROIDIN      0x20
+#define TYPE_CENTROIDOUT     0x40
+#define TYPE_CENTROIDDUP     0x80
+#define TYPE_NODEONE         0x100
+#define TYPE_NODETWO         0x200
+#define TYPE_VERTEX          0x400
+#define TYPE_AREA            0x800
+#define TYPE_ISLE            0x1000
+#define TYPE_DIRECTION       0x2000
+
+#define DRAW_POINT           0x01
+#define DRAW_LINE	     0x02
+#define DRAW_BOUNDARYNO      0x04
+#define DRAW_BOUNDARYTWO     0x08
+#define DRAW_BOUNDARYONE     0x10
+#define DRAW_CENTROIDIN      0x20
+#define DRAW_CENTROIDOUT     0x40
+#define DRAW_CENTROIDDUP     0x80
+#define DRAW_NODEONE         0x100
+#define DRAW_NODETWO         0x200
+#define DRAW_VERTEX          0x400
+#define DRAW_AREA            0x800
+#define DRAW_DIRECTION       0x1000
+
+struct rpoint {
+    /* screen coordinates */
+    int x, y;
+};
+
+struct robject {
+    /* object to be rendered */
+    int            fid;       /* feature id */
+    int            type;
+    int            npoints;
+    struct rpoint *point;     /* list of points */
+};
+
+struct robject_list {
+    /* list of objects to be rendered */
+    int              nitems;
+    struct robject **item;
+};
+
 /* break.c */
 int Vedit_split_lines(struct Map_info *, struct ilist *,
 		      struct line_pnts *, double, struct ilist *);
@@ -45,6 +94,10 @@
 int Vedit_move_lines(struct Map_info *, struct Map_info **, int,
 		     struct ilist *, double, double, double, int, double);
 
+/* render.c */
+struct robject_list *Vedit_render_map(struct Map_info *, struct bound_box *, int,
+				      double, double, int, int, double);
+
 /* select.c */
 int Vedit_select_by_query(struct Map_info *,
 			  int, int, double, int, struct ilist *);


Property changes on: grass/branches/develbranch_6/lib/vector/vedit
___________________________________________________________________
Modified: svn:ignore
   - OBJ.*

   + OBJ.*




Property changes on: grass/branches/develbranch_6/lib/vector/vedit/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Modified: grass/branches/develbranch_6/lib/vector/vedit/break.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/break.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/break.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,16 +1,14 @@
-/**
-   \file vector/vedit/break.c
+/*!
+  \file lib/vector/vedit/break.c
 
-   \brief Vedit library - split, break, connect lines
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+  \brief Vedit library - split, break, connect lines
+  
+  (C) 2007-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <math.h>
@@ -19,17 +17,17 @@
 static int connect_lines(struct Map_info *, int, int, int,
 			 double, struct ilist *);
 
-/**
-   \brief Split selected lines on given position
-   
-   \param Map vector map
-   \param List list of selected lines
-   \param coord points location
-   \param[out] List_updated list of rewritten features (or NULL)
-
-   \return number of modified lines
-   \return -1 on error
- */
+/*!
+  \brief Split selected lines on given position
+  
+  \param Map pointer to Map_info
+  \param List list of selected lines
+  \param coord points location
+  \param[out] List_updated list of rewritten features (or NULL)
+  
+  \return number of modified lines
+  \return -1 on error
+*/
 int Vedit_split_lines(struct Map_info *Map, struct ilist *List,
 		      struct line_pnts *coord, double thresh,
 		      struct ilist *List_updated)
@@ -130,20 +128,20 @@
     return nlines_modified;
 }
 
-/**
-   \brief Connect lines in given threshold
- 
-   <pre>
-        \         	     \
+/*!
+  \brief Connect lines in given threshold
+  
+  \code
+        \	             \
    id1   \           ->	      \
                                \
    id2 ---------           -----+---
-   </pre>
+   \endcode
 
    If two lines are selected and <i>thresh</i> is -1, no limit is
    applied.
 
-   \param Map vector map
+   \param Map pointer to Map_info
    \param List list of selected lines
    \param thresh threshold value
 

Modified: grass/branches/develbranch_6/lib/vector/vedit/cats.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/cats.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/cats.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,34 +1,31 @@
+/*!
+  \file lib/vector/vedit/cats.c
 
-/**
-   \file vector/vedit/cats.c
+  \brief Vedit library - category manipulation
+  
+  (C) 2006-2008 by the GRASS Development Team
 
-   \brief Vedit library - category manipulation
-
-   (C) 2006-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Jachym Cepicky <jachym.cepicky gmail.com>
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2006-2008
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Jachym Cepicky <jachym.cepicky gmail.com>
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/glocale.h>
 #include <grass/vedit.h>
 
-/**
-   \brief Add / remove categories
-
-   \param Map vector map
-   \param List list of selected primitives
-   \param layer layer number
-   \param del action (non-zero for delete otherwise add)
-   \param cats_list list of category numbers
-
-   \return number of modified primitives
-   \return -1 on error
+/*!
+  \brief Add / remove categories
+  
+  \param Map pointer to Map_info
+  \param List list of selected primitives
+  \param layer layer number
+  \param del action (non-zero for delete otherwise add)
+  \param cats_list list of category numbers
+  
+  \return number of modified primitives
+  \return -1 on error
 */
 int Vedit_modify_cats(struct Map_info *Map, struct ilist *List,
 		      int layer, int del, struct cat_list *Clist)

Modified: grass/branches/develbranch_6/lib/vector/vedit/chtype.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/chtype.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/chtype.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,33 +1,30 @@
-
-/**
-   \file vector/vedit/chtype.c
-
-   \brief Vedit library - change primitives type
-
-    (C) 2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2008
+/*!
+  \file vector/vedit/chtype.c
+  
+  \brief Vedit library - change primitives type
+  
+  (C) 2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Change primitive type
+/*!
+  \brief Change primitive type
+  
+  Supported conversions:
+   - point <-> centroid
+   - line <-> boundary
 
-   Supported conversions:
-    - point <-> centroid
-    - line <-> boundary
-
-    \param Map vector map
-    \param List list of selected primitives
-
-    \return number of modified primitives
-    \return -1 on error
+   \param Map pointer to Map_info
+   \param List list of selected primitives
+   
+   \return number of modified primitives
+   \return -1 on error
 */
 int Vedit_chtype_lines(struct Map_info *Map, struct ilist *List)
 {


Property changes on: grass/branches/develbranch_6/lib/vector/vedit/chtype.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc

Modified: grass/branches/develbranch_6/lib/vector/vedit/copy.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/copy.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/copy.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,32 +1,29 @@
+/*!
+  \file lib/vector/vedit/copy.c
 
-/**
-   \file vector/vedit/copy.c
-
-   \brief Vedit library - copy primitives
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Jachym Cepicky <jachym.cepicky gmail.com>
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+  \brief Vedit library - copy primitives
+  
+  (C) 2007-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Jachym Cepicky <jachym.cepicky gmail.com>
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Copy selected primitives
-
-   \param Map vector map copy to
-   \param FromMap vector map copy from (if not given use Map)
-   \param List list of selected primitives (to be copied)
-
-   \return number of copied primitives
-   \return -1 on error 
- */
+/*!
+  \brief Copy selected primitives
+  
+  \param Map pointer to Map_info copy to
+  \param FromMap vector map copy from (if not given use Map)
+  \param List list of selected primitives (to be copied)
+  
+  \return number of copied primitives
+  \return -1 on error 
+*/
 int Vedit_copy_lines(struct Map_info *Map, struct Map_info *FromMap,
 		     struct ilist *List)
 {

Modified: grass/branches/develbranch_6/lib/vector/vedit/delete.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/delete.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/delete.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,30 +1,27 @@
+/*!
+  \file lib/vector/vedit/delete.c
 
-/**
-   \file vector/vedit/delete.c
+  \brief Vedit library - delete primitives
 
-   \brief Vedit library - delete primitives
+  (C) 2007-2008 by the GRASS Development Team
 
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Delete selected primitives
-
-   \param Map vector map
-   \param List list of primitives to be deleted
-
-   \return number of deleted primitives
-   \return -1 on on error
- */
+/*!
+  \brief Delete selected primitives
+  
+  \param Map pointer to Map_info
+  \param List list of primitives to be deleted
+  
+  \return number of deleted primitives
+  \return -1 on on error
+*/
 int Vedit_delete_lines(struct Map_info *Map, struct ilist *List)
 {
     int i, line;

Modified: grass/branches/develbranch_6/lib/vector/vedit/distance.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/distance.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/distance.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,31 +1,28 @@
+/*!
+  \file lib/vector/vedit/distance.c
 
-/**
-   \file vector/vedit/distance.c
+  \brief Vedit library - distance calculation
+  
+  (C) 2007-2008 by the GRASS Development Team
 
-   \brief Vedit library - distance calculation
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Calculate distances between two lines
- 
-   \todo LL projection
-
-   \param Points1 first line geometry
-   \param Points2 second line geometry
-   \param[out] index of minimal distance
-
-   \return minimal distance betwen two lines (their nodes)
+/*!
+  \brief Calculate distances between two lines
+  
+  \todo LL projection
+  
+  \param Points1 first line geometry
+  \param Points2 second line geometry
+  \param[out] index of minimal distance
+  
+  \return minimal distance betwen two lines (their nodes)
 */
 double Vedit_get_min_distance(struct line_pnts *Points1,
 			      struct line_pnts *Points2, int with_z,


Property changes on: grass/branches/develbranch_6/lib/vector/vedit/distance.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass/branches/develbranch_6/lib/vector/vedit/flip.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/flip.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/flip.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,30 +1,27 @@
-
-/**
-   \file vector/vedit/flip.c
-
-   \brief Vedit library - flip lines
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+/*!
+  \file lib/vector/vedit/flip.c
+   
+  \brief Vedit library - flip lines
+  
+  (C) 2007-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Flip direction of selected lines
-
-   \param Map vector map
-   \param List list of selected lines
-
-   \return number of modified lines
-   \return -1 on error
- */
+/*!
+  \brief Flip direction of selected lines
+  
+  \param Map pointer to Map_info
+  \param List list of selected lines
+  
+  \return number of modified lines
+  \return -1 on error
+*/
 int Vedit_flip_lines(struct Map_info *Map, struct ilist *List)
 {
     struct line_cats *Cats;

Modified: grass/branches/develbranch_6/lib/vector/vedit/merge.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/merge.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/merge.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,49 +1,46 @@
-
-/**
-   \file vector/vedit/merge.c
-
-   \brief Vedit library - merge lines
-
-   (C) 2006-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Jachym Cepicky <jachym.cepicky gmail.com>
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2006-2008
+/*!
+  \file lib/vector/vedit/merge.c
+  
+  \brief Vedit library - merge lines
+  
+  (C) 2006-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Jachym Cepicky <jachym.cepicky gmail.com>
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Merge two given lines a, b
+/*!
+  \brief Merge two given lines a, b
+  
+  a : Points1/Cats1
+  b : Points2/Cats2
+  merged line : Points/Cats
    
-   a : Points1/Cats1
-   b : Points2/Cats2
-   merged line : Points/Cats
-   
-   \param Points1,Cats1 first line
-   \param Points2,Cats2 second line
-   \param thresh threshold value
-   \param[out] Points result line
-
-   \return 1 on success
-   \return 0 on error
+  \param Points1,Cats1 first line
+  \param Points2,Cats2 second line
+  \param thresh threshold value
+  \param[out] Points result line
+  
+  \return 1 on success
+  \return 0 on error
 */
 static int merge_lines(struct line_pnts *Points1, struct line_cats *Cats1,
 		       struct line_pnts *Points2, struct line_cats *Cats2,
 		       double thresh, struct line_pnts **Points);
 
-/**
-   \brief Merge lines/boundaries
- 
-   At least two lines need to be given.
-
-   \param Map vector map
-   \param List list of selected lines
-
+/*!
+  \brief Merge lines/boundaries
+  
+  At least two lines need to be given.
+  
+  \param Map pointer to Map_info
+  \param List list of selected lines
+  
    \return number of merged lines
    \return -1 on error
 */

Modified: grass/branches/develbranch_6/lib/vector/vedit/move.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/move.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/move.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,33 +1,30 @@
-
-/**
-   \file vector/vedit/move.c
-
-   \brief Vedit library - move primitives
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-   \author Jachym Cepicky <jachym.cepicky gmail.com>
-
-   \date 2007-2008
+/*!
+  \file lib/vector/vedit/move.c
+  
+  \brief Vedit library - move primitives
+  
+  (C) 2007-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
+  \author Jachym Cepicky <jachym.cepicky gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Move selected primitives
-   
-   \param Map vector map
-   \param BgMap, nbgmaps list of background vector maps used for snapping   
-   \param List list of primitives to be moved
-   \param move_x,move_y,move_z direction (move_z used only if map is 3D)
-   \param snap enable snapping (see globals.h)
-
-   \return number of modified primitives
-   \return -1 on error
+/*!
+  \brief Move selected primitives
+  
+  \param Map pointer to Map_info
+  \param BgMap, nbgmaps list of background vector maps used for snapping   
+  \param List list of primitives to be moved
+  \param move_x,move_y,move_z direction (move_z used only if map is 3D)
+  \param snap enable snapping (see globals.h)
+  
+  \return number of modified primitives
+  \return -1 on error
 */
 int Vedit_move_lines(struct Map_info *Map, struct Map_info **BgMap,
 		     int nbgmaps, struct ilist *List, double move_x,

Copied: grass/branches/develbranch_6/lib/vector/vedit/render.c (from rev 44823, grass/trunk/lib/vector/vedit/render.c)
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/render.c	                        (rev 0)
+++ grass/branches/develbranch_6/lib/vector/vedit/render.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -0,0 +1,496 @@
+/*!
+   \file lib/vector/vedit/render.c
+
+   \brief Vedit library - render vector features (used by wxGUI digitizer)
+
+   (C) 2010-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.
+
+   \author Martin Landa <landa.martin gmail.com>
+ */
+
+#include <math.h>
+
+#include <grass/vedit.h>
+
+static struct _region
+{
+    double center_easting;
+    double center_northing;
+    double map_west;
+    double map_north;
+    int map_width;
+    int map_height;
+    double map_res;
+} region;
+
+static struct _state
+{
+    int nitems_alloc;
+
+    int type;
+    struct line_pnts *Points;
+} state;
+
+static struct robject *draw_line(struct Map_info *, int, int);
+static struct robject *draw_line_vertices();
+static void draw_line_nodes(struct Map_info *, int, int,
+			    struct robject_list *);
+static int draw_line_dir(struct robject_list *, int);
+static void list_append(struct robject_list *, struct robject *);
+static struct robject *robj_alloc(int, int);
+static void robj_points(struct robject *, const struct line_pnts *);
+static double dist_in_px(double);
+static void en_to_xy(double, double, int *, int *);
+static void draw_arrow(int, int, int, int, double, int, int,
+		       struct robject_list *);
+static void draw_area(struct Map_info *, int, struct robject_list *);
+
+/*!
+  \brief Render vector features into list
+  
+  \param Map pointer to Map_info structure
+  \param box bounding box of region to be rendered
+  \param draw_flag types of objects to be rendered (see vedit.h)
+  \param center_easing, center_northing, map_width, map_height, map_res values used for conversion en->xy
+  
+  \return pointer to robject_list structure
+*/
+struct robject_list *Vedit_render_map(struct Map_info *Map,
+				      struct bound_box *box, int draw_flag,
+				      double center_easting,
+				      double center_northing, int map_width,
+				      int map_height, double map_res)
+{
+    int i, nfeat, fid;
+    struct ilist *list;
+    struct robject_list *list_obj;
+    struct robject *robj;
+
+    /* define region */
+    region.center_easting = center_easting;
+    region.center_northing = center_northing;
+    region.map_width = map_width;
+    region.map_height = map_height;
+    region.map_res = map_res;
+    region.map_west = center_easting - (map_width / 2.) * map_res;
+    region.map_north = center_northing + (map_height / 2.) * map_res;
+
+    list = Vect_new_list();
+    list_obj = NULL;
+    state.nitems_alloc = 1000;
+
+    list_obj = (struct robject_list *)G_malloc(sizeof(struct robject_list));
+    list_obj->nitems = 0;
+    list_obj->item =
+	(struct robject **)G_malloc(state.nitems_alloc *
+				    sizeof(struct robject *));
+
+    /* area */
+    if (draw_flag & DRAW_AREA) {
+	nfeat = Vect_select_areas_by_box(Map, box, list);
+	for (i = 0; i < nfeat; i++) {
+	    fid = list->value[i];
+	    draw_area(Map, fid, list_obj);
+	}
+    }
+
+    /* draw lines inside of current display region */
+    nfeat = Vect_select_lines_by_box(Map, box, GV_POINTS | GV_LINES,	// fixme
+				     list);
+    G_debug(1, "Vedit_render_map(): region: w=%f, e=%f, s=%f, n=%f nlines=%d",
+	    box->W, box->E, box->S, box->N, nfeat);
+
+    /* features */
+    for (i = 0; i < list->n_values; i++) {
+	fid = list->value[i];
+	robj = draw_line(Map, fid, draw_flag);
+	if (!robj)
+	    continue;
+	list_append(list_obj, robj);
+
+	if (state.type & GV_LINES) {
+	    /* vertices */
+	    if (draw_flag & DRAW_VERTEX) {
+		robj = draw_line_vertices();
+		robj->fid = fid;
+		if (robj)
+		    list_append(list_obj, robj);
+	    }
+	    /* nodes */
+	    if (draw_flag & (DRAW_NODEONE | DRAW_NODETWO)) {
+		draw_line_nodes(Map, fid, draw_flag, list_obj);
+	    }
+	    /* direction */
+	    if (draw_flag & DRAW_DIRECTION) {
+		draw_line_dir(list_obj, fid);
+	    }
+	}
+    }
+
+    list_obj->item =
+	(struct robject **)G_realloc(list_obj->item,
+				     list_obj->nitems *
+				     sizeof(struct robject *));
+
+    Vect_destroy_list(list);
+
+    return list_obj;
+}
+
+/*!
+   \brief Draw one feature
+ */
+struct robject *draw_line(struct Map_info *Map, int line, int draw_flag)
+{
+    int draw;
+    struct robject *obj;
+
+    if (!state.Points)
+	state.Points = Vect_new_line_struct();
+
+    if (!Vect_line_alive(Map, line))
+	return NULL;
+
+    state.type = Vect_read_line(Map, state.Points, NULL, line);
+
+    obj = (struct robject *)G_malloc(sizeof(struct robject));
+    obj->fid = line;
+    draw = FALSE;
+    if (state.type & GV_LINES) {
+	if (state.type == GV_LINE) {
+	    obj->type = TYPE_LINE;
+	    draw = draw_flag & DRAW_LINE;
+	}
+	else if (state.type == GV_BOUNDARY) {
+	    int left, right;
+
+	    Vect_get_line_areas(Map, line, &left, &right);
+	    if (left == 0 && right == 0) {
+		obj->type = TYPE_BOUNDARYNO;
+		draw = draw_flag & DRAW_BOUNDARYNO;
+	    }
+	    else if (left > 0 && right > 0) {
+		obj->type = TYPE_BOUNDARYTWO;
+		draw = draw_flag & DRAW_BOUNDARYTWO;
+	    }
+	    else {
+		obj->type = TYPE_BOUNDARYONE;
+		draw = draw_flag & DRAW_BOUNDARYONE;
+	    }
+	}
+    }
+    else if (state.type & GV_POINTS) {
+	if (state.type == GV_POINT) {
+	    obj->type = TYPE_POINT;
+	    draw = draw_flag & DRAW_POINT;
+	}
+	else if (state.type == GV_CENTROID) {
+	    int cret = Vect_get_centroid_area(Map, line);
+
+	    if (cret > 0) {	// -> area
+		obj->type = TYPE_CENTROIDIN;
+		draw = draw_flag & DRAW_CENTROIDIN;
+	    }
+	    else if (cret == 0) {
+		obj->type = TYPE_CENTROIDOUT;
+		draw = draw_flag & DRAW_CENTROIDOUT;
+	    }
+	    else {
+		obj->type = TYPE_CENTROIDDUP;
+		draw = draw_flag & DRAW_CENTROIDDUP;
+	    }
+	}
+    }
+    G_debug(3, "  draw_line(): type=%d rtype=%d npoints=%d draw=%d",
+	    state.type, obj->type, state.Points->n_points, draw);
+
+    if (!draw)
+	return NULL;
+
+    obj->npoints = state.Points->n_points;
+    obj->point =
+	(struct rpoint *)G_malloc(obj->npoints * sizeof(struct rpoint));
+    robj_points(obj, state.Points);
+
+    return obj;
+}
+
+/*!
+   \brief Convert geographic coordinates to the screen
+ */
+void en_to_xy(double east, double north, int *x, int *y)
+{
+    double n, w;
+
+    w = region.center_easting - (region.map_width / 2) * region.map_res;
+    n = region.center_northing + (region.map_height / 2) * region.map_res;
+
+    if (x)
+	*x = (east - w) / region.map_res;
+    if (y)
+	*y = (n - north) / region.map_res;
+
+    return;
+}
+
+/*!
+   \brief Draw line nodes
+ */
+void draw_line_nodes(struct Map_info *Map, int line, int draw_flag,
+		     struct robject_list *list)
+{
+    unsigned int i;
+    int type, nodes[2];
+    int x, y;
+    double east, north;
+    struct robject *robj;
+
+    Vect_get_line_nodes(Map, line, &(nodes[0]), &(nodes[1]));
+    
+    for (i = 0; i < sizeof(nodes) / sizeof(int); i++) {
+	type = 0;
+	if (Vect_get_node_n_lines(Map, nodes[i]) == 1) {
+	    if (draw_flag & DRAW_NODEONE) {
+		type = TYPE_NODEONE;
+	    }
+	}
+	else {
+	    if (draw_flag & DRAW_NODETWO) {
+		type = TYPE_NODETWO;
+	    }
+	}
+
+	if (type == 0)
+	    continue;
+
+	Vect_get_node_coor(Map, nodes[i], &east, &north, NULL);
+
+	robj = robj_alloc(type, 1);
+	en_to_xy(east, north, &x, &y);
+	robj->fid = line;
+	robj->point->x = x;
+	robj->point->y = y;
+
+	list_append(list, robj);
+    }
+}
+
+/*!
+   \brief Append object to the list
+ */
+void list_append(struct robject_list *list, struct robject *obj)
+{
+    if (list->nitems >= state.nitems_alloc) {
+	state.nitems_alloc += 1000;
+	list->item =
+	    (struct robject **)G_realloc(list->item,
+					 state.nitems_alloc *
+					 sizeof(struct robject *));
+    }
+    list->item[list->nitems++] = obj;
+}
+
+/*!
+   \brief Allocate robject 
+ */
+struct robject *robj_alloc(int type, int npoints)
+{
+    struct robject *robj;
+
+    robj = (struct robject *)G_malloc(sizeof(struct robject));
+    robj->type = type;
+    robj->npoints = npoints;
+    robj->point = (struct rpoint *)G_malloc(npoints * sizeof(struct rpoint));
+
+    return robj;
+}
+
+/*!
+   \brief Draw line vertices
+ */
+struct robject *draw_line_vertices()
+{
+    int i;
+    int x, y;
+    struct robject *robj;
+
+    robj = robj_alloc(TYPE_VERTEX, state.Points->n_points - 2);	/* ignore nodes */
+
+    for (i = 1; i < state.Points->n_points - 1; i++) {
+	en_to_xy(state.Points->x[i], state.Points->y[i], &x, &y);
+	robj->point[i - 1].x = x;
+	robj->point[i - 1].y = y;
+    }
+
+    return robj;
+}
+
+/*!
+   \brief Draw line dirs
+ */
+int draw_line_dir(struct robject_list *list, int line)
+{
+    int narrows;
+    int size;			/* arrow length in pixels */
+    int limit;			/* segment length limit for drawing symbol (in pixels) */
+    double dist, angle, pos;
+    double e, n;
+    int x0, y0, x1, y1;
+
+    narrows = 0;
+    size = 5;
+    limit = 5;			// 5px for line segment
+
+    dist = Vect_line_length(state.Points);
+    G_debug(5, "  draw_line_dir() line=%d", line);
+						  
+    if (dist_in_px(dist) >= limit) {
+	while (1) {
+	    pos = (narrows + 1) * 8 * limit * region.map_res;
+
+	    if (Vect_point_on_line(state.Points, pos,
+				   &e, &n, NULL, NULL, NULL) < 1) {
+		break;
+	    }
+
+	    en_to_xy(e, n, &x0, &y0);
+
+	    if (Vect_point_on_line
+		(state.Points, pos - 3 * size * region.map_res, &e, &n, NULL,
+		 &angle, NULL) < 1) {
+		break;
+	    }
+
+	    en_to_xy(e, n, &x1, &y1);
+
+	    draw_arrow(x0, y0, x1, y1, angle, size, line, list);
+
+	    if (narrows > 1e2)	// low resolution, break
+		break;
+
+	    narrows++;
+	}
+
+	// draw at least one arrow in the middle of line
+	if (narrows < 1) {
+	    dist /= 2.;
+	    if (Vect_point_on_line(state.Points, dist,
+				   &e, &n, NULL, NULL, NULL) > 0) {
+
+		en_to_xy(e, n, &x0, &y0);
+
+		if (Vect_point_on_line
+		    (state.Points, dist - 3 * size * region.map_res, &e, &n,
+		     NULL, &angle, NULL) > 0) {
+
+		    en_to_xy(e, n, &x1, &y1);
+
+		    draw_arrow(x0, y0, x1, y1, angle, size, line, list);
+		}
+	    }
+	}
+    }
+
+    return narrows;
+}
+
+/*!
+   \brief Calculate distance in pixels (on screen)
+ */
+double dist_in_px(double dist)
+{
+    int x, y;
+
+    en_to_xy(region.map_west + dist, region.map_north, &x, &y);
+
+    return sqrt(x * x);
+}
+
+/*!
+   \brief Draw arrow
+ */
+void draw_arrow(int x0, int y0, int x1, int y1, double angle, int size, int line,
+		struct robject_list *list)
+{
+    double angle_symb;
+    struct robject *robj;
+
+    robj = robj_alloc(TYPE_DIRECTION, 3);
+    robj->fid = line;
+    
+    angle_symb = angle - M_PI / 2.;
+    robj->point[0].x = (int)x1 + size * cos(angle_symb);
+    robj->point[0].y = (int)y1 - size * sin(angle_symb);
+
+    robj->point[1].x = x0;
+    robj->point[1].y = y0;
+
+    angle_symb = M_PI / 2. + angle;
+    robj->point[2].x = (int)x1 + size * cos(angle_symb);
+    robj->point[2].y = (int)y1 - size * sin(angle_symb);
+
+    list_append(list, robj);
+}
+
+/*!
+   \brief Draw area
+ */
+void draw_area(struct Map_info *Map, int area, struct robject_list *list)
+{
+    int i, centroid, isle;
+    int num_isles;
+    struct line_pnts *ipoints;
+
+    struct robject *robj;
+
+    if (!state.Points)
+	state.Points = Vect_new_line_struct();
+
+    if (!Vect_area_alive(Map, area))
+	return;
+
+    /* check for other centroids -- only area with one centroid is valid */
+    centroid = Vect_get_area_centroid(Map, area);
+    if (centroid <= 0)
+	return;
+
+    ipoints = Vect_new_line_struct();
+    /* get area's boundary */
+    Vect_get_area_points(Map, area, state.Points);
+    robj = robj_alloc(TYPE_AREA, state.Points->n_points);
+    robj_points(robj, state.Points);
+    list_append(list, robj);
+
+    /* check for isles */
+    num_isles = Vect_get_area_num_isles(Map, area);
+    for (i = 0; i < num_isles; i++) {
+	isle = Vect_get_area_isle(Map, area, i);
+	if (!Vect_isle_alive(Map, isle))
+	    continue;
+
+	Vect_get_isle_points(Map, isle, ipoints);
+	robj = robj_alloc(TYPE_ISLE, ipoints->n_points);
+	robj_points(robj, ipoints);
+	list_append(list, robj);
+    }
+
+    Vect_destroy_line_struct(ipoints);
+}
+
+/*!
+   \brief convert EN -> XY
+ */
+void robj_points(struct robject *robj, const struct line_pnts *points)
+{
+    int i;
+    int x, y;
+
+    for (i = 0; i < points->n_points; i++) {
+	en_to_xy(points->x[i], points->y[i], &x, &y);
+	robj->point[i].x = x;
+	robj->point[i].y = y;
+    }
+}

Modified: grass/branches/develbranch_6/lib/vector/vedit/select.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/select.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/select.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,17 +1,14 @@
+/*!
+  \file lib/vector/vedit/select.c
 
-/**
-   \file vector/vedit/select.c
-
-   \brief Vedit library - select primitives by query
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+  \brief Vedit library - select primitives by query
+  
+  (C) 2007-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/glocale.h>
@@ -22,24 +19,24 @@
 
 static int merge_lists(struct ilist *alist, struct ilist *blist);
 
-/**
-   \brief Select primitives by query (based on geometry properties)
+/*!
+  \brief Select primitives by query (based on geometry properties)
+  
+  Currently supported:
+   - QUERY_LENGTH, select all lines longer than threshold (or shorter if threshold is < 0)
+   - QUERY_DANGLE, select all dangles longer than threshold (or shorter if threshold is < 0)
 
-   Currently supported:
-    - QUERY_LENGTH, select all lines longer than threshold (or shorter if threshold is < 0)
-    - QUERY_DANGLE, select all dangles longer than threshold (or shorter if threshold is < 0)
+  Perform global query if <i>List</i> is empty otherwise query only
+  selected vector objects.
 
-   Perform global query if <i>List</i> is empty otherwise query only
-   selected vector objects.
-
-   \param Map vector map
-   \param type feature type
-   \param layer layer number
-   \param thresh threshold value (< 0 for 'shorter', > 0 for 'longer')
-   \param query query (length, dangle, ...)
-   \param[in,out] List list of selected features
- 
-   \return number of selected primitives
+  \param Map pointer to Map_info
+  \param type feature type
+  \param layer layer number
+  \param thresh threshold value (< 0 for 'shorter', > 0 for 'longer')
+  \param query query (length, dangle, ...)
+  \param[in,out] List list of selected features
+  
+  \return number of selected primitives
 */
 int Vedit_select_by_query(struct Map_info *Map,
 			  int type, int layer, double thresh, int query,
@@ -125,7 +122,7 @@
     return List->n_values;
 }
 
-/**
+/*!
    \brief Query selected primitive
 
    \return 1 line test positive 
@@ -236,7 +233,7 @@
     return 0;
 }
 
-/**
+/*!
    \brief Merge two lists, i.e. store only duplicate items
 
    \param[in,out] alist list to be merged


Property changes on: grass/branches/develbranch_6/lib/vector/vedit/select.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass/branches/develbranch_6/lib/vector/vedit/snap.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/snap.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/snap.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,32 +1,29 @@
+/*!
+  \file lib/vector/vedit/snap.c
 
-/**
-   \file vector/vedit/snap.c
-
-   \brief Vedit library - snapping
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+  \brief Vedit library - snapping
+  
+  (C) 2007-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Snap given point to the nearest primitive
-   
-   \param Map vector map
-   \param line line to be excluded (point on line)
-   \param x,y,z point on line to be snapped
-   \param thresh snapping threshold (>0)
-   \param vertex snap also to vertex (non-zero)
-
-   \return 1 snapped
-   \return 0 not snapped
+/*!
+  \brief Snap given point to the nearest primitive
+  
+  \param Map pointer to Map_info
+  \param line line to be excluded (point on line)
+  \param x,y,z point on line to be snapped
+  \param thresh snapping threshold (>0)
+  \param vertex snap also to vertex (non-zero)
+  
+  \return 1 snapped
+  \return 0 not snapped
 */
 int Vedit_snap_point(struct Map_info *Map,
 		     int line, double *x, double *y, double *z, double thresh,
@@ -84,20 +81,20 @@
     return snapped;
 }
 
-/**
-   \brief Snap selected primitive to its nearest primitive
-   
-   \param Map vector map
-   \param BgMap,nbgmaps list of background maps used for snapping
-   \param line line id to be snapped (if already written, otherwise -1)
-   \param Points line geometry
-   \param layer layer number
-   \param thresh threshold value used for snapping (>0)
-   \param to_vertex allow snapping also to vertex
-
-   \return 1 line snapped
-   \return 0 line not snapped
-   \return -1 line is dead (if 'line' is > 0)
+/*!
+  \brief Snap selected primitive to its nearest primitive
+  
+  \param Map pointer to Map_info
+  \param BgMap,nbgmaps list of background maps used for snapping
+  \param line line id to be snapped (if already written, otherwise -1)
+  \param Points line geometry
+  \param layer layer number
+  \param thresh threshold value used for snapping (>0)
+  \param to_vertex allow snapping also to vertex
+  
+  \return 1 line snapped
+  \return 0 line not snapped
+  \return -1 line is dead (if 'line' is > 0)
 */
 int Vedit_snap_line(struct Map_info *Map, struct Map_info **BgMap,
 		    int nbgmaps, int line, struct line_pnts *Points,
@@ -162,18 +159,18 @@
     return rewrite;
 }
 
-/**
-   \brief Snap lines/boundaries
-   
-   \param Map vector map
-   \param BgMap,nbgmaps list of background maps used for snapping
-   \param List list of lines to be snapped
-   \param layer layer number
-   \param thresh threshold value used for snapping (>0)
-   \param to_vertex allow snapping also to vertex
-
-   \return number of snapped lines
-   \return -1 on error
+/*!
+  \brief Snap lines/boundaries
+  
+  \param Map pointer to Map_info
+  \param BgMap,nbgmaps list of background maps used for snapping
+  \param List list of lines to be snapped
+  \param layer layer number
+  \param thresh threshold value used for snapping (>0)
+  \param to_vertex allow snapping also to vertex
+  
+  \return number of snapped lines
+  \return -1 on error
 */
 int Vedit_snap_lines(struct Map_info *Map, struct Map_info **BgMap,
 		     int nbgmaps, struct ilist *List, double thresh,

Modified: grass/branches/develbranch_6/lib/vector/vedit/veditlib.dox
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/veditlib.dox	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/veditlib.dox	2011-02-03 14:53:02 UTC (rev 45292)
@@ -65,15 +65,16 @@
 
  - Vedit_bulk_labeling()
 
-\section contacts Contacts
+ - Vedit_render_map()
 
- Martin Landa <landa.martin gmail.com>
-
 \section seealso See Also
 
  - \ref Vector_Library
   
  - \ref dbmilib
 
-Last change: $Date$
+\section authors Authors
+
+ Martin Landa <landa.martin gmail.com>
+
 */

Modified: grass/branches/develbranch_6/lib/vector/vedit/vertex.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/vertex.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/vertex.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,38 +1,35 @@
-
-/**
-   \file vector/vedit/vertex.c
-
-   \brief Vedit library - vertex manipulation
-
-   (C) 2006-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Jachym Cepicky <jachym.cepicky gmail.com>
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2006-2008
+/*!
+  \file lib/vector/vedit/vertex.c
+  
+  \brief Vedit library - vertex manipulation
+  
+  (C) 2006-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Jachym Cepicky <jachym.cepicky gmail.com>
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/vedit.h>
 
-/**
-   \brief Move all vertices in bounding box(es)
-
-   \param Map vector map
-   \param BgMap, nbgmaps list of background vector maps for snapping
-   \param List list of selected lines
-   \param coord points location
-   \param thresh_coords threshold value for selecting lines
-   \param thresh_snap threshold value used for snapping
-   \param move_x,move_y,move_z direction (move_z is used when map is 3D)
-   \param move_first move only first vertex found in the bounding box
-   \param snap snapping mode (see vedit.h)
-
-   \return number of moved verteces
-   \return -1 on error
- */
+/*!
+  \brief Move all vertices in bounding box(es)
+  
+  \param Map pointer to Map_info
+  \param BgMap, nbgmaps list of background vector maps for snapping
+  \param List list of selected lines
+  \param coord points location
+  \param thresh_coords threshold value for selecting lines
+  \param thresh_snap threshold value used for snapping
+  \param move_x,move_y,move_z direction (move_z is used when map is 3D)
+  \param move_first move only first vertex found in the bounding box
+  \param snap snapping mode (see vedit.h)
+  
+  \return number of moved verteces
+  \return -1 on error
+*/
 int Vedit_move_vertex(struct Map_info *Map, struct Map_info **BgMap,
 		      int nbgmaps, struct ilist *List,
 		      struct line_pnts *coord, double thresh_coords,
@@ -179,20 +176,20 @@
     return nvertices_moved;
 }
 
-/**
-   \brief Add new vertex to line
-
-   Shape of line is not changed.
-
-   \todo 3D
-
-   \param Map vector map
-   \param List list of lines
-   \param coord points location
-   \param thresh find line in given threshold
-
-   \return number of add verteces
-   \return -1 on error
+/*!
+  \brief Add new vertex to line
+  
+  Shape of line is not changed.
+  
+  \todo 3D
+  
+  \param Map pointer to Map_info
+  \param List list of lines
+  \param coord points location
+  \param thresh find line in given threshold
+  
+  \return number of add verteces
+  \return -1 on error
 */
 int Vedit_add_vertex(struct Map_info *Map, struct ilist *List,
 		     struct line_pnts *coord, double thresh)
@@ -269,18 +266,18 @@
     return nvertices_added;
 }
 
-/**
-   \brief Remove vertex from line
-
-   \todo 3D
-
-   \param Map vector map
-   \param List list of selected lines
-   \param coord points location
-   \param thresh threshold value to find a line
-
-   \return number of removed vertices
-   \return -1 on error
+/*!
+  \brief Remove vertex from line
+  
+  \todo 3D
+  
+  \param Map pointer to Map_info
+  \param List list of selected lines
+  \param coord points location
+  \param thresh threshold value to find a line
+  
+  \return number of removed vertices
+  \return -1 on error
 */
 int Vedit_remove_vertex(struct Map_info *Map, struct ilist *List,
 			struct line_pnts *coord, double thresh)

Modified: grass/branches/develbranch_6/lib/vector/vedit/zbulk.c
===================================================================
--- grass/branches/develbranch_6/lib/vector/vedit/zbulk.c	2011-02-03 14:50:46 UTC (rev 45291)
+++ grass/branches/develbranch_6/lib/vector/vedit/zbulk.c	2011-02-03 14:53:02 UTC (rev 45292)
@@ -1,36 +1,33 @@
+/*!
+  \file lib/vector/vedit/zbulk.c
 
-/**
-   \file vector/vedit/zbulk.c
-
-   \brief Vedit library - Bulk labeling (automated labeling of vector
-   features)
-
-   (C) 2007-2008 by the GRASS Development Team
-
-   This program is free software under the GNU General Public License
-   (>=v2).  Read the file COPYING that comes with GRASS for details.
-
-   \author Martin Landa <landa.martin gmail.com>
-
-   \date 2007-2008
+  \brief Vedit library - Bulk labeling (automated labeling of vector
+  features)
+  
+  (C) 2007-2008 by the GRASS Development Team
+  
+  This program is free software under the GNU General Public License
+  (>=v2).  Read the file COPYING that comes with GRASS for details.
+  
+  \author Martin Landa <landa.martin gmail.com>
 */
 
 #include <grass/dbmi.h>
 #include <grass/vedit.h>
 
-/**
-   \brief Lines z-bulk labeling
-
-   Automated labeling (z coordinate assignment) of vector lines (iso-lines).
-
-   \param Map vector map
-   \param List list of selected lines
-   \param point_start_end staring and ending point
-   \param start starting value
-   \param step step value
-
-   \return number of modified features
-   \return -1 on error
+/*!
+  \brief Lines z-bulk labeling
+  
+  Automated labeling (z coordinate assignment) of vector lines (iso-lines).
+  
+  \param Map pointer to Map_info
+  \param List list of selected lines
+  \param point_start_end staring and ending point
+  \param start starting value
+  \param step step value
+  
+  \return number of modified features
+  \return -1 on error
 */
 int Vedit_bulk_labeling(struct Map_info *Map, struct ilist *List,
 			double x1, double y1, double x2, double y2,



More information about the grass-commit mailing list