Browse Source

wxGUI: replacing wx events by pydispatcher signals, first steps (co-author: annakrat)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@55326 15284696-431f-4ddb-bdfa-cd5b030d7da7
Vaclav Petras 12 years ago
parent
commit
94b4f929a8

+ 0 - 12
gui/wxpython/core/events.py

@@ -33,18 +33,6 @@ from wx.lib.newevent import NewCommandEvent
 from wx.lib.newevent import NewEvent
 from wx.lib.newevent import NewEvent
 
 
 
 
-# Notification event intended to update statusbar.
-# The message attribute contains the text of the message (plain text)
-gShowNotification, EVT_SHOW_NOTIFICATION = NewCommandEvent()
-
-
-# Occurs event when some map is created or updated by a module.
-# attributes: name: map name, ltype: map type,
-# add: if map should be added to layer tree (questionable attribute)
-gMapCreated, EVT_MAP_CREATED = NewCommandEvent()
-
-gZoomChanged, EVT_ZOOM_CHANGED = NewEvent()
-
 # Post it to BufferedWindow instance, which you want to update.
 # Post it to BufferedWindow instance, which you want to update.
 # For relevant attributes for the event see 
 # For relevant attributes for the event see 
 # mapdisp.mapwindow.BufferedWindow UpdateMap method arguments.
 # mapdisp.mapwindow.BufferedWindow UpdateMap method arguments.

+ 8 - 5
gui/wxpython/core/gconsole.py

@@ -35,9 +35,10 @@ from wx.lib.newevent import NewEvent
 import grass.script as grass
 import grass.script as grass
 from   grass.script import task as gtask
 from   grass.script import task as gtask
 
 
+from grass.pydispatch.signal import Signal
+
 from core import globalvar
 from core import globalvar
 from core.gcmd import CommandThread, GError, GException
 from core.gcmd import CommandThread, GError, GException
-from core.events import gMapCreated
 from gui_core.forms import GUI
 from gui_core.forms import GUI
 from core.debug import Debug
 from core.debug import Debug
 from core.settings import UserSettings
 from core.settings import UserSettings
@@ -348,6 +349,10 @@ class GConsole(wx.EvtHandler):
         """
         """
         wx.EvtHandler.__init__(self)
         wx.EvtHandler.__init__(self)
 
 
+        # Signal when some map is created or updated by a module.
+        # attributes: name: map name, ltype: map type,
+        self.mapCreated = Signal('GConsole.mapCreated')
+
         self._guiparent = guiparent
         self._guiparent = guiparent
         self._giface = giface
         self._giface = giface
         self._ignoredCmdPattern = ignoredCmdPattern
         self._ignoredCmdPattern = ignoredCmdPattern
@@ -595,7 +600,7 @@ class GConsole(wx.EvtHandler):
     def OnCmdDone(self, event):
     def OnCmdDone(self, event):
         """!Command done (or aborted)
         """!Command done (or aborted)
 
 
-        Posts event EVT_MAP_CREATED.
+        Sends signal mapCreated if map is recognized in output parameters.
         """
         """
         # Process results here
         # Process results here
         try:
         try:
@@ -650,9 +655,7 @@ class GConsole(wx.EvtHandler):
                 name = p.get('value')
                 name = p.get('value')
                 if '@' not in name:
                 if '@' not in name:
                     name = name + '@' + grass.gisenv()['MAPSET']
                     name = name + '@' + grass.gisenv()['MAPSET']
-                mapEvent = gMapCreated(self._guiparent.GetId(),
-                                       name=name, ltype=prompt, add=None)
-                wx.PostEvent(self._guiparent, mapEvent)
+                self.mapCreated.emit(name=name, ltype=prompt)
 
 
         event.Skip()
         event.Skip()
 
 

+ 10 - 0
gui/wxpython/core/giface.py

@@ -22,6 +22,7 @@ from core.gconsole import GConsole, \
 
 
 import grass.script as grass
 import grass.script as grass
 
 
+from grass.pydispatch.signal import Signal
 
 
 # to disable Abstract class not referenced
 # to disable Abstract class not referenced
 #pylint: disable=R0921
 #pylint: disable=R0921
@@ -136,6 +137,15 @@ class GrassInterface:
 class StandaloneGrassInterface():
 class StandaloneGrassInterface():
     """!@implements GrassInterface"""
     """!@implements GrassInterface"""
     def __init__(self):
     def __init__(self):
+
+        # Signal when some map is created or updated by a module.
+        # attributes: name: map name, ltype: map type,
+        # add: if map should be added to layer tree (questionable attribute)
+        self.mapCreated = Signal('StandaloneGrassInterface.mapCreated')
+
+        # Signal emitted to request updating of map
+        self.updateMap = Signal('StandaloneGrassInterface.updateMap')
+
         self._gconsole = GConsole()
         self._gconsole = GConsole()
         self._gconsole.Bind(EVT_CMD_PROGRESS, self._onCmdProgress)
         self._gconsole.Bind(EVT_CMD_PROGRESS, self._onCmdProgress)
         self._gconsole.Bind(EVT_CMD_OUTPUT, self._onCmdOutput)
         self._gconsole.Bind(EVT_CMD_OUTPUT, self._onCmdOutput)

+ 2 - 12
gui/wxpython/gmodeler/frame.py

@@ -37,7 +37,6 @@ from gui_core.widgets     import GNotebook
 from core.gconsole        import GConsole, \
 from core.gconsole        import GConsole, \
     EVT_CMD_RUN, EVT_CMD_DONE, EVT_CMD_PREPARE, EVT_CMD_RUN, EVT_CMD_DONE
     EVT_CMD_RUN, EVT_CMD_DONE, EVT_CMD_PREPARE, EVT_CMD_RUN, EVT_CMD_DONE
 from gui_core.goutput     import GConsoleWindow
 from gui_core.goutput     import GConsoleWindow
-from core.events          import EVT_MAP_CREATED, EVT_SHOW_NOTIFICATION
 from core.debug           import Debug
 from core.debug           import Debug
 from core.gcmd            import GMessage, GException, GWarning, GError, RunCommand
 from core.gcmd            import GMessage, GException, GWarning, GError, RunCommand
 from gui_core.dialogs     import GetImageHandlers
 from gui_core.dialogs     import GetImageHandlers
@@ -110,6 +109,8 @@ class ModelFrame(wx.Frame):
         
         
         self._gconsole = GConsole(guiparent = self)
         self._gconsole = GConsole(guiparent = self)
         self.goutput = GConsoleWindow(parent = self, gconsole = self._gconsole)
         self.goutput = GConsoleWindow(parent = self, gconsole = self._gconsole)
+        self.goutput.showNotification.connect(lambda message: self.SetStatusText(message))
+
         # here events are binded twice
         # here events are binded twice
         self._gconsole.Bind(EVT_CMD_RUN,
         self._gconsole.Bind(EVT_CMD_RUN,
                                 lambda event:
                                 lambda event:
@@ -120,9 +121,6 @@ class ModelFrame(wx.Frame):
         self.Bind(EVT_CMD_RUN, self.OnCmdRun)
         self.Bind(EVT_CMD_RUN, self.OnCmdRun)
         self.Bind(EVT_CMD_DONE, self.OnCmdDone)
         self.Bind(EVT_CMD_DONE, self.OnCmdDone)
         self.Bind(EVT_CMD_PREPARE, self.OnCmdPrepare)
         self.Bind(EVT_CMD_PREPARE, self.OnCmdPrepare)
-        self.Bind(EVT_MAP_CREATED, self.OnMapCreated)
-        self.Bind(EVT_SHOW_NOTIFICATION,
-                  lambda event: self.SetStatusText(event.message))
 
 
         self.notebook.AddPage(page = self.canvas, text=_('Model'), name = 'model')
         self.notebook.AddPage(page = self.canvas, text=_('Model'), name = 'model')
         self.notebook.AddPage(page = self.itemPanel, text=_('Items'), name = 'items')
         self.notebook.AddPage(page = self.itemPanel, text=_('Items'), name = 'items')
@@ -240,14 +238,6 @@ class ModelFrame(wx.Frame):
         except IndexError:
         except IndexError:
             pass
             pass
 
 
-    def OnMapCreated(self, event):
-        """!Map was created but we don't want to add it to layer tree.
-        """
-        # remove this method if you want to add it to layer tree
-        # or see gui_core.forms.TaskFrame.OnMapCreated
-        event.add = False
-        event.Skip()
-
     def OnCloseWindow(self, event):
     def OnCloseWindow(self, event):
         """!Close window"""
         """!Close window"""
         if self.modelChanged and \
         if self.modelChanged and \

+ 12 - 7
gui/wxpython/gui_core/forms.py

@@ -87,6 +87,8 @@ try:
 except ImportError:
 except ImportError:
     import elementtree.ElementTree as etree # Python <= 2.4
     import elementtree.ElementTree as etree # Python <= 2.4
 
 
+from grass.pydispatch.signal import Signal
+
 from grass.script import core as grass
 from grass.script import core as grass
 from grass.script import task as gtask
 from grass.script import task as gtask
 
 
@@ -96,7 +98,6 @@ from gui_core         import gselect
 from core             import gcmd
 from core             import gcmd
 from core             import utils
 from core             import utils
 from core.settings    import UserSettings
 from core.settings    import UserSettings
-from core.events      import EVT_MAP_CREATED
 from gui_core.widgets import FloatValidator, GNotebook, FormNotebook, FormListbook
 from gui_core.widgets import FloatValidator, GNotebook, FormNotebook, FormListbook
 
 
 wxUpdateDialog, EVT_DIALOG_UPDATE = NewEvent()
 wxUpdateDialog, EVT_DIALOG_UPDATE = NewEvent()
@@ -456,6 +457,9 @@ class TaskFrame(wx.Frame):
                                       frame = self)
                                       frame = self)
         self._gconsole = self.notebookpanel._gconsole
         self._gconsole = self.notebookpanel._gconsole
         self.goutput = self.notebookpanel.goutput
         self.goutput = self.notebookpanel.goutput
+        if self._gconsole:
+            self._gconsole.mapCreated.connect(self.OnMapCreated)
+
         self.notebookpanel.OnUpdateValues = self.updateValuesHook
         self.notebookpanel.OnUpdateValues = self.updateValuesHook
         guisizer.Add(item = self.notebookpanel, proportion = 1, flag = wx.EXPAND)
         guisizer.Add(item = self.notebookpanel, proportion = 1, flag = wx.EXPAND)
         
         
@@ -558,7 +562,6 @@ class TaskFrame(wx.Frame):
         # bindings
         # bindings
         self.Bind(wx.EVT_CLOSE,  self.OnCancel)
         self.Bind(wx.EVT_CLOSE,  self.OnCancel)
         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
-        self.Bind(EVT_MAP_CREATED, self.OnMapCreated)
         
         
         # do layout
         # do layout
         # called automatically by SetSizer()
         # called automatically by SetSizer()
@@ -650,12 +653,12 @@ class TaskFrame(wx.Frame):
             # was closed also when aborted but better is leave it open
             # was closed also when aborted but better is leave it open
             wx.FutureCall(2000, self.Close)
             wx.FutureCall(2000, self.Close)
 
 
-    def OnMapCreated(self, event):
+    def OnMapCreated(self, name, ltype):
         if hasattr(self, "addbox") and self.addbox.IsChecked():
         if hasattr(self, "addbox") and self.addbox.IsChecked():
-            event.add = True
+            add = True
         else:
         else:
-            event.add = False
-        event.Skip()
+            add = False
+        self._giface.mapCreated.emit(name=name, ltype=ltype, add=add)
     
     
     def OnOK(self, event):
     def OnOK(self, event):
         """!OK button pressed"""
         """!OK button pressed"""
@@ -782,7 +785,9 @@ class CmdPanel(wx.Panel):
         self._giface = giface
         self._giface = giface
         
         
         wx.Panel.__init__(self, parent, id = id, *args, **kwargs)
         wx.Panel.__init__(self, parent, id = id, *args, **kwargs)
-        
+
+        self.mapCreated = Signal
+
         # Determine tab layout
         # Determine tab layout
         sections = []
         sections = []
         is_section = {}
         is_section = {}

+ 11 - 4
gui/wxpython/gui_core/goutput.py

@@ -29,8 +29,9 @@ import wx
 from   wx import stc
 from   wx import stc
 from wx.lib.newevent import NewEvent
 from wx.lib.newevent import NewEvent
 
 
+from grass.pydispatch.signal import Signal
+
 from core.gcmd       import GError, EncodeString
 from core.gcmd       import GError, EncodeString
-from core.events     import gShowNotification
 from core.gconsole   import GConsole, \
 from core.gconsole   import GConsole, \
     EVT_CMD_OUTPUT, EVT_CMD_PROGRESS, EVT_CMD_RUN, EVT_CMD_DONE, \
     EVT_CMD_OUTPUT, EVT_CMD_PROGRESS, EVT_CMD_RUN, EVT_CMD_DONE, \
     EVT_WRITE_LOG, EVT_WRITE_CMD_LOG, EVT_WRITE_WARNING, EVT_WRITE_ERROR
     EVT_WRITE_LOG, EVT_WRITE_CMD_LOG, EVT_WRITE_WARNING, EVT_WRITE_ERROR
@@ -80,6 +81,9 @@ class GConsoleWindow(wx.SplitterWindow):
         self._gcstyle = gcstyle
         self._gcstyle = gcstyle
         self.lineWidth       = 80
         self.lineWidth       = 80
 
 
+        # signal which requests showing of a notification
+        self.showNotification = Signal("GConsoleWindow.showNotification")
+
         # progress bar
         # progress bar
         self.progressbar = wx.Gauge(parent = self.panelOutput, id = wx.ID_ANY,
         self.progressbar = wx.Gauge(parent = self.panelOutput, id = wx.ID_ANY,
                                     range = 100, pos = (110, 50), size = (-1, 25),
                                     range = 100, pos = (110, 50), size = (-1, 25),
@@ -121,6 +125,7 @@ class GConsoleWindow(wx.SplitterWindow):
         self.cmdPrompt.Bind(EVT_GPROMPT_RUN_CMD, 
         self.cmdPrompt.Bind(EVT_GPROMPT_RUN_CMD, 
                             lambda event:
                             lambda event:
                                 self._gconsole.RunCmd(command = event.cmd))
                                 self._gconsole.RunCmd(command = event.cmd))
+        self.cmdPrompt.showNotification.connect(self.showNotification)
 
 
         if not self._gcstyle & GC_PROMPT:
         if not self._gcstyle & GC_PROMPT:
             self.cmdPrompt.Hide()
             self.cmdPrompt.Hide()
@@ -259,7 +264,9 @@ class GConsoleWindow(wx.SplitterWindow):
         
         
         self.search = SearchModuleWidget(parent = pane,
         self.search = SearchModuleWidget(parent = pane,
                                          modulesData = modulesData)
                                          modulesData = modulesData)
-        
+
+        self.search.showNotification.connect(self.showNotification)
+
         border.Add(item = self.search, proportion = 0,
         border.Add(item = self.search, proportion = 0,
                    flag = wx.EXPAND | wx.ALL, border = 1)
                    flag = wx.EXPAND | wx.ALL, border = 1)
         
         
@@ -391,7 +398,7 @@ class GConsoleWindow(wx.SplitterWindow):
             finally:
             finally:
                 output.close()
                 output.close()
             message = _("Commands output saved into '%s'") % path
             message = _("Commands output saved into '%s'") % path
-            wx.PostEvent(self, gShowNotification(self.GetId(), message = message))
+            self.showNotification.emit(message = message)
         
         
         dlg.Destroy()
         dlg.Destroy()
 
 
@@ -444,7 +451,7 @@ class GConsoleWindow(wx.SplitterWindow):
             output.close()
             output.close()
         
         
         message = _("Commands protocol saved into '%s'") % self.cmdFileProtocol
         message = _("Commands protocol saved into '%s'") % self.cmdFileProtocol
-        wx.PostEvent(self, gShowNotification(self.GetId(), message = message))
+        self.showNotification.emit(message = message)
         del self.cmdFileProtocol
         del self.cmdFileProtocol
         
         
     def OnCmdProtocol(self, event = None):
     def OnCmdProtocol(self, event = None):

+ 19 - 16
gui/wxpython/gui_core/mapdisp.py

@@ -27,7 +27,6 @@ import wx.aui
 
 
 from core        import globalvar
 from core        import globalvar
 from core.debug  import Debug
 from core.debug  import Debug
-from core.events import EVT_ZOOM_CHANGED
 
 
 from grass.script import core as grass
 from grass.script import core as grass
 
 
@@ -56,7 +55,7 @@ class MapFrameBase(wx.Frame):
                  style = wx.DEFAULT_FRAME_STYLE,
                  style = wx.DEFAULT_FRAME_STYLE,
                  auimgr = None, name = None, **kwargs):
                  auimgr = None, name = None, **kwargs):
         """!
         """!
-        
+
         @warning Use \a auimgr parameter only if you know what you are doing.
         @warning Use \a auimgr parameter only if you know what you are doing.
         
         
         @param parent gui parent
         @param parent gui parent
@@ -529,28 +528,30 @@ class DoubleMapFrame(MapFrameBase):
     
     
     def ActivateFirstMap(self, event = None):
     def ActivateFirstMap(self, event = None):
         """!Make first Map and MapWindow active and (un)bind regions of the two Maps."""
         """!Make first Map and MapWindow active and (un)bind regions of the two Maps."""
+        if self.MapWindow == self.firstMapWindow:
+            return
+
         self.Map = self.firstMap
         self.Map = self.firstMap
         self.MapWindow = self.firstMapWindow
         self.MapWindow = self.firstMapWindow
         self.GetMapToolbar().SetActiveMap(0)
         self.GetMapToolbar().SetActiveMap(0)
 
 
         # bind/unbind regions
         # bind/unbind regions
         if self._bindRegions:
         if self._bindRegions:
-            self.firstMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedFirstMap)
-        else:
-            self.firstMapWindow.Unbind(EVT_ZOOM_CHANGED)
-        self.secondMapWindow.Unbind(EVT_ZOOM_CHANGED)
+            self.firstMapWindow.zoomChanged.connect(self.OnZoomChangedFirstMap)
+            self.secondMapWindow.zoomChanged.disconnect(self.OnZoomChangedSecondMap)
 
 
     def ActivateSecondMap(self, event = None):
     def ActivateSecondMap(self, event = None):
         """!Make second Map and MapWindow active and (un)bind regions of the two Maps."""
         """!Make second Map and MapWindow active and (un)bind regions of the two Maps."""
+        if self.MapWindow == self.secondMapWindow:
+            return        
+
         self.Map = self.secondMap
         self.Map = self.secondMap
         self.MapWindow = self.secondMapWindow
         self.MapWindow = self.secondMapWindow
         self.GetMapToolbar().SetActiveMap(1)
         self.GetMapToolbar().SetActiveMap(1)
 
 
         if self._bindRegions:
         if self._bindRegions:
-            self.secondMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedSecondMap)
-        else:
-            self.secondMapWindow.Unbind(EVT_ZOOM_CHANGED)
-        self.firstMapWindow.Unbind(EVT_ZOOM_CHANGED)
+            self.secondMapWindow.zoomChanged.connect(self.OnZoomChangedSecondMap)
+            self.firstMapWindow.zoomChanged.disconnect(self.OnZoomChangedFirstMap)
 
 
     def SetBindRegions(self, on):
     def SetBindRegions(self, on):
         """!Set or unset binding display regions."""
         """!Set or unset binding display regions."""
@@ -558,14 +559,16 @@ class DoubleMapFrame(MapFrameBase):
 
 
         if on:
         if on:
             if self.MapWindow == self.firstMapWindow:
             if self.MapWindow == self.firstMapWindow:
-                self.firstMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedFirstMap)
+                self.firstMapWindow.zoomChanged.connect(self.OnZoomChangedFirstMap)
             else:
             else:
-                self.secondMapWindow.Bind(EVT_ZOOM_CHANGED, self.OnZoomChangedSecondMap)
+                self.secondMapWindow.zoomChanged.connect(self.OnZoomChangedSecondMap)
         else:
         else:
-            self.firstMapWindow.Unbind(EVT_ZOOM_CHANGED)
-            self.secondMapWindow.Unbind(EVT_ZOOM_CHANGED)
+            if self.MapWindow == self.firstMapWindow:
+                self.firstMapWindow.zoomChanged.disconnect(self.OnZoomChangedFirstMap)
+            else:
+                self.secondMapWindow.zoomChanged.disconnect(self.OnZoomChangedSecondMap)
 
 
-    def OnZoomChangedFirstMap(self, event):
+    def OnZoomChangedFirstMap(self):
         """!Display region of the first window (Map) changed.
         """!Display region of the first window (Map) changed.
 
 
         Synchronize the region of the second map and re-render it.
         Synchronize the region of the second map and re-render it.
@@ -575,7 +578,7 @@ class DoubleMapFrame(MapFrameBase):
         self.GetSecondMap().region.update(region)
         self.GetSecondMap().region.update(region)
         self.Render(mapToRender = self.GetSecondWindow())
         self.Render(mapToRender = self.GetSecondWindow())
 
 
-    def OnZoomChangedSecondMap(self, event):
+    def OnZoomChangedSecondMap(self):
         """!Display region of the second window (Map) changed.
         """!Display region of the second window (Map) changed.
 
 
         Synchronize the region of the second map and re-render it.
         Synchronize the region of the second map and re-render it.

+ 4 - 6
gui/wxpython/gui_core/menu.py

@@ -27,7 +27,6 @@ from core              import utils
 from core.modulesdata  import ModulesData
 from core.modulesdata  import ModulesData
 from core.gcmd         import EncodeString
 from core.gcmd         import EncodeString
 from core.settings     import UserSettings
 from core.settings     import UserSettings
-from core.events       import EVT_SHOW_NOTIFICATION
 from gui_core.widgets  import ItemTree, SearchModuleWidget
 from gui_core.widgets  import ItemTree, SearchModuleWidget
 from lmgr.menudata     import LayerManagerMenuData
 from lmgr.menudata     import LayerManagerMenuData
 
 
@@ -155,14 +154,13 @@ class SearchModuleWindow(wx.Panel):
         self.tree.Bind(wx.EVT_TREE_SEL_CHANGED,    self.OnItemSelected)
         self.tree.Bind(wx.EVT_TREE_SEL_CHANGED,    self.OnItemSelected)
         self.search.GetCtrl().Bind(wx.EVT_TEXT,    self.OnUpdateStatusBar)
         self.search.GetCtrl().Bind(wx.EVT_TEXT,    self.OnUpdateStatusBar)
         self.search.GetCtrl().Bind(wx.EVT_KEY_UP,  self.OnKeyUp)
         self.search.GetCtrl().Bind(wx.EVT_KEY_UP,  self.OnKeyUp)
-        
-        # stop propagation of event
+
         # because number of matched items differs
         # because number of matched items differs
         # from number of matched items in tree
         # from number of matched items in tree
         # TODO: find the reason for this difference
         # TODO: find the reason for this difference
-        # TODO: use this event for updating statusbar (i.e., don't do this bind)
-        self.Bind(EVT_SHOW_NOTIFICATION, lambda event: None)
-        
+        # TODO: use this event for updating statusbar
+        # TODO: some showNotification usage?
+
         self._layout()
         self._layout()
         
         
         self.search.SetFocus()
         self.search.SetFocus()

+ 8 - 8
gui/wxpython/gui_core/prompt.py

@@ -29,10 +29,11 @@ from wx.lib.newevent import NewEvent
 from grass.script import core as grass
 from grass.script import core as grass
 from grass.script import task as gtask
 from grass.script import task as gtask
 
 
+from grass.pydispatch.signal import Signal
+
 from core          import globalvar
 from core          import globalvar
 from core          import utils
 from core          import utils
 from core.gcmd     import EncodeString, DecodeString, GetRealCmd
 from core.gcmd     import EncodeString, DecodeString, GetRealCmd
-from core.events   import gShowNotification
 
 
 gPromptRunCmd, EVT_GPROMPT_RUN_CMD = NewEvent()
 gPromptRunCmd, EVT_GPROMPT_RUN_CMD = NewEvent()
 
 
@@ -197,7 +198,10 @@ class GPromptSTC(GPrompt, wx.stc.StyledTextCtrl):
         self.Bind(wx.stc.EVT_STC_AUTOCOMP_SELECTION, self.OnItemSelected)
         self.Bind(wx.stc.EVT_STC_AUTOCOMP_SELECTION, self.OnItemSelected)
         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemChanged)
         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemChanged)
         self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
         self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
-        
+
+        # signal which requests showing of a notification
+        self.showNotification = Signal('GPromptSTC.showNotification')
+
     def OnTextSelectionChanged(self, event):
     def OnTextSelectionChanged(self, event):
         """!Copy selected text to clipboard and skip event.
         """!Copy selected text to clipboard and skip event.
         The same function is in GStc class (goutput.py).
         The same function is in GStc class (goutput.py).
@@ -586,12 +590,8 @@ class GPromptSTC(GPrompt, wx.stc.StyledTextCtrl):
             event.Skip()
             event.Skip()
 
 
     def ShowStatusText(self, text):
     def ShowStatusText(self, text):
-        """!Sets statusbar text, if it's too long, it is cut off"""
-        # event is not propagated beyond dialog
-        # thus when GPrompt in Modeler is inside a dialog, 
-        # it does not show text in modeler statusbar which is probably
-        # the right behaviour. The dialog itself should display the text.
-        wx.PostEvent(self, gShowNotification(self.GetId(), message = text))
+        """!Requests showing of notification, e.g. showing in a statusbar."""
+        self.showNotification.emit(message=text)
         
         
     def GetTextLeft(self):
     def GetTextLeft(self):
         """!Returns all text left of the caret"""
         """!Returns all text left of the caret"""

+ 7 - 4
gui/wxpython/gui_core/widgets.py

@@ -49,10 +49,11 @@ try:
 except ImportError:
 except ImportError:
     import wx.lib.customtreectrl as CT
     import wx.lib.customtreectrl as CT
 
 
+from grass.pydispatch.signal import Signal
+
 from core        import globalvar
 from core        import globalvar
 from core.gcmd   import GMessage
 from core.gcmd   import GMessage
 from core.debug  import Debug
 from core.debug  import Debug
-from core.events import gShowNotification
 
 
 from wx.lib.newevent import NewEvent
 from wx.lib.newevent import NewEvent
 wxSymbolSelectionChanged, EVT_SYMBOL_SELECTION_CHANGED  = NewEvent()
 wxSymbolSelectionChanged, EVT_SYMBOL_SELECTION_CHANGED  = NewEvent()
@@ -861,7 +862,10 @@ class SearchModuleWidget(wx.Panel):
         self._searchDict = { _('description') : 'description',
         self._searchDict = { _('description') : 'description',
                              _('command') : 'command',
                              _('command') : 'command',
                              _('keywords') : 'keywords' }
                              _('keywords') : 'keywords' }
-        
+
+        # signal which requests showing of a notification
+        self.showNotification = Signal('SearchModuleWidget.showNotification')
+
         self.box = wx.StaticBox(parent = self, id = wx.ID_ANY,
         self.box = wx.StaticBox(parent = self, id = wx.ID_ANY,
                                 label = " %s " % _("Find module - (press Enter for next match)"))
                                 label = " %s " % _("Find module - (press Enter for next match)"))
 
 
@@ -949,8 +953,7 @@ class SearchModuleWidget(wx.Panel):
         if self.showTip:
         if self.showTip:
             self.searchTip.SetLabel(label)
             self.searchTip.SetLabel(label)
 
 
-        newEvent = gShowNotification(self.GetId(), message = label)
-        wx.PostEvent(self, newEvent)
+        self.showNotification.emit(message=label)
 
 
         event.Skip()
         event.Skip()
 
 

+ 13 - 9
gui/wxpython/lmgr/frame.py

@@ -43,7 +43,6 @@ from grass.script          import core as grass
 from core.gcmd             import RunCommand, GError, GMessage, GException
 from core.gcmd             import RunCommand, GError, GMessage, GException
 from core.settings         import UserSettings, GetDisplayVectSettings
 from core.settings         import UserSettings, GetDisplayVectSettings
 from core.utils            import SetAddOnPath, GetLayerNameFromCmd, command2ltype
 from core.utils            import SetAddOnPath, GetLayerNameFromCmd, command2ltype
-from core.events           import EVT_SHOW_NOTIFICATION, EVT_MAP_CREATED
 from gui_core.preferences  import MapsetAccess, PreferencesDialog, EVT_SETTINGS_CHANGED
 from gui_core.preferences  import MapsetAccess, PreferencesDialog, EVT_SETTINGS_CHANGED
 from lmgr.layertree        import LayerTree, LMIcons
 from lmgr.layertree        import LayerTree, LMIcons
 from lmgr.menudata         import LayerManagerMenuData
 from lmgr.menudata         import LayerManagerMenuData
@@ -162,9 +161,8 @@ class GMFrame(wx.Frame):
         # bindings
         # bindings
         self.Bind(wx.EVT_CLOSE,    self.OnCloseWindow)
         self.Bind(wx.EVT_CLOSE,    self.OnCloseWindow)
         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
-        self.Bind(EVT_SHOW_NOTIFICATION,
-                  lambda event: self.SetStatusText(event.message))
-        self.Bind(EVT_MAP_CREATED, self.OnMapCreated)
+
+        self._giface.mapCreated.connect(self.OnMapCreated)
 
 
         # minimal frame size
         # minimal frame size
         self.SetMinSize((globalvar.GM_WINDOW_SIZE[0], 400))
         self.SetMinSize((globalvar.GM_WINDOW_SIZE[0], 400))
@@ -278,6 +276,11 @@ class GMFrame(wx.Frame):
         self.goutput = GConsoleWindow(parent = self, gconsole = self._gconsole,
         self.goutput = GConsoleWindow(parent = self, gconsole = self._gconsole,
                                       gcstyle = GC_SEARCH | GC_PROMPT)
                                       gcstyle = GC_SEARCH | GC_PROMPT)
         self.notebook.AddPage(page = self.goutput, text = _("Command console"), name = 'output')
         self.notebook.AddPage(page = self.goutput, text = _("Command console"), name = 'output')
+
+        self.goutput.showNotification.connect(lambda message: self.SetStatusText(message))
+
+        self._gconsole.mapCreated.connect(self.OnMapCreated)
+
         # EVT_CMD_OUTPUT and EVT_GC_CONTENT_CHANGED are similar but should be distinct
         # EVT_CMD_OUTPUT and EVT_GC_CONTENT_CHANGED are similar but should be distinct
         # (logging/messages may be splited from GConsole commad running interface)
         # (logging/messages may be splited from GConsole commad running interface)
         # thus, leaving this bind here
         # thus, leaving this bind here
@@ -1448,6 +1451,7 @@ class GMFrame(wx.Frame):
                 cmd = ['r.mapcalc']
                 cmd = ['r.mapcalc']
         
         
         win = MapCalcFrame(parent = self,
         win = MapCalcFrame(parent = self,
+                           giface = self._giface,
                            cmd = cmd[0])
                            cmd = cmd[0])
         win.CentreOnScreen()
         win.CentreOnScreen()
         win.Show()
         win.Show()
@@ -1663,14 +1667,14 @@ class GMFrame(wx.Frame):
                                        lcmd = cmd,
                                        lcmd = cmd,
                                        lgroup = None)
                                        lgroup = None)
 
 
-    def OnMapCreated(self, event):
+    def OnMapCreated(self, name, ltype, add=None):
         """!Decides wheter the map should be added to layer tree."""
         """!Decides wheter the map should be added to layer tree."""
-        if event.add is None:
+        if add is None:
             if UserSettings.Get(group = 'cmd',
             if UserSettings.Get(group = 'cmd',
                                 key = 'addNewLayer', subkey = 'enabled'):
                                 key = 'addNewLayer', subkey = 'enabled'):
-                self.AddOrUpdateMap(event.name, event.ltype)
-        elif event.add:
-            self.AddOrUpdateMap(event.name, event.ltype)
+                self.AddOrUpdateMap(name, ltype)
+        elif add:
+            self.AddOrUpdateMap(name, ltype)
 
 
     def AddOrUpdateMap(self, mapName, ltype):
     def AddOrUpdateMap(self, mapName, ltype):
         """!Add map layer or update"""
         """!Add map layer or update"""

+ 20 - 5
gui/wxpython/lmgr/giface.py

@@ -15,6 +15,7 @@ This program is free software under the GNU General Public License
 @author Vaclav Petras <wenzeslaus gmail.com>
 @author Vaclav Petras <wenzeslaus gmail.com>
 """
 """
 
 
+from grass.pydispatch.signal import Signal
 
 
 class Layer(object):
 class Layer(object):
     """!@implements core::giface::Layer
     """!@implements core::giface::Layer
@@ -64,6 +65,14 @@ class LayerManagerGrassInterface(object):
         """
         """
         self.lmgr = lmgr
         self.lmgr = lmgr
 
 
+        # Signal when some map is created or updated by a module.
+        # attributes: name: map name, ltype: map type,
+        # add: if map should be added to layer tree (questionable attribute)
+        self.mapCreated = Signal('LayerManagerGrassInterface.mapCreated')
+
+        # Signal emitted to request updating of map
+        self.updateMap = Signal('LayerManagerGrassInterface.updateMap')
+
     def RunCmd(self, *args, **kwargs):
     def RunCmd(self, *args, **kwargs):
         self.lmgr._gconsole.RunCmd(*args, **kwargs)
         self.lmgr._gconsole.RunCmd(*args, **kwargs)
 
 
@@ -107,18 +116,21 @@ class LayerManagerGrassInterface(object):
         return self.lmgr.goutput.GetProgressBar()
         return self.lmgr.goutput.GetProgressBar()
 
 
 
 
-class LayerManagerGrassInterfaceForMapDisplay(LayerManagerGrassInterface):
+class LayerManagerGrassInterfaceForMapDisplay(object):
     """!Provides reference only to the given layer list (according to tree),
     """!Provides reference only to the given layer list (according to tree),
         not to the current.
         not to the current.
     """
     """
-    def __init__(self, lmgr, tree):
+    def __init__(self, giface, tree):
         """!
         """!
-        @lmgr layer manager
-        @tree tree which will be used instead of the lmgr.tree
+        @giface original grass interface
+        @tree tree which will be used instead of the tree from giface
         """
         """
-        LayerManagerGrassInterface.__init__(self, lmgr)
+        self._giface = giface
         self.tree = tree
         self.tree = tree
 
 
+        # Signal emitted to request updating of map
+        self.updateMap = Signal('LayerManagerGrassInterfaceForMapDisplay.updateMap')
+
     def GetLayerTree(self):
     def GetLayerTree(self):
         return self.tree
         return self.tree
 
 
@@ -127,3 +139,6 @@ class LayerManagerGrassInterfaceForMapDisplay(LayerManagerGrassInterface):
 
 
     def GetMapWindow(self):
     def GetMapWindow(self):
         return self.tree.GetMapDisplay()
         return self.tree.GetMapDisplay()
+
+    def __getattr__(self, name):
+        return getattr(self._giface, name)

+ 1 - 1
gui/wxpython/lmgr/layertree.py

@@ -155,7 +155,7 @@ class LayerTree(treemixin.DragAndDrop, CT.CustomTreeCtrl):
         
         
         # init associated map display
         # init associated map display
         pos = wx.Point((self.displayIndex + 1) * 25, (self.displayIndex + 1) * 25)
         pos = wx.Point((self.displayIndex + 1) * 25, (self.displayIndex + 1) * 25)
-        gifaceForDisplay = LayerManagerGrassInterfaceForMapDisplay(self.lmgr,
+        gifaceForDisplay = LayerManagerGrassInterfaceForMapDisplay(self._giface,
                                                                    self)
                                                                    self)
         self.mapdisplay = MapFrame(self, giface = gifaceForDisplay,
         self.mapdisplay = MapFrame(self, giface = gifaceForDisplay,
                                    id = wx.ID_ANY, pos = pos,
                                    id = wx.ID_ANY, pos = pos,

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

@@ -1293,7 +1293,7 @@ class MapFrame(SingleMapFrame):
             return
             return
         
         
         from vnet.dialogs import VNETDialog
         from vnet.dialogs import VNETDialog
-        self.dialogs['vnet'] = VNETDialog(parent = self)
+        self.dialogs['vnet'] = VNETDialog(parent=self, giface=self._giface)
         self.dialogs['vnet'].CenterOnScreen()
         self.dialogs['vnet'].CenterOnScreen()
         self.dialogs['vnet'].Show()
         self.dialogs['vnet'].Show()
             
             

+ 11 - 8
gui/wxpython/mapdisp/main.py

@@ -38,7 +38,6 @@ from core          import utils
 from core.giface   import StandaloneGrassInterface
 from core.giface   import StandaloneGrassInterface
 from core.gcmd     import RunCommand
 from core.gcmd     import RunCommand
 from core.render   import Map, MapLayer
 from core.render   import Map, MapLayer
-from core.events   import gUpdateMap
 from mapdisp.frame import MapFrame
 from mapdisp.frame import MapFrame
 from grass.script  import core as grass
 from grass.script  import core as grass
 from core.debug    import Debug
 from core.debug    import Debug
@@ -56,7 +55,7 @@ monSize = list(globalvar.MAP_WINDOW_SIZE)
 
 
 
 
 class DMonMap(Map):
 class DMonMap(Map):
-    def __init__(self, cmdfile=None, mapfile=None):
+    def __init__(self, giface, cmdfile=None, mapfile=None):
         """!Map composition (stack of map layers and overlays)
         """!Map composition (stack of map layers and overlays)
 
 
         @param cmdline full path to the cmd file (defined by d.mon)
         @param cmdline full path to the cmd file (defined by d.mon)
@@ -65,6 +64,8 @@ class DMonMap(Map):
 
 
         Map.__init__(self)
         Map.__init__(self)
 
 
+        self._giface = giface
+
         # environment settings
         # environment settings
         self.env   = dict()
         self.env   = dict()
 
 
@@ -125,8 +126,7 @@ class DMonMap(Map):
         fd.close()
         fd.close()
 
 
         if nlayers:
         if nlayers:
-            event = gUpdateMap()
-            wx.PostEvent(self.receiver, event)
+            self._giface.updateMap.emit()
 
 
         Debug.msg(1, "Map.GetLayersFromCmdFile(): cmdfile=%s" % self.cmdfile)
         Debug.msg(1, "Map.GetLayersFromCmdFile(): cmdfile=%s" % self.cmdfile)
         Debug.msg(1, "                            nlayers=%d" % nlayers)
         Debug.msg(1, "                            nlayers=%d" % nlayers)
@@ -232,15 +232,18 @@ class MapApp(wx.App):
     def OnInit(self):
     def OnInit(self):
         if not globalvar.CheckWxVersion([2, 9]):
         if not globalvar.CheckWxVersion([2, 9]):
             wx.InitAllImageHandlers()
             wx.InitAllImageHandlers()
+
+        # actual use of StandaloneGrassInterface not yet tested
+        # needed for adding functionality in future
+        giface = DMonGrassInterface(None)
+
         if __name__ == "__main__":
         if __name__ == "__main__":
             self.cmdTimeStamp = os.path.getmtime(monFile['cmd'])
             self.cmdTimeStamp = os.path.getmtime(monFile['cmd'])
-            self.Map = DMonMap(cmdfile = monFile['cmd'], mapfile = monFile['map'])
+            self.Map = DMonMap(giface=giface, cmdfile=monFile['cmd'],
+                               mapfile = monFile['map'])
         else:
         else:
             self.Map = None
             self.Map = None
 
 
-        # actual use of StandaloneGrassInterface not yet tested
-        # needed for adding functionality in future
-        giface = DMonGrassInterface(None)
         self.mapFrm = DMonFrame(parent = None, id = wx.ID_ANY, Map = self.Map,
         self.mapFrm = DMonFrame(parent = None, id = wx.ID_ANY, Map = self.Map,
                                 giface = giface, size = monSize)
                                 giface = giface, size = monSize)
         # FIXME: hack to solve dependency
         # FIXME: hack to solve dependency

+ 13 - 6
gui/wxpython/mapdisp/mapwindow.py

@@ -28,13 +28,15 @@ from copy import copy
 
 
 import wx
 import wx
 
 
+from grass.pydispatch.signal import Signal
+
 import grass.script as grass
 import grass.script as grass
 
 
 from gui_core.dialogs   import SavedRegion
 from gui_core.dialogs   import SavedRegion
 from core.gcmd          import RunCommand, GException, GError, GMessage
 from core.gcmd          import RunCommand, GException, GError, GMessage
 from core.debug         import Debug
 from core.debug         import Debug
 from core.settings      import UserSettings
 from core.settings      import UserSettings
-from core.events        import gZoomChanged, EVT_UPDATE_MAP
+from core.events        import EVT_UPDATE_MAP
 from gui_core.mapwindow import MapWindow
 from gui_core.mapwindow import MapWindow
 from core.ws            import EVT_UPDATE_PRGBAR
 from core.ws            import EVT_UPDATE_PRGBAR
 from core.utils         import GetGEventAttribsForHandler
 from core.utils         import GetGEventAttribsForHandler
@@ -77,7 +79,12 @@ class BufferedWindow(MapWindow, wx.Window):
         self.lineid = None
         self.lineid = None
         # ID of poly line resulting from cumulative rubber band lines (e.g. measurement)
         # ID of poly line resulting from cumulative rubber band lines (e.g. measurement)
         self.plineid = None
         self.plineid = None
-        
+
+        # Emitted when zoom of a window is changed
+        self.zoomChanged = Signal('BufferedWindow.zoomChanged')
+
+        self._giface.updateMap.connect(self.UpdateMap)
+
         # event bindings
         # event bindings
         self.Bind(wx.EVT_PAINT,           self.OnPaint)
         self.Bind(wx.EVT_PAINT,           self.OnPaint)
         self.Bind(wx.EVT_SIZE,            self.OnSize)
         self.Bind(wx.EVT_SIZE,            self.OnSize)
@@ -603,9 +610,9 @@ class BufferedWindow(MapWindow, wx.Window):
         underlaying images or to the geometry of the canvas.
         underlaying images or to the geometry of the canvas.
         
         
         This method should not be called directly.
         This method should not be called directly.
-        Post core.events.gUpdateMap event to instance of this class. 
 
 
-        @todo change direct calling of UpdateMap method to posting core.events.gUpdateMap
+        @todo change direct calling of UpdateMap method to emittig grass
+        interface updateMap signal
 
 
         @param render re-render map composition
         @param render re-render map composition
         @param renderVector re-render vector map layer enabled for editing (used for digitizer)
         @param renderVector re-render vector map layer enabled for editing (used for digitizer)
@@ -1521,7 +1528,7 @@ class BufferedWindow(MapWindow, wx.Window):
         # update statusbar
         # update statusbar
         self.frame.StatusbarUpdate()
         self.frame.StatusbarUpdate()
 
 
-        wx.PostEvent(self, gZoomChanged())
+        self.zoomChanged.emit()
 
 
     def ZoomHistory(self, n, s, e, w):
     def ZoomHistory(self, n, s, e, w):
         """!Manages a list of last 10 zoom extents
         """!Manages a list of last 10 zoom extents
@@ -1553,7 +1560,7 @@ class BufferedWindow(MapWindow, wx.Window):
         
         
         toolbar.Enable('zoomBack', enable)
         toolbar.Enable('zoomBack', enable)
 
 
-        wx.PostEvent(self, gZoomChanged())
+        self.zoomChanged.emit()
         
         
         return removed
         return removed
 
 

+ 7 - 9
gui/wxpython/modules/extensions.py

@@ -33,7 +33,6 @@ from grass.script import task as gtask
 from core             import globalvar
 from core             import globalvar
 from core.gcmd        import GError, RunCommand
 from core.gcmd        import GError, RunCommand
 from core.utils       import SetAddOnPath
 from core.utils       import SetAddOnPath
-from core.events      import EVT_SHOW_NOTIFICATION
 from gui_core.forms   import GUI
 from gui_core.forms   import GUI
 from gui_core.widgets import ItemTree, GListCtrl, SearchModuleWidget, EVT_MODULE_SELECTED
 from gui_core.widgets import ItemTree, GListCtrl, SearchModuleWidget, EVT_MODULE_SELECTED
 
 
@@ -150,7 +149,9 @@ class InstallExtensionWindow(wx.Frame):
                                          showChoice = False)
                                          showChoice = False)
         self.search.SetSelection(0)
         self.search.SetSelection(0)
         self.search.Bind(EVT_MODULE_SELECTED, self.OnShowItem)
         self.search.Bind(EVT_MODULE_SELECTED, self.OnShowItem)
-        
+        # show text in statusbar when notification appears
+        self.search.showNotification.connect(lambda message: self.SetStatusText(message))
+
         self.optionBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
         self.optionBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
                                       label = " %s " % _("Options"))
                                       label = " %s " % _("Options"))
         if sys.platform == 'win32':
         if sys.platform == 'win32':
@@ -193,13 +194,7 @@ class InstallExtensionWindow(wx.Frame):
         self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
         self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnItemActivated)
         self.tree.Bind(wx.EVT_TREE_SEL_CHANGED,    self.OnItemSelected)
         self.tree.Bind(wx.EVT_TREE_SEL_CHANGED,    self.OnItemSelected)
         self.search.Bind(wx.EVT_TEXT_ENTER,        self.OnShowItem)
         self.search.Bind(wx.EVT_TEXT_ENTER,        self.OnShowItem)
-        self.search.Bind(wx.EVT_TEXT,              self.OnUpdateStatusBar)
 
 
-        # show text in statusbar when notification command event occurs
-        # propagation stops here, no need to show text twice
-        self.Bind(EVT_SHOW_NOTIFICATION,
-                  lambda event: self.SetStatusText(event.message))
-        
         wx.CallAfter(self._fetch)
         wx.CallAfter(self._fetch)
         
         
         self._layout()
         self._layout()
@@ -271,7 +266,10 @@ class InstallExtensionWindow(wx.Frame):
                                           'svnurl=' + self.repo.GetValue().strip()]
                                           'svnurl=' + self.repo.GetValue().strip()]
     
     
     def OnUpdateStatusBar(self, event):
     def OnUpdateStatusBar(self, event):
-        """!Update statusbar text"""
+        """!Update statusbar text
+
+        @todo This method is a dead code. Is it useful?
+        """
         element = self.search.GetSelection()
         element = self.search.GetSelection()
         if not self.tree.IsLoaded():
         if not self.tree.IsLoaded():
             self.SetStatusText(_("Fetch list of available extensions by clicking on 'Fetch' button"), 0)
             self.SetStatusText(_("Fetch list of available extensions by clicking on 'Fetch' button"), 0)

+ 9 - 7
gui/wxpython/modules/mcalc_builder.py

@@ -27,7 +27,6 @@ if __name__ == "__main__":
 
 
 from core             import globalvar
 from core             import globalvar
 from core.gcmd        import GError, RunCommand
 from core.gcmd        import GError, RunCommand
-from core.events      import gMapCreated
 from gui_core.gselect import Select
 from gui_core.gselect import Select
 from gui_core.forms   import GUI
 from gui_core.forms   import GUI
 from core.settings    import UserSettings
 from core.settings    import UserSettings
@@ -36,9 +35,11 @@ class MapCalcFrame(wx.Frame):
     """!Mapcalc Frame class. Calculator-style window to create and run
     """!Mapcalc Frame class. Calculator-style window to create and run
     r(3).mapcalc statements.
     r(3).mapcalc statements.
     """
     """
-    def __init__(self, parent, cmd, id = wx.ID_ANY,
+    def __init__(self, parent, giface, cmd, id = wx.ID_ANY,
                  style = wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER, **kwargs):
                  style = wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER, **kwargs):
         self.parent = parent
         self.parent = parent
+        self._giface = giface
+
         if self.parent:
         if self.parent:
             self.log = self.parent.GetLogWindow()
             self.log = self.parent.GetLogWindow()
         else:
         else:
@@ -59,7 +60,7 @@ class MapCalcFrame(wx.Frame):
         
         
         self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
         self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
         self.CreateStatusBar()
         self.CreateStatusBar()
-        
+
         #
         #
         # variables
         # variables
         #
         #
@@ -503,16 +504,17 @@ class MapCalcFrame(wx.Frame):
                        overwrite = overwrite)
                        overwrite = overwrite)
         
         
     def OnDone(self, cmd, returncode):
     def OnDone(self, cmd, returncode):
-        """!Add create map to the layer tree"""
+        """!Add create map to the layer tree
+
+        Sends the mapCreated signal from the grass interface.
+        """
         if returncode != 0:
         if returncode != 0:
             return
             return
         name = self.newmaptxt.GetValue().strip(' "') + '@' + grass.gisenv()['MAPSET']
         name = self.newmaptxt.GetValue().strip(' "') + '@' + grass.gisenv()['MAPSET']
         ltype = 'rast'
         ltype = 'rast'
         if self.rast3d:
         if self.rast3d:
             ltype = 'rast3d'
             ltype = 'rast3d'
-        mapEvent = gMapCreated(self.GetId(),
-                               name=name, ltype=ltype, add=self.addbox.IsChecked())
-        wx.PostEvent(self, mapEvent)
+        self._giface.mapCreated.emit(name=name, ltype=ltype, add=self.addbox.IsChecked())
 
 
     def OnSaveExpression(self, event):
     def OnSaveExpression(self, event):
         """!Saves expression to file
         """!Saves expression to file

+ 2 - 1
gui/wxpython/vnet/dialogs.py

@@ -62,7 +62,7 @@ from vnet.toolbars    import MainToolbar, PointListToolbar, AnalysisToolbar
 #   it's destructor is not called
 #   it's destructor is not called
 
 
 class VNETDialog(wx.Dialog):
 class VNETDialog(wx.Dialog):
-    def __init__(self, parent,
+    def __init__(self, parent, giface,
                  id = wx.ID_ANY, title = _("GRASS GIS Vector Network Analysis Tool"),
                  id = wx.ID_ANY, title = _("GRASS GIS Vector Network Analysis Tool"),
                  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
                  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
         """!Dialog for vector network analysis"""
         """!Dialog for vector network analysis"""
@@ -72,6 +72,7 @@ class VNETDialog(wx.Dialog):
 
 
         self.parent  = parent  # mapdisp.frame MapFrame class
         self.parent  = parent  # mapdisp.frame MapFrame class
         self.mapWin = parent.MapWindow 
         self.mapWin = parent.MapWindow 
+        self._giface = giface
 
 
         # contains current analysis result (do not have to be last one, when history is browsed), 
         # contains current analysis result (do not have to be last one, when history is browsed), 
         # it is instance of VectMap class
         # it is instance of VectMap class