Bladeren bron

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 jaren geleden
bovenliggende
commit
5fcf7ee23a

+ 2 - 3
gui/wxpython/Makefile

@@ -1,8 +1,7 @@
 MODULE_TOPDIR = ../..
 
-SUBDIRS = docs vdigit
+SUBDIRS = docs
 EXTRA_CLEAN_FILES = menustrings.py build_ext.pyc
-CLEAN_SUBDIRS = vdigit
 
 include $(MODULE_TOPDIR)/include/Make/Dir.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
 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
 	$(MAKE) parsubdirs

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

@@ -40,4 +40,6 @@ all = [
     "vdigit.py",
     "workspace.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
         if self.toolbars['vdigit'] and self.digit:
-            self.digit.driver.SetSelected([])
+            self.digit.GetDisplay().SetSelected(None)
             self.MapWindow.UpdateMap(render = True, renderVector = True)
         else:
             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 VDigitZBulkDialog
 from vdigit import VDigitDuplicatesDialog
-from vdigit import PseudoDC as VDigitPseudoDC
 
 class MapWindow(object):
     """!Abstract map window class
@@ -303,44 +302,17 @@ class BufferedWindow(MapWindow, wx.Window):
         self.dragid   = -1
         self.lastpos  = (0, 0)
 
-    def DefinePseudoDC(self, vdigit = False):
-        """!Define PseudoDC class to use
-
-        @vdigit True to use PseudoDC from vdigit
+    def DefinePseudoDC(self):
+        """!Define PseudoDC objects to use
         """
         # create PseudoDC used for background map, map decorations like scales and legends
-        self.pdc = self.PseudoDC(vdigit)
+        self.pdc = wx.PseudoDC()
         # used for digitization tool
         self.pdcVector = None
         # decorations (region box, etc.)
-        self.pdcDec = self.PseudoDC(vdigit)
+        self.pdcDec = wx.PseudoDC()
         # pseudoDC for temporal objects (select box, measurement tool, etc.)
-        self.pdcTmp = self.PseudoDC(vdigit)
-        
-    def PseudoDC(self, vdigit = False):
-        """!Create PseudoDC instance"""
-        if vdigit:
-            PseudoDC = VDigitPseudoDC
-        else:
-            PseudoDC = wx.PseudoDC
-        
-        return PseudoDC()
-    
-    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]):
         """!Draws map and overlay decorations
@@ -808,9 +780,9 @@ class BufferedWindow(MapWindow, wx.Window):
         if renderVector and digitToolbar and \
                 digitToolbar.GetLayer():
             # set region
-            self.parent.digit.driver.UpdateRegion()
+            self.parent.digit.GetDisplay().UpdateRegion()
             # re-calculate threshold for digitization tool
-            self.parent.digit.driver.GetThreshold()
+            # self.parent.digit.driver.GetThreshold()
             # draw map
             if self.pdcVector:
                 self.pdcVector.Clear()
@@ -821,7 +793,7 @@ class BufferedWindow(MapWindow, wx.Window):
                 item = None
             
             if item and self.tree.IsItemChecked(item):
-                self.parent.digit.driver.DrawMap()
+                self.parent.digit.GetDisplay().DrawMap()
 
             # translate tmp objects (pointer position)
             if digitToolbar.GetAction() == 'moveLine':
@@ -906,7 +878,7 @@ class BufferedWindow(MapWindow, wx.Window):
         else:
             self.parent.statusbarWin['mask'].SetLabel('')
         
-        Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s -> time=%g" % \
+        Debug.msg (1, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s -> time=%g" % \
                    (render, renderVector, (stop-start)))
         
         return True
@@ -2334,10 +2306,10 @@ class BufferedWindow(MapWindow, wx.Window):
         event.Skip()
 
     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']
         # digitization tool
@@ -2751,7 +2723,7 @@ class BufferedWindow(MapWindow, wx.Window):
             elif l.type == 'vector':
                 digitToolbar = self.parent.toolbars['vdigit']
                 if digitToolbar and digitToolbar.GetLayer() == l:
-                    w, s, b, e, n, t = self.parent.digit.driver.GetMapBoundingBox()
+                    w, s, b, e, n, t = self.parent.digit.GetDisplay().GetMapBoundingBox()
                     self.Map.GetRegion(n = n, s = s, w = w, e = e,
                                        update = True)
                     updated = True

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

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

File diff suppressed because it is too large
+ 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;
-}

File diff suppressed because it is too large
+ 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_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 */
 int Vedit_split_lines(struct Map_info *, 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,
 		     struct ilist *, double, double, double, int, double);
 
+/* render.c */
+struct robject_list *Vedit_render_map(struct Map_info *, struct bound_box *, int,
+				      double, double, int, int, double);
+
 /* select.c */
 int Vedit_select_by_query(struct Map_info *,
 			  int, int, double, int, struct ilist *);

+ 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;
+    }
+}