浏览代码

wxGUI/vdigit: converted to python & veditlib updated - Vedit_render_map()
very initial version - displays features to PseudoDC
todo1: complete conversion (full functionality)
todo2: improve bulk data processing (replacing PseudoDC)


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@44823 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 14 年之前
父节点
当前提交
5fcf7ee23a

+ 2 - 3
gui/wxpython/Makefile

@@ -1,8 +1,7 @@
 MODULE_TOPDIR = ../..
 MODULE_TOPDIR = ../..
 
 
-SUBDIRS = docs vdigit
+SUBDIRS = docs
 EXTRA_CLEAN_FILES = menustrings.py build_ext.pyc
 EXTRA_CLEAN_FILES = menustrings.py build_ext.pyc
-CLEAN_SUBDIRS = vdigit
 
 
 include $(MODULE_TOPDIR)/include/Make/Dir.make
 include $(MODULE_TOPDIR)/include/Make/Dir.make
 include $(MODULE_TOPDIR)/include/Make/Doxygen.make
 include $(MODULE_TOPDIR)/include/Make/Doxygen.make
@@ -13,7 +12,7 @@ ETCDIR = $(ETC)/gui/wxpython
 SRCFILES := $(wildcard scripts/* compat/* gui_modules/* icons/*.* icons/silk/* images/* xml/*) gis_set.py gis_set_error.py wxgui.py README
 SRCFILES := $(wildcard scripts/* compat/* gui_modules/* icons/*.* icons/silk/* images/* xml/*) gis_set.py gis_set_error.py wxgui.py README
 DSTFILES := $(patsubst %,$(ETCDIR)/%,$(SRCFILES)) $(patsubst %.py,$(ETCDIR)/%.pyc,$(filter %.py,$(SRCFILES)))
 DSTFILES := $(patsubst %,$(ETCDIR)/%,$(SRCFILES)) $(patsubst %.py,$(ETCDIR)/%.pyc,$(filter %.py,$(SRCFILES)))
 
 
-DSTDIRS := $(patsubst %,$(ETCDIR)/%,compat gui_modules icons icons/silk images scripts vdigit xml)
+DSTDIRS := $(patsubst %,$(ETCDIR)/%,compat gui_modules icons icons/silk images scripts xml)
 
 
 default: $(DSTFILES) menustrings.py
 default: $(DSTFILES) menustrings.py
 	$(MAKE) parsubdirs
 	$(MAKE) parsubdirs

+ 2 - 0
gui/wxpython/gui_modules/__init__.py

@@ -40,4 +40,6 @@ all = [
     "vdigit.py",
     "vdigit.py",
     "workspace.py",
     "workspace.py",
     "wxnviz.py",
     "wxnviz.py",
+    "wxvdriver.py",
+    "wxvdigit.py",
 ]
 ]

+ 1 - 1
gui/wxpython/gui_modules/mapdisp.py

@@ -542,7 +542,7 @@ class MapFrame(wx.Frame):
         
         
         # deselect features in vdigit
         # deselect features in vdigit
         if self.toolbars['vdigit'] and self.digit:
         if self.toolbars['vdigit'] and self.digit:
-            self.digit.driver.SetSelected([])
+            self.digit.GetDisplay().SetSelected(None)
             self.MapWindow.UpdateMap(render = True, renderVector = True)
             self.MapWindow.UpdateMap(render = True, renderVector = True)
         else:
         else:
             self.MapWindow.UpdateMap(render = True)
             self.MapWindow.UpdateMap(render = True)

+ 13 - 41
gui/wxpython/gui_modules/mapdisp_window.py

@@ -42,7 +42,6 @@ from vdigit import GV_LINES as VDigit_Lines_Type
 from vdigit import VDigitCategoryDialog
 from vdigit import VDigitCategoryDialog
 from vdigit import VDigitZBulkDialog
 from vdigit import VDigitZBulkDialog
 from vdigit import VDigitDuplicatesDialog
 from vdigit import VDigitDuplicatesDialog
-from vdigit import PseudoDC as VDigitPseudoDC
 
 
 class MapWindow(object):
 class MapWindow(object):
     """!Abstract map window class
     """!Abstract map window class
@@ -303,44 +302,17 @@ class BufferedWindow(MapWindow, wx.Window):
         self.dragid   = -1
         self.dragid   = -1
         self.lastpos  = (0, 0)
         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
         # 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
         # used for digitization tool
         self.pdcVector = None
         self.pdcVector = None
         # decorations (region box, etc.)
         # decorations (region box, etc.)
-        self.pdcDec = self.PseudoDC(vdigit)
+        self.pdcDec = wx.PseudoDC()
         # pseudoDC for temporal objects (select box, measurement tool, etc.)
         # pseudoDC for temporal objects (select box, measurement tool, etc.)
-        self.pdcTmp = self.PseudoDC(vdigit)
-        
-    def PseudoDC(self, vdigit = False):
-        """!Create PseudoDC instance"""
-        if vdigit:
-            PseudoDC = VDigitPseudoDC
-        else:
-            PseudoDC = wx.PseudoDC
-        
-        return PseudoDC()
-    
-    def CheckPseudoDC(self):
-        """!Try to draw background
-        
-        @return True on success
-        @return False on failure
-        """
-        try:
-            self.pdc.BeginDrawing()
-            self.pdc.SetBackground(wx.Brush(self.GetBackgroundColour()))
-            self.pdc.BeginDrawing()
-        except StandardError, e:
-            traceback.print_exc(file = sys.stderr)
-            return False
-        
-        return True
+        self.pdcTmp = wx.PseudoDC()
     
     
     def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0, 0, 0, 0]):
     def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0, 0, 0, 0]):
         """!Draws map and overlay decorations
         """!Draws map and overlay decorations
@@ -808,9 +780,9 @@ class BufferedWindow(MapWindow, wx.Window):
         if renderVector and digitToolbar and \
         if renderVector and digitToolbar and \
                 digitToolbar.GetLayer():
                 digitToolbar.GetLayer():
             # set region
             # set region
-            self.parent.digit.driver.UpdateRegion()
+            self.parent.digit.GetDisplay().UpdateRegion()
             # re-calculate threshold for digitization tool
             # re-calculate threshold for digitization tool
-            self.parent.digit.driver.GetThreshold()
+            # self.parent.digit.driver.GetThreshold()
             # draw map
             # draw map
             if self.pdcVector:
             if self.pdcVector:
                 self.pdcVector.Clear()
                 self.pdcVector.Clear()
@@ -821,7 +793,7 @@ class BufferedWindow(MapWindow, wx.Window):
                 item = None
                 item = None
             
             
             if item and self.tree.IsItemChecked(item):
             if item and self.tree.IsItemChecked(item):
-                self.parent.digit.driver.DrawMap()
+                self.parent.digit.GetDisplay().DrawMap()
 
 
             # translate tmp objects (pointer position)
             # translate tmp objects (pointer position)
             if digitToolbar.GetAction() == 'moveLine':
             if digitToolbar.GetAction() == 'moveLine':
@@ -906,7 +878,7 @@ class BufferedWindow(MapWindow, wx.Window):
         else:
         else:
             self.parent.statusbarWin['mask'].SetLabel('')
             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)))
                    (render, renderVector, (stop-start)))
         
         
         return True
         return True
@@ -2334,10 +2306,10 @@ class BufferedWindow(MapWindow, wx.Window):
         event.Skip()
         event.Skip()
 
 
     def OnMiddleDown(self, event):
     def OnMiddleDown(self, event):
-        """!
-        Middle mouse button pressed
+        """!Middle mouse button pressed
         """
         """
-        self.mouse['begin'] = event.GetPositionTuple()[:]
+        if event:
+            self.mouse['begin'] = event.GetPositionTuple()[:]
         
         
         digitToolbar = self.parent.toolbars['vdigit']
         digitToolbar = self.parent.toolbars['vdigit']
         # digitization tool
         # digitization tool
@@ -2751,7 +2723,7 @@ class BufferedWindow(MapWindow, wx.Window):
             elif l.type == 'vector':
             elif l.type == 'vector':
                 digitToolbar = self.parent.toolbars['vdigit']
                 digitToolbar = self.parent.toolbars['vdigit']
                 if digitToolbar and digitToolbar.GetLayer() == l:
                 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,
                     self.Map.GetRegion(n = n, s = s, w = w, e = e,
                                        update = True)
                                        update = True)
                     updated = True
                     updated = True

+ 13 - 33
gui/wxpython/gui_modules/toolbars.py

@@ -35,8 +35,7 @@ import wx
 import globalvar
 import globalvar
 import gcmd
 import gcmd
 import gdialogs
 import gdialogs
-import vdigit
-from vdigit import VDigitSettingsDialog, haveVDigit
+from vdigit import VDigitSettingsDialog, haveVDigit, VDigit
 from debug import Debug
 from debug import Debug
 from preferences import globalSettings as UserSettings
 from preferences import globalSettings as UserSettings
 from nviz import haveNviz
 from nviz import haveNviz
@@ -193,6 +192,7 @@ class MapToolbar(AbstractToolbar):
                            'In the meantime you can use "NVIZ" from the File menu.'), wrap = 60)
                            'In the meantime you can use "NVIZ" from the File menu.'), wrap = 60)
             
             
             self.toolId['3d'] = -1
             self.toolId['3d'] = -1
+
         if haveVDigit:
         if haveVDigit:
             choices.append(_('Digitize'))
             choices.append(_('Digitize'))
             if self.toolId['3d'] > -1:
             if self.toolId['3d'] > -1:
@@ -787,7 +787,7 @@ class VDigitToolbar(AbstractToolbar):
         if self.action['id'] != id:
         if self.action['id'] != id:
             self.parent.MapWindow.ClearLines(pdc = self.parent.MapWindow.pdcTmp)
             self.parent.MapWindow.ClearLines(pdc = self.parent.MapWindow.pdcTmp)
             if self.parent.digit and \
             if self.parent.digit and \
-                    len(self.parent.digit.driver.GetSelected()) > 0:
+                    len(self.parent.digit.GetDisplay().GetSelected()) > 0:
                 # cancel action
                 # cancel action
                 self.parent.MapWindow.OnMiddleDown(None)
                 self.parent.MapWindow.OnMiddleDown(None)
         
         
@@ -986,10 +986,8 @@ class VDigitToolbar(AbstractToolbar):
     def OnSettings(self, event):
     def OnSettings(self, event):
         """!Show settings dialog"""
         """!Show settings dialog"""
         if self.parent.digit is None:
         if self.parent.digit is None:
-            reload(vdigit)
-            from vdigit import VDigit as VDigit
             try:
             try:
-                self.parent.digit = VDigit(mapwindow=self.parent.MapWindow)
+                self.parent.digit = VDigit(mapwindow = self.parent.MapWindow)
             except SystemExit:
             except SystemExit:
                 self.parent.digit = None
                 self.parent.digit = None
         
         
@@ -1268,13 +1266,13 @@ class VDigitToolbar(AbstractToolbar):
     def StartEditing (self, mapLayer):
     def StartEditing (self, mapLayer):
         """!Start editing selected vector map layer.
         """!Start editing selected vector map layer.
 
 
-        @param mapLayer reference to MapLayer instance
+        @param mapLayer MapLayer to be edited
         """
         """
         # deactive layer
         # deactive layer
         self.mapcontent.ChangeLayerActive(mapLayer, False)
         self.mapcontent.ChangeLayerActive(mapLayer, False)
         
         
         # clean map canvas
         # clean map canvas
-        ### self.parent.MapWindow.EraseMap()
+        self.parent.MapWindow.EraseMap()
         
         
         # unset background map if needed
         # unset background map if needed
         if mapLayer:
         if mapLayer:
@@ -1284,25 +1282,17 @@ class VDigitToolbar(AbstractToolbar):
                                  subkey = 'value', value = '', internal = True)
                                  subkey = 'value', value = '', internal = True)
             
             
             self.parent.statusbar.SetStatusText(_("Please wait, "
             self.parent.statusbar.SetStatusText(_("Please wait, "
-                                                  "opening vector map <%s> for editing...") % \
-                                                    mapLayer.GetName(),
+                                                  "opening vector map <%s> for editing...") % mapLayer.GetName(),
                                                 0)
                                                 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.parent.digit = VDigit(mapwindow = self.parent.MapWindow)
         
         
         self.mapLayer = mapLayer
         self.mapLayer = mapLayer
         
         
         # open vector map
         # open vector map
         try:
         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())
+            self.parent.digit.OpenMap(mapLayer.GetName())
         except gcmd.GException, e:
         except gcmd.GException, e:
             self.mapLayer = None
             self.mapLayer = None
             self.StopEditing()
             self.StopEditing()
@@ -1320,10 +1310,6 @@ class VDigitToolbar(AbstractToolbar):
         if self.parent.MapWindow.mouse['use'] == 'pointer':
         if self.parent.MapWindow.mouse['use'] == 'pointer':
             self.parent.MapWindow.SetCursor(self.parent.cursors["cross"])
             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:
         if not self.parent.MapWindow.resize:
             self.parent.MapWindow.UpdateMap(render = True)
             self.parent.MapWindow.UpdateMap(render = True)
         
         
@@ -1340,9 +1326,6 @@ class VDigitToolbar(AbstractToolbar):
         @return True on success
         @return True on success
         @return False on failure
         @return False on failure
         """
         """
-        # use wx's PseudoDC
-        self.parent.MapWindow.DefinePseudoDC(vdigit = False)
-        
         self.combo.SetValue (_('Select vector map'))
         self.combo.SetValue (_('Select vector map'))
         
         
         # save changes
         # save changes
@@ -1364,9 +1347,9 @@ class VDigitToolbar(AbstractToolbar):
                                                   "closing and rebuilding topology of "
                                                   "closing and rebuilding topology of "
                                                   "vector map <%s>...") % self.mapLayer.GetName(),
                                                   "vector map <%s>...") % self.mapLayer.GetName(),
                                                 0)
                                                 0)
-        
-            self.parent.digit.SetMapName(None) # -> close map
-        
+            
+            self.parent.digit.CloseMap()
+            
             # re-active layer 
             # re-active layer 
             item = self.parent.tree.FindItemByData('maplayer', self.mapLayer)
             item = self.parent.tree.FindItemByData('maplayer', self.mapLayer)
             if item and self.parent.tree.IsItemChecked(item):
             if item and self.parent.tree.IsItemChecked(item):
@@ -1374,10 +1357,7 @@ class VDigitToolbar(AbstractToolbar):
         
         
         # change cursor
         # change cursor
         self.parent.MapWindow.SetCursor(self.parent.cursors["default"])
         self.parent.MapWindow.SetCursor(self.parent.cursors["default"])
-        
-        # disable pseudodc for vector map layer
         self.parent.MapWindow.pdcVector = None
         self.parent.MapWindow.pdcVector = None
-        self.parent.digit.driver.SetDevice(None)
         
         
         # close dialogs
         # close dialogs
         for dialog in ('attributes', 'category'):
         for dialog in ('attributes', 'category'):

文件差异内容过多而无法显示
+ 408 - 1496
gui/wxpython/gui_modules/vdigit.py


+ 798 - 0
gui/wxpython/gui_modules/wxvdigit.py

@@ -0,0 +1,798 @@
+"""!
+@package wxvdigit.py
+
+@brief wxGUI vector digitizer (base class)
+
+Code based on wxVdigit C++ component from GRASS 6.4.0. Converted to
+Python in 2010/12-2011/01.
+
+List of classes:
+ - 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.
+
+@author Martin Landa <landa.martin gmail.com>
+"""
+
+from debug       import Debug
+from preferences import globalSettings as UserSettings
+
+from wxvdriver import DisplayDriver
+
+from grass.lib.grass  import *
+from grass.lib.vector import *
+
+class IVDigit:
+    def __init__(self, mapwindow):
+        self.map       = None
+        self.mapWindow = 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']
+        
+        self._display = DisplayDriver(device    = mapwindow.pdcVector,
+                                      deviceTmp = mapwindow.pdcTmp,
+                                      mapObj    = mapwindow.Map,
+                                      log       = self.log)
+        
+        # self.SetCategory()
+        
+        # layer / max category
+        self.cats = dict()
+        # settings
+        self._settings = {
+            'breakLines'  : None,
+            'addCentroid' : None,
+            'catBoundary' : None
+            }
+        # undo/redo
+        self.changesets = dict()
+        self.changesetCurrent = None # first changeset to apply
+        self.changesetEnd     = None # last changeset to be applied
+        
+        if self._display.mapInfo:
+            self.InitCats()
+        
+        # initial value for undo/redo
+        self.changesetEnd = self.changesetCurrent = -1
+        
+    def __del__(self):
+        pass # free changesets ?
+
+    def _setCategory(self):
+        pass
+    
+    def _openBackgroundVectorMap(self):
+        pass
+
+    def _breakLineAtIntersection(self):
+        pass
+    
+    def _addActionsBefore(self):
+        """!Register action before operation
+  
+        @return changeset id
+        """
+        pass
+    
+    def _addActionsAfter(self):
+        pass
+
+    def _addActionToChangeset(self):
+        pass
+
+    def _applyChangeset(self):
+        pass
+
+    def _freeChangeset(self):
+        pass
+
+    def _removeActionFromChangeset(self):
+        pass
+
+    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
+        """
+        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
+        
+    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 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)
+
+    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)
+        self.map = name
+        
+        name, mapset = name.split('@')
+        try:
+            ret = self._display.OpenMap(str(name), str(mapset), True)
+        except SystemExit:
+                ret = -1
+        
+        # except StandardError, e:
+        #     raise gcmd.GException(_("Unable to initialize display driver of vector "
+        #                             "digitizer. See 'Command output' for details.\n\n"
+        #                             "Details: ") + repr(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)
+        
+        self.InitCats()
+
+    def CloseMap(self):
+        """!Close currently open vector map
+        """
+        if not self.map:
+            return
+        
+        self._display.CloseMap()
+
+    def InitCats(self):
+        """!Initialize categories information
+        
+        @return 0 on success
+        @return -1 on error
+        """
+        self.cats.clear()
+        mapInfo = self._display.mapInfo
+        if not mapInfo:
+            return -1
+        
+        ndblinks = Vect_get_num_dblinks(byref(mapInfo))
+        for i in range(ndblinks):
+            fi = Vect_get_dblink(byref(mapInfo), i).contents
+            if fi:
+                self.cats[fi.number] = None
+        
+        # find max category
+        nfields = Vect_cidx_get_num_fields(byref(mapInfo))
+        Debug.msg(2, "wxDigit.InitCats(): nfields=%d", nfields)
+        
+        for i in range(nfields):
+            field = Vect_cidx_get_field_number(byref(mapInfo), i)
+            ncats = Vect_cidx_get_num_cats_by_index(byref(mapInfo), 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(byref(mapInfo), 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 AddLine(self):
+        pass
+
+    def RewriteLine(self):
+        pass
+    
+    def SplitLine(self):
+        pass
+
+    def DeleteLines(self):
+        pass
+
+    def MoveLines(self):
+        pass
+
+    def FlipLines(self):
+        pass
+
+    def MergeLines(self):
+        pass
+
+    def BreakLines(self):
+        pass
+
+    def SnapLines(self):
+        pass
+
+    def ConnectLines(self):
+        pass
+
+    def TypeConvLines(self):
+        pass
+
+    def ZBulkLabeling(self):
+        pass
+
+    def CopyLines(self):
+        pass
+
+    def MoveVertex(self):
+        pass
+
+    def ModifyLineVertex(self):
+        pass
+
+    def SelectLinesByQuery(self):
+        pass
+
+    def GetLineLength(self):
+        pass
+
+    def GetAreaSize(self):
+        pass
+
+    def GetAreaPerimeter(self):
+        pass
+
+    def CopyCats(self):
+        pass
+
+    def GetCategory(self, layer):
+        """!Get max category number for layer
+        
+        @param layer layer number
+        
+        @return category number (0 if no category found)
+        @return -1 on error
+        """
+        if cats.find(layer) != cats.end():
+            Debug.msg(3, "vdigit.GetCategory(): layer=%d, cat=%d", layer, cats[layer])
+            return cats[layer]
+        
+        return 0
+    
+    def GetLineCats(self):
+        pass
+
+    def SetLineCats(self):
+        pass
+    
+    def GetLayers(self):
+        pass
+    
+    def Undo(self):
+        pass
+
+    def GetUndoLevel(self):
+        pass
+
+    def UpdateSettings(self, breakLines, addCentroid, catBoundary):
+        """!Update digit settings
+        
+        @param breakLines break lines on intersection
+        @param addCentroid add centroid to left/right area
+        @param catBoundary attach category to boundary
+        """
+        self._settings['breakLines']  = breakLines
+        self._settings['addCentroid'] = addCentroid
+        self._settings['catBoundary'] = None # !catBoundary # do not attach
+
+    def SetCategory(self):
+        """!Return category number to use (according Settings)"""
+        if not UserSettings.Get(group = 'vdigit', key = 'categoryMode', subkey = 'selection'):
+            self.SetCategoryNextToUse()
+        
+        return UserSettings.Get(group = 'vdigit', key = 'category', subkey = 'value')
+
+    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.GetCategory(UserSettings.Get(group = 'vdigit', key = 'layer', subkey = 'value'))
+            cat += 1
+            UserSettings.Set(group = 'vdigit', key = 'category', subkey = 'value',
+                             value = cat)

+ 567 - 0
gui/wxpython/gui_modules/wxvdriver.py

@@ -0,0 +1,567 @@
+"""!
+@package wxvdriver.py
+
+@brief wxGUI vector digitizer (display driver)
+
+Code based on wxVdigit C++ component from GRASS 6.4.0. 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.
+
+@author Martin Landa <landa.martin gmail.com>
+"""
+
+import math
+
+import wx
+
+from debug import Debug as Debug
+from preferences import globalSettings as UserSettings
+
+from grass.lib.grass  import *
+from grass.lib.vector import *
+from grass.lib.vedit  import *
+
+class DisplayDriver:
+    def __init__(self, device, deviceTmp, mapObj, log = None):
+        """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
+        """
+        G_gisinit("")             # initialize GRASS libs
+        
+        self.mapInfo = None       # open vector map (Map_Info structure)
+        self.dc      = device     # PseudoDC devices
+        self.dcTmp   = deviceTmp
+        self.mapObj  = mapObj
+        self.region  = mapObj.GetCurrentRegion()
+        self.log     = log        # log device
+        
+        # objects used by GRASS vector library
+        self.points       = line_pnts()
+        self.pointsScreen = list()
+        self.cats         = line_cats()
+        
+        # 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.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,
+            }
+        
+        self.drawSelected = None
+        self.drawSegments = False
+
+        self.UpdateSettings()
+        
+    # def __del__(self):
+    #     """!Close currently open vector map"""
+    #     if self.mapInfo:
+    #         self.CloseMap()
+    
+    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
+        
+        dcId = 0
+        pdc = self.dc
+        # draw object to the device
+        pdc.SetId(dcId) # 0 | 1 (selected)
+        
+        Debug.msg(3, "_drawObject(): type=%d npoints=%d", robj.type, robj.npoints)
+        points = list() 
+        self._setPen(robj.type, pdc)
+        
+        for i in range(robj.npoints):
+            p = robj.point[i]
+
+            if robj.type & (TYPE_POINT | TYPE_CENTROIDIN | TYPE_CENTROIDOUT | TYPE_CENTROIDDUP |
+                            TYPE_NODEONE | TYPE_NODETWO | TYPE_VERTEX): # -> point
+                self._drawCross(pdc, p)
+            else: # -> line
+                # if dcId > 0 and self.drawSegments:
+                #     dcId = 2 # first segment
+                #     i = 0
+                #     while (i < len(self.pointsScreen) - 2):
+                #         point_beg = wx.Point(self.pointsScreen[i])
+                #         point_end = wx.Point(self.pointsScreen[i + 1])
+                        
+                #         pdc.SetId(dcId) # set unique id & set bbox for each segment
+                #         pdc.SetPen(pen)
+                #         rect = wx.Rect(point_beg, point_end)
+                #         pdc.SetIdBounds(dcId, rect)
+                #         pdc.DrawLine(point_beg.x, point_beg.y,
+                #                      point_end.x, point_end.y)
+                #         i    += 2
+                #         dcId += 2
+                # else:
+                points.append(wx.Point(p.x, p.y))
+        
+        if points:
+            if robj.type == TYPE_AREA:
+                pdc.DrawPolygon(points)
+            else:
+                pdc.DrawLines(points)
+        
+    def _setPen(self, rtype, pdc):
+        """!Set pen/brush based on rendered object)
+        
+        Updates also self.topology dict
+        """
+        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':
+                pdc.SetBrush(wx.Brush(self.settings[key]['color'], wx.SOLID))
+            else:
+                pdc.SetBrush(wx.TRANSPARENT_BRUSH)
+        else:
+            pdc.SetPen(wx.Pen(self.settings[key]['color'], self.settings['lineWidth'], wx.SOLID))
+        
+    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 |= TYPE_POINT
+        if self.settings['line']['enabled']:
+            ret |= TYPE_LINE
+        if self.settings['boundaryNo']['enabled']:
+            ret |= TYPE_BOUNDARYNO
+        if self.settings['boundaryTwo']['enabled']:
+            ret |= TYPE_BOUNDARYTWO
+        if self.settings['boundaryOne']['enabled']:
+            ret |= TYPE_BOUNDARYONE
+        if self.settings['centroidIn']['enabled']:
+            ret |= TYPE_CENTROIDIN
+        if self.settings['centroidOut']['enabled']:
+            ret |= TYPE_CENTROIDOUT
+        if self.settings['centroidDup']['enabled']:
+            ret |= TYPE_CENTROIDDUP
+        if self.settings['nodeOne']['enabled']:
+            ret |= TYPE_NODEONE
+        if self.settings['nodeTwo']['enabled']:
+            ret |= TYPE_NODETWO
+        if self.settings['vertex']['enabled']:
+            ret |= TYPE_VERTEX
+        if self.settings['area']['enabled']:
+            ret |= TYPE_AREA
+        if self.settings['direction']['enabled']:
+            ret |= TYPE_DIRECTION
+        
+        return ret
+        
+    def _printIds(self):
+        pass
+
+    def _isSelected(self, featId, foo = False):
+        return False
+
+    def _isDuplicated(self, featId):
+        return False
+
+    def _resetTopology(self):
+        pass
+
+    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.mapInfo or not self.dc or not self.dcTmp:
+            return -1
+        
+        rlist = Vedit_render_map(byref(self.mapInfo), 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
+        # 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()
+        ### selected.field = -1;
+        ### Vect_reset_list(selected.cats);
+        
+    def SelectLinesByBox(self):
+        pass
+
+    def SelectLineByPoint(self):
+        pass
+
+    def GetSelected(self, grassId = False):
+        """!Get ids of selected objects
+        
+        @param grassId if true return GRASS line ids, false to return PseudoDC ids
+   
+        @return list of ids of selected vector objects
+        """
+        if grassId:
+            # return ListToVector(selected.ids);
+            pass
+
+        dc_ids = list()
+
+        if not self.drawSegments:
+            dc_ids.append(1)
+        else:
+            # only first selected feature
+            # Vect_read_line(byref(self.mapInfo), byref(self.points), None,
+            # self.selected.ids->value[0]);
+            npoints = self.points.n_points
+            # node - segment - vertex - segment - node
+            for i in range(1, 2 * self.points.npoints):
+                dc_ids.append(i)
+        
+        return dc_ids
+
+
+    def GetSelectedCoord(self):
+        pass
+
+    def GetDuplicates(self):
+        pass
+
+    def GetRegionSelected(self):
+        pass
+
+    def SetSelected(self, ids, layer = -1):
+        """!Set selected vector objects
+   
+        @param ids list of feature ids to be set
+        @param layer field number (-1 for ids instead of cats)
+        """
+        if ids:
+            self.drawSelected = True
+        else:
+            self.drawSelected = False
+            return
+
+        if layer > 0:
+            selected.field = layer
+            # VectorToList(selected.cats, id);
+        else:
+            field = -1
+            # VectorToList(selected.ids, id);
+        
+        return 1
+
+    def UnSelect(self):
+        pass
+
+    def GetSelectedVertex(self):
+        pass
+
+    def DrawSelected(self):
+        pass
+    
+    def CloseMap(self):
+        """!Close vector map
+        
+        @return 0 on success
+        @return non-zero on error
+        """
+        ret = 0
+        if self.mapInfo:
+            if self.mapInfo.mode == GV_MODE_RW:
+                # rebuild topology
+                Vect_build_partial(byref(self.mapInfo), GV_BUILD_NONE)
+                Vect_build(byref(self.mapInfo))
+
+            # close map and store topo/cidx
+            ret = Vect_close(byref(self.mapInfo))
+            del self.mapInfo
+            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 topo level on success
+        @return -1 on error
+        """
+        Debug.msg("DisplayDriver.OpenMap(): name=%s mapset=%s updated=%d",
+                  name, mapset, update)
+        if not self.mapInfo:
+            self.mapInfo = Map_info()
+        
+        # define open level (level 2: topology)
+        Vect_set_open_level(2)
+        
+        # avoid GUI crash when G_fatal_error() is called (opening the vector map)
+        Vect_set_fatal_error(GV_FATAL_PRINT)
+        
+        # open existing map
+        if update:
+            ret = Vect_open_update(byref(self.mapInfo), name, mapset)
+        else:
+            ret = Vect_open_old(byref(self.mapInfo), name, mapset)
+        
+        if ret == -1: # error
+            del self.mapInfo
+            self.mapInfo = None
+        
+        return ret
+    
+    def ReloadMap(self):
+        pass
+
+    def SetDevice(self):
+        pass
+
+    def GetMapBoundingBox(self):
+        """!Get bounding box of (opened) vector map layer
+
+        @return (w,s,b,e,n,t)
+        """
+        if not self.mapInfo:
+            return None
+        
+        bbox = bound_box()
+        Vect_get_map_box(byref(self.mapInfo), byref(bbox))
+
+        return bbox.W, bbox.S, bbox.B, \
+            bbox.E, bbox.N, bbox.T
+    
+    def Is3D(self):
+        pass
+
+    def SetRegion(self):
+        pass
+    
+    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 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')
+        
+        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'])
+            threshold = value * res
+        else:
+            threshold = value
+        
+        Debug.msg(4, "DisplayDriver.GetThreshold(): type=%s, thresh=%f" % (type, threshold))
+        
+        return threshold

+ 0 - 56
gui/wxpython/vdigit/Makefile

@@ -1,56 +0,0 @@
-MODULE_TOPDIR = ../../..
-
-include $(MODULE_TOPDIR)/include/Make/Lib.make
-
-# substitute OSX arch flags for wxpython
-ifneq ($(MACOSX_ARCHS),)
-CFLAGS := $(subst $(MACOSX_ARCHS),,$(CFLAGS)) $(MACOSX_ARCHS_WXPYTHON)
-CXXFLAGS := $(subst $(MACOSX_ARCHS),,$(CXXFLAGS)) $(MACOSX_ARCHS_WXPYTHON)
-LDFLAGS := $(subst $(MACOSX_ARCHS),,$(LDFLAGS)) $(MACOSX_ARCHS_WXPYTHON)
-endif
-
-LIB_NAME = grass7_wxvdigit
-
-SHLIB = $(OBJDIR)/_$(LIB_NAME).so
-
-ETCDIR = $(ETC)/gui/wxpython
-
-EXTRA_CLEAN_FILES = $(LIB_NAME).i $(LIB_NAME).py $(LIB_NAME)_wrap.cpp
-
-ifneq ($(USE_WXWIDGETS),)
-ifneq ($(USE_PYTHON),)
-ifneq ($(strip $(CXX)),)
-default: install_vdigit
-endif
-endif
-endif
-
-$(LIB_NAME).i: digit.i dig_types.i pseudodc.i driver.h digit.h
-	cat digit.i pseudodc.i dig_types.i > $(LIB_NAME).i
-	echo "/* auto-generated swig typedef file */" >> $(LIB_NAME).i
-	cat driver.h digit.h >> $(LIB_NAME).i
-
-$(LIB_NAME).py: $(SHLIB)
-
-$(SHLIB): $(LIB_NAME).i cats.cpp digit.cpp driver.cpp driver_draw.cpp \
-	driver_select.cpp line.cpp message.cpp select.cpp undo.cpp vertex.cpp
-	GISBASE="$(GISBASE)" \
-	ARCH_DISTDIR="$(ARCH_DISTDIR)" \
-	GDALCFLAGS="$(GDALCFLAGS)" \
-	GDALLIBS="$(GDALLIBS)" \
-	GEOSCFLAGS="$(GEOSCFLAGS)" \
-	WXWIDGETSCXXFLAGS="$(WXWIDGETSCXXFLAGS)" \
-	WXWIDGETSLIB="$(WXWIDGETSLIB)" \
-	CXXFLAGS="$(COMPILE_FLAGS_CXX)" \
-	GRASS_VERSION_NUMBER="$(GRASS_VERSION_NUMBER)" \
-	$(PYTHON) setup.py build_ext --swig=$(SWIG) --swig-opts=-c++ --build-lib=$(OBJDIR) --build-temp=$(OBJDIR)
-
-.NOTPARALLEL: $(LIB_NAME).py $(LIB_NAME)_wrap.cpp
-
-install_vdigit: $(ETCDIR)/vdigit/_$(LIB_NAME).so $(ETCDIR)/vdigit/$(LIB_NAME).py
-
-$(ETCDIR)/vdigit/_$(LIB_NAME).so: $(SHLIB)
-	$(INSTALL) $< $@
-
-$(ETCDIR)/vdigit/$(LIB_NAME).py: $(LIB_NAME).py
-	$(INSTALL_DATA) $< $@

+ 0 - 472
gui/wxpython/vdigit/cats.cpp

@@ -1,472 +0,0 @@
-/**
-   \file vdigit/cats.cpp
-
-   \brief wxvdigit - category management
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-extern "C" {
-#include <grass/dbmi.h>
-}
-
-#include "driver.h"
-#include "digit.h"
-
-/**
-   \brief Initialize cats structure.
-
-   \return 0 on success
-   \return -1 on error
-*/
-int Digit::InitCats()
-{
-    int ndblinks, nfields, field, ncats;
-    int cat, type, id; 
-
-    struct field_info *fi;
-
-    if (!cats.empty()) {	
-	cats.clear();
-    }
-
-    if (!display->mapInfo) {
-	/* DisplayMsg(); */
-	return -1;
-    }
-
-    /* initialization */
-    ndblinks = Vect_get_num_dblinks(display->mapInfo);
-    for (int i = 0; i < ndblinks; i++) {
-	fi = Vect_get_dblink(display->mapInfo, i);
-	if (fi) {
-	    cats[fi->number] = PORT_INT_MIN;
-	}
-    }
-
-    /* find max category */
-    nfields = Vect_cidx_get_num_fields (display->mapInfo);
-    G_debug(2, "wxDigit.InitCats(): nfields=%d", nfields);    
-
-    for (int i = 0; i < nfields; i++ ) {
-	field = Vect_cidx_get_field_number(display->mapInfo, i);
-	ncats = Vect_cidx_get_num_cats_by_index(display->mapInfo, i);
-	if (field <= 0) {
-	    continue;
-	}
-	for (int j = 0; j < ncats; j++) {
-	    Vect_cidx_get_cat_by_index (display->mapInfo, i, j, &cat, &type, &id);
-	    if (cat > cats[field])
-		cats[field] = cat;
-	}
-
-	G_debug(3, "wxDigit.InitCats(): layer=%d, cat=%d", field, cats[field]);
-    }
-
-    /* set default values */
-    for(std::map<int, int>::const_iterator b = cats.begin(), e = cats.end();
-	b != e; ++b ) {
-	if (b->second == PORT_INT_MIN) {
-	    cats[b->first] = 0; /* first category 1 */
-	    G_debug(3, "wxDigit.InitCats(): layer=%d, cat=%d", b->first, cats[b->first]);
-	}
-
-    }
-
-    return 0;
-}
-
-/**
-   \brief Get max category number for layer
-
-   \param layer layer number
-
-   \return category number (0 if no category found)
-   \return -1 on error
-*/
-int Digit::GetCategory(int layer)
-{
-    if (cats.find(layer) != cats.end()) {
-	G_debug(3, "v.digit.GetCategory(): layer=%d, cat=%d", layer, cats[layer]);
-	return cats[layer];
-    }
-
-    return 0;
-}
-
-/**
-   \brief Set max category number for layer
-
-   \param layer layer number
-   \param cats  category number to be set
-
-   \return previously set category
-   \return -1 if layer not available
-*/
-int Digit::SetCategory(int layer, int cat)
-{
-    int old_cat;
-
-    if (cats.find(layer) != cats.end()) {
-	old_cat = cats[layer];
-    }
-    else {
-	old_cat = -1;
-    }
-
-    cats[layer] = cat;
-    G_debug(3, "wxDigit.SetCategory(): layer=%d, cat=%d old_cat=%d",
-	    layer, cat, old_cat);
-
-    return old_cat;
-}
-
-/**
-   Get list of layers
-
-   Requires InitCats() to be called.
-
-   \return list of layers
-*/
-std::vector<int> Digit::GetLayers()
-{
-    std::vector<int> layers;
-
-    for(std::map<int, int>::const_iterator b = cats.begin(), e = cats.end();
-	b != e; ++b ) {
-	layers.push_back(b->first);
-    }
-
-    return layers;
-}
-
-/**
-   \brief Get list of layer/category(ies) for selected feature.
-
-   \param line feature id (-1 for first selected feature)
-
-   \return list of layer/cats
-*/
-std::map<int, std::vector<int> > Digit::GetLineCats(int line_id)
-{
-    std::map<int, std::vector<int> > lc;
-    int line;
-    struct line_cats *Cats;
-
-    if (!display->mapInfo) {
-	display->DisplayMsg();
-	return lc;
-    }
-
-    if (line_id == -1 && display->selected.ids->n_values < 1) {
-	/* GetLineCatsMsg(line_id); */
-	return lc;
-    }
-    
-    line = line_id;
-    if (line_id == -1) {
-	line = display->selected.ids->value[0];
-    }
-
-    if (!Vect_line_alive(display->mapInfo, line)) {
-	display->DeadLineMsg(line);
-	return lc;
-    }
-
-    Cats = Vect_new_cats_struct();
-
-    if (Vect_read_line(display->mapInfo, NULL, Cats, line) < 0) {
-	Vect_destroy_cats_struct(Cats);
-	display->ReadLineMsg(line);
-	return lc;
-    }
-    
-    for (int i = 0; i < Cats->n_cats; i++) {
-	if (lc.find(Cats->field[i]) == lc.end()) {
-	    std::vector<int> cats;
-	    lc[Cats->field[i]] = cats;
-	}
-	lc[Cats->field[i]].push_back(Cats->cat[i]);
-    }
-
-    Vect_destroy_cats_struct(Cats);
-
-    return lc;
-}
-
-/**
-   \brief Set categories for given feature/layer
-
-   \param line feature id (-1 for first selected feature)
-   \param layer layer number
-   \param cats list of cats
-   \param add True for add, False for delete
-
-   \return new feature id (feature need to be rewritten)
-   \return -1 on error
-*/
-int Digit::SetLineCats(int line_id, int layer, std::vector<int> cats, bool add)
-{
-    int line, ret, type;
-    struct line_pnts *Points;
-    struct line_cats *Cats;
-
-    if (!display->mapInfo) {
-	display->DisplayMsg();
-	return -1;
-    }
-
-    if (line_id == -1 && display->selected.ids->n_values < 1) {
-	display->GetLineCatsMsg(line_id);
-	return -1;
-    }
-    
-    if (line_id == -1) {
-	line = display->selected.ids->value[0];
-    }
-    else {
-	line = line_id;
-    }
-
-    if (!Vect_line_alive(display->mapInfo, line)) {
-	display->DeadLineMsg(line);
-	return -1;
-    }
-
-    Points = Vect_new_line_struct();
-    Cats = Vect_new_cats_struct();
-    type = Vect_read_line(display->mapInfo, Points, Cats, line);
-    if (type < 0) {
-	Vect_destroy_line_struct(Points);
-	Vect_destroy_cats_struct(Cats);
-	display->ReadLineMsg(line);
-	return -1;
-    }
-
-    for (std::vector<int>::const_iterator c = cats.begin(), e = cats.end();
-	 c != e; ++c) {
-	if (add) {
-	    Vect_cat_set(Cats, layer, *c);
-	}
-	else {
-	    Vect_field_cat_del(Cats, layer, *c);
-	}
-	G_debug(3, "Digit.SetLineCats(): layer=%d, cat=%d, add=%d",
-		layer, *c, add);
-    }
-
-    /* register changeset */
-    // AddActionToChangeset(changesets.size(), REWRITE, display->selected.ids->value[0]);
-
-    ret = Vect_rewrite_line(display->mapInfo, line, type,
-			    Points, Cats);
-
-    /* TODO
-       updates feature id (id is changed since line has been rewriten)
-       if (ret > 0) {
-       
-       changesets[changesets.size()-1][0].line = ret;
-       }
-       else {
-       changesets.erase(changesets.size()-1);
-       }
-    */
-    
-    if (line_id == -1) {
-	/* update line id since the line was rewritten */
-	display->selected.ids->value[0] = ret;
-    }
-
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_cats_struct(Cats);
-
-    return ret;
-}
-
-/**
-   \brief Copy categories from one vector feature to other
-
-   \param fromId list of 'from' feature ids
-   \param toId   list of 'to' feature ids
-   \param copyAttrb duplicate attribures instead of copying categories
-
-   \return number of modified features
-   \return -1 on error
-*/
-int Digit::CopyCats(std::vector<int> fromId, std::vector<int> toId, bool copyAttrb)
-{
-    int fline, tline, nlines, type;
-    int cat;
-    
-    struct line_pnts *Points;
-    struct line_cats *Cats_from, *Cats_to;
-
-    Points = Vect_new_line_struct();
-    Cats_from = Vect_new_cats_struct();
-    Cats_to = Vect_new_cats_struct();
-
-    nlines = 0;
-
-    for (std::vector<int>::const_iterator fi = fromId.begin(), fe = fromId.end();
-	 fi != fe; ++fi) {
-
-	fline = *fi;
-	if (!Vect_line_alive(display->mapInfo, fline))
-	    continue;
-
-	type = Vect_read_line(display->mapInfo, NULL, Cats_from, fline);
-	if (type < 0) {
-	    display->ReadLineMsg(fline);
-	    return -1;
-	}
-
-	for(std::vector<int>::const_iterator ti = toId.begin(), te = toId.end();
-	    ti != te; ++ti) {
-
-	    tline = *ti;
-	    if (!Vect_line_alive(display->mapInfo, tline))
-		continue;
-
-	    type = Vect_read_line(display->mapInfo, Points, Cats_to, tline);
-	    if (type < 0) {
-		display->ReadLineMsg(tline);
-		return -1;
-	    }
-
-	    for (int i = 0; i < Cats_from->n_cats; i++) {
-		if (!copyAttrb) {
-		    cat = Cats_from->cat[i]; /* duplicate category */
-		}
-		else {
-		    /* duplicate attributes */
-		    struct field_info *fi;
-		    char buf[GSQL_MAX];
-		    dbDriver *driver;
-		    dbHandle handle;
-		    dbCursor cursor;
-		    dbTable *table;
-		    dbColumn *column;
-		    dbValue *value;
-		    dbString stmt, value_string;
-		    int col, ncols;
-		    int more, ctype;
-		    		    
-		    cat = ++cats[Cats_from->field[i]];
-
-		    fi = Vect_get_field(display->mapInfo, Cats_from->field[i]);
-
-		    if (fi == NULL) {
-			display->DblinkMsg(Cats_from->field[i]);
-			return -1;
-		    }
-		    
-		    driver = db_start_driver(fi->driver);
-		    if (driver == NULL) {
-			display->DbDriverMsg(fi->driver);
-			return -1;
-		    }
-		    
-		    db_init_handle (&handle);
-		    db_set_handle (&handle, fi->database, NULL);
-		    if (db_open_database(driver, &handle) != DB_OK) {
-			db_shutdown_driver(driver);
-			display->DbDatabaseMsg(fi->driver, fi->database);
-			return -1;
-		    }
-
-		    db_init_string (&stmt);
-		    sprintf (buf, "SELECT * FROM %s WHERE %s=%d",
-			     fi->table, fi->key, Cats_from->cat[i]);
-		    db_set_string(&stmt, buf);
-
-		    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK) {
-			db_close_database(driver);
-			db_shutdown_driver(driver);
-			display->DbSelectCursorMsg(db_get_string(&stmt));
-			return -1;
-		    }
-
-
-		    table = db_get_cursor_table(&cursor);
-		    ncols = db_get_table_number_of_columns(table);
-		    
-		    sprintf(buf, "INSERT INTO %s VALUES (", fi->table);
-		    db_set_string(&stmt, buf);
-
-		    /* fetch the data */
-		    while (1) {
-			if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
-			    db_close_database(driver);
-			    db_shutdown_driver(driver);
-			    return -1;
-			}
-			if (!more)
-			    break;
-			
-			for (col = 0; col < ncols; col++) {
-			    if (col > 0)
-				db_append_string(&stmt, ",");
-			    
-			    column = db_get_table_column(table, col);
-			    if (strcmp(db_get_column_name(column), fi->key) == 0) {
-				sprintf(buf, "%d", cat);
-				db_append_string(&stmt, buf);
-				continue;
-			    }
-			    
-			    value = db_get_column_value(column);
-			    db_convert_column_value_to_string(column, &value_string);
-			    if (db_test_value_isnull(value))
-				db_append_string(&stmt, "NULL");
-			    else {
-				ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
-				if (ctype != DB_C_TYPE_STRING) 
-				    db_append_string(&stmt, db_get_string(&value_string));
-				else {
-				    sprintf(buf, "'%s'", db_get_string(&value_string));
-				    db_append_string(&stmt, buf);
-				}
-			    }
-			}
-		    }
-		    db_append_string(&stmt, ")");
-		    
-		    if (db_execute_immediate (driver, &stmt) != DB_OK ) {
-			db_close_database(driver);
-			db_shutdown_driver(driver);
-			display->DbExecuteMsg(db_get_string(&stmt));
-			return -1;
-		    }
-		    
-		    db_close_database(driver);
-		    db_shutdown_driver(driver);
-		}
-		
-		if (Vect_cat_set(Cats_to, Cats_from->field[i], cat) < 1) {
-		    continue;
-		}
-	    }
-	    
-	    if (Vect_rewrite_line(display->mapInfo, tline, type, Points, Cats_to) < 0) {
-		display->WriteLineMsg();
-		return -1;
-	    }
-	
-	    G_debug(1, "Digit::CopyCats(): fline=%d, tline=%d", fline, tline);
-	    
-	    nlines++;
-	}
-    }
-    
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_cats_struct(Cats_from);
-    Vect_destroy_cats_struct(Cats_to);
-
-    return nlines;
-}

+ 0 - 25
gui/wxpython/vdigit/dig_types.i

@@ -1,25 +0,0 @@
-/* extracted from include/vect/dig_defines.h */
-
-#define GV_POINT      0x01
-#define GV_LINE       0x02
-#define GV_BOUNDARY   0x04
-#define GV_CENTROID   0x08
-#define GV_FACE       0x10
-#define GV_KERNEL     0x20
-#define GV_AREA       0x40
-#define GV_VOLUME     0x80
-
-#define GV_POINTS (GV_POINT | GV_CENTROID )
-#define GV_LINES (GV_LINE | GV_BOUNDARY )
-
-#define PORT_DOUBLE_MAX 1.7976931348623157e+308
-
-/* extracted from vector/v.edit/lib/vedit.h */
-
-#define NO_SNAP    0 /* snapping disabled */
-#define SNAP       1 /* snapping enabled for nodes */
-#define SNAPVERTEX 2 /* snapping enabled for vertex also */
-
-#define QUERY_UNKNOWN -1
-#define QUERY_LENGTH   0 /* select by line length */
-#define QUERY_DANGLE   1 /* select dangles */

+ 0 - 120
gui/wxpython/vdigit/digit.cpp

@@ -1,120 +0,0 @@
-/**
-   \file vdigit/digit.cpp
-
-   \brief wxvdigit - C++ interace for wxGUI vector digitizer.
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-extern "C" {
-#include <grass/glocale.h>
-}
-
-#include "driver.h"
-#include "digit.h"
-
-#if defined _WIN32 && defined MSVC_VER
-#ifndef _CPPRTTI
-#error "compile with /GR!"
-#endif
-#endif
-
-/**
-   \brief Initialize digit interface
-
-   \param driver display driver instance
-   \param window parent window for message dialog
-*/
-Digit::Digit(DisplayDriver *ddriver, wxWindow *window)
-{
-    display = ddriver;
-    if (!display)
-	return;
-    
-    if (display->mapInfo) {
-	InitCats();
-    }
-
-    changesetEnd = changesetCurrent = -1; // initial value for undo/redo
-
-    display->msgCaption = _("Digitization error");
-    
-    // avoid GUI crash
-    // Vect_set_fatal_error(GV_FATAL_PRINT);
-}
-
-/**
-   \brief Digit class destructor
-
-   Frees changeset structure
-*/
-Digit::~Digit()
-{
-    for(int changeset = 0; changeset < (int) changesets.size(); changeset++) {
-	FreeChangeset(changeset);
-    }
-}
-
-/**
-   \brief Update digit settings
-
-   \param breakLines break lines on intersection
-   \param addCentroid add centroid to left/right area
-   \param catBoundary attach category to boundary
-*/
-void Digit::UpdateSettings(bool breakLines,
-			   bool addCentroid, bool catBoundary)
-{
-    settings.breakLines = breakLines;
-    settings.addCentroid = addCentroid;
-    settings.catBoundary = !catBoundary; /* do not attach */
-    
-    return;
-}
-
-/*!
-  \brief Register action before operation
-  
-  \return changeset id
-*/
-int Digit::AddActionsBefore(void)
-{
-    int changeset;
-
-    /* register changeset */
-    changeset = changesets.size();
-    for (int i = 0; i < display->selected.ids->n_values; i++) {
-	int line = display->selected.ids->value[i];
-	if (Vect_line_alive(display->mapInfo, line))
-	    AddActionToChangeset(changeset, DEL, line);
-    }
-    
-    return changeset;
-}
-
-/*!
-  \brief Register action after operation
-*/
-void Digit::AddActionsAfter(int changeset, int nlines)
-{
-    for (int i = 0; i < display->selected.ids->n_values; i++) {
-	int line = display->selected.ids->value[i];
-	if (Vect_line_alive(display->mapInfo, line)) {
-	    RemoveActionFromChangeset(changeset, DEL, line);
-	}
-    }
-
-    for (int line = nlines + 1; line <= Vect_get_num_lines(display->mapInfo); line++) {
-	if (Vect_line_alive(display->mapInfo, line)) {
-	    AddActionToChangeset(changeset, ADD, line);
-	}
-    }
-    
-    return;
-}

+ 0 - 102
gui/wxpython/vdigit/digit.h

@@ -1,102 +0,0 @@
-#ifndef WXVDIGIT_DIGIT_H
-#define WXVDIGIT_DIGIT_H
-
-#define GSQL_MAX 4000
-
-#include <vector>
-#include <map>
-
-class Digit
-{
-private:
-    /* layer / max category */
-    std::map<int, int> cats;
-
-    DisplayDriver *display;
-    
-    int SetCategory(int, int);
-    struct Map_info** OpenBackgroundVectorMap(const char *);
-    int BreakLineAtIntersection(int, struct line_pnts*, int);
-    
-    int AddActionsBefore(void);
-    void AddActionsAfter(int, int);
-
-    /* settings */
-    struct _settings {
-	bool breakLines;
-	bool addCentroid;
-	bool catBoundary;
-    } settings;
-
-    /* undo/redo */
-    enum action_type { ADD, DEL };
-    struct action_meta {
-	action_type type;
-	int line;
-	long offset;
-    };
-
-    std::map<int, std::vector<action_meta> > changesets;
-    int changesetCurrent;  /* first changeset to apply */
-    int changesetEnd;      /* last changeset to be applied */
-    
-    int AddActionToChangeset(int, action_type, int);
-    int ApplyChangeset(int, bool);
-    void FreeChangeset(int);
-    int RemoveActionFromChangeset(int, action_type, int);
-
-public:
-    Digit(DisplayDriver *, wxWindow *);
-    ~Digit();
-
-    int InitCats();
-
-    int AddLine(int, std::vector<double>, int, int,
-		const char*, int, double);
-    int RewriteLine(int, std::vector<double>,
-		    const char*, int, double);
-    int SplitLine(double, double, double,
-		  double);
-
-    int DeleteLines(bool);
-    int MoveLines(double, double, double,
-		  const char*, int, double);
-    int FlipLines();
-    int MergeLines();
-    int BreakLines();
-    int SnapLines(double);
-    int ConnectLines(double);
-    int TypeConvLines();
-    int ZBulkLabeling(double, double, double, double,
-		      double, double);
-    int CopyLines(std::vector<int>, const char*);
-
-    int MoveVertex(double, double, double,
-		   double, double, double,
-		   const char*, int,
-		   double, double);
-    int ModifyLineVertex(int, double, double, double,
-			 double);
-
-    std::vector<int> SelectLinesByQuery(double, double, double,
-					double, double, double, bool,
-					int, int, double);
-
-    double GetLineLength(int);
-    double GetAreaSize(int);
-    double GetAreaPerimeter(int);
-
-    int CopyCats(std::vector<int>, std::vector<int>, bool);
-    int GetCategory(int);
-    std::map<int, std::vector<int> > GetLineCats(int);
-    int SetLineCats(int, int, std::vector<int>, bool);
-    std::vector<int> GetLayers();
-
-    int Undo(int);
-    int GetUndoLevel();
-
-    void UpdateSettings(bool, 
-			bool, bool);
-};
-
-#endif /* WXVDIGIT_DIGIT_H */

+ 0 - 27
gui/wxpython/vdigit/digit.i

@@ -1,27 +0,0 @@
-/* File: digit.i */
-
-%module grass7_wxvdigit
-%{
-#include <grass/gis.h>
-#include <grass/gisdefs.h>
-#include <grass/vector.h>
-#include <grass/vect/dig_structs.h>
-#include "driver.h"
-#include "digit.h"
-%}
-
-%include "std_vector.i"
-namespace std { 
-   %template(IntVector) vector<int>;
-   %template(DoubleVector) vector<double>;
-}
-%include "std_map.i"
-namespace std { 
-   %template(IntVecIntMap) map<int, vector<int> >;
-}
-namespace std { 
-   %template(DoubleVecIntMap) map<int, vector<double> >;
-}
-
-%include "driver.h"
-%include "digit.h"

+ 0 - 630
gui/wxpython/vdigit/driver.cpp

@@ -1,630 +0,0 @@
-/**
-   \file vdigit/driver.cpp
-   
-   \brief wxvdigit - Display driver
-
-   This driver is designed for wxGUI (vector digitizer) - to draw
-   vector map layer to PseudoDC.
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-#include <unistd.h>
-#include <cmath>
-
-#include "driver.h"
-
-#define MSG  0
-#define WARN 1
-#define ERR  2
-
-static int print_error(const char *, const int);
-static int print_percent(int);
-static void print_sentence (PyObject*, const int, const char *);
-static PyObject *logStream;
-static int message_id = 1;
-
-/**
-   \brief Initialize driver
-
-   Allocate given structures.
-   
-   \param[in,out] PseudoDC device where to draw vector objects
-   \param[in,out] PseudoDC device where to draw vector objects (tmp, selected)
-   
-   \return
-*/
-DisplayDriver::DisplayDriver(gwxPseudoDC *device, gwxPseudoDC *deviceTmp,
-			     PyObject *log)
-{
-    G_gisinit(""); /* GRASS functions */
-
-    mapInfo = NULL;
-
-    dc = device;
-    dcTmp = deviceTmp;
-    logStream = log;
-    
-    points = Vect_new_line_struct();
-    pointsScreen = new wxList();
-    cats = Vect_new_cats_struct();
-
-    selected.field = -1;
-    selected.cats = Vect_new_list();
-    selected.ids = Vect_new_list();
-    selected.idsDupl = Vect_new_list();
-
-    drawSegments = false;
-
-    G_set_error_routine(&print_error);
-    G_set_percent_routine(&print_percent);
-
-    // avoid GUI crash when G_fatal_error() is called (opening the vector map)
-    // Vect_set_fatal_error(GV_FATAL_PRINT);
-}
-
-/**
-   \brief Destroy driver
-
-   Close the map, deallocate given structures.
-
-   \param
-
-   \return
-*/
-DisplayDriver::~DisplayDriver()
-{
-    if (mapInfo)
-	CloseMap();
-
-    G_unset_error_routine();
-    G_unset_percent_routine();
-    
-    Vect_destroy_line_struct(points);
-    delete pointsScreen;
-    Vect_destroy_cats_struct(cats);
-    Vect_destroy_list(selected.cats);
-    Vect_destroy_list(selected.ids);
-    Vect_destroy_list(selected.idsDupl);
-}
-
-/**
-   \brief Set device for drawing
-   
-   \param[in,out] PseudoDC device where to draw vector objects
-
-   \return
-*/
-void DisplayDriver::SetDevice(void *device)
-{
-    dc = (gwxPseudoDC *) device;
-
-    return;
-}
-
-/*
-  \brief Close vector map layer
-  
-  \param void
-
-  \return 0 on success
-  \return non-zero on error
-*/
-int DisplayDriver::CloseMap()
-{
-    int ret;
-
-    ret = -1;
-    if (mapInfo) {
-	if (mapInfo->mode == GV_MODE_RW) {
-	    /* rebuild topology */
-	    Vect_build_partial(mapInfo, GV_BUILD_NONE);
-	    Vect_build(mapInfo);
-	}
-	/* close map and store topo/cidx */
-	ret = Vect_close(mapInfo); 
-	G_free ((void *) mapInfo);
-	mapInfo = NULL;
-    }
-    
-    return ret;
-}
-
-/**
-   \brief Open vector map layer
- 
-   \param[in] mapname name of vector map
-   \param[in] mapset name of mapset where the vector map layer is stored
-   
-   \return topo level
-   \return -1 on error
-*/
-int DisplayDriver::OpenMap(const char* mapname, const char *mapset, bool update)
-{
-    int ret;
-
-    if (!mapInfo)
-	mapInfo = (struct Map_info *) G_malloc (sizeof (struct Map_info));
-
-    // define open level (level 2: topology)
-    Vect_set_open_level(2);
-
-    // avoid GUI crash when G_fatal_error() is called (opening the vector map)
-    Vect_set_fatal_error(GV_FATAL_PRINT);
-
-    // open existing map
-    if (!update) {
-	ret = Vect_open_old(mapInfo, (char*) mapname, (char *) mapset);
-    }
-    else {
-	ret = Vect_open_update(mapInfo, (char*) mapname, (char *) mapset);
-    }
-
-    if (ret == -1) { // error
-	G_free((void *) mapInfo);
-	mapInfo = NULL;
-    }
-
-    return ret;
-}
-
-/**
-   \brief Reload vector map layer
-
-   Close and open again. Needed for modification using v.edit.
-
-   TODO: Get rid of that...
-
-   \param
-   
-   \return
-*/
-void DisplayDriver::ReloadMap()
-{
-    // char* name   = G_store(Vect_get_map_name(mapInfo)); ???
-    char* name   = G_store(mapInfo->name);
-    char* mapset = G_store(Vect_get_mapset(mapInfo));
-
-    Vect_close(mapInfo);
-    mapInfo = NULL;
-
-    OpenMap(name, mapset, false); // used only for v.edit
-    //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr);
-    //Vect_build(mapInfo, stderr);
-
-    return;
-}
-
-/*
-  \brief Conversion from geographic coordinates (east, north)
-  to screen (x, y)
-  
-  TODO: 3D stuff...
-
-  \param[in] east,north,depth geographical coordinates
-  \param[out] x, y, z screen coordinates
-  
-  \return 
-*/
-void DisplayDriver::Cell2Pixel(double east, double north, double depth,
-			       double *x, double *y, double *z)
-{
-    double n, w;
-    /*
-    *x = int((east  - region.map_west) / region.map_res);
-    *y = int((region.map_north - north) / region.map_res);
-    */
-    w = region.center_easting  - (region.map_width / 2)  * region.map_res;
-    n = region.center_northing + (region.map_height / 2) * region.map_res;
-
-    /*
-    *x = int((east  - w) / region.map_res);
-    *y = int((n - north) / region.map_res);
-    */
-    if (x)
-	*x = (east  - w) / region.map_res;
-    if (y)
-	*y = (n - north) / region.map_res;
-    if (z)
-	*z = 0.;
-
-    return;
-}
-
-/**
-   \brief Calculate distance in pixels
-
-   \todo LL projection
-
-   \param dist real distance
-*/
-double DisplayDriver::DistanceInPixels(double dist)
-{
-    double x;
-    
-    Cell2Pixel(region.map_west + dist, region.map_north, 0.0, &x, NULL, NULL);
-
-    return std::sqrt(x * x);
-}
-
-/**
-   \brief Set geographical region
- 
-   Region must be upgraded because of Cell2Pixel().
-   
-   \param[in] north,south,east,west,ns_res,ew_res region settings
- 
-   \return
-*/
-void DisplayDriver::SetRegion(double north, double south, double east, double west,
-			      double ns_res, double ew_res,
-			      double center_easting, double center_northing,
-			      double map_width, double map_height)
-{
-    region.box.N  = north;
-    region.box.S  = south;
-    region.box.E  = east;
-    region.box.W  = west;
-    region.box.T  = PORT_DOUBLE_MAX;
-    region.box.B  = -PORT_DOUBLE_MAX;
-    region.ns_res = ns_res;
-    region.ew_res = ew_res;
-
-    region.center_easting = center_easting;
-    region.center_northing = center_northing;
-
-    region.map_width  = map_width;
-    region.map_height = map_height;
-
-    // calculate real region
-    region.map_res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res;
-
-    region.map_west  = region.center_easting - (region.map_width / 2.) * region.map_res;
-    region.map_north = region.center_northing + (region.map_height / 2.) * region.map_res;
-
-    return;
-}
-
-/*
-  \brief Set settings for displaying vector feature
- 
-  E.g. line width, color, ...
-  
-  \param[in] lineWidth,... settgings
-  
-  \return 
-*/
-void DisplayDriver::UpdateSettings(unsigned long highlight,
-				   bool ehighlightDupl, unsigned long chighlightDupl,
-				   bool ePoint,       unsigned long cPoint, /* enabled, color */
-				   bool eLine,        unsigned long cLine,
-				   bool eBoundaryNo,  unsigned long cBoundaryNo,
-				   bool eBoundaryOne, unsigned long cBoundaryOne,
-				   bool eBoundaryTwo, unsigned long cBoundaryTwo,
-				   bool eCentroidIn,  unsigned long cCentroidIn,
-				   bool eCentroidOut, unsigned long cCentroidOut,
-				   bool eCentroidDup, unsigned long cCentroidDup,
-				   bool eNodeOne,     unsigned long cNodeOne,
-				   bool eNodeTwo,     unsigned long cNodeTwo,
-				   bool eVertex,      unsigned long cVertex,
-				   bool eArea,        unsigned long cArea,
-				   bool eDirection,   unsigned long cDirection,
-				   int lineWidth, int alpha)
-{
-    settings.highlight.Set(highlight);
-
-    settings.highlightDupl.enabled = ehighlightDupl;
-    settings.highlightDupl.color.Set(chighlightDupl);
-
-    settings.point.enabled = ePoint;
-    settings.point.color.Set(cPoint);
-    
-    settings.line.enabled = eLine;
-    settings.line.color.Set(cLine);
-
-    settings.boundaryNo.enabled = eBoundaryNo;
-    settings.boundaryNo.color.Set(cBoundaryNo);
-    settings.boundaryOne.enabled = eBoundaryOne;
-    settings.boundaryOne.color.Set(cBoundaryOne);
-    settings.boundaryTwo.enabled = eBoundaryTwo;
-    settings.boundaryTwo.color.Set(cBoundaryTwo);
-
-
-    settings.centroidIn.enabled = eCentroidIn;
-    settings.centroidIn.color.Set(cCentroidIn);
-    settings.centroidOut.enabled = eCentroidOut;
-    settings.centroidOut.color.Set(cCentroidOut);
-    settings.centroidDup.enabled = eCentroidDup;
-    settings.centroidDup.color.Set(cCentroidDup);
-
-    settings.nodeOne.enabled = eNodeOne;
-    settings.nodeOne.color.Set(cNodeOne);
-    settings.nodeTwo.enabled = eNodeTwo;
-    settings.nodeTwo.color.Set(cNodeTwo);
-
-    settings.vertex.enabled = eVertex;
-    settings.vertex.color.Set(cVertex);
-
-    settings.area.enabled = eArea;
-    settings.area.color.Set(cArea);
-    settings.area.color.Set(settings.area.color.Red(),
-			    settings.area.color.Green(),
-			    settings.area.color.Blue(),
-			    alpha);
-    
-    settings.direction.enabled = eDirection;
-    settings.direction.color.Set(cDirection);
-
-    settings.lineWidth = lineWidth;
-    
-    return;
-}
-
-/**
-   \brief Prints gId: dcIds
-
-   Useful for debugging purposes.
-
-   \param
-
-   \return
-*/
-void DisplayDriver::PrintIds()
-{
-    std::cerr << "topology.highlight: " << topology.highlight << std::endl;
-
-    std::cerr << "topology.point: " << topology.point << std::endl;
-    std::cerr << "topology.line: " << topology.line << std::endl;
-
-    std::cerr << "topology.boundaryNo: " << topology.boundaryNo << std::endl;
-    std::cerr << "topology.boundaryOne: " << topology.boundaryOne << std::endl;
-    std::cerr << "topology.boundaryTwo: " << topology.boundaryTwo << std::endl;
-
-    std::cerr << "topology.centroidIn: " << topology.centroidIn << std::endl;
-    std::cerr << "topology.centroidOut: " << topology.centroidOut << std::endl;
-    std::cerr << "topology.centroidDup: " << topology.centroidDup << std::endl;
-
-    std::cerr << "topology.nodeOne: " << topology.nodeOne << std::endl;
-    std::cerr << "topology.nodeTwo: " << topology.nodeTwo << std::endl;
-
-    std::cerr << "topology.vertex: " << topology.vertex << std::endl;
-
-    std::cerr << std::endl << "nobjects: "
-	      << topology.point * 2 + // cross
-      topology.line + 
-      topology.boundaryNo +
-      topology.boundaryOne +
-      topology.boundaryTwo +
-      topology.centroidIn * 2 +
-      topology.centroidOut * 2 +
-      topology.centroidDup * 2 +
-      topology.nodeOne * 2 +
-      topology.nodeTwo * 2 +
-      topology.vertex * 2 << std::endl;
-
-    std::cerr << "selected: ";
-
-    for (int i = 0; i < selected.ids->n_values; i++) {
-	std::cerr << selected.ids->value[i] << " ";
-    }
-    std::cerr << std::endl;
-
-    return;
-}
-
-/**
-   \brief Reset topology structure.
-
-   \return
-*/
-void DisplayDriver::ResetTopology()
-{
-    topology.highlight = 0;
-    
-    topology.point = 0;
-    topology.line = 0;
-    
-    topology.boundaryNo = 0;
-    topology.boundaryOne = 0;
-    topology.boundaryTwo = 0;
-    
-    topology.centroidIn = 0;
-    topology.centroidOut = 0;
-    topology.centroidDup = 0;
-    
-    topology.nodeOne = 0;
-    topology.nodeTwo = 0;
-    
-    topology.vertex = 0;
-
-    return;
-}
-
-/**
-   \brief Convert vect list to std::vector
-
-   \param list vect list
-
-   \return std::vector
-*/
-std::vector<int> DisplayDriver::ListToVector(struct ilist *list)
-{
-    std::vector<int> vect;
-
-    if (!list)
-	return vect;
-
-    for (int i = 0; i < list->n_values; i++) {
-	vect.push_back(list->value[i]);
-    }
-
-    return vect;
-}
-
-/**
-   \brief Convert std::vector to vect list
-
-   \param list vect list
-   \param vec  std::vector instance
-
-   \return number of items
-   \return -1 on error
-*/
-int DisplayDriver::VectorToList(struct ilist *list, const std::vector<int>& vec)
-{
-    if (!list)
-	return -1;
-
-    Vect_reset_list(list);
-
-    for (std::vector<int>::const_iterator i = vec.begin(), e = vec.end();
-	 i != e; ++i) {
-	Vect_list_append(list, *i);
-    }
-
-    return list->n_values;
-}
-
-/**
-   \brief Get bounding box of (opened) vector map layer
-
-   \return (w,s,b,e,n,t)
-*/
-std::vector<double> DisplayDriver::GetMapBoundingBox()
-{
-    std::vector<double> region;
-    struct bound_box bbox;
-
-    if (!mapInfo) {
-	return region;
-    }
-    
-    Vect_get_map_box(mapInfo, &bbox);
-
-    region.push_back(bbox.W);
-    region.push_back(bbox.S);
-    region.push_back(bbox.B);
-
-    region.push_back(bbox.E);
-    region.push_back(bbox.N);
-    region.push_back(bbox.T);
-
-    return region;
-}
-
-/*
-  \brief Print one message, prefix inserted before each new line
-
-  From lib/gis/error.c
-*/
-void print_sentence (PyObject *pyFd, const int type, const char *msg)
-{
-    char prefix[256];
-    const char *start;
-    char* sentence;
-
-    switch (type) {
-    case MSG: 
-	sprintf (prefix, "GRASS_INFO_MESSAGE(%d,%d): Vdigit: ", getpid(), message_id);
-	break;
-    case WARN:
-	sprintf (prefix, "GRASS_INFO_WARNING(%d,%d): Vdigit: ", getpid(), message_id);
-	break;
-    case ERR:
-	sprintf (prefix, "GRASS_INFO_ERROR(%d,%d): Vdigit: ", getpid(), message_id);
-	break;
-    }
-
-    start = msg;
-    
-    PyFile_WriteString("\n", pyFd);
-
-    while (*start != '\0') {
-	const char *next = start;
-	
-	PyFile_WriteString(prefix, pyFd);
-	
-	while ( *next != '\0' ) {
-	    next++;
-	    
-	    if ( *next == '\n' ) {
-	        next++;
-		break;
-	    }
-	}
-	
-	sentence = (char *) G_malloc((next - start + 1) * sizeof (char));
-	strncpy(sentence, start, next - start + 1);
-	sentence[next-start] = '\0';
-	
-	PyFile_WriteString(sentence, pyFd);
-	G_free((void *)sentence);
-	
-	PyFile_WriteString("\n", pyFd);
-	start = next;
-    }
-    
-    PyFile_WriteString("\n", pyFd);
-    sprintf(prefix, "GRASS_INFO_END(%d,%d)\n", getpid(), message_id);
-    PyFile_WriteString(prefix, pyFd);
-    
-    message_id++;
-}
-
-/*!
-  \brief Print error/warning/message
-
-  \param msg message buffer
-  \param type message type
-
-  \return 0
-*/
-int print_error(const char *msg, const int type)
-{
-    if (logStream) {
-	print_sentence(logStream, type, msg);
-    }
-    else {
-	fprintf(stderr, "Vdigit: %s\n", msg);
-    }
-
-    return 0;
-}
-
-/*!
-  \brief Print percentage information
-
-  \param x value
-
-  \return 0
-*/
-int print_percent(int x)
-{
-    char msg[256];
-
-    if (logStream) {
-	sprintf(msg, "GRASS_INFO_PERCENT: %d\n", x);
-	PyFile_WriteString(msg, logStream);
-    }
-    else {
-	fprintf(stderr, "GRASS_INFO_PERCENT: %d\n", x);
-    }
-    
-    return 0;
-}
-
-/**
-   \brief Check if vector map is 3D
-
-   \return True for 3D otherwise False
-*/
-bool DisplayDriver::Is3D()
-{
-    return (bool) Vect_is_3d(mapInfo);
-}

+ 0 - 235
gui/wxpython/vdigit/driver.h

@@ -1,235 +0,0 @@
-#ifndef WXVDIGIT_DRIVER_H
-#define WXVDIGIT_DRIVER_H
-
-#include <iostream> // debug
-#include <vector>
-#include <map>
-#include <cmath>
-
-// For compilers that support precompilation, includes "wx.h".
-#include <wx/wxprec.h>
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#ifndef WX_PRECOMP
-// Include your minimal set of headers here, or wx.h
-#include <wx/wx.h>
-#endif
-
-#include <wx/dc.h>
-#include <wx/list.h>
-#include <wx/string.h>
-
-#include <Python.h>
-#include "pseudodc.h"
-#include <wx/gdicmn.h>
-
-extern "C" {
-#include <grass/gis.h>
-#include <grass/vector.h>
-}
-
-class DisplayDriver
-{
-private:
-    friend class Digit;
-    gwxPseudoDC *dc, *dcTmp;  // device content
-    wxWindow *parentWin;
-    
-    /* disabled due to expensive calling dc->SetId()
-     *
-     * currently all objects are drawn without id
-     *
-     * only selected lines with id '1'
-     *
-     * segments with unique id (starting with '1')
-     * are drawn only when line was selected using SelectLineByPoint()
-     */
-    
-    struct _selected {
-	int field;              // field number
-	struct ilist *cats;     // list of cats
-	struct ilist *ids;      // list of ids
-	struct ilist *idsDupl;  // list of duplicated features
-    } selected;
-    
-    bool drawSelected;
-
-    bool drawSegments;         // draw segments of selected line
-    
-    struct Map_info  *mapInfo;
-    struct line_pnts *points;       // east, north, depth
-    wxList           *pointsScreen; // x, y, z
-    struct line_cats *cats;
-    
-    struct _region {
-	// GRASS region section
-	struct bound_box box; // W,E,N,S,T,B
-	double ns_res;
-	double ew_res;
-	double center_easting;
-	double center_northing;
-
-	// map window section
-	double map_width;  // px
-	double map_height;
-	double map_west;
-	double map_north;
-	double map_res;
-    } region;
-
-    struct symbol {
-	bool enabled;
-	wxColor color;
-    };
-
-    struct _settings {
-	wxColor highlight;
-	symbol highlightDupl;
-
-	symbol point;
-	symbol line;
-	
-	symbol boundaryNo;
-	symbol boundaryOne;
-	symbol boundaryTwo;
-
-	symbol centroidIn;
-	symbol centroidOut;
-	symbol centroidDup;
-	
-	symbol nodeOne;
-	symbol nodeTwo;
-
-	symbol vertex;
-
-	symbol area;
-
-	symbol direction;
-
-	int lineWidth;    // screen units 
-    } settings;
-
-    struct _topology {
-	long int highlight;
-
-	long int point;
-	long int line;
-
-	long int boundaryNo;
-	long int boundaryOne;
-	long int boundaryTwo;
-
-	long int centroidIn;
-	long int centroidOut;
-	long int centroidDup;
-
-	long int nodeOne;
-	long int nodeTwo;
-
-	long int vertex;
-    } topology;
-
-    void Cell2Pixel (double, double, double,
-		     double *, double *, double *);
-    double DistanceInPixels(double);
-
-    int DrawCross(gwxPseudoDC *, int, const wxPoint *, int size=5);
-    int DrawArrow(double, double, double, double, double,
-		   int);
-
-    int DrawLine(int);
-    int DrawLineVerteces(int);
-    int DrawLineNodes(int);
-    int DrawDirectionArrow();
-
-    int DrawArea(const line_pnts *);
-
-    /* debug */
-    void PrintIds();
-
-    /* select feature */
-    bool IsSelected(int, bool force=false);
-    bool IsDuplicated(int);
-
-    std::vector<int> ListToVector(struct ilist *);
-    int VectorToList(struct ilist *, const std::vector<int>&);
-
-    void ResetTopology();
-
-    /* message dialogs */
-    wxString msgCaption;
-    void DisplayMsg(void);
-    void Only2DMsg(void);
-    void ReadLineMsg(int);
-    void DeadLineMsg(int);
-    void WriteLineMsg(void);
-    void BackgroundMapMsg(const char *);
-    void DblinkMsg(int);
-    void DbDriverMsg(const char *);
-    void DbDatabaseMsg(const char *, const char *);
-    void DbExecuteMsg(const char *);
-    void DbSelectCursorMsg(const char *);
-    void GetLineCatsMsg(int);
-    
-public:
-    /* constructor */
-    DisplayDriver(gwxPseudoDC *, gwxPseudoDC *, PyObject *);
-    /* destructor */
-    ~DisplayDriver();
-
-    /* display */
-    int DrawMap(bool);
-
-    /* select */
-    int SelectLinesByBox(double, double, double, double,
-			 double, double, int, bool, bool);
-    std::vector<double> SelectLineByPoint(double, double, double,
-					  double, int, int);
-
-    std::vector<int> GetSelected(bool);
-    std::map<int, std::vector<double> > GetSelectedCoord();
-    std::map<int, std::vector <int> > GetDuplicates();
-    std::vector<double> GetRegionSelected();
-    int SetSelected(std::vector<int>, int);
-    int UnSelect(std::vector<int>);
-    std::vector<int> GetSelectedVertex(double, double, double);
-    void DrawSelected(bool);
-
-    /* general */
-    int CloseMap();
-    int OpenMap(const char *, const char *, bool);
-    void ReloadMap();
-    void SetDevice(void *);
-
-    /* misc */
-    std::vector<double> GetMapBoundingBox();
-    bool Is3D();
-
-    /* set */
-    void SetRegion(double, double, double, double,
-		   double, double,
-		   double, double,
-		   double, double);
-
-    void UpdateSettings(unsigned long,
-			bool, unsigned long,
-			bool, unsigned long, /* enabled, color */
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			bool, unsigned long,
-			int, int);
-};
-
-#endif /* WXVDIGIT_DRIVER_H */

+ 0 - 699
gui/wxpython/vdigit/driver_draw.cpp

@@ -1,699 +0,0 @@
-/**
-   \file vdigit/driver_draw.cpp
-   
-   \brief wxvdigit - Display driver (draw methods)
-
-   This driver is designed for wxGUI (vector digitizer) - to draw
-   vector map layer to PseudoDC.
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-#include <cmath>
-
-#include "driver.h"
-
-
-/**
-   \brief Draw content of the vector map to device
-   
-   \return number of drawn features
-   \return -1 on error
- */
-int DisplayDriver::DrawMap(bool force)
-{
-    if (!mapInfo || !dc || !dcTmp)
-	return -1;
-
-    int nlines;
-    struct bound_box mapBox;
-    struct ilist *listLines;
-
-    // ids.clear();
-    listLines = Vect_new_list();
-
-    ResetTopology();
-
-    /* nlines = Vect_get_num_lines(mapInfo); */
-
-    Vect_get_map_box(mapInfo, &mapBox);
-
-    // draw lines inside of current display region
-    nlines = Vect_select_lines_by_box(mapInfo, &(region.box),
-     				      GV_POINTS | GV_LINES, // fixme
-				      listLines);
-
-    G_debug(3, "wxDriver.DrawMap(): region: w=%f, e=%f, s=%f, n=%f",
-	    region.box.W, region.box.E, region.box.S, region.box.N);
-
-    dc->BeginDrawing();
-    dcTmp->BeginDrawing();
-
-    if (settings.area.enabled) {
-	/* draw area fills first */
-	int area, centroid, isle;
-	int num_isles;
-	bool draw;
-	struct ilist *listAreas, *listCentroids;
-	struct line_pnts *points, *ipoints, **isles;
-
-	wxBrush *fillArea, *fillAreaSelected, *fillIsle;
-
-	fillArea = new wxBrush(settings.area.color);
-	fillAreaSelected = new wxBrush(settings.highlight);
-	fillIsle = new wxBrush(*wxWHITE_BRUSH);
-	
-	listAreas = Vect_new_list();
-	listCentroids = Vect_new_list();
-	
-	points = Vect_new_line_struct();
-	ipoints = NULL;
-
-	Vect_select_areas_by_box(mapInfo, &region.box,
-				 listAreas);
-
-	for (int i = 0; i < listAreas->n_values; i++) {
-	    area = listAreas->value[i];
-	    
-	    if (!Vect_area_alive (mapInfo, area))
-		return -1;
-
-	    /* check for other centroids -- only area with one centroid is valid */
-	    centroid = Vect_get_area_centroid(mapInfo, area);
-
-	    if(centroid > 0) {
-		/* check for isles */
-		num_isles = Vect_get_area_num_isles(mapInfo, area); /* TODO */
-		if (num_isles < 1)
-		    isles = NULL;
-		else
-		    isles = (struct line_pnts **) G_malloc(num_isles * sizeof(struct line_pnts *));
-		for (int j = 0; j < num_isles; j++) {
-		    ipoints = Vect_new_line_struct();
-		    isle = Vect_get_area_isle(mapInfo, area, j);
-
-		    if (!Vect_isle_alive (mapInfo, isle))
-			return -1;
-
-		    Vect_get_isle_points(mapInfo, isle, ipoints);
-		    isles[j] = ipoints;
-		}
-
-		Vect_get_area_points(mapInfo, area, points);
-
-		/* avoid processing areas with large number of polygon points (ugly) */
-		if (points->n_points < 5000) {
-		    Vect_select_lines_by_polygon(mapInfo, points,
-						 num_isles, isles, GV_CENTROID, listCentroids);
-		}
-		else {
-		    Vect_reset_list(listCentroids);
-		}
-
-		draw = true;
-		for (int c = 0; c < listCentroids->n_values; c++) {
-		    if(Vect_get_centroid_area(mapInfo, listCentroids->value[c]) < 0) {
-			draw = false;
-			break;
-		    }
-		}
-		
-		if (draw) {
-		    int cat;
-		    cat = Vect_get_area_cat(mapInfo, area, 1); /* TODO: field */
-		    if (cat > -1 && IsSelected(cat, true)) {
-			dc->SetBrush(*fillAreaSelected);
-		    }
-		    else {
-			dc->SetBrush(*fillArea);
-		    }
-		    dc->SetPen(*wxTRANSPARENT_PEN);
-		    DrawArea(points);
-
-		    for (int j = 0; j < num_isles; j++) {
-			/* draw isles in white */
-			dc->SetBrush(*fillIsle);
-			dc->SetPen(*wxTRANSPARENT_PEN);
-			DrawArea(isles[j]);
-		    }
-		}
-
-		if(isles) {
-		    for (int j = 0; j < num_isles; j++) {
-			Vect_destroy_line_struct(isles[j]);
-			isles[j] = NULL;
-		    }
-		    G_free((void *) isles);
-		    isles = NULL;
-		}
-	    }
-	}
-
-	delete fillArea;
-	delete fillIsle;
-
-	Vect_destroy_line_struct(points);
-
-	Vect_destroy_list(listAreas);
-	Vect_destroy_list(listCentroids);
-    }
-
-    for (int i = 0; i < listLines->n_values; i++) {
-	DrawLine(listLines->value[i]);
-    }
-
-    dcTmp->EndDrawing();
-    dc->EndDrawing();
-    
-    /* reset list of selected features by cat 
-       -> list of ids - see IsSelected()
-    */
-    selected.field = -1;
-    Vect_reset_list(selected.cats);
-	
-    Vect_destroy_list(listLines);
-
-    return listLines->n_values;
-}	
-
-/**
-   \brief Draw area fill
-
-   \param area boundary points
-
-   \return 1 on success
-   \return -1 on failure (vector object is dead, etc.)
-*/
-int DisplayDriver::DrawArea(const line_pnts* points)
-{
-    double x, y, z;
-
-    // convert EN -> xy
-    wxPoint *wxPoints = new wxPoint[points->n_points];
-
-    for (int i = 0; i < points->n_points; i++) {
-	Cell2Pixel(points->x[i], points->y[i], points->z[i],
-		   &x, &y, &z);
-	wxPoints[i] = wxPoint((int) x, (int) y);
-    }
-
-    // draw polygon
-    dc->DrawPolygon(points->n_points, wxPoints);
-
-    delete [] wxPoints;
-
-    return 1;
-}
-
-/**
-   \brief Draw selected vector objects to the device
- 
-   \param[in] line id
-
-   \return 1 on success
-   \return -1 on failure (vector object is dead, etc.)
-*/
-int DisplayDriver::DrawLine(int line)
-{
-    int dcId;       // 0 | 1 | segment id
-    int type;       // line type
-    double x, y, z; // screen coordinates
-    bool draw;      // draw object ?
-    wxPen *pen;
-    gwxPseudoDC *pdc;
-
-    pen = NULL;
-    draw = false;
-
-    if (!dc || !dcTmp || !Vect_line_alive (mapInfo, line))
-	return -1;
-
-    // read line
-    type = Vect_read_line (mapInfo, points, cats, line);
-
-    pdc = NULL;
-
-    if (IsSelected(line)) { // line selected ?
-	pdc = dcTmp;
-
-	if (settings.highlightDupl.enabled && IsDuplicated(line)) {
-	    pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
-	}
-	else {
-	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	}
-	if (drawSelected) {
-	    draw = true;
-	}
-	else {
-	    draw = false;
-	}
-	dcId = 1;
-	topology.highlight++;
-    }
-    else {
-	pdc = dc;
-	
-	dcId = 0;
-	if (type & GV_LINES) {
-	    switch (type) {
-	    case GV_LINE:
-		pen = new wxPen(settings.line.color, settings.lineWidth, wxSOLID);
-		topology.line++;
-		draw = settings.line.enabled;
-		break;
-	    case GV_BOUNDARY:
-		int left, right;
-		Vect_get_line_areas(mapInfo, line,
-				    &left, &right);
-		if (left == 0 && right == 0) {
-		    pen = new wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryNo++;
-		    draw = settings.boundaryNo.enabled;
-		}
-		else if (left > 0 && right > 0) {
-		    pen = new wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryTwo++;
-		    draw = settings.boundaryTwo.enabled;
-		}
-		else {
-		    pen = new wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID);
-		    topology.boundaryOne++;
-		    draw = settings.boundaryOne.enabled;
-		}
-		break;
-	    default:
-		draw = false;
-		break;
-	    }
-	}
-	else if (type & GV_POINTS) {
-	    if (type == GV_POINT && settings.point.enabled) {
-		pen = new wxPen(settings.point.color, settings.lineWidth, wxSOLID);
-		topology.point++;
-		draw = settings.point.enabled;
-	    }
-	    else if (type == GV_CENTROID) {
-		int cret = Vect_get_centroid_area(mapInfo, line);
-		if (cret > 0) { // -> area
-		    draw = settings.centroidIn.enabled;
-		    pen = new wxPen(settings.centroidIn.color, settings.lineWidth, wxSOLID);
-		    topology.centroidIn++;
-		}
-		else if (cret == 0) {
-		    draw = settings.centroidOut.enabled;
-		    pen = new wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID);
-		    topology.centroidOut++;
-		}
-		else {
-		    draw = settings.centroidDup.enabled;
-		    pen = new wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID);
-		    topology.centroidDup++;
-		}
-	    }
-	}
-    }
-    
-    // clear screen points & convert EN -> xy
-    pointsScreen->Clear();
-    for (int i = 0; i < points->n_points; i++) {
-	Cell2Pixel(points->x[i], points->y[i], points->z[i],
-		   &x, &y, &z);
-	pointsScreen->Append((wxObject*) new wxPoint((int) x, (int) y)); /* TODO: 3D */
-    }
-    
-    pdc->SetId(dcId); /* 0 | 1 (selected) */
-   
-    if (draw) {
-	pdc->SetPen(*pen);
-	if (type & GV_POINTS) {
-	    DrawCross(pdc, line, (const wxPoint *) pointsScreen->GetFirst()->GetData());
-	}
-	else {
-	    // long int startId = ids[line].startId + 1;
-	    if (dcId > 0 && drawSegments) {
-		dcId = 2; // first segment
-		for (size_t i = 0; i < pointsScreen->GetCount() - 1; dcId += 2) {
-		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
-		    wxPoint *point_end = (wxPoint *) pointsScreen->Item(++i)->GetData();
-		    
-		    // set bounds for line
-		    // wxRect rect (*point_beg, *point_end);
-		    // dc->SetIdBounds(startId, rect);
-		    
-		    pdc->SetId(dcId); // set unique id & set bbox for each segment
-		    pdc->SetPen(*pen);
-		    wxRect rect (*point_beg, *point_end);
-		    pdc->SetIdBounds(dcId, rect);
-		    pdc->DrawLine(point_beg->x, point_beg->y,
-				  point_end->x, point_end->y);
-		}
-	    }
-	    else {
-		wxPoint *wxPoints = new wxPoint[pointsScreen->GetCount()];
-		for (size_t i = 0; i < pointsScreen->GetCount(); i++) {
-		    wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
-		    wxPoints[i] = *point_beg;
-		}
-		
-		pdc->DrawLines(pointsScreen->GetCount(), wxPoints);
-
-		delete [] wxPoints;
-
-		if (!IsSelected(line) && settings.direction.enabled) {
-		    DrawDirectionArrow();
-		    // restore pen
-		    pdc->SetPen(*pen);
-		}
-	    }
-	}
-    }
-
-    if (type & GV_LINES) {
-	DrawLineVerteces(line); // draw vertices
-	DrawLineNodes(line);    // draw nodes
-    }
-
-    delete pen;
-
-    return 1;
-}
-
-/**
-   \brief Draw line verteces to the device
- 
-   Except of first and last vertex, see DrawLineNodes().
-
-   \param line id
-
-   \return number of verteces which were drawn
-   \return -1 if drawing vertices is disabled
-*/
-int DisplayDriver::DrawLineVerteces(int line)
-{
-    int dcId;
-    wxPoint *point;
-    wxPen *pen;
-    gwxPseudoDC *pdc;
-
-    if (!IsSelected(line) && !settings.vertex.enabled)
-	return -1;
-
-    pdc = NULL;
-
-    // determine color
-    if (!IsSelected(line)) {
-	pdc = dc;
-
-	pen = new wxPen(settings.vertex.color, settings.lineWidth, wxSOLID);
-	dcId = 0;
-    }
-    else {
-	pdc = dcTmp;
-	
-	if (!drawSelected) {
-	    return -1;
-	}
-	if (settings.highlightDupl.enabled && IsDuplicated(line)) {
-	    pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
-	}
-	else {
-	    pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	}
-	if (drawSegments) {
-	    dcId = 3; // first vertex
-	}
-	else {
-	    dcId = 1;
-	}
-    }
-
-    pdc->SetId(dcId); /* 0 | 1 (selected) */
-    pdc->SetPen(*pen);
-
-    for (size_t i = 1; i < pointsScreen->GetCount() - 1; i++, dcId += 2) {
-	point = (wxPoint*) pointsScreen->Item(i)->GetData();
-
-	if (IsSelected(line) && drawSegments) {
-	    pdc->SetId(dcId);
-	    pdc->SetPen(*pen);
-	    wxRect rect (*point, *point);
-	    pdc->SetIdBounds(dcId, rect);
-	}
-	
-	if (settings.vertex.enabled) {
-	    DrawCross(pdc, line, (const wxPoint*) pointsScreen->Item(i)->GetData());
-	    topology.vertex++;
-	}
-    }
-
-    delete pen;
-
-    return pointsScreen->GetCount() - 2;
-}
-
-/**
-   \brief Draw line nodes to the device
- 
-   \param line id
-
-   \return 1
-   \return -1 if no nodes were drawn
-*/
-int DisplayDriver::DrawLineNodes(int line)
-{
-    int dcId;
-    int node;
-    double east, north, depth;
-    double x, y, z;
-    int nodes [2];
-    bool draw;
-
-    wxPen *pen;
-    gwxPseudoDC *pdc;
-
-    pdc = NULL;
-
-    // draw nodes??
-    if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled)
-	return -1;
-
-    // get nodes
-    Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1]));
-        
-    for (size_t i = 0; i < sizeof(nodes) / sizeof(int); i++) {
-	node = nodes[i];
-	// get coordinates
-	Vect_get_node_coor(mapInfo, node,
-			   &east, &north, &depth);
-
-	// convert EN->xy
-	Cell2Pixel(east, north, depth,
-		   &x, &y, &z);
-
-	// determine color
-	if (IsSelected(line)) {
-	    pdc = dcTmp;
-	    
-	    if (!drawSelected) {
-		return -1;
-	    }
-	    if (settings.highlightDupl.enabled && IsDuplicated(line)) {
-		pen = new wxPen(settings.highlightDupl.color, settings.lineWidth, wxSOLID);
-	    }
-	    else {
-		pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
-	    }
-	    draw = true;
-	    if (!drawSegments) {
-		dcId = 1;
-	    }
-	    else {
-		// node1, line1, vertex1, line2, vertex2, ..., node2
-		if (i == 0) // first node
-		    dcId = 1; 
-		else // last node
-		    dcId = 2 * points->n_points - 1;
-	    }
-	}
-	else {
-	    pdc = dc;
-	    
-	    dcId = 0;
-	    if (Vect_get_node_n_lines(mapInfo, node) == 1) {
-		pen = new wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID);
-		topology.nodeOne++;
-		draw = settings.nodeOne.enabled;
-	    }
-	    else {
-		pen = new wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID);
-		topology.nodeTwo++;
-		draw = settings.nodeTwo.enabled;
-	    }
-	}
-	
-	wxPoint point((int) x, (int) y);
-	if (IsSelected(line) && drawSegments) {
-	    wxRect rect (point, point);
-	    pdc->SetIdBounds(dcId, rect);
-	}
-
-	// draw node if needed
-	if (draw) {
-	    pdc->SetId(dcId);
-	    pdc->SetPen(*pen);
-	    DrawCross(pdc, line, &point);
-	}
-    }
-    
-    delete pen;
-
-    return 1;
-}
-/**
-   \brief Draw cross symbol of given size to device content
-   
-   Used for points, nodes, vertices
-
-   \param[in,out] PseudoDC where to draw
-   \param[in] point coordinates of center
-   \param[in] size size of the cross symbol
-   
-   \return 1 on success
-   \return -1 on failure
-*/
-int DisplayDriver::DrawCross(gwxPseudoDC *pdc, int line, const wxPoint* point, int size)
-{
-    if (!pdc || !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 1;
-}
-
-/**
-   \brief Draw selected features
-
-   \param draw if true draw selected features
-*/
-void DisplayDriver::DrawSelected(bool draw)
-{
-    drawSelected = draw;
-
-    return;
-}
-
-/**
-   \brief Draw line direction arrow
-
-   \return number of drawn arrows
-*/
-int DisplayDriver::DrawDirectionArrow()
-{
-    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, d, x0, y0, z0, x1, y1, z1;
-    struct line_pnts *points_seg;
-    wxPen *pen_arrow;
-    
-    narrows = 0;
-    size = 5;
-    limit = 5; // 5px for line segment
-
-    points_seg = Vect_new_line_struct();
-    pen_arrow = new wxPen(settings.direction.color, settings.lineWidth, wxSOLID);
-
-    dc->SetPen(*pen_arrow);
-
-    dist = Vect_line_length(points);
-    
-    if (DistanceInPixels(dist) >= limit) {
-	while (1) {
-	    pos = (narrows + 1) * 8 * limit * region.map_res;
-
-	    if (Vect_point_on_line(points, pos,
-				   &e, &n, &d, NULL, NULL) < 1) {
-		break;
-	    }
-	    
-	    Cell2Pixel(e, n, d, &x0, &y0, &z0);
-	    
-	    if (Vect_point_on_line(points, pos - 3 * size * region.map_res,
-				   &e, &n, &d, &angle, NULL) < 1) {
-		break;
-	    }
-	    
-	    Cell2Pixel(e, n, d, &x1, &y1, &z1);
-	    
-	    DrawArrow(x0, y0, x1, y1, angle, size);
-
-	    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(points, dist,
-				   &e, &n, &d, NULL, NULL) > 0) {
-	    
-		Cell2Pixel(e, n, d, &x0, &y0, &z0);
-		
-		if (Vect_point_on_line(points, dist - 3 * size * region.map_res,
-				       &e, &n, &d, &angle, NULL) > 0) {
-		    
-		    Cell2Pixel(e, n, d, &x1, &y1, &z1);
-		    
-		    DrawArrow(x0, y0, x1, y1, angle, size);
-		}
-	    }
-	}
-    }
-
-    Vect_destroy_line_struct(points_seg);
-    
-    return narrows;
-}
-
-/**
-   \brief Draw arrow symbol on line
-
-   \param x0,y0 arrow origin
-   \param x1,x1 arrow ending point (on line)
-   \param angle point ending point angle
-   \param size arrow size
-
-   \return 1
-*/
-int DisplayDriver::DrawArrow(double x0, double y0,
-			     double x1, double y1, double angle,
-			     int size)
-{
-    double x, y;
-    double angle_symb;
-
-    angle_symb = angle - M_PI / 2.;
-    x = x1 + size * cos(angle_symb);
-    y = y1 - size * sin(angle_symb);
-    dc->DrawLine((wxCoord) x, (wxCoord) y, (wxCoord) x0, (wxCoord) y0);
-    
-    angle_symb = M_PI / 2. + angle;
-    x = x1 + size * cos(angle_symb);
-    y = y1 - size * sin(angle_symb);
-    dc->DrawLine((wxCoord) x0, (wxCoord) y0, (wxCoord) x, (wxCoord) y);
-
-    return 1;
-}
-

+ 0 - 564
gui/wxpython/vdigit/driver_select.cpp

@@ -1,564 +0,0 @@
-/**
-   \file vdigit/driver_select.cpp
-   
-   \brief wxvdigit - Display driver (selection methods)
-
-   This driver is designed for wxGUI (vector digitizer) - to draw
-   vector map layer to PseudoDC.
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-#include <cmath>
-
-#include "driver.h"
-
-/**
-   \brief 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[in] x1,y1,z1,x2,y2,z3 bounding box definition
-   \param[in] type feature type
-   \param[in] onlyInside if true select only features inside
-   of bounding box (not overlapping)
-
-   \return number of selected features
-   \return -1 on error
-*/
-int DisplayDriver::SelectLinesByBox(double x1, double y1, double z1, 
-				    double x2, double y2, double z2,
-				    int type, bool onlyInside, bool drawSeg)
-{
-    if (!mapInfo)
-	return -1;
-
-    int line;
-
-    struct ilist *list;
-    struct line_pnts *bbox;
-
-    drawSegments = drawSeg;
-    drawSelected = true;
-    
-    /* select by ids */
-    Vect_reset_list(selected.cats);
-
-    list = Vect_new_list();
-    bbox = Vect_new_line_struct();
-
-    Vect_append_point(bbox, x1, y1, z1);
-    Vect_append_point(bbox, x2, y1, z2);
-    Vect_append_point(bbox, x2, y2, z1);
-    Vect_append_point(bbox, x1, y2, z2);
-    Vect_append_point(bbox, x1, y1, z1);
-        
-    Vect_select_lines_by_polygon(mapInfo, bbox,
-				 0, NULL, /* isles */
-				 type, list);
-
-    for (int i = 0; i < list->n_values; i++) {
-	line = list->value[i];
-	if (onlyInside) {
-	    bool inside;
-	    inside = true;
-	    Vect_read_line(mapInfo, points, cats, line);
-	    for (int p = 0; p < points->n_points; p++) {
-		if (!Vect_point_in_poly(points->x[p], points->y[p],
-					bbox)) {
-		    inside = false;
-		    break;
-		}
-	    }
-	    if (!inside)
-		continue; /* skip lines just overlapping bbox */
-	}
-	
-	if (!IsSelected(line)) {
-	    Vect_list_append(selected.ids, line);
-	}
-	else {
-	    Vect_list_delete(selected.ids, line);
-	}
-    }
-
-    Vect_destroy_line_struct(bbox);
-    Vect_destroy_list(list);
-
-    return list->n_values;
-}
-
-/**
-   \brief Select vector feature by given point in given
-   threshold
-   
-   Only one vector object can be selected. Bounding boxes of
-   all segments are stores.
-
-   \param[in] x,y point of searching
-   \param[in] thresh threshold value where to search
-   \param[in] type select vector object of given type
-
-   \return point on line if line found
-*/
-std::vector<double> DisplayDriver::SelectLineByPoint(double x, double y, double z,
-						     double thresh, int type, int with_z)
-{
-  long int line, line_nearest;
-    double px, py, pz;
-
-    std::vector<double> p;
-
-    struct ilist *found;
-
-    found = Vect_new_list();
-
-    drawSelected = true;
-
-    /* select by ids */
-    Vect_reset_list(selected.cats);
-
-    line_nearest = Vect_find_line_list(mapInfo, x, y, z,
-				       type, thresh, with_z,
-				       NULL, found);
-
-    if (line_nearest > 0) {
-	if (!IsSelected(line_nearest)) {
-	    Vect_list_append(selected.ids, line_nearest);
-	}
-	else {
-	    Vect_list_delete(selected.ids, line_nearest);
-	}
-	
-	type = Vect_read_line (mapInfo, points, cats, line_nearest);
-	Vect_line_distance (points, x, y, z, with_z,
-			    &px, &py, &pz,
-			    NULL, NULL, NULL);
-	p.push_back(px);
-	p.push_back(py);
-	if (with_z) {
-	    p.push_back(pz);
-	}
-	
-	/* check for duplicates */
-	if (settings.highlightDupl.enabled) {
-	    for (int i = 0; i < found->n_values; i++) {
-		line = found->value[i];
-		if (line != line_nearest) {
-		    Vect_list_append(selected.ids, found->value[i]);
-		}
-	    }
-	    
-	    GetDuplicates();
-	    
-	    for (int i = 0; i < found->n_values; i++) {
-		line = found->value[i];
-		if (line != line_nearest && !IsDuplicated(line)) {
-		    Vect_list_delete(selected.ids, line);
-		}
-	    }
-	}
-    }
-	
-    Vect_destroy_list(found);
-
-    // drawing segments can be very expensive
-    // only one features selected
-    drawSegments = true;
-
-    return p;
-}
-
-/**
-   \brief Is vector object selected?
-   
-   \param[in] line id
-
-   \return true if vector object is selected
-   \return false if vector object is not selected
-*/
-bool DisplayDriver::IsSelected(int line, bool force)
-{
-    if (selected.cats->n_values < 1 || force) {
-	/* select by id */
-	if (Vect_val_in_list(selected.ids, line)) {
-	    return true;
-	}
-    }
-    else { /* select by cat */
-	for (int i = 0; i < cats->n_cats; i++) {
-	    if (cats->field[i] == selected.field &&
-		Vect_val_in_list(selected.cats, cats->cat[i])) {
-		/* remember id
-		   -> after drawing all features selected.cats is reseted */
-		Vect_list_append(selected.ids, line);
-		return true;
-	    }
-	}
-    }
-    
-    return false;
-}
-
-/**
-   \brief Get ids of selected objects
-
-   \param[in] grassId if true return GRASS line ids
-   if false return PseudoDC ids
-   
-   \return list of ids of selected vector objects
-*/
-std::vector<int> DisplayDriver::GetSelected(bool grassId)
-{
-    if (grassId)
-	return ListToVector(selected.ids);
-
-    std::vector<int> dc_ids;
-
-    if (!drawSegments) {
-	dc_ids.push_back(1);
-    }
-    else {
-	// only first selected feature !
-	int npoints;
-	Vect_read_line(mapInfo, points, NULL, selected.ids->value[0]);
-	npoints = points->n_points;
-	// node - segment - vertex - segment - node
-	for (int i = 1; i < 2 * npoints; i++) {
-	  dc_ids.push_back(i);
-	}
-    }
-
-    return dc_ids;
-}
-
-std::map<int, std::vector<double> > DisplayDriver::GetSelectedCoord()
-{
-  std::map<int, std::vector<double> > ret;
-  int id, npoints;
-
-  id = 1;
-  
-  for (int is = 0; is < selected.ids->n_values; is++) {
-      if (Vect_read_line(mapInfo, points, NULL, selected.ids->value[is]) < 0) {
-	  ReadLineMsg(selected.ids->value[is]);
-	  return ret;
-      }
-      
-      npoints = points->n_points;
-      for (int i = 0; i < points->n_points; i++, id += 2) {
-	  std::vector<double> c;
-	  c.push_back(points->x[i]);
-	  c.push_back(points->y[i]);
-	  c.push_back(points->z[i]);
-	  ret[id] = c;
-      }
-      id--;
-  }
-  
-  return ret;
-}
-
-
-/**
-   \brief Get feature (grass) ids of duplicated objects
-
-   \return list of ids
-*/
-std::map<int, std::vector <int> > DisplayDriver::GetDuplicates()
-{
-    std::map<int, std::vector<int> > ids;
-
-    struct line_pnts *APoints, *BPoints;
- 
-    int line;
-
-    APoints = Vect_new_line_struct();
-    BPoints = Vect_new_line_struct();
-
-    Vect_reset_list(selected.idsDupl);
-
-    for (int i = 0; i < selected.ids->n_values; i++) {
-	line = selected.ids->value[i];
-	if (IsDuplicated(line))
-	    continue;
-	
-	Vect_read_line(mapInfo, APoints, NULL, line);
-	
-	for (int j = 0; j < selected.ids->n_values; j++) {
-	    if (i == j || IsDuplicated(selected.ids->value[j]))
-		continue;
-	    
-	    Vect_read_line(mapInfo, BPoints, NULL, selected.ids->value[j]);
-	    
-	    if (Vect_line_check_duplicate (APoints, BPoints, WITHOUT_Z)) {
-		if (ids.find(i) == ids.end()) {
-		    ids[i] = std::vector<int> ();
-		    ids[i].push_back(selected.ids->value[i]);
-		    Vect_list_append(selected.idsDupl, selected.ids->value[i]);
-		}
-		ids[i].push_back(selected.ids->value[j]);
-		Vect_list_append(selected.idsDupl, selected.ids->value[j]);
-	    }
-	}
-    }
-    
-    Vect_destroy_line_struct(APoints);
-    Vect_destroy_line_struct(BPoints);
-    
-    return ids;
-}
-
-/**
-   \brief Check for already marked duplicates
-
-   \param line line id
-
-   \return 1 line already marked as duplicated
-   \return 0 not duplicated
-*/
-bool DisplayDriver::IsDuplicated(int line)
-{
-    if (Vect_val_in_list(selected.idsDupl, line))
-	return true;
-    
-    return false;
-}
-
-/**
-   \brief Set selected vector objects
-   
-   \param id list of feature ids to be set
-   \param field field number (-1 for ids instead of cats)
-
-   \return 1
-*/
-int DisplayDriver::SetSelected(std::vector<int> id, int field)
-{
-    drawSelected = true;
-
-    if (field > 0) {
-	selected.field = field;
-	VectorToList(selected.cats, id);
-    }
-    else {
-	field = -1;
-	VectorToList(selected.ids, id);
-    }
-    
-    if (id.size() < 1)
-	drawSegments = false;
-
-    return 1;
-}
-
-/**
-   \brief Unselect selected vector features
-   
-   \param[in] list of GRASS feature ids
-
-   \return number of selected features
-*/
-int DisplayDriver::UnSelect(std::vector<int> id)
-{
-    bool checkForDupl;
-
-    checkForDupl = false;
-
-    for (std::vector<int>::const_iterator i = id.begin(), e = id.end();
-	 i != e; ++i) {
-	if (IsSelected(*i)) {
-	    Vect_list_delete(selected.ids, *i);
-	}
-	if (settings.highlightDupl.enabled && IsDuplicated(*i)) {
-	    checkForDupl = true;
-	}
-    }
-
-    if (checkForDupl) {
-	GetDuplicates();
-    }
-
-    return selected.ids->n_values;
-}
-
-/**
-   \brief Get PseudoDC vertex id of selected line
-
-   Set bounding box for vertices of line.
-
-   \param[in] x,y coordinates of click
-   \param[in] thresh threshold value
-
-   \return id of center, left and right vertex
-
-   \return 0 no line found
-   \return -1 on error
-*/
-std::vector<int> DisplayDriver::GetSelectedVertex(double x, double y, double thresh)
-{
-    int startId;
-    int line, type;
-    int Gid, DCid;
-    double vx, vy, vz;      // vertex screen coordinates
-
-    double dist, minDist;
-
-    std::vector<int> returnId;
-
-    // only one object can be selected
-    if (selected.ids->n_values != 1 || !drawSegments) 
-	return returnId;
-
-    startId = 1;
-    line = selected.ids->value[0];
-
-    type = Vect_read_line (mapInfo, points, cats, line);
-
-    minDist = 0.0;
-    Gid = -1;
-    // find the closest vertex (x, y)
-    DCid = 1;
-    for(int idx = 0; idx < points->n_points; idx++) {
-	dist = Vect_points_distance(x, y, 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;
-	    }
-	}
-
-	Cell2Pixel(points->x[idx], points->y[idx], points->z[idx],
-		   &vx, &vy, &vz);
-	wxRect rect (wxPoint ((int) vx, (int) vy), wxPoint ((int) vx, (int) vy));
-	dc->SetIdBounds(DCid, rect);
-	DCid+=2;
-    }	
-
-    if (minDist > thresh)
-	return returnId;
-
-    // desc = &(ids[line]);
-
-    // translate id
-    DCid = Gid * 2 + 1;
-
-    // add selected vertex
-    returnId.push_back(DCid);
-    // left vertex
-    if (DCid == startId) {
-	returnId.push_back(-1);
-    }
-    else {
-	returnId.push_back(DCid - 2);
-    }
-
-    // right vertex
-    if (DCid == (points->n_points - 1) * 2 + startId) {
-	returnId.push_back(-1);
-    }
-    else {
-	returnId.push_back(DCid + 2);
-    }
-
-    return returnId;
-}
-
-/*!
-  \brief Get minimal region extent of selected features
-
-  \return n,s,w,e
-*/
-std::vector<double> DisplayDriver::GetRegionSelected()
-{
-    int line, area, nareas;
-    
-    std::vector<double> region;
-
-    struct bound_box region_box, line_box;
-    struct ilist *list, *list_tmp;
-
-    list = list_tmp = NULL;
-
-    G_zero(&region_box, sizeof(region_box));
-    
-    if (selected.cats->n_values > 0) { /* -> cats */
-	list = Vect_new_list();
-	list_tmp = Vect_new_list();
-	/* can't use here
-	 *
-	  Vect_cidx_find_all(mapInfo, 1, GV_POINTS | GV_LINES,
-	  selected.ids->value[i],
-	  list_tmp);
-	*/
-	int type;
-	bool found;
-	for (int line = 1; line <= Vect_get_num_lines(mapInfo); line++) {
-	    type = Vect_read_line (mapInfo, NULL, cats, line);
-	    if (!(type & (GV_POINTS | GV_LINES)))
-		continue;
-	    
-	    found = false;
-	    for (int i = 0; i < cats->n_cats && !found; i++) {
-		for (int j = 0; j < selected.ids->n_values && !found; j++) {
-		    if (cats->cat[i] == selected.ids->value[j])
-			found = true;
-		}
-	    }
-	    if (found)
-		Vect_list_append(list, line);
-	}
-    }
-    else {
-	list = selected.ids;
-    }
-
-    nareas = Vect_get_num_areas(mapInfo);
-    for (int i = 0; i < list->n_values; i++) {
-	line = list->value[i];
-	area = Vect_get_centroid_area(mapInfo, line);
-
-	if (area > 0 && area <= nareas) {
-	    if (!Vect_get_area_box(mapInfo, area, &line_box))
-		continue;
-	}
-	else {
-	    if (!Vect_get_line_box(mapInfo, line, &line_box))
-		continue;
-	}
-	
-	if (i == 0) {
-	    Vect_box_copy(&region_box, &line_box);
-	}
-	else {
-	    Vect_box_extend(&region_box, &line_box);
-	}
-    }
-    
-    if (list && list != selected.ids) {
-	Vect_destroy_list(list);
-    }
-    if (list_tmp)
-	Vect_destroy_list(list_tmp);
-	
-    region.push_back(region_box.N);
-    region.push_back(region_box.S);
-    region.push_back(region_box.W);
-    region.push_back(region_box.E);
-
-    return region;
-}

文件差异内容过多而无法显示
+ 0 - 1133
gui/wxpython/vdigit/line.cpp


+ 0 - 207
gui/wxpython/vdigit/message.cpp

@@ -1,207 +0,0 @@
-/**
-   \file vdigit/message.cpp
-
-   \brief wxvdigit - Error message dialogs
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-extern "C" {
-#include <grass/glocale.h>
-}
-
-#include "driver.h"
-#include "digit.h"
-
-/**
-   \brief Error message - no display driver available
-*/
-void DisplayDriver::DisplayMsg(void)
-{
-    wxMessageDialog dlg(parentWin, _("Display driver not available."),
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-
-    return;
-}
-
-/**
-   \brief Error message - cannot edit 3d features
-*/
-void DisplayDriver::Only2DMsg(void)
-{
-    wxMessageDialog dlg(parentWin, _("3D vector features are not currently supported."),
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to write line
-*/
-void DisplayDriver::WriteLineMsg(void)
-{
-    wxMessageDialog dlg(parentWin, _("Unable to write new line"),
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to read line
-
-   \param line line id
-*/
-void DisplayDriver::ReadLineMsg(int line)
-{
-    wxString msg;
-    msg.Printf(_("Unable to read line %d"), line);
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - trying to read dead line
-
-   \param line line id
-*/
-void DisplayDriver::DeadLineMsg(int line)
-{
-    wxString msg;
-    msg.Printf(_("Unable to read line %d, line is dead"), line);
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to open background map
-
-   \param bgmap map name
-*/
-void DisplayDriver::BackgroundMapMsg(const char *bgmap)
-{
-    wxString msg;
-    msg.Printf(_("Unable to open background vector map <%s>. Please check digitizer settings."),
-	       wxString (bgmap, wxConvUTF8).c_str());
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - dblink not defined
-
-   \param layer layer id
-*/
-void DisplayDriver::DblinkMsg(int layer)
-{
-    wxString msg;
-    msg.Printf(_("Database connection not defined for layer %d"), layer);
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to start driver
-
-   \param driver driver name
-*/
-void DisplayDriver::DbDriverMsg(const char *driver)
-{
-    wxString msg;
-    msg.Printf(_("Unable to start driver <%s>"),
-	       wxString(driver, wxConvUTF8).c_str());
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to open database
-
-   \param driver driver name
-   \param database database name
-*/
-void DisplayDriver::DbDatabaseMsg(const char *driver, const char *database)
-{
-    wxString msg;
-    msg.Printf(_("Unable to open database <%s> by driver <%s>"),
-	       wxString(database, wxConvUTF8).c_str(),
-	       wxString(driver, wxConvUTF8).c_str());
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to execute SQL command
-
-   \param sql sql command
-*/
-void DisplayDriver::DbExecuteMsg(const char *sql)
-{
-    wxString msg;
-    msg.Printf(_("Unable to execute: '%s'"),
-	       wxString(sql, wxConvUTF8).c_str());
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to open select cursor
-
-   \param sql sql command
-*/
-void DisplayDriver::DbSelectCursorMsg(const char *sql)
-{
-    wxString msg;
-    msg.Printf(_("Unable to open select cursor: '%s'"),
-	       wxString(sql, wxConvUTF8).c_str());
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}
-
-/**
-   \brief Error message - unable to get line categories
-
-   \param line line id
-*/
-void DisplayDriver::GetLineCatsMsg(int line)
-{
-    wxString msg;
-    msg.Printf(_("Unable to get feature (%d) categories"), line);
-    wxMessageDialog dlg(parentWin, msg,
-			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
-    dlg.ShowModal();
-    
-    return;
-}

+ 0 - 633
gui/wxpython/vdigit/pseudodc.cpp

@@ -1,633 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        pseudodc.cpp
-// Purpose:     Implementation of the gwxPseudoDC Class
-// Author:      Paul Lanier
-// Modified by: Glynn Clements 2009-01-14
-// Created:     05/25/06
-// RCS-ID:      $Id: pseudodc.cpp 51090 2008-01-08 04:36:23Z RD $
-// Copyright:   (c) wxWidgets team
-// Licence:     wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-// For compilers that support precompilation, includes "wx.h".
-//include "wx/wxprec.h"
-
-#undef DEBUG
-#include <Python.h>
-#include <wx/wxPython/wxPython.h>
-#include "pseudodc.h"
-
-// wxList based class definitions
-#include <wx/listimpl.cpp>
-WX_DEFINE_LIST(gpdcOpList);
-WX_DEFINE_LIST(gpdcObjectList);
-
-//----------------------------------------------------------------------------
-// Helper functions used for drawing greyed out versions of objects
-//----------------------------------------------------------------------------
-wxColour &gwxMakeColourGrey(const wxColour &c)
-{
-    static wxColour rval;
-    rval.Set(byte((230-c.Red())*0.7+c.Red()),
-             byte((230-c.Green())*0.7+c.Green()),
-             byte((230-c.Blue())*0.7+c.Blue()));
-    return rval;
-}
-wxBrush &gwxGetGreyBrush(wxBrush &brush)
-{
-	static wxBrush b;
-	wxColour c;
-	b = brush;
-	c = gwxMakeColourGrey(brush.GetColour());
-	b.SetColour(c);
-	return b;
-}
-
-wxPen &gwxGetGreyPen(wxPen &pen)
-{
-	static wxPen p;
-	wxColour c;
-	p = pen;
-	c = gwxMakeColourGrey(pen.GetColour());
-	p.SetColour(c);
-	return p;
-}
-
-void gwxGreyOutImage(wxImage &img)
-{
-    unsigned char *data = img.GetData();
-    unsigned char r,g,b;
-    unsigned char mr,mg,mb;
-    int i, tst;
-    int len = img.GetHeight()*img.GetWidth()*3;
-    if (img.HasMask())
-    {
-        mr = img.GetMaskRed();
-        mg = img.GetMaskGreen();
-        mb = img.GetMaskBlue();
-    }
-    tst=0;
-    for (i=0;i<len;i+=3)
-    {
-        r=data[i]; g=data[i+1]; b=data[i+2];
-        if (!img.HasMask() || 
-            r!=mr || g!=mg || b!=mb)
-        {
-            if (!tst)
-            {
-                tst=1;
-            }
-            r = (unsigned char)((230.0-r)*0.7+r);
-            g = (unsigned char)((230.0-g)*0.7+g);
-            b = (unsigned char)((230.0-b)*0.7+b);
-            data[i]=r; data[i+1]=g; data[i+2]=b;
-        }
-    }
-}
-
-wxIcon &gwxGetGreyIcon(wxIcon &icon)
-{
-    wxBitmap bmp;
-    bmp.CopyFromIcon(icon);
-    wxImage img = bmp.ConvertToImage();
-    gwxGreyOutImage(img);
-    wxBitmap bmp2(img,32);
-    static wxIcon rval;
-    rval.CopyFromBitmap(bmp2);
-    return rval;
-}
-
-wxBitmap &gwxGetGreyBitmap(wxBitmap &bmp)
-{
-    wxImage img = bmp.ConvertToImage();
-    gwxGreyOutImage(img);
-    static wxBitmap rval(img,32);
-    return rval;
-}
-
-// ============================================================================
-// various gpdcOp class implementation methods
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// gpdcDrawPolyPolygonOp constructor
-// ----------------------------------------------------------------------------
-gpdcDrawPolyPolygonOp::gpdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
-                 wxCoord xoffset, wxCoord yoffset, int fillStyle) 
-{
-    m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
-    int total_n=0;
-    if (n)
-    {
-        m_count = new int[n];
-        for(int i=0; i<n; i++) 
-        {
-            total_n+=count[i];
-            m_count[i]=count[i];
-        }
-        if (total_n)
-        {
-            m_points = new wxPoint[total_n];
-            for(int j=0; j<total_n; j++)
-                m_points[j] = points[j];
-        }
-        else m_points=NULL;
-    }
-    else
-    {
-        m_points=NULL;
-        m_count=NULL;
-    }
-    m_totaln = total_n;
-}
-
-// ----------------------------------------------------------------------------
-// gpdcDrawPolyPolygonOp destructor
-// ----------------------------------------------------------------------------
-gpdcDrawPolyPolygonOp::~gpdcDrawPolyPolygonOp()
-{
-    if (m_points) delete m_points;
-    if (m_count) delete m_count;
-    m_points=NULL;
-    m_count=NULL;
-}
-        
-// ----------------------------------------------------------------------------
-// gpdcDrawLinesOp constructor
-// ----------------------------------------------------------------------------
-gpdcDrawLinesOp::gpdcDrawLinesOp(int n, wxPoint points[],
-             wxCoord xoffset, wxCoord yoffset)
-{
-    m_n=n; m_xoffset=xoffset; m_yoffset=yoffset;
-    if (n)
-    {
-        m_points = new wxPoint[n];
-        for (int i=0; i<n; i++)
-            m_points[i] = points[i];
-    }
-    else m_points=NULL;
-}
-
-// ----------------------------------------------------------------------------
-// gpdcDrawLinesOp destructor
-// ----------------------------------------------------------------------------
-gpdcDrawLinesOp::~gpdcDrawLinesOp()
-{
-    if (m_points) delete m_points;
-    m_points=NULL;
-}
-        
-// ----------------------------------------------------------------------------
-// gpdcDrawPolygonOp constructor
-// ----------------------------------------------------------------------------
-gpdcDrawPolygonOp::gpdcDrawPolygonOp(int n, wxPoint points[],
-             wxCoord xoffset, wxCoord yoffset, int fillStyle)
-{
-    m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
-    if (n)
-    {
-        m_points = new wxPoint[n];
-        for (int i=0; i<n; i++)
-            m_points[i] = points[i];
-    }
-    else m_points=NULL;
-}
-
-// ----------------------------------------------------------------------------
-// gpdcDrawPolygonOp destructor
-// ----------------------------------------------------------------------------
-gpdcDrawPolygonOp::~gpdcDrawPolygonOp()
-{
-    if (m_points) delete m_points;
-    m_points=NULL;
-}
-
-#if wxUSE_SPLINES
-// ----------------------------------------------------------------------------
-// gpdcDrawSplineOp constructor
-// ----------------------------------------------------------------------------
-gpdcDrawSplineOp::gpdcDrawSplineOp(int n, wxPoint points[])
-{
-    m_n=n;
-    if (n)
-    {
-        m_points = new wxPoint[n];
-        for(int i=0; i<n; i++)
-            m_points[i] = points[i];
-    }
-    else m_points=NULL;
-}
-
-// ----------------------------------------------------------------------------
-// gpdcDrawSplineOp destructor
-// ----------------------------------------------------------------------------
-gpdcDrawSplineOp::~gpdcDrawSplineOp()
-{
-    if (m_points) delete m_points;
-    m_points=NULL;
-}
-#endif // wxUSE_SPLINES
-
-// ============================================================================
-// gpdcObject implementation
-// ============================================================================
-// ----------------------------------------------------------------------------
-// DrawToDC - play back the op list to the DC 
-// ----------------------------------------------------------------------------
-void gpdcObject::DrawToDC(wxDC *dc)
-{
-    gpdcOpList::compatibility_iterator node = m_oplist.GetFirst(); 
-    while(node)
-    {
-        node->GetData()->DrawToDC(dc, m_greyedout);
-        node = node->GetNext();
-    }
-}
-
-// ----------------------------------------------------------------------------
-// Translate - translate all the operations by some dx,dy
-// ----------------------------------------------------------------------------
-void gpdcObject::Translate(wxCoord dx, wxCoord dy)
-{
-    gpdcOpList::compatibility_iterator node = m_oplist.GetFirst(); 
-    while(node)
-    {
-        node->GetData()->Translate(dx,dy);
-        node = node->GetNext();
-    }
-    if (m_bounded) 
-    {
-        m_bounds.x += dx;
-        m_bounds.y += dy;
-    }
-}
-
-// ----------------------------------------------------------------------------
-// SetGreyedOut - set the greyout member and cache grey versions of everything
-// if greyout is true
-// ----------------------------------------------------------------------------
-void gpdcObject::SetGreyedOut(bool greyout) 
-{
-    m_greyedout=greyout;
-    if (greyout)
-    {
-        gpdcOpList::compatibility_iterator node = m_oplist.GetFirst(); 
-        gpdcOp *obj;
-        while(node)
-        {
-            obj = node->GetData();
-            obj->CacheGrey();
-            node = node->GetNext();
-        }
-    }
-}
-
-// ============================================================================
-// gwxPseudoDC implementation
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// Destructor
-// ----------------------------------------------------------------------------
-gwxPseudoDC::~gwxPseudoDC()
-{
-    // delete all the nodes in the list
-	RemoveAll();
-	
-}
-
-// ----------------------------------------------------------------------------
-// ClearAll - remove all nodes from list
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::RemoveAll(void)
-{
-    m_objectlist.Clear();
-    m_objectIndex.clear();
-    m_currId = -1;
-	m_lastObject = NULL;
-    
-}
-
-// ----------------------------------------------------------------------------
-// GetLen - return the number of operations in the current op list
-// ----------------------------------------------------------------------------
-int gwxPseudoDC::GetLen(void)
-{
-    gpdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
-    int len=0;
-    while (pt) 
-    {
-        len += pt->GetData()->GetLen();
-        pt = pt->GetNext();
-    }
-    return len;
-}
-
-// ----------------------------------------------------------------------------
-// FindObject - find and return an object node by id.  If node doesn't exist
-//               and create is true then create one and return it.  Otherwise
-//               return NULL.
-// ----------------------------------------------------------------------------
-gpdcObject *gwxPseudoDC::FindObject(int id, bool create)
-{
-    // see if last operation was for same id
-    //~ if (m_lastObject && m_lastObject->GetId() == id)
-        //~ return m_lastObject;
-    // if not then search for it    
-    gpdcObjectHash::iterator lookup = m_objectIndex.find(id);
-    if (lookup == m_objectIndex.end()) {//not found
-        if (create) {
-            m_lastObject = new gpdcObject(id);
-            m_objectlist.Append(m_lastObject);
-			gpdcObjectHash::value_type insert(id, m_lastObject);
-            m_objectIndex.insert(insert);
-            return m_lastObject;
-        } else {
-            return NULL;
-        }
-    } else { //found
-        return lookup->second;
-    }
-}
-
-// ----------------------------------------------------------------------------
-// AddToList - Add a node to the list at the end (preserve draw order)
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::AddToList(gpdcOp *newOp)
-{
-    gpdcObject *obj = FindObject(m_currId, true);
-    obj->AddOp(newOp);
-}
-
-// ----------------------------------------------------------------------------
-// ClearID - remove all the operations associated with a single ID
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::ClearId(int id)
-{
-    gpdcObject *obj = FindObject(id);
-    if (obj) obj->Clear();
-}
-
-// ----------------------------------------------------------------------------
-// RemoveID - Remove the object node (and all operations) associated with an id
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::RemoveId(int id)
-{
-    gpdcObject *obj = FindObject(id);
-    if (obj) 
-    {
-        if (m_lastObject == obj)
-            m_lastObject = obj;
-        m_objectlist.DeleteObject(obj);
-    }
-    m_objectIndex.erase(id);
-}
-
-// ----------------------------------------------------------------------------
-// SetIdBounds - Set the bounding rect for a given id
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::SetIdBounds(int id, wxRect& rect)
-{
-    gpdcObject *obj = FindObject(id, true);
-    obj->SetBounds(rect);
-}
-
-// ----------------------------------------------------------------------------
-// GetIdBounds - Get the bounding rect for a given id
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::GetIdBounds(int id, wxRect& rect)
-{
-    gpdcObject *obj = FindObject(id);
-	if (obj && obj->IsBounded())
-		rect = obj->GetBounds();
-	else
-		rect.x = rect.y = rect.width = rect.height = 0;
-}
-
-// ----------------------------------------------------------------------------
-// TranslateId - Translate all the operations of a single id
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::TranslateId(int id, wxCoord dx, wxCoord dy)
-{
-    gpdcObject *obj = FindObject(id);
-    if (obj) obj->Translate(dx,dy);
-}
-
-// ----------------------------------------------------------------------------
-// DrawIdToDC - Draw a specific id to the dc passed in
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::DrawIdToDC(int id, wxDC *dc)
-{
-    gpdcObject *obj = FindObject(id);
-    if (obj) obj->DrawToDC(dc);
-}
-
-// ----------------------------------------------------------------------------
-// SetIdGreyedOut - Set the greyedout member of id
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::SetIdGreyedOut(int id, bool greyout)
-{
-    gpdcObject *obj = FindObject(id);
-    if (obj) obj->SetGreyedOut(greyout);
-}
-
-// ----------------------------------------------------------------------------
-// GetIdGreyedOut - Get the greyedout member of id
-// ----------------------------------------------------------------------------
-bool gwxPseudoDC::GetIdGreyedOut(int id)
-{
-    gpdcObject *obj = FindObject(id);
-    if (obj) return obj->GetGreyedOut();
-	else return false;
-}
-
-// ----------------------------------------------------------------------------
-// FindObjectsByBBox - Return a list of all the ids whose bounding boxes
-//                     contain (x,y)
-// ----------------------------------------------------------------------------
-PyObject *gwxPseudoDC::FindObjectsByBBox(wxCoord x, wxCoord y)
-{
-    //wxPyBlock_t blocked = wxPyBeginBlockThreads();
-    gpdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
-    gpdcObject *obj;
-    PyObject* pyList = NULL;
-    pyList = PyList_New(0);
-    wxRect r;
-    while (pt) 
-    {
-        obj = pt->GetData();
-        r = obj->GetBounds();
-        if (obj->IsBounded() && r.Contains(x,y))
-        {
-            PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
-            PyList_Insert(pyList, 0, pyObj);
-            Py_DECREF(pyObj);
-        }
-        pt = pt->GetNext();
-    }
-    //wxPyEndBlockThreads(blocked);
-    return pyList;
-}
-
-// ----------------------------------------------------------------------------
-// FindObjects - Return a list of all the ids that draw to (x,y)
-// ----------------------------------------------------------------------------
-PyObject *gwxPseudoDC::FindObjects(wxCoord x, wxCoord y, 
-                                  wxCoord radius, const wxColor& bg)
-{
-    //wxPyBlock_t blocked = wxPyBeginBlockThreads();
-    gpdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
-    gpdcObject *obj;
-    PyObject* pyList = NULL;
-    pyList = PyList_New(0);
-    wxBrush bgbrush(bg);
-    wxPen bgpen(bg);
-    // special case radius = 0
-    if (radius == 0)
-    {
-        wxBitmap bmp(4,4,24);
-        wxMemoryDC memdc;
-        wxColor pix;
-        wxRect viewrect(x-2,y-2,4,4);
-        // setup the memdc for rendering
-        memdc.SelectObject(bmp);
-        memdc.SetBackground(bgbrush);
-        memdc.Clear();
-        memdc.SetDeviceOrigin(2-x,2-y);
-        while (pt) 
-        {
-            obj = pt->GetData();
-            if (obj->IsBounded() && obj->GetBounds().Contains(x,y))
-            {
-                // start clean
-                memdc.SetBrush(bgbrush);
-                memdc.SetPen(bgpen);
-                memdc.DrawRectangle(viewrect);
-                // draw the object
-                obj->DrawToDC(&memdc);
-                memdc.GetPixel(x,y,&pix);
-                // clear and update rgn2
-                if (pix != bg)
-                {
-                    PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
-                    PyList_Insert(pyList, 0, pyObj);
-                    Py_DECREF(pyObj);
-                }
-            }
-            pt = pt->GetNext();
-        }
-        memdc.SelectObject(wxNullBitmap);
-    }
-    else
-    {
-        wxRect viewrect(x-radius,y-radius,2*radius,2*radius);
-        wxBitmap maskbmp(2*radius,2*radius,24);
-        wxMemoryDC maskdc;
-        // create bitmap with circle for masking
-        maskdc.SelectObject(maskbmp);
-        maskdc.SetBackground(*wxBLACK_BRUSH);
-        maskdc.Clear();
-        maskdc.SetBrush(*wxWHITE_BRUSH);
-        maskdc.SetPen(*wxWHITE_PEN);
-        maskdc.DrawCircle(radius,radius,radius);
-        // now setup a memdc for rendering our object
-        wxBitmap bmp(2*radius,2*radius,24);
-        wxMemoryDC memdc;
-        memdc.SelectObject(bmp);
-        // set the origin so (x,y) is in the bmp center
-        memdc.SetDeviceOrigin(radius-x,radius-y);
-        // a region will be used to see if the result is empty
-        wxRegion rgn2;
-        while (pt) 
-        {
-            obj = pt->GetData();
-            if (obj->IsBounded() && viewrect.Intersects(obj->GetBounds()))
-            {
-                // start clean
-                //memdc.Clear();
-                memdc.SetBrush(bgbrush);
-                memdc.SetPen(bgpen);
-                memdc.DrawRectangle(viewrect);
-                // draw the object
-                obj->DrawToDC(&memdc);
-                // remove background color
-                memdc.SetLogicalFunction(wxXOR);
-                memdc.SetBrush(bgbrush);
-                memdc.SetPen(bgpen);
-                memdc.DrawRectangle(viewrect);
-                memdc.SetLogicalFunction(wxCOPY);
-#ifdef __WXMAC__
-                // wxAND is not supported on wxMac, but it doesn't seem to
-                // hurt anything to use wxCOPY instead...
-                memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxCOPY);
-#else
-                // AND with circle bitmap
-                memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxAND);
-#endif
-                // clear and update rgn2
-                memdc.SelectObject(wxNullBitmap);
-                rgn2.Clear();
-                rgn2.Union(bmp, *wxBLACK);
-                //rgn2.Intersect(rgn);
-                memdc.SelectObject(bmp);
-                if (!rgn2.IsEmpty())
-                {
-                    PyObject* pyObj = PyInt_FromLong((long)obj->GetId());
-                    PyList_Insert(pyList, 0, pyObj);
-                    Py_DECREF(pyObj);
-                }
-            }
-            pt = pt->GetNext();
-        }
-        maskdc.SelectObject(wxNullBitmap);
-        memdc.SelectObject(wxNullBitmap);
-    }
-    //wxPyEndBlockThreads(blocked);
-    return pyList;
-}
-
-// ----------------------------------------------------------------------------
-// DrawToDCClipped - play back the op list to the DC but clip any objects
-//                   known to be not in rect.  This is a coarse level of 
-//                   clipping to speed things up when lots of objects are off 
-//                   screen and doesn't affect the dc level clipping
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect)
-{
-    gpdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
-    gpdcObject *obj;
-    while (pt) 
-    {
-        obj = pt->GetData();
-        if (!obj->IsBounded() || rect.Intersects(obj->GetBounds()))
-            obj->DrawToDC(dc);
-        pt = pt->GetNext();
-    }
-}
-void gwxPseudoDC::DrawToDCClippedRgn(wxDC *dc, const wxRegion& region)
-{
-    gpdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
-    gpdcObject *obj;
-    while (pt) 
-    {
-        obj = pt->GetData();
-        if (!obj->IsBounded() || 
-		    (region.Contains(obj->GetBounds()) != wxOutRegion))
-            obj->DrawToDC(dc);
-        pt = pt->GetNext();
-    }
-}
-
-// ----------------------------------------------------------------------------
-// DrawToDC - play back the op list to the DC 
-// ----------------------------------------------------------------------------
-void gwxPseudoDC::DrawToDC(wxDC *dc)
-{
-    gpdcObjectList::compatibility_iterator pt = m_objectlist.GetFirst();
-    while (pt) 
-    {
-        pt->GetData()->DrawToDC(dc);
-        pt = pt->GetNext();
-    }
-}
-        

+ 0 - 826
gui/wxpython/vdigit/pseudodc.h

@@ -1,826 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        pseudodc.h
-// Purpose:     gwxPseudoDC class
-// Author:      Paul Lanier
-// Modified by: Glynn Clements 2009-01-14
-// Created:     05/25/06
-// RCS-ID:      $Id: pseudodc.h 49047 2007-10-05 18:08:39Z RD $
-// Copyright:   (c) wxWidgets team
-// Licence:     wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-#ifndef _GWX_PSUEDO_DC_H_BASE_
-#define _GWX_PSUEDO_DC_H_BASE_
-
-//----------------------------------------------------------------------------
-// Base class for all gpdcOp classes
-//----------------------------------------------------------------------------
-class gpdcOp
-{
-    public:
-        // Constructor and Destructor
-        gpdcOp() {}
-        virtual ~gpdcOp() {}
-
-        // Virtual Drawing Methods
-        virtual void DrawToDC(wxDC *dc, bool grey=false)=0;
-        virtual void Translate(wxCoord dx, wxCoord dy) {}
-        virtual void CacheGrey() {}
-};
-
-//----------------------------------------------------------------------------
-// declare a list class for list of gpdcOps
-//----------------------------------------------------------------------------
-WX_DECLARE_LIST(gpdcOp, gpdcOpList);
-
-
-//----------------------------------------------------------------------------
-// Helper functions used for drawing greyed out versions of objects
-//----------------------------------------------------------------------------
-wxColour &gwxMakeColourGrey(const wxColour &c);
-wxBrush &gwxGetGreyBrush(wxBrush &brush);
-wxPen &gwxGetGreyPen(wxPen &pen);
-wxIcon &gwxGetGreyIcon(wxIcon &icon);
-wxBitmap &gwxGetGreyBitmap(wxBitmap &bmp);
-void gwxGreyOutImage(wxImage &img);
-
-//----------------------------------------------------------------------------
-// Classes derived from gpdcOp
-// There is one class for each method mirrored from wxDC to gwxPseudoDC
-//----------------------------------------------------------------------------
-class gpdcSetFontOp : public gpdcOp
-{
-    public:
-        gpdcSetFontOp(const wxFont& font) 
-            {m_font=font;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->SetFont(m_font);}
-    protected:
-        wxFont m_font;
-};
-
-class gpdcSetBrushOp : public gpdcOp
-{
-    public:
-        gpdcSetBrushOp(const wxBrush& brush) 
-            {m_greybrush=m_brush=brush;} 
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-        {
-            if (!grey) dc->SetBrush(m_brush);
-            else dc->SetBrush(m_greybrush);
-        }
-        virtual void CacheGrey() {m_greybrush=gwxGetGreyBrush(m_brush);}
-    protected:
-        wxBrush m_brush;
-        wxBrush m_greybrush;
-};
-
-class gpdcSetBackgroundOp : public gpdcOp
-{
-    public:
-        gpdcSetBackgroundOp(const wxBrush& brush) 
-            {m_greybrush=m_brush=brush;} 
-        virtual void DrawToDC(wxDC *dc, bool grey=false)
-        {
-            if (!grey) dc->SetBackground(m_brush);
-            else dc->SetBackground(m_greybrush);
-        }
-        virtual void CacheGrey() {m_greybrush=gwxGetGreyBrush(m_brush);}
-    protected:
-        wxBrush m_brush;
-        wxBrush m_greybrush;
-};
-
-class gpdcSetPenOp : public gpdcOp
-{
-    public:
-        gpdcSetPenOp(const wxPen& pen) 
-            {m_greypen=m_pen=pen;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false)
-        {
-            if (!grey) dc->SetPen(m_pen);
-            else dc->SetPen(m_greypen);
-        }
-        virtual void CacheGrey() {m_greypen=gwxGetGreyPen(m_pen);}
-    protected:
-        wxPen m_pen;
-        wxPen m_greypen;
-};
-
-class gpdcSetTextBackgroundOp : public gpdcOp
-{
-    public:
-        gpdcSetTextBackgroundOp(const wxColour& colour) 
-            {m_colour=colour;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-        {
-            if (!grey) dc->SetTextBackground(m_colour);
-            else dc->SetTextBackground(gwxMakeColourGrey(m_colour));
-        }
-    protected:
-        wxColour m_colour;
-};
-
-class gpdcSetTextForegroundOp : public gpdcOp
-{
-    public:
-        gpdcSetTextForegroundOp(const wxColour& colour) 
-            {m_colour=colour;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false)
-        {
-            if (!grey) dc->SetTextForeground(m_colour);
-            else dc->SetTextForeground(gwxMakeColourGrey(m_colour));
-        }
-    protected:
-        wxColour m_colour;
-};
-
-class gpdcDrawRectangleOp : public gpdcOp
-{
-    public:
-        gpdcDrawRectangleOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
-            {m_x=x; m_y=y; m_w=w; m_h=h;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->DrawRectangle(m_x,m_y,m_w,m_h);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx;m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y,m_w,m_h;
-};
-
-class gpdcDrawLineOp : public gpdcOp
-{
-    public:
-        gpdcDrawLineOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
-            {m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->DrawLine(m_x1,m_y1,m_x2,m_y2);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x1+=dx; m_y1+=dy; m_x2+=dx; m_y2+=dy;}
-    protected:
-        wxCoord m_x1,m_y1,m_x2,m_y2;
-};
-
-class gpdcSetBackgroundModeOp : public gpdcOp
-{
-    public:
-        gpdcSetBackgroundModeOp(int mode) {m_mode=mode;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->SetBackgroundMode(m_mode);}
-    protected:
-        int m_mode;
-};
-
-class gpdcDrawTextOp : public gpdcOp
-{
-    public:
-        gpdcDrawTextOp(const wxString& text, wxCoord x, wxCoord y)
-            {m_text=text; m_x=x; m_y=y;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->DrawText(m_text, m_x, m_y);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxString m_text;
-        wxCoord m_x, m_y;
-};
-
-class gpdcClearOp : public gpdcOp
-{
-    public:
-        gpdcClearOp() {}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->Clear();}
-};
-
-class gpdcBeginDrawingOp : public gpdcOp
-{
-    public:
-        gpdcBeginDrawingOp() {}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {}
-};
-
-class gpdcEndDrawingOp : public gpdcOp
-{
-    public:
-        gpdcEndDrawingOp() {}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {}
-};
-
-class gpdcFloodFillOp : public gpdcOp
-{
-    public:
-        gpdcFloodFillOp(wxCoord x, wxCoord y, const wxColour& col,
-                   int style) {m_x=x; m_y=y; m_col=col; m_style=style;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-        {
-            if (!grey) dc->FloodFill(m_x,m_y,m_col,m_style);
-            else dc->FloodFill(m_x,m_y,gwxMakeColourGrey(m_col),m_style);
-        }
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y;
-        wxColour m_col;
-        int m_style;
-};
-
-class gpdcCrossHairOp : public gpdcOp
-{
-    public:
-        gpdcCrossHairOp(wxCoord x, wxCoord y) {m_x=x; m_y=y;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->CrossHair(m_x,m_y);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y;
-};
-
-class gpdcDrawArcOp : public gpdcOp
-{
-    public:
-        gpdcDrawArcOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
-                         wxCoord xc, wxCoord yc) 
-            {m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2; m_xc=xc; m_yc=yc;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawArc(m_x1,m_y1,m_x2,m_y2,m_xc,m_yc);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x1+=dx; m_x2+=dx; m_y1+=dy; m_y2+=dy;}
-    protected:
-        wxCoord m_x1,m_x2,m_xc;
-        wxCoord m_y1,m_y2,m_yc;
-};
-
-class gpdcDrawCheckMarkOp : public gpdcOp
-{
-    public:
-        gpdcDrawCheckMarkOp(wxCoord x, wxCoord y,
-                       wxCoord width, wxCoord height) 
-            {m_x=x; m_y=y; m_w=width; m_h=height;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawCheckMark(m_x,m_y,m_w,m_h);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y,m_w,m_h;
-};
-
-class gpdcDrawEllipticArcOp : public gpdcOp
-{
-    public:
-        gpdcDrawEllipticArcOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
-                         double sa, double ea) 
-            {m_x=x; m_y=y; m_w=w; m_h=h; m_sa=sa; m_ea=ea;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawEllipticArc(m_x,m_y,m_w,m_h,m_sa,m_ea);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y,m_w,m_h;
-        double m_sa,m_ea;
-};
-
-class gpdcDrawPointOp : public gpdcOp
-{
-    public:
-        gpdcDrawPointOp(wxCoord x, wxCoord y) 
-            {m_x=x; m_y=y;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->DrawPoint(m_x,m_y);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y;
-};
-
-class gpdcDrawRoundedRectangleOp : public gpdcOp
-{
-    public:
-        gpdcDrawRoundedRectangleOp(wxCoord x, wxCoord y, wxCoord width, 
-                                  wxCoord height, double radius) 
-            {m_x=x; m_y=y; m_w=width; m_h=height; m_r=radius;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawRoundedRectangle(m_x,m_y,m_w,m_h,m_r);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y,m_w,m_h;
-        double m_r;
-};
-
-class gpdcDrawEllipseOp : public gpdcOp
-{
-    public:
-        gpdcDrawEllipseOp(wxCoord x, wxCoord y, wxCoord width, wxCoord height) 
-            {m_x=x; m_y=y; m_w=width; m_h=height;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->DrawEllipse(m_x,m_y,m_w,m_h);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxCoord m_x,m_y,m_w,m_h;
-};
-
-class gpdcDrawIconOp : public gpdcOp
-{
-    public:
-        gpdcDrawIconOp(const wxIcon& icon, wxCoord x, wxCoord y) 
-            {m_icon=icon; m_x=x; m_y=y;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-        {
-            if (grey) dc->DrawIcon(m_greyicon,m_x,m_y);
-            else dc->DrawIcon(m_icon,m_x,m_y);
-        }
-        virtual void CacheGrey() {m_greyicon=gwxGetGreyIcon(m_icon);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxIcon m_icon;
-        wxIcon m_greyicon;
-        wxCoord m_x,m_y;
-};
-
-class gpdcDrawLinesOp : public gpdcOp
-{
-    public:
-        gpdcDrawLinesOp(int n, wxPoint points[],
-               wxCoord xoffset = 0, wxCoord yoffset = 0);
-        virtual ~gpdcDrawLinesOp();
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawLines(m_n,m_points,m_xoffset,m_yoffset);}
-        virtual void Translate(wxCoord dx, wxCoord dy)
-        { 
-            for(int i=0; i<m_n; i++)
-            {
-                m_points[i].x+=dx; 
-                m_points[i].y+=dy;
-            }
-        }
-    protected:
-        int m_n;
-        wxPoint *m_points;
-        wxCoord m_xoffset,m_yoffset;
-};
-
-class gpdcDrawPolygonOp : public gpdcOp
-{
-    public:
-        gpdcDrawPolygonOp(int n, wxPoint points[],
-                     wxCoord xoffset = 0, wxCoord yoffset = 0,
-                     int fillStyle = wxODDEVEN_RULE);
-        virtual ~gpdcDrawPolygonOp();
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawPolygon(m_n,m_points,m_xoffset,m_yoffset,m_fillStyle);}
-        
-        virtual void Translate(wxCoord dx, wxCoord dy)
-        { 
-            for(int i=0; i<m_n; i++)
-            {
-                m_points[i].x+=dx; 
-                m_points[i].y+=dy;
-            }
-        }
-    protected:
-        int m_n;
-        wxPoint *m_points;
-        wxCoord m_xoffset,m_yoffset;
-        int m_fillStyle;
-};
-
-class gpdcDrawPolyPolygonOp : public gpdcOp
-{
-    public:
-        gpdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
-                         wxCoord xoffset = 0, wxCoord yoffset = 0,
-                         int fillStyle = wxODDEVEN_RULE);
-        virtual ~gpdcDrawPolyPolygonOp();
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawPolyPolygon(m_n,m_count,m_points,
-                    m_xoffset,m_yoffset,m_fillStyle);}
-        virtual void Translate(wxCoord dx, wxCoord dy)
-        { 
-            for(int i=0; i<m_totaln; i++)
-            {
-                m_points[i].x += dx; 
-                m_points[i].y += dy;
-            }
-        }
-    protected:
-        int m_n;
-        int m_totaln;
-        int *m_count;
-        wxPoint *m_points;
-        wxCoord m_xoffset, m_yoffset;
-        int m_fillStyle;
-};
-
-class gpdcDrawRotatedTextOp : public gpdcOp
-{
-    public:
-        gpdcDrawRotatedTextOp(const wxString& text, wxCoord x, wxCoord y, double angle) 
-            {m_text=text; m_x=x; m_y=y; m_angle=angle;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawRotatedText(m_text,m_x,m_y,m_angle);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxString m_text;
-        wxCoord m_x,m_y;
-        double m_angle;
-};
-
-class gpdcDrawBitmapOp : public gpdcOp
-{
-    public:
-        gpdcDrawBitmapOp(const wxBitmap &bmp, wxCoord x, wxCoord y,
-                        bool useMask = false) 
-            {m_bmp=bmp; m_x=x; m_y=y; m_useMask=useMask;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-        {
-            if (grey) dc->DrawBitmap(m_greybmp,m_x,m_y,m_useMask);
-            else dc->DrawBitmap(m_bmp,m_x,m_y,m_useMask);
-        }
-        virtual void CacheGrey() {m_greybmp=gwxGetGreyBitmap(m_bmp);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_x+=dx; m_y+=dy;}
-    protected:
-        wxBitmap m_bmp;
-        wxBitmap m_greybmp;
-        wxCoord m_x,m_y;
-        bool m_useMask;
-};
-
-class gpdcDrawLabelOp : public gpdcOp
-{
-    public:
-        gpdcDrawLabelOp(const wxString& text,
-                           const wxBitmap& image,
-                           const wxRect& rect,
-                           int alignment = wxALIGN_LEFT | wxALIGN_TOP,
-                           int indexAccel = -1)
-            {m_text=text; m_image=image; m_rect=rect; 
-             m_align=alignment; m_iAccel=indexAccel;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) 
-            {dc->DrawLabel(m_text,m_image,m_rect,m_align,m_iAccel);}
-        virtual void Translate(wxCoord dx, wxCoord dy) 
-            {m_rect.x+=dx; m_rect.y+=dy;}
-    protected:
-        wxString m_text;
-        wxBitmap m_image;
-        wxRect m_rect;
-        int m_align;
-        int m_iAccel;
-};
-
-#if wxUSE_SPLINES
-class gpdcDrawSplineOp : public gpdcOp
-{
-    public:
-        gpdcDrawSplineOp(int n, wxPoint points[]);
-        virtual ~gpdcDrawSplineOp();
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->DrawSpline(m_n,m_points);}
-        virtual void Translate(wxCoord dx, wxCoord dy)
-        {
-            int i;
-            for(i=0; i<m_n; i++)
-                m_points[i].x+=dx; m_points[i].y+=dy;
-        }
-    protected:
-        wxPoint *m_points;
-        int m_n;
-};
-#endif // wxUSE_SPLINES
-
-#if wxUSE_PALETTE
-class gpdcSetPaletteOp : public gpdcOp
-{
-    public:
-        gpdcSetPaletteOp(const wxPalette& palette) {m_palette=palette;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->SetPalette(m_palette);}
-    protected:
-        wxPalette m_palette;
-};
-#endif // wxUSE_PALETTE
-
-class gpdcSetLogicalFunctionOp : public gpdcOp
-{
-    public:
-        gpdcSetLogicalFunctionOp(int function) {m_function=function;}
-        virtual void DrawToDC(wxDC *dc, bool grey=false) {dc->SetLogicalFunction(m_function);}
-    protected:
-        int m_function;
-};
-
-//----------------------------------------------------------------------------
-// gpdcObject type to contain list of operations for each real (Python) object
-//----------------------------------------------------------------------------
-class gpdcObject
-{
-    public:
-        gpdcObject(int id) 
-            {m_id=id; m_bounded=false; m_oplist.DeleteContents(true);
-             m_greyedout=false;}
-
-        virtual ~gpdcObject() {m_oplist.Clear();}
-        
-        // Protected Member Access
-        void SetId(int id) {m_id=id;}
-        int  GetId() {return m_id;}
-        void   SetBounds(wxRect& rect) {m_bounds=rect; m_bounded=true;}
-        wxRect GetBounds() {return m_bounds;}
-        void SetBounded(bool bounded) {m_bounded=bounded;}
-        bool IsBounded() {return m_bounded;}
-        void SetGreyedOut(bool greyout=true);
-        bool GetGreyedOut() {return m_greyedout;}
-    
-        // Op List Management Methods
-        void Clear() {m_oplist.Clear();}
-        void AddOp(gpdcOp *op) 
-        {
-            m_oplist.Append(op);
-            if (m_greyedout) op->CacheGrey();
-        }
-        int  GetLen() {return m_oplist.GetCount();}
-        virtual void Translate(wxCoord dx, wxCoord dy);
-        
-        // Drawing Method
-        virtual void DrawToDC(wxDC *dc);
-    protected:
-        int m_id; // id of object (associates this gpdcObject
-                  //               with a Python object with same id)
-        wxRect m_bounds;  // bounding rect of this object
-        bool m_bounded;   // true if bounds is valid, false by default
-        gpdcOpList m_oplist; // list of operations for this object
-        bool m_greyedout; // if true then draw this object in greys only
-};
-
-
-//----------------------------------------------------------------------------
-// Declare a wxList to hold all the objects.  List order reflects drawing
-// order (Z order) and is the same order as objects are added to the list
-//----------------------------------------------------------------------------
-class gpdcObjectList;
-WX_DECLARE_LIST(gpdcObject, gpdcObjectList);
-
-//Declare a hashmap that maps from ids to nodes in the object list.
-WX_DECLARE_HASH_MAP(
-    int,
-    gpdcObject *,
-    wxIntegerHash,
-    wxIntegerEqual,
-    gpdcObjectHash
-);
-
-
-// ----------------------------------------------------------------------------
-// gwxPseudoDC class
-// ----------------------------------------------------------------------------
-// This is the actual PseudoDC class
-// This class stores a list of recorded dc operations in m_list
-// and plays them back to a real dc using DrawToDC or DrawToDCClipped.
-// Drawing methods are mirrored from wxDC but add nodes to m_list 
-// instead of doing any real drawing.
-// ----------------------------------------------------------------------------
-class gwxPseudoDC : public wxObject
-{
-public:
-    gwxPseudoDC() 
-        {m_currId=-1; m_lastObject=NULL; m_objectlist.DeleteContents(true);m_objectIndex.clear();}
-    ~gwxPseudoDC();
-    // ------------------------------------------------------------------------
-    // List managment methods
-    // 
-    void RemoveAll();
-    int GetLen();
-    
-    // ------------------------------------------------------------------------
-    // methods for managing operations by ID
-    // 
-    // Set the Id for all subsequent operations (until SetId is called again)
-    void SetId(int id) {m_currId = id;}
-    // Remove all the operations associated with an id so it can be redrawn
-    void ClearId(int id);
-    // Remove the object node (and all operations) associated with an id
-    void RemoveId(int id);
-    // Set the bounding rect of a given object
-    // This will create an object node if one doesn't exist
-    void SetIdBounds(int id, wxRect& rect);
-    void GetIdBounds(int id, wxRect& rect);
-    // Translate all the operations for this id
-    void TranslateId(int id, wxCoord dx, wxCoord dy);
-    // Grey-out an object
-    void SetIdGreyedOut(int id, bool greyout=true);
-    bool GetIdGreyedOut(int id);
-    // Find Objects at a point.  Returns Python list of id's
-    // sorted in reverse drawing order (result[0] is top object)
-    // This version looks at drawn pixels
-    PyObject *FindObjects(wxCoord x, wxCoord y, 
-                          wxCoord radius=1, const wxColor& bg=*wxWHITE);
-    // This version only looks at bounding boxes
-    PyObject *FindObjectsByBBox(wxCoord x, wxCoord y);
-
-    // ------------------------------------------------------------------------
-    // Playback Methods
-    //
-    // draw to dc but skip objects known to be outside of rect
-    // This is a coarse level of clipping to speed things up 
-    // when lots of objects are off screen and doesn't affect the dc level 
-    // clipping
-    void DrawToDCClipped(wxDC *dc, const wxRect& rect);
-        void DrawToDCClippedRgn(wxDC *dc, const wxRegion& region);
-    // draw to dc with no clipping (well the dc will still clip)
-    void DrawToDC(wxDC *dc);
-    // draw a single object to the dc
-    void DrawIdToDC(int id, wxDC *dc);
-
-    // ------------------------------------------------------------------------
-    // Hit Detection Methods
-    //
-    // returns list of object with a drawn pixel within radius pixels of (x,y)
-    // the list is in reverse draw order so last drawn is first in list
-    // PyObject *HitTest(wxCoord x, wxCoord y, double radius)
-    // returns list of objects whose bounding boxes include (x,y)
-    // PyObject *HitTestBB(wxCoord x, wxCoord y)
-    
-        
-    // ------------------------------------------------------------------------
-    // Methods mirrored from wxDC
-    //
-    void FloodFill(wxCoord x, wxCoord y, const wxColour& col,
-                   int style = wxFLOOD_SURFACE)
-        {AddToList(new gpdcFloodFillOp(x,y,col,style));}
-    void FloodFill(const wxPoint& pt, const wxColour& col,
-                   int style = wxFLOOD_SURFACE)
-        { FloodFill(pt.x, pt.y, col, style); }
-
-    void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
-        {AddToList(new gpdcDrawLineOp(x1, y1, x2, y2));}
-    void DrawLine(const wxPoint& pt1, const wxPoint& pt2)
-        { DrawLine(pt1.x, pt1.y, pt2.x, pt2.y); }
-
-    void CrossHair(wxCoord x, wxCoord y)
-        {AddToList(new gpdcCrossHairOp(x,y));}
-    void CrossHair(const wxPoint& pt)
-        { CrossHair(pt.x, pt.y); }
-
-    void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
-                 wxCoord xc, wxCoord yc)
-        {AddToList(new gpdcDrawArcOp(x1,y1,x2,y2,xc,yc));}
-    void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre)
-        { DrawArc(pt1.x, pt1.y, pt2.x, pt2.y, centre.x, centre.y); }
-
-    void DrawCheckMark(wxCoord x, wxCoord y,
-                       wxCoord width, wxCoord height)
-        {AddToList(new gpdcDrawCheckMarkOp(x,y,width,height));}
-    void DrawCheckMark(const wxRect& rect)
-        { DrawCheckMark(rect.x, rect.y, rect.width, rect.height); }
-
-    void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
-                         double sa, double ea)
-        {AddToList(new gpdcDrawEllipticArcOp(x,y,w,h,sa,ea));}
-    void DrawEllipticArc(const wxPoint& pt, const wxSize& sz,
-                         double sa, double ea)
-        { DrawEllipticArc(pt.x, pt.y, sz.x, sz.y, sa, ea); }
-
-    void DrawPoint(wxCoord x, wxCoord y)
-        {AddToList(new gpdcDrawPointOp(x,y));}
-    void DrawPoint(const wxPoint& pt)
-        { DrawPoint(pt.x, pt.y); }
-
-    void DrawPolygon(int n, wxPoint points[],
-                     wxCoord xoffset = 0, wxCoord yoffset = 0,
-                     int fillStyle = wxODDEVEN_RULE)
-        {AddToList(new gpdcDrawPolygonOp(n,points,xoffset,yoffset,fillStyle));}
-
-    void DrawPolyPolygon(int n, int count[], wxPoint points[],
-                         wxCoord xoffset = 0, wxCoord yoffset = 0,
-                         int fillStyle = wxODDEVEN_RULE)
-        {AddToList(new gpdcDrawPolyPolygonOp(n,count,points,xoffset,yoffset,fillStyle));}
-
-    void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
-        {AddToList(new gpdcDrawRectangleOp(x, y, width, height));}
-    void DrawRectangle(const wxPoint& pt, const wxSize& sz)
-        { DrawRectangle(pt.x, pt.y, sz.x, sz.y); }
-    void DrawRectangle(const wxRect& rect)
-        { DrawRectangle(rect.x, rect.y, rect.width, rect.height); }
-
-    void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height,
-                              double radius)
-        {AddToList(new gpdcDrawRoundedRectangleOp(x,y,width,height,radius));}
-    void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz,
-                             double radius)
-        { DrawRoundedRectangle(pt.x, pt.y, sz.x, sz.y, radius); }
-    void DrawRoundedRectangle(const wxRect& r, double radius)
-        { DrawRoundedRectangle(r.x, r.y, r.width, r.height, radius); }
-
-    void DrawCircle(wxCoord x, wxCoord y, wxCoord radius)
-        { DrawEllipse(x - radius, y - radius, 2*radius, 2*radius); }
-    void DrawCircle(const wxPoint& pt, wxCoord radius)
-        { DrawCircle(pt.x, pt.y, radius); }
-
-    void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
-        {AddToList(new gpdcDrawEllipseOp(x,y,width,height));}
-    void DrawEllipse(const wxPoint& pt, const wxSize& sz)
-        { DrawEllipse(pt.x, pt.y, sz.x, sz.y); }
-    void DrawEllipse(const wxRect& rect)
-        { DrawEllipse(rect.x, rect.y, rect.width, rect.height); }
-
-    void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
-        {AddToList(new gpdcDrawIconOp(icon,x,y));}
-    void DrawIcon(const wxIcon& icon, const wxPoint& pt)
-        { DrawIcon(icon, pt.x, pt.y); }
-
-    void DrawLines(int n, wxPoint points[],
-               wxCoord xoffset = 0, wxCoord yoffset = 0)
-        {AddToList(new gpdcDrawLinesOp(n,points,xoffset,yoffset));}
-
-    void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
-                    bool useMask = false)
-        {AddToList(new gpdcDrawBitmapOp(bmp,x,y,useMask));}
-    void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt,
-                    bool useMask = false)
-        { DrawBitmap(bmp, pt.x, pt.y, useMask); }
-
-    void DrawText(const wxString& text, wxCoord x, wxCoord y)
-        {AddToList(new gpdcDrawTextOp(text, x, y));}
-    void DrawText(const wxString& text, const wxPoint& pt)
-        { DrawText(text, pt.x, pt.y); }
-
-    void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
-        {AddToList(new gpdcDrawRotatedTextOp(text,x,y,angle));}
-    void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle)
-        { DrawRotatedText(text, pt.x, pt.y, angle); }
-
-    // this version puts both optional bitmap and the text into the given
-    // rectangle and aligns is as specified by alignment parameter; it also
-    // will emphasize the character with the given index if it is != -1 
-    void DrawLabel(const wxString& text,
-                           const wxBitmap& image,
-                           const wxRect& rect,
-                           int alignment = wxALIGN_LEFT | wxALIGN_TOP,
-                           int indexAccel = -1)
-        {AddToList(new gpdcDrawLabelOp(text,image,rect,alignment,indexAccel));}
-
-    void DrawLabel(const wxString& text, const wxRect& rect,
-                   int alignment = wxALIGN_LEFT | wxALIGN_TOP,
-                   int indexAccel = -1)
-        { DrawLabel(text, wxNullBitmap, rect, alignment, indexAccel); }
-
-/*?????? I don't think that the source dc would stick around
-    void Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
-              wxDC *source, wxCoord xsrc, wxCoord ysrc,
-              int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord)
-                {AddToList(new gpdcBlitOp(xdest,ydest,width,height,source,xsrc,
-                                         ysrc,rop,useMask,xsrcMask,ysrcMask));}
-    void Blit(const wxPoint& destPt, const wxSize& sz,
-              wxDC *source, const wxPoint& srcPt,
-              int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition)
-    {
-        Blit(destPt.x, destPt.y, sz.x, sz.y, source, srcPt.x, srcPt.y, 
-             rop, useMask, srcPtMask.x, srcPtMask.y);
-    }
-??????*/
-
-#if wxUSE_SPLINES
-    void DrawSpline(int n, wxPoint points[])
-        {AddToList(new gpdcDrawSplineOp(n,points));}
-#endif // wxUSE_SPLINES
-
-#if wxUSE_PALETTE
-    void SetPalette(const wxPalette& palette)
-        {AddToList(new gpdcSetPaletteOp(palette));}
-#endif // wxUSE_PALETTE
-
-    void SetLogicalFunction(int function)
-        {AddToList(new gpdcSetLogicalFunctionOp(function));}
-    void SetFont(const wxFont& font) 
-        {AddToList(new gpdcSetFontOp(font));}
-    void SetPen(const wxPen& pen)
-        {AddToList(new gpdcSetPenOp(pen));}
-    void SetBrush(const wxBrush& brush)
-        {AddToList(new gpdcSetBrushOp(brush));}
-    void SetBackground(const wxBrush& brush)
-        {AddToList(new gpdcSetBackgroundOp(brush));}
-    void SetBackgroundMode(int mode)
-        {AddToList(new gpdcSetBackgroundModeOp(mode));}
-    void SetTextBackground(const wxColour& colour)
-        {AddToList(new gpdcSetTextBackgroundOp(colour));}
-    void SetTextForeground(const wxColour& colour)
-        {AddToList(new gpdcSetTextForegroundOp(colour));}
-
-    void Clear()
-        {AddToList(new gpdcClearOp());}
-    void BeginDrawing()
-        {AddToList(new gpdcBeginDrawingOp());}
-    void EndDrawing()
-        {AddToList(new gpdcEndDrawingOp());}
-
-protected:
-    // ------------------------------------------------------------------------
-    // protected helper methods
-    void AddToList(gpdcOp *newOp);
-    gpdcObject *FindObject(int id, bool create=false);
-    
-    // ------------------------------------------------------------------------
-    // Data members
-    // 
-    int m_currId; // id to use for operations done on the PseudoDC
-    gpdcObject *m_lastObject; // used to find last used object quickly
-    gpdcObjectList m_objectlist; // list of objects
-    gpdcObjectHash m_objectIndex; //id->object lookup index
-    
-};
-
-#endif
-

+ 0 - 102
gui/wxpython/vdigit/pseudodc.i

@@ -1,102 +0,0 @@
-%{
-#include <wx/wxPython/wxPython.h>
-#include <wx/wxPython/pyclasses.h>
-#include <wx/dcbuffer.h>
-%}
-
-%{
-#include "pseudodc.h"
-%}
-
-%rename(PseudoDC) gwxPseudoDC;
-
-%typemap(in) wxString& (bool temp=false) {
-    $1 = wxString_in_helper($input);
-    if ($1 == NULL) SWIG_fail;
-    temp = true;
-}
-%typemap(freearg) wxString& {
-    if (temp$argnum)
-        delete $1;
-}
-
-%apply wxString& { wxString* };
-
-
-%typemap(in) wxRect& (wxRect temp) {
-    $1 = &temp;
-    if ( ! wxRect_helper($input, &$1)) SWIG_fail;
-}
-%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) wxRect& {
-    $1 = wxPySimple_typecheck($input, wxT("wxRect"), 4);
-}
-
-%apply wxRect& { wxRect* };
-
-%typemap(out) wxRect {
-    $result = Py_BuildValue("[iiii]", $1.x, $1.y, $1.width, $1.height);
-}
-
-%typemap(out) wxArrayInt& {
-    $result = wxArrayInt2PyList_helper(*$1);
-}
-
-%typemap(out) wxArrayInt {
-    $result = wxArrayInt2PyList_helper($1);
-}
-
-class gwxPseudoDC
-{
-public:
-	gwxPseudoDC();
-	~gwxPseudoDC();
-	void Clear();
-    	void ClearId(int);
-	void RemoveAll();
-	void RemoveId(int);
-	void BeginDrawing();
-	void EndDrawing();
-        void SetBackground(const wxBrush&);
-	void SetId(int);
-        void SetBrush(const wxBrush&);
-        void SetPen(const wxPen&);
-	void SetIdBounds(int, wxRect&);
-	void DrawLine(const wxPoint&, const wxPoint&);
-	void SetFont(const wxFont&);
-	void SetTextForeground(const wxColour&);
-	%extend {
-		void DrawToDC(void *dc) {
-			self->DrawToDC((wxDC *) dc);
-		}
-		void DrawToDCClipped(void *dc, const wxRect& rect) {
-			self->DrawToDCClipped((wxDC *) dc, rect);
-		}
-		wxRect GetIdBounds(int id) {
-			wxRect rect;
-			self->GetIdBounds(id, rect);
-			return rect;
-		}
-		void TranslateId(int id, float dx, float dy) {
-		        self->TranslateId(id, (wxCoord) dx, (wxCoord) dy);
-		}
-		PyObject *FindObjects(float x, float y, int radius) {
-		        return self->FindObjects((wxCoord) x, (wxCoord) y,
-			                         (wxCoord) radius, *wxWHITE);
-                }
-		void DrawRectangleRect(const wxRect& rect) {
-		        return self->DrawRectangle(rect);
-                }
-		void DrawText(const wxString& text, float x, float y) {
-		        return self->DrawText(text, (wxCoord) x, (wxCoord) y);
-		}
-		void DrawRotatedText(const wxString& text, float x, float y, double angle) {
-		        return self->DrawRotatedText(text, (wxCoord) x, (wxCoord) y, angle);
-		}
-                void DrawBitmap(const wxBitmap& bitmap, float x, float y, bool useMask) {
-                        return self->DrawBitmap(bitmap, (wxCoord) x, (wxCoord) y, useMask);
-                }
-		void DrawLinePoint(const wxPoint& p1, const wxPoint& p2) {
-		        return self->DrawLine(p1, p2);
-                }
-	}
-};

+ 0 - 90
gui/wxpython/vdigit/select.cpp

@@ -1,90 +0,0 @@
-/**
-   \file vdigit/select.cpp
-
-   \brief wxvdigit - Select lines (by query)
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-extern "C" {
-#include <grass/vedit.h>
-}
-#include "driver.h"
-#include "digit.h"
-
-/**
-   \brief Select features by query (based on geometry)
-
-   Currently supported:
-    - QUERY_LENGTH, select all lines longer then threshold (or shorter if threshold is negative)
-    - QUERY_DANGLE, select all dangles then threshold (or shorter if threshold is negative)
-
-   \todo Rewrite dangle part to use Vector library functionality
-   \todo 3D
-
-   \param x1,y1,z1,x2,y2,z2 bounding box 
-   \param query query (length, dangle, ...)
-   \param thresh threshold value (< 0 for 'shorter', > 0 for 'longer')
-   \param type feature type
-   \param box query features in bounding box
-
-   \return list of selected features
-*/
-
-std::vector<int> Digit::SelectLinesByQuery(double x1, double y1, double z1,
-					   double x2, double y2, double z2, bool box,
-					   int query, int type, double thresh)
-{
-    int layer;
-    std::vector<int> ids;
-    struct ilist *List;
-    struct line_pnts *bbox;
-
-    if (!display->mapInfo) {
-	display->DisplayMsg();
-	return ids;
-    }
-
-    layer = 1; // TODO
-    bbox  = NULL;
-
-    List = Vect_new_list();
-
-    if (box) {
-	bbox = Vect_new_line_struct();
-	
-	Vect_append_point(bbox, x1, y1, z1);
-	Vect_append_point(bbox, x2, y1, z2);
-	Vect_append_point(bbox, x2, y2, z1);
-	Vect_append_point(bbox, x1, y2, z2);
-	Vect_append_point(bbox, x1, y1, z1);
-	
-	Vect_select_lines_by_polygon (display->mapInfo, bbox, 0, NULL, type, List);
-	if (List->n_values == 0) {
-	    return ids;
-	}
-    }
-    
-    G_debug(3, "wxDigit.SelectLinesByQuery(): lines=%d", List->n_values);
-
-    Vedit_select_by_query(display->mapInfo,
-			  type, layer, thresh, query,
-			  List);
-    
-    ids = display->ListToVector(List); // TODO
-
-    G_debug(3, "wxDigit.SelectLinesByQuery(): lines=%d", List->n_values);
-
-    Vect_destroy_list(List);
-    if (bbox) {
-	Vect_destroy_line_struct(bbox);
-    }
-
-    return ids;
-}

+ 0 - 68
gui/wxpython/vdigit/setup.py

@@ -1,68 +0,0 @@
-#!/usr/bin/env python
- 
-# Setup script for wxGUI vdigit extension.
-
-import os
-import sys
-
-sys.path.append('..')
-from build_ext import update_opts
-
-from distutils.core import setup, Extension
-
-if sys.platform == "win32":
-    package = '\\"grasslibs\\"'
-else:
-    package = '"grasslibs"'
-macros = [('PACKAGE', package)]
-
-inc_dirs = [os.path.join(os.path.normpath(os.getenv('ARCH_DISTDIR')), 'include'),
-	    os.path.join(os.path.normpath(os.getenv('GISBASE')), 'include')]
-lib_dirs = [os.path.join(os.path.normpath(os.getenv('ARCH_DISTDIR')), 'lib'),
-	    os.path.join(os.path.normpath(os.getenv('GISBASE')), 'lib')]
-
-gversion = os.getenv('GRASS_VERSION_NUMBER')
-libs = ['grass_%s.%s' % (name, gversion)
-        for name in ['dbmibase',
-                     'dbmiclient',
-                     'vector',
-                     'gis',
-                     'vedit']]
-
-extras = []
-
-for flag in ['CXXFLAGS',
-	     'GDALCFLAGS',
-             'GDALLIBS',
-             'GEOSCFLAGS',
-             'WXWIDGETSLIB',
-             'WXWIDGETSCXXFLAGS']:
-    update_opts(os.getenv(flag), macros, inc_dirs, lib_dirs, libs, extras)
-
-setup(
-    ext_modules= [
-        Extension(
-            name = '_grass7_wxvdigit',
-            sources = ["cats.cpp",
-                       "driver.cpp",
-                       "driver_draw.cpp",
-                       "driver_select.cpp",
-                       "line.cpp",
-                       "message.cpp",
-                       "select.cpp",
-                       "undo.cpp",
-                       "vertex.cpp",
-                       "pseudodc.cpp",
-                       "digit.cpp",
-                       "grass7_wxvdigit.i"],
-            swig_opts = ['-c++',
-                         '-shadow'],
-            define_macros = macros,
-            include_dirs = inc_dirs,
-            library_dirs = lib_dirs,
-            libraries = libs,
-            extra_link_args = extras,
-            )
-	]
-    )
-

+ 0 - 232
gui/wxpython/vdigit/undo.cpp

@@ -1,232 +0,0 @@
-/**
-   \file vdigit/undo.cpp
-
-   \brief wxvdigit - Undo/Redo functionality
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2010 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-#include "driver.h"
-#include "digit.h"
-
-/**
-   \brief Undo/Redo changes in geometry
-
-   level=0 to revert all changes
-
-   \param level level for undo/redo
-
-   \return id of current chanset
-   \return -2 on error
-*/
-int Digit::Undo(int level)
-{
-    int changesetLast;
-
-    changesetLast = (int) changesets.size() - 1;
-
-    if (changesetLast < 0)
-	return changesetLast;
-
-    if (changesetCurrent == -2) { /* value uninitialized */
-	changesetCurrent = changesetLast;
-    }
-
-    if (level > 0 && changesetCurrent < 0) {
-	changesetCurrent = 0;
-    }
-
-    if (level == 0) {
-	/* 0 -> undo all */
-	level = -(changesetLast + 1);
-    }
-
-    G_debug(2, "Digit.Undo(): changeset_last=%d, changeset_current=%d, level=%d",
-	    changesetLast, changesetCurrent, level);
-    
-    if (level < 0) { /* undo */
-	if (changesetCurrent + level < -1)
-	    return changesetCurrent;
-	for (int changeset = changesetCurrent; changeset > changesetCurrent + level; --changeset) {
-	    ApplyChangeset(changeset, true);
-	}
-    }
-    else if (level > 0) { /* redo */
-	if (changesetCurrent + level > (int) changesets.size())
-	    return changesetCurrent;
-	for (int changeset = changesetCurrent; changeset < changesetCurrent + level; ++changeset) {
-	    ApplyChangeset(changeset, false);
-	}
-    }
-
-    changesetCurrent += level;
-
-    G_debug(2, "Digit.Undo(): changeset_current=%d, changeset_last=%d, changeset_end=%d",
-	    changesetCurrent, changesetLast, changesetEnd);
-    
-    if (changesetCurrent == changesetEnd) {
-	changesetEnd = changesetLast;
-	return -1;
-    }
-    
-    return changesetCurrent;
-}
-
-/**
-   \brief Apply changeset (undo/redo changeset)
-
-   \param changeset changeset id
-   \param undo if true -> undo otherwise redo
-
-   \return 1 changeset applied
-   \return 0 changeset not applied
-   \return -1 on error
-*/
-int Digit::ApplyChangeset(int changeset, bool undo)
-{ 
-    int ret, line, type;
-
-    if (changeset < 0 || changeset > (int) changesets.size())
-	return -1;
-
-    if (changesetEnd < 0)
-	changesetEnd = changeset;
-    
-    ret = 0;
-    std::vector<action_meta> action = changesets[changeset];
-    for (std::vector<action_meta>::const_reverse_iterator i = action.rbegin(), e = action.rend();
-	 i != e; ++i) {
-	type = (*i).type;
-	line = (*i).line;
-	
-	if ((undo && type == ADD) ||
-	    (!undo && type == DEL)) {
-	    if (Vect_line_alive(display->mapInfo, line)) {
-		G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=add, line=%d -> deleted",
-			changeset, line);
-		Vect_delete_line(display->mapInfo, line);
-		if (!ret)
-		    ret = 1;
-	    }
-	    else {
-		G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=add, line=%d dead",
-			changeset, (*i).line);
-	    }
-	}
-	else { /* DELETE */
-	    long offset = (*i).offset;
-	    if (!Vect_line_alive(display->mapInfo, line)) {
-		G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d -> added",
-			changeset, line);
-		if (Vect_restore_line(display->mapInfo, line, offset) < 0)
-		    return -1;
-		if (!ret)
-		    ret = 1;
-	    }
-	    else {
-		G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d alive",
-			changeset, line);
-	    }
-	}
-    }
-    
-    return ret;
-}
-
-/**
-   \brief Add action to changeset
-
-   \param type action type (ADD, DEL)
-
-   \return 0 on success
-   \return -1 on error
-*/
-int Digit::AddActionToChangeset(int changeset, Digit::action_type type, int line)
-{
-    long offset;
-
-    if (!display->mapInfo) {
-	display->DisplayMsg();
-	return -1;
-    }
-
-    if (!Vect_line_alive(display->mapInfo, line)) {
-	// display->DeadLineMsg(line);
-	return -1;
-    }
-
-    offset = Vect_get_line_offset(display->mapInfo, line);
-
-    action_meta data = { type, line, offset };
-    if (changesets.find(changeset) == changesets.end()) {
-	changesets[changeset] = std::vector<action_meta>();
-	changesetCurrent = changeset;
-    }
-    changesets[changeset].push_back(data);
-    G_debug (3, "Digit.AddActionToChangeset(): changeset=%d, type=%d, line=%d, offset=%ld",
-	     changeset, type, line, offset);
-
-    return 0;
-}
-
-/**
-   \brief Free changeset structures
-
-   \param changeset changeset id
-*/
-void Digit::FreeChangeset(int changeset)
-{
-    if (changesets.find(changeset) == changesets.end())
-	return;
-
-    std::vector<action_meta> action = changesets[changeset];
-    for (std::vector<action_meta>::iterator i = action.begin(), e = action.end();
-	 i != e; ++i) {
-	;
-    }
-
-    return;
-}
-
-/**
-   \brief Remove action from changeset
-
-   \param changeset changeset id
-   \param type action type (ADD, DEL)
-   \param line line id
-
-   \return number of actions in changeset
-   \return -1 on error
-*/
-int Digit::RemoveActionFromChangeset(int changeset, Digit::action_type type, int line)
-{
-    if (changesets.find(changeset) == changesets.end())
-	return -1;
-
-    std::vector<action_meta>& action = changesets[changeset];
-    for (std::vector<action_meta>::iterator i = action.begin(); i != action.end(); ++i) {
-	if ((*i).type == type && (*i).line == line) {
-	    G_debug (3, "Digit.RemoveActionFromChangeset(): changeset=%d, type=%d, line=%d",
-		     changeset, type, line);
-	    action.erase(i--);
-	}
-    }
-
-    return action.size();
-}
-
-/**
-   \brief Get undo level (number of active changesets)
-
-   \return number
-*/
-int Digit::GetUndoLevel()
-{
-    return changesetCurrent;
-}

+ 0 - 159
gui/wxpython/vdigit/vertex.cpp

@@ -1,159 +0,0 @@
-/**
-   \file vdigit/vertex.cpp
-
-   \brief wxvdigit - Vertex manipulation
-
-   This program is free software under the GNU General Public
-   License (>=v2). Read the file COPYING that comes with GRASS
-   for details.
-
-   (C) 2008-2009 by Martin Landa, and the GRASS development team
-
-   \author Martin Landa <landa.martin gmail.com>
-*/
-
-extern "C" {
-#include <grass/vedit.h>
-}
-#include "driver.h"
-#include "digit.h"
-
-/**
-   \brief Move vertex
-
-   \param x,y,z coordinates (z is used only if map is 3d)
-   \param move_x,move_y,move_z direction for moving vertex
-   \param bgmap  map of background map or NULL
-   \param snap snap mode (see vector/v.edit/lib/vedit.h)
-   \param thresh_coords threshold value to identify vertex position
-   \param thresh_snap threshold value to snap moved vertex
-
-   \param id id of the new feature
-   \param 0 nothing changed
-   \param -1 error
-*/
-int Digit::MoveVertex(double x, double y, double z,
-		      double move_x, double move_y, double move_z,
-		      const char *bgmap, int snap,
-		      double thresh_coords, double thresh_snap) {
-
-    int ret;
-    int changeset, nlines;
-    struct line_pnts *point;
-    struct Map_info **BgMap; /* backgroud vector maps */
-    int nbgmaps;             /* number of registrated background maps */
-
-    if (!display->mapInfo) {
-	display->DisplayMsg();
-	return -1;
-    }
-
-    if (display->selected.ids->n_values != 1)
-	return 0;
-
-    BgMap = NULL;
-    nbgmaps = 0;
-    if (bgmap && strlen(bgmap) > 0) {
-	BgMap = OpenBackgroundVectorMap(bgmap);
-	if (!BgMap) {
-	    display->BackgroundMapMsg(bgmap);
-	    return -1;
-	}
-	else {
-	    nbgmaps = 1;
-	}
-    }
-
-    point = Vect_new_line_struct();
-    Vect_append_point(point, x, y, z);
-
-    nlines = Vect_get_num_lines(display->mapInfo);
-
-    changeset = AddActionsBefore();
-
-    /* move only first found vertex in bbox */
-    ret = Vedit_move_vertex(display->mapInfo, BgMap, nbgmaps, 
-			    display->selected.ids,
-			    point, thresh_coords, thresh_snap,
-			    move_x, move_y, move_z,
-			    1, snap);
-
-    if (ret > 0) {
-	AddActionsAfter(changeset, nlines);
-    }
-    else {
-	changesets.erase(changeset);
-    }
-    
-    if (ret > 0 && settings.breakLines) {
-	BreakLineAtIntersection(Vect_get_num_lines(display->mapInfo), NULL, changeset);
-    }
-
-    if (BgMap && BgMap[0]) {
-	Vect_close(BgMap[0]);
-    }
-
-    Vect_destroy_line_struct(point);
-
-    return nlines + 1; // feature is write at the end of the file
-}
-
-/**
-   \brief Add or remove vertex
-
-   Shape of line/boundary is not changed when adding new vertex.
-   
-   \param add add or remove vertex?
-   \param x,y,z coordinates (z is used only if map is 3d
-   \param thresh threshold value to identify vertex position
-
-   \param id id of the new feature
-   \param 0 nothing changed
-   \param -1 error
-*/
-int Digit::ModifyLineVertex(int add, double x, double y, double z,
-			    double thresh)
-{
-    int ret;
-    int changeset, nlines;
-    struct line_pnts *point;
-
-    if (!display->mapInfo) {
-	display->DisplayMsg();
-	return -1;
-    }
-
-    if (display->selected.ids->n_values != 1)
-	return 0;
-
-    point = Vect_new_line_struct();
-    Vect_append_point(point, x, y, z);
-
-    nlines = Vect_get_num_lines(display->mapInfo);
-
-    changeset = AddActionsBefore();
-
-    if (add) {
-	ret = Vedit_add_vertex(display->mapInfo, display->selected.ids,
-			       point, thresh);
-    }
-    else {
-	ret = Vedit_remove_vertex(display->mapInfo, display->selected.ids,
-				  point, thresh);
-    }
-
-    if (ret > 0) {
-	AddActionsAfter(changeset, nlines);
-    }
-    else {
-	changesets.erase(changeset);
-    }
-    
-    if (!add && ret > 0 && settings.breakLines) {
-	BreakLineAtIntersection(Vect_get_num_lines(display->mapInfo), NULL, changeset);
-    }
-
-    Vect_destroy_line_struct(point);
-
-    return nlines + 1; // feature is write at the end of the file
-}

+ 52 - 0
include/vedit.h

@@ -12,6 +12,54 @@
 #define QUERY_LENGTH   0	/* select by line length */
 #define QUERY_LENGTH   0	/* select by line length */
 #define QUERY_DANGLE   1	/* select dangles */
 #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            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 */
 /* break.c */
 int Vedit_split_lines(struct Map_info *, struct ilist *,
 int Vedit_split_lines(struct Map_info *, struct ilist *,
 		      struct line_pnts *, double, struct ilist *);
 		      struct line_pnts *, double, struct ilist *);
@@ -45,6 +93,10 @@ int Vedit_merge_lines(struct Map_info *, struct ilist *);
 int Vedit_move_lines(struct Map_info *, struct Map_info **, int,
 int Vedit_move_lines(struct Map_info *, struct Map_info **, int,
 		     struct ilist *, double, double, double, int, double);
 		     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 */
 /* select.c */
 int Vedit_select_by_query(struct Map_info *,
 int Vedit_select_by_query(struct Map_info *,
 			  int, int, double, int, struct ilist *);
 			  int, int, double, int, struct ilist *);

+ 491 - 0
lib/vector/vedit/render.c

@@ -0,0 +1,491 @@
+/*!
+   \file lib/vector/vedit/render.c
+
+   \brief Vedit library - render vector features (used by wxGUI digitizer)
+
+   (C) 2010 by the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
+
+   \author Martin Landa <landa.martin gmail.com>
+ */
+
+#include <math.h>
+
+#include <grass/vedit.h>
+
+struct _region
+{
+    double center_easting;
+    double center_northing;
+    double map_west;
+    double map_north;
+    int map_width;
+    int map_height;
+    double map_res;
+} region;
+
+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 *);
+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,
+		       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();
+		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);
+	    }
+	}
+    }
+
+    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));
+    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->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 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);
+
+    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, 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, 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,
+		struct robject_list *list)
+{
+    double angle_symb;
+    struct robject *robj;
+
+    robj = robj_alloc(TYPE_DIRECTION, 3);
+
+    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;
+    }
+}