[GRASS-SVN] r52255 - in grass/trunk/gui/wxpython: gui_core lmgr mapdisp vdigit wxplot

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jul 1 01:46:10 PDT 2012


Author: martinl
Date: 2012-07-01 01:46:09 -0700 (Sun, 01 Jul 2012)
New Revision: 52255

Modified:
   grass/trunk/gui/wxpython/gui_core/dialogs.py
   grass/trunk/gui/wxpython/gui_core/forms.py
   grass/trunk/gui/wxpython/gui_core/goutput.py
   grass/trunk/gui/wxpython/gui_core/gselect.py
   grass/trunk/gui/wxpython/gui_core/mapdisp.py
   grass/trunk/gui/wxpython/gui_core/mapwindow.py
   grass/trunk/gui/wxpython/gui_core/toolbars.py
   grass/trunk/gui/wxpython/lmgr/frame.py
   grass/trunk/gui/wxpython/mapdisp/frame.py
   grass/trunk/gui/wxpython/mapdisp/mapwindow.py
   grass/trunk/gui/wxpython/vdigit/toolbars.py
   grass/trunk/gui/wxpython/wxplot/profile.py
Log:
wxGUI: implementation of handlers registration
       (patch provided by Stepan Turek based on contribution with Vaclav Petras)


Modified: grass/trunk/gui/wxpython/gui_core/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/dialogs.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/gui_core/dialogs.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -692,6 +692,7 @@
         
     def OnResize(self, event):
         if self.FindWindowByName('resize').GetValue():
+            self.parent.SwitchTool(self.parent.toolbars['map'], event)
             self.parent.MapWindow.SetCursor(self.parent.cursors["cross"])
             self.parent.MapWindow.mouse['use'] = 'legend'
             self.parent.MapWindow.mouse['box'] = 'box'

Modified: grass/trunk/gui/wxpython/gui_core/forms.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/forms.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/gui_core/forms.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -43,6 +43,7 @@
 @author Daniel Calvelo <dca.gis at gmail.com>
 @author Martin Landa <landa.martin at gmail.com>
 @author Luca Delucchi <lucadeluge at gmail.com>
+ at author Stepan Turek <stepan.turek seznam.cz> (CoordinatesSelect)
 """
 
 import sys
@@ -348,11 +349,12 @@
     """
     def __init__(self, parent, task_description, id = wx.ID_ANY,
                  get_dcmd = None, layer = None,
-                 style = wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL, **kwargs):
+                 style = wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL, lmgr = None, **kwargs):
         self.get_dcmd = get_dcmd
         self.layer    = layer
         self.task     = task_description
-        self.parent   = parent            # LayerTree | Modeler | None | ...
+        self.parent   = parent             # LayerTree | Modeler | None | ...
+        self.lmgr     = lmgr  
         if parent and parent.GetName() == 'Modeler':
             self.modeler = self.parent
         else:
@@ -418,7 +420,7 @@
         
         # notebooks
         self.notebookpanel = CmdPanel(parent = self.panel, task = self.task,
-                                      frame = self)
+                                      frame = self, lmgr = self.lmgr)
         self.goutput = self.notebookpanel.goutput
         self.notebookpanel.OnUpdateValues = self.updateValuesHook
         guisizer.Add(item = self.notebookpanel, proportion = 1, flag = wx.EXPAND)
@@ -736,7 +738,7 @@
     """!A panel containing a notebook dividing in tabs the different
     guisections of the GRASS cmd.
     """
-    def __init__(self, parent, task, id = wx.ID_ANY, frame = None, *args, **kwargs):
+    def __init__(self, parent, task, id = wx.ID_ANY, frame = None, lmgr = None, *args, **kwargs):
         if frame:
             self.parent = frame
         else:
@@ -778,7 +780,7 @@
 
         panelsizer = wx.BoxSizer(orient = wx.VERTICAL)
 
-        # Build notebook
+        # build notebook
         self.notebook = GNotebook(self, style = globalvar.FNPageStyle | FN.FNB_NO_X_BUTTON )
         self.notebook.SetTabAreaColour(globalvar.FNPageColor)
         self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChange)
@@ -1101,7 +1103,8 @@
                                               'layer_all',
                                               'location',
                                               'mapset',
-                                              'dbase') and \
+                                              'dbase',
+                                              'coords') and \
                                               p.get('element', '') not in ('file', 'dir'):
                     multiple = p.get('multiple', False)
                     if p.get('age', '') == 'new':
@@ -1414,7 +1417,29 @@
                     # a textctl and a button;
                     # we have to target the button here
                     p['wxId'] = [ fbb.GetChildren()[1].GetId() ]
-
+                    
+                # interactive inserting of coordinates from map window
+                elif prompt == 'coords':
+                    # interactive inserting if layer manager is accessible
+                    if lmgr:
+                        win = gselect.CoordinatesSelect(parent = which_panel, 
+                                                        lmgr = lmgr, 
+                                                        multiple =  p.get('multiple', False),
+                                                        param = p)
+                        p['wxId'] = [win.GetTextWin().GetId()]
+                        win.GetTextWin().Bind(wx.EVT_TEXT, self.OnSetValue)
+                    
+                    # normal text field
+                    else:
+                        win = wx.TextCtrl(parent = which_panel)
+                        p['wxId'] = [win.GetId()]
+                        win.Bind(wx.EVT_TEXT, self.OnSetValue)
+                    
+                    which_sizer.Add(item = win, 
+                                    proportion = 0,
+                                    flag = wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 
+                                    border = 5)
+            
             if self.parent.GetName() == 'MainFrame' and self.parent.modeler:
                 parChk = wx.CheckBox(parent = which_panel, id = wx.ID_ANY,
                                      label = _("Parameterized in model"))
@@ -1934,13 +1959,14 @@
         
 class GUI:
     def __init__(self, parent = None, show = True, modal = False,
-                 centreOnParent = False, checkError = False):
+                 centreOnParent = False, checkError = False, lmgr = None):
         """!Parses GRASS commands when module is imported and used from
         Layer Manager.
         """
         self.parent = parent
         self.show   = show
         self.modal  = modal
+        self.lmgr   = lmgr
         self.centreOnParent = centreOnParent
         self.checkError     = checkError
         
@@ -2046,7 +2072,8 @@
         if self.show is not None:
             self.mf = TaskFrame(parent = self.parent,
                                 task_description = self.grass_task,
-                                get_dcmd = get_dcmd, layer = layer)
+                                get_dcmd = get_dcmd, layer = layer,
+                                lmgr = self.lmgr)
         else:
             self.mf = None
         

Modified: grass/trunk/gui/wxpython/gui_core/goutput.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/goutput.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/gui_core/goutput.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -577,7 +577,7 @@
                         command[0] != 'v.krige':
                     # no arguments given
                     try:
-                        GUI(parent = self).ParseCommand(command)
+                        GUI(parent = self, lmgr = self.parent).ParseCommand(command)
                     except GException, e:
                         print >> sys.stderr, e
                     return
@@ -618,7 +618,7 @@
                 
             if task:
                 # process GRASS command without argument
-                GUI(parent = self).ParseCommand(command)
+                GUI(parent = self, lmgr = self.parent).ParseCommand(command)
             else:
                 self.cmdThread.RunCmd(command, stdout = self.cmdStdOut, stderr = self.cmdStdErr,
                                       onDone = onDone, onPrepare = onPrepare, userData = userData)

Modified: grass/trunk/gui/wxpython/gui_core/gselect.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/gselect.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/gui_core/gselect.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -22,6 +22,7 @@
  - gselect::ProjSelect
  - gselect::ElementSelect
  - gselect::OgrTypeSelect
+ - gselect::CoordinatesSelect
 
 (C) 2007-2012 by the GRASS Development Team 
 
@@ -31,6 +32,7 @@
 @author Michael Barton
 @author Martin Landa <landa.martin gmail.com>
 @author Vaclav Petras <wenzeslaus gmail.com> (menu customization)
+ at author Stepan Turek <stepan.turek seznam.cz> (CoordinatesSelect)
 """
 
 import os
@@ -39,7 +41,9 @@
 
 import wx
 import wx.combo
+import wx.lib.buttons          as  buttons
 import wx.lib.filebrowsebutton as filebrowse
+
 from wx.lib.newevent import NewEvent
 
 from core import globalvar
@@ -1909,3 +1913,82 @@
             return 'line'
         elif sel == 2:
             return 'boundary'
+
+class CoordinatesSelect(wx.Panel):
+    def __init__(self, parent, lmgr = None, multiple = False, **kwargs):
+        """!Widget to get coordinates from map window  by mouse click
+        
+        @param parent parent window
+        @param lmgr layer manager 
+        @param multiple - True if it is possible to insert more coordinates
+        """
+        self.lmgr     = lmgr
+        self.multiple = multiple
+        self.mapWin   = None
+        
+        super(CoordinatesSelect, self).__init__(parent = parent, id = wx.ID_ANY)
+        
+        self.coordsField = wx.TextCtrl(parent = self, id = wx.ID_ANY, 
+                                       size = globalvar.DIALOG_TEXTCTRL_SIZE)
+        
+        icon = wx.Bitmap(os.path.join(globalvar.ETCICONDIR, "grass", "pointer.png"))
+        self.buttonInsCoords = buttons.ThemedGenBitmapToggleButton(parent = self, id = wx.ID_ANY,
+                                                                   bitmap = icon,
+                                                                   size = globalvar.DIALOG_COLOR_SIZE)
+        
+        self.buttonInsCoords.Bind(wx.EVT_BUTTON, self._onClick)
+        self._doLayout()
+        
+    def _doLayout(self):
+        self.dialogSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.dialogSizer.Add(item = self.coordsField,  
+                             proportion = 1, 
+                             flag = wx.EXPAND)
+        self.dialogSizer.Add(item = self.buttonInsCoords)
+        self.SetSizer(self.dialogSizer)
+        
+    def _onClick(self, event):
+        """!Button for interacitve inserting of coordinates clicked"""
+        if self.buttonInsCoords.GetToggle() and self.lmgr.GetLayerTree():   
+            self.mapWin = self.lmgr.GetLayerTree().GetMapDisplay().GetWindow()            
+            if self.mapWin.RegisterMouseEventHandler(wx.EVT_LEFT_DOWN, 
+                                                     self._onMapClickHandler,
+                                                     wx.StockCursor(wx.CURSOR_CROSS)) == False:
+                self.buttonInsCoords.SetToggle(False)
+                return
+            
+            self.lmgr.GetLayerTree().GetMapDisplay().Raise()
+        else:
+            if self.mapWin and \
+                    self.mapWin.UnregisterMouseEventHandler(wx.EVT_LEFT_DOWN,  
+                                                            self._onMapClickHandler):
+                    return
+            
+            self.buttonInsCoords.SetToggle(False)           
+    
+    def _onMapClickHandler(self, event):
+        """!Gets coordinates from mapwindow"""
+        if event == "unregistered":
+            self.buttonInsCoords.SetToggle(False)
+            return
+        
+        e, n = self.mapWin.GetLastEN()
+        prevCoords = ""
+        
+        if self.multiple:
+            prevCoords = self.coordsField.GetValue().strip()
+            if prevCoords != "":
+                prevCoords += ","
+        
+        value = prevCoords + str(e) + "," + str(n)
+        self.coordsField.SetValue(value)
+        
+    def __del__(self):
+        """!Unregistrates _onMapClickHandler from mapWin"""
+        if self.mapWin:
+            self.mapWin.UnregisterMouseEventHandler(wx.EVT_LEFT_DOWN,  
+                                                    self._onMapClickHandler)
+
+    def GetTextWin(self):
+        """!Get TextCtrl widget"""
+        return self.coordsField

Modified: grass/trunk/gui/wxpython/gui_core/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/mapdisp.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/gui_core/mapdisp.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -8,7 +8,7 @@
  - mapdisp::SingleMapFrame
  - mapdisp::DoubleMapFrame
 
-(C) 2009-2011 by the GRASS Development Team
+(C) 2009-2012 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.
@@ -282,7 +282,7 @@
         Set mouse cursor, zoombox attributes, and zoom direction
         """
         toolbar = self.GetMapToolbar()
-        self._switchTool(toolbar, event)
+        self.SwitchTool(toolbar, event)
         
         win = self.GetWindow()
         self._prepareZoom(mapWindow = win, zoomType = 1)
@@ -292,7 +292,7 @@
         Set mouse cursor, zoombox attributes, and zoom direction
         """
         toolbar = self.GetMapToolbar()
-        self._switchTool(toolbar, event)
+        self.SwitchTool(toolbar, event)
         
         win = self.GetWindow()
         self._prepareZoom(mapWindow = win, zoomType = -1)
@@ -311,8 +311,12 @@
         # change the cursor
         mapWindow.SetCursor(self.cursors["cross"])
     
-    def _switchTool(self, toolbar, event):
+    def SwitchTool(self, toolbar, event):
         """!Helper function to switch tools"""
+        # unregistration of all registered mouse event handlers of
+        # Mapwindow
+        self.MapWindow.UnregisterAllHandlers()
+        
         if toolbar:
             toolbar.OnTool(event)
             toolbar.action['desc'] = ''
@@ -321,7 +325,7 @@
         """!Panning, set mouse to drag
         """
         toolbar = self.GetMapToolbar()
-        self._switchTool(toolbar, event)
+        self.SwitchTool(toolbar, event)
         
         win = self.GetWindow()
         self._preparePan(mapWindow = win)
@@ -522,7 +526,7 @@
         Set mouse cursor, zoombox attributes, and zoom direction
         """
         toolbar = self.GetMapToolbar()
-        self._switchTool(toolbar, event)
+        self.SwitchTool(toolbar, event)
         
         win = self.GetFirstWindow()
         self._prepareZoom(mapWindow = win, zoomType = 1)
@@ -535,7 +539,7 @@
         Set mouse cursor, zoombox attributes, and zoom direction
         """
         toolbar = self.GetMapToolbar()
-        self._switchTool(toolbar, event)
+        self.SwitchTool(toolbar, event)
         
         win = self.GetFirstWindow()
         self._prepareZoom(mapWindow = win, zoomType = -1)
@@ -547,7 +551,7 @@
         """!Panning, set mouse to drag
         """
         toolbar = self.GetMapToolbar()
-        self._switchTool(toolbar, event)
+        self.SwitchTool(toolbar, event)
         
         win = self.GetFirstWindow()
         self._preparePan(mapWindow = win)

Modified: grass/trunk/gui/wxpython/gui_core/mapwindow.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/mapwindow.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/gui_core/mapwindow.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -6,7 +6,7 @@
 Classes:
  - mapwindow::MapWindow
 
-(C) 2006-2011 by the GRASS Development Team
+(C) 2006-2012 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.
@@ -14,12 +14,17 @@
 @author Martin Landa <landa.martin gmail.com>
 @author Michael Barton
 @author Jachym Cepicky
+ at author Vaclav Petras <wenzeslaus gmail.com> (handlers support)
+ at author Stepan Turek <stepan.turek seznam.cz> (handlers support)
 """
 
 import wx
 
 from core.settings import UserSettings
+from core.gcmd     import GError
 
+from grass.script import core as grass
+
 class MapWindow(object):
     """!Abstract map display window class
     
@@ -30,7 +35,6 @@
      - _bindMouseEvents method which binds MouseEvent handlers
      - Pixel2Cell
      - Cell2Pixel (if it is possible)
-    
     """
     def __init__(self, parent, id = wx.ID_ANY,
                  Map = None, tree = None, lmgr = None, **kwargs):
@@ -53,19 +57,73 @@
         # stores overridden cursor
         self._overriddenCursor = None
 
+        # dictionary where event types are stored as keys and lists of
+        # handlers for these types as values
+        self.handlersContainer = {
+            wx.EVT_LEFT_DOWN : [],
+            wx.EVT_LEFT_UP : [],
+            wx.EVT_LEFT_DCLICK : [],
+            wx.EVT_MIDDLE_DOWN : [],
+            wx.EVT_MIDDLE_UP : [],
+            wx.EVT_MIDDLE_DCLICK : [],
+            wx.EVT_RIGHT_DOWN : [],
+            wx.EVT_RIGHT_UP : [],
+            wx.EVT_RIGHT_DCLICK : [],
+            wx.EVT_MOTION : [],
+            wx.EVT_ENTER_WINDOW : [],
+            wx.EVT_LEAVE_WINDOW : [],
+            wx.EVT_MOUSEWHEEL : [],
+            wx.EVT_MOUSE_EVENTS : []
+            }
+        
+        wx.CallAfter(self.InitBinding)
+
+    def __del__(self):
+        self.UnregisterAllHandlers()
+
+    def InitBinding(self):
+        """!Binds helper functions, which calls all handlers
+           registered to events with the events
+        """
+        for ev, handlers in self.handlersContainer.iteritems():
+            self.Bind(ev, self.EventTypeHandler(handlers))
+    
+    def EventTypeHandler(self, evHandlers):
+         return lambda event:self.HandlersCaller(event, evHandlers)  
+    
+    def HandlersCaller(self, event, handlers):
+        """!Hepler function which calls all handlers registered for
+        event
+        """
+        for handler in handlers:
+            try:
+                handler(event)
+            except:
+                handlers.remove(handler)
+                GError(parent = self,
+                       message=_("Error occured during calling of handler: %s \n"
+                                 "Handler was unregistered.") % handler.__name__)
+        
+        event.Skip() 
+
     def RegisterMouseEventHandler(self, event, handler, cursor = None):
         """!Binds event handler
         
         Call event.Skip() in handler to allow default processing in MapWindow.
-        
+
+        If any error occures inside of handler, the handler is removed.
+
+        Before handler is unregistered it is called with 
+        string value "unregistered" of event parameter.
+
         @code
         # your class methods
         def OnButton(self, event):
             # current map display's map window
             # expects LayerManager to be the parent
             self.mapwin = self.parent.GetLayerTree().GetMapDisplay().GetWindow()
-            if self.mapwin.RegisterMouseEventHandler(wx.EVT_LEFT_DOWN, self.OnMouseAction,
-                                                     wx.StockCursor(wx.CURSOR_CROSS)):
+            if self.mapwin.RegisterEventHandler(wx.EVT_LEFT_DOWN, self.OnMouseAction,
+                                                wx.StockCursor(wx.CURSOR_CROSS)):
                 self.parent.GetLayerTree().GetMapDisplay().Raise()
             else:
                 # handle that you cannot get coordinates
@@ -74,7 +132,7 @@
             # get real world coordinates of mouse click
             coor = self.mapwin.Pixel2Cell(event.GetPositionTuple()[:])
             self.text.SetLabel('Coor: ' + str(coor))
-            self.mapwin.UnregisterMouseEventHandler(wx.EVT_LEFT_DOWN)
+            self.mapwin.UnregisterMouseEventHandler(wx.EVT_LEFT_DOWN, self.OnMouseAction)
             event.Skip()
         @endcode
         
@@ -85,13 +143,11 @@
         @return True if successful
         @return False if event cannot be bind
         """
+        # inserts handler into list
+        for containerEv, handlers in self.handlersContainer.iteritems():
+            if event == containerEv: 
+                handlers.append(handler)
         
-        # if it is a VDigitWindow it cannot be used
-        # hasattr is ugly
-        if hasattr(self, "digit"):
-            return False
-        
-        self.Bind(event, handler)
         self.mouse['useBeforeGenericEvent'] = self.mouse['use']
         self.mouse['use'] = 'genericEvent'
         
@@ -101,27 +157,52 @@
         
         return True
 
+    def UnregisterAllHandlers(self):
+        """!Unregisters all registered handlers 
 
-    def UnregisterMouseEventHandler(self, event):
-        """!Unbinds event handler a restores previous state
+        Before each handler is unregistered it is called with string
+        value "unregistered" of event parameter.
+        """
+        for containerEv, handlers in self.handlersContainer.iteritems():
+            for handler in handlers:
+                try:
+                    handler("unregistered")
+                    handlers.remove(handler)
+                except:
+                    GError(parent = self,
+                           message = _("Error occured during unregistration of handler: %s \n \
+                                       Handler was unregistered.") % handler.__name__)
+                    handlers.remove(handler)
         
-        You should unbind to restore normal MapWindow behaviour.
-        Note that this operation will unbind any other external (non-MapWindow) handlers.
+    def UnregisterMouseEventHandler(self, event, handler):
+        """!Unbinds event handler for event
         
-        @param event event to unbind
+        Before handler is unregistered it is called with string value
+        "unregistered" of event parameter.
+
+        @param handler handler to unbind
+        @param event event from which handler will be unbinded
         
         @return True if successful
         @return False if event cannot be unbind
         """
-        if hasattr(self, "digit"):
-            return False
+        # removes handler from list 
+        for containerEv, handlers in self.handlersContainer.iteritems():
+            if event != containerEv:
+                continue
+            try:
+                handler("unregistered")
+                if handler in handlers:
+                    handlers.remove(handler)
+                else:
+                    grass.warning(_("Handler: %s was not registered") \
+                                      % handler.__name__)
+            except:
+                GError(parent = self,
+                       message = _("Error occured during unregistration of handler: %s \n \
+                                       Handler was unregistered") % handler.__name__)
+                handlers.remove(handler) 
         
-        # it is not yet possible in wxPython to unbind exact event
-        ret = self.Unbind(event)
-        
-        # restore bind state
-        self._bindMouseEvents()
-        
         # restore mouse use (previous state)
         self.mouse['use'] = self.mouse['useBeforeGenericEvent']
         
@@ -129,7 +210,7 @@
         if self._overriddenCursor:
             self.SetCursor(self._overriddenCursor)
         
-        return ret
+        return True
     
     def Pixel2Cell(self, (x, y)):
         raise NotImplementedError()

Modified: grass/trunk/gui/wxpython/gui_core/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/toolbars.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/gui_core/toolbars.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -164,24 +164,19 @@
         if self.parent.GetName() == "GCPFrame":
             return
         
-        if hasattr(self.parent, 'toolbars'):
-            if self.parent.GetToolbar('vdigit'):
-                # update vdigit toolbar (unselect currently selected tool)
-                id = self.parent.toolbars['vdigit'].GetAction(type = 'id')
-                self.parent.toolbars['vdigit'].ToggleTool(id, False)
+        id = self.action.get('id', -1)
         
         if event:
             # deselect previously selected tool
-            id = self.action.get('id', -1)
-            if id != event.GetId():
+            if id != -1 and id != event.GetId() :
                 self.ToggleTool(self.action['id'], False)
-            else:
+            elif id != -1:
                 self.ToggleTool(self.action['id'], True)
             
             self.action['id'] = event.GetId()
             
             event.Skip()
-        else:
+        elif id != -1:
             # initialize toolbar
             self.ToggleTool(self.action['id'], True)
         

Modified: grass/trunk/gui/wxpython/lmgr/frame.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/frame.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/lmgr/frame.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -481,7 +481,9 @@
 
     def GetLayerTree(self):
         """!Get current layer tree"""
-        return self.curr_page.maptree
+        if self.curr_page:
+            return self.curr_page.maptree
+        return None
     
     def GetLogWindow(self):
         """!Get widget for command output"""

Modified: grass/trunk/gui/wxpython/mapdisp/frame.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/frame.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/mapdisp/frame.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -9,7 +9,7 @@
 Classes:
  - mapdisp::MapFrame
 
-(C) 2006-2011 by the GRASS Development Team
+(C) 2006-2012 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.
@@ -17,8 +17,9 @@
 @author Michael Barton
 @author Jachym Cepicky
 @author Martin Landa <landa.martin gmail.com>
- at author Vaclav Petras <wenzeslaus gmail.com> (SingleMapFrame)
+ at author Vaclav Petras <wenzeslaus gmail.com> (SingleMapFrame, handlers support)
 @author Anna Kratochvilova <kratochanna gmail.com> (SingleMapFrame)
+ at author Stepan Turek <stepan.turek seznam.cz> (handlers support)
 """
 
 import os
@@ -466,7 +467,7 @@
         """
         if self.GetMapToolbar():
             if event:
-                self.toolbars['map'].OnTool(event)
+                self.SwitchTool(self.toolbars['map'], event)
             self.toolbars['map'].action['desc'] = ''
         
         self.MapWindow.mouse['use'] = "pointer"
@@ -497,7 +498,7 @@
         """!Rotate 3D view
         """
         if self.GetMapToolbar():
-            self.toolbars['map'].OnTool(event)
+            self.SwitchTool(self.toolbars['map'], event)
             self.toolbars['map'].action['desc'] = ''
         
         self.MapWindow.mouse['use'] = "rotate"
@@ -509,7 +510,7 @@
         """!Fly-through mode
         """
         if self.GetMapToolbar():
-            self.toolbars['map'].OnTool(event)
+            self.SwitchTool(self.toolbars['map'], event)
             self.toolbars['map'].action['desc'] = ''
         
         self.MapWindow.mouse['use'] = "fly"
@@ -826,12 +827,12 @@
     def OnQuery(self, event):
         """!Query tools menu"""
         if self.GetMapToolbar():
-            self.toolbars['map'].OnTool(event)
+            self.SwitchTool(self.toolbars['map'], event)
             action = self.toolbars['map'].GetAction()
-            
+        
         self.toolbars['map'].action['desc'] = 'queryMap'
         self.MapWindow.mouse['use'] = "query"
-        
+
         if not self.IsStandalone():
             # switch to output console to show query results
             self._layerManager.notebook.SetSelectionByName('output')
@@ -902,6 +903,8 @@
         """
         self.totaldist = 0.0 # total measured distance
         
+        self.SwitchTool(self.toolbars['map'], event)
+        
         # switch Layer Manager to output console to show measure results
         self._layerManager.notebook.SetSelectionByName('output')
         
@@ -1095,6 +1098,7 @@
         """
         if self.dialogs['barscale']:
             return
+        self.SwitchTool(self.toolbars['map'], event)
         
         id = 0 # unique index for overlay layer
 
@@ -1156,6 +1160,7 @@
     def OnAddText(self, event):
         """!Handler for text decoration menu selection.
         """
+        self.SwitchTool(self.toolbars['map'], event)
         if self.MapWindow.dragid > -1:
             id = self.MapWindow.dragid
             self.MapWindow.dragid = -1
@@ -1316,3 +1321,32 @@
     def GetMapToolbar(self):
         """!Returns toolbar with zooming tools"""
         return self.toolbars['map']
+
+    def SwitchTool(self, toolbar, event):
+        """!Calls UpdateTools to manage connected toolbars"""
+        self.UpdateTools(event)
+        SingleMapFrame.SwitchTool(self, toolbar, event)
+
+    def UpdateTools(self, event):
+        """!Method deals with relations of toolbars and other
+        elements""" 
+        # untoggles button in other toolbars
+        for toolbar in self.toolbars.itervalues():
+            if hasattr(event, 'GetEventObject') == True:
+                if event.GetEventObject() == toolbar:
+                    continue
+            toolbar.ToggleTool(toolbar.action['id'], False)
+            toolbar.action['id'] = -1
+            toolbar.OnTool(None)
+        
+        # mouse settings
+        self.MapWindow.mouse['box'] = 'point' 
+        self.MapWindow.mouse['use'] = 'pointer'
+        
+        # untoggles button in add legend dialog
+        if self.dialogs['legend']:
+            if hasattr(event ,'GetEventObject'):
+                if event.GetEventObject().GetId() == \
+                        self.dialogs['legend'].FindWindowByName('resize').GetId():
+                    return
+            self.dialogs['legend'].FindWindowByName('resize').SetValue(0)

Modified: grass/trunk/gui/wxpython/mapdisp/mapwindow.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/mapwindow.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/mapdisp/mapwindow.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -6,7 +6,7 @@
 Classes:
  - mapwindow::BufferedWindow
 
-(C) 2006-2011 by the GRASS Development Team
+(C) 2006-2012 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.
@@ -14,6 +14,8 @@
 @author Martin Landa <landa.martin gmail.com>
 @author Michael Barton
 @author Jachym Cepicky
+ at author Vaclav Petras <wenzeslaus gmail.com> (handlers support)
+ at author Stepan Turek <stepan.turek seznam.cz> (handlers support)
 """
 
 import os
@@ -1742,3 +1744,18 @@
     def GetMap(self):
         """!Get render.Map() instance"""
         return self.Map
+
+    def RegisterMouseEventHandler(self, event, handler, cursor = None):
+        """!Calls UpdateTools to manage connected toolbars"""
+        self.parent.UpdateTools(None)
+        MapWindow.RegisterMouseEventHandler(self, event, handler, cursor)
+
+    def UnregisterMouseEventHandler(self, event, handler):
+        """!Sets pointer and toggles it after unregistration"""
+        MapWindow.UnregisterMouseEventHandler(self, event, handler)
+        
+        # sets pointer mode
+        toolbar = self.parent.toolbars['map']
+        toolbar.action['id'] = vars(toolbar)["pointer"]
+        toolbar.OnTool(None)
+        self.parent.OnPointer(event = None)

Modified: grass/trunk/gui/wxpython/vdigit/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/vdigit/toolbars.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/vdigit/toolbars.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -6,12 +6,13 @@
 List of classes:
  - toolbars::VDigitToolbar
 
-(C) 2007-2011 by the GRASS Development Team
+(C) 2007-2012 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>
+ at author Stepan Turek <stepan.turek seznam.cz> (handlers support)
 """
 import wx
 
@@ -53,7 +54,7 @@
         
         # create toolbars (two rows optionally)
         self.InitToolbar(self._toolbarData())
-        self.Bind(wx.EVT_TOOL, self.OnTool)
+        self.Bind(wx.EVT_TOOL, self._toolChosen)
         
         # default action (digitize new point, line, etc.)
         self.action = { 'desc' : '',
@@ -233,42 +234,46 @@
         
         return self._getToolbarData(data)
     
+    def _toolChosen(self, event):
+        """!Tool selected -> untoggles selected tools in other
+        toolbars
+
+        @todo implement iclass front-end
+        """
+        self.parent.MapWindow.UnregisterAllHandlers()
+        
+        if hasattr(self.parent, "UpdateTools"):
+            self.parent.UpdateTools(event)
+        self.OnTool(event)
+        
     def OnTool(self, event):
-        """!Tool selected -> disable selected tool in map toolbar"""
-        aId = self.parent.GetMapToolbar().GetAction(type = 'id')
-        self.parent.GetMapToolbar().ToggleTool(aId, False)
-                
+        """!Tool selected -> untoggles previusly selected tool in
+        toolbar"""
         # set cursor
         cursor = self.parent.cursors["cross"]
         self.MapWindow.SetCursor(cursor)
         
         # pointer
         self.parent.OnPointer(None)
-                
-        if event:
-            # deselect previously selected tool
-            aId = self.action.get('id', -1)
-            if aId != event.GetId() and \
-                    self.action['id'] != -1:
-                self.ToggleTool(self.action['id'], False)
-            else:
-                self.ToggleTool(self.action['id'], True)
-            
-            self.action['id'] = event.GetId()
-            
-            event.Skip()
-        
-        if self.action['id'] != -1:
-            self.ToggleTool(self.action['id'], True)
-        
+         
+        aId = self.action.get('id', -1)       
+        BaseToolbar.OnTool(self, event)
+
         # clear tmp canvas
-        if self.action['id'] != aId:
+        if self.action['id'] != aId or aId == -1:
+            self.MapWindow.polycoords = []
             self.MapWindow.ClearLines(pdc = self.MapWindow.pdcTmp)
             if self.digit and \
                     len(self.MapWindow.digit.GetDisplay().GetSelected()) > 0:
                 # cancel action
                 self.MapWindow.OnMiddleDown(None)
         
+        # set no action
+        if self.action['id'] == -1:
+            self.action = { 'desc' : '',
+                            'type' : '',
+                            'id'   : -1 }
+        
         # set focus
         self.MapWindow.SetFocus()
         

Modified: grass/trunk/gui/wxpython/wxplot/profile.py
===================================================================
--- grass/trunk/gui/wxpython/wxplot/profile.py	2012-06-30 09:28:25 UTC (rev 52254)
+++ grass/trunk/gui/wxpython/wxplot/profile.py	2012-07-01 08:46:09 UTC (rev 52255)
@@ -88,6 +88,7 @@
     def OnDrawTransect(self, event):
         """!Draws transect to profile in map display
         """
+        self.parent.SwitchTool(self.parent.toolbars['map'], event)
         self.mapwin.polycoords = []
         self.seglist = []
         self.mapwin.ClearLines(self.mapwin.pdc)
@@ -118,13 +119,10 @@
         dlg.Destroy()
 
     def SetupProfile(self):
-        """!Create coordinate string for profiling. Create segment list for
-           transect segment markers.
+        """!Create coordinate string for profiling. Create segment
+           list for transect segment markers.
         """
-
-        #
         # create list of coordinate points for r.profile
-        #                
         dist = 0
         cumdist = 0
         self.coordstr = ''
@@ -141,20 +139,18 @@
                     self.coordstr = '%d,%d' % (point[0], point[1])
                 else:
                     self.coordstr = '%s,%d,%d' % (self.coordstr, point[0], point[1])
-
+        
         if not insideRegion:
             GWarning(message = _("Not all points of profile lie inside computational region."),
                      parent = self)
-
+        
         if len(self.rasterList) == 0:
             return
-
+        
         # title of window
         self.ptitle = _('Profile of')
-
-        #
+        
         # create list of coordinates for transect segment markers
-        #
         if len(self.mapwin.polycoords) > 0:
             self.seglist = []
             for point in self.mapwin.polycoords:
@@ -166,7 +162,8 @@
                                  coordinates = '%d,%d' % (point[0],point[1]))
                 
                 val = ret.splitlines()[0].split('|')[3]
-                if val == None or val == '*': continue
+                if val == None or val == '*':
+                    continue
                 val = float(val)
                 
                 # calculate distance between coordinate points
@@ -174,14 +171,14 @@
                     dist = math.sqrt(math.pow((lasteast-point[0]),2) + math.pow((lastnorth-point[1]),2))
                 cumdist += dist
                 
-                #store total transect length
+                # store total transect length
                 self.transect_length = cumdist
-
+                
                 # build a list of distance,value pairs for each segment of transect
                 self.seglist.append((cumdist,val))
                 lasteast = point[0]
                 lastnorth = point[1]
-
+            
             # delete extra first segment point
             try:
                 self.seglist.pop(0)



More information about the grass-commit mailing list