[GRASS-SVN] r57082 - in grass/trunk/gui/wxpython: core gui_core lmgr mapdisp web_services

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Jul 13 09:06:32 PDT 2013


Author: annakrat
Date: 2013-07-13 09:06:32 -0700 (Sat, 13 Jul 2013)
New Revision: 57082

Modified:
   grass/trunk/gui/wxpython/core/render.py
   grass/trunk/gui/wxpython/core/ws.py
   grass/trunk/gui/wxpython/gui_core/mapwindow.py
   grass/trunk/gui/wxpython/lmgr/frame.py
   grass/trunk/gui/wxpython/lmgr/giface.py
   grass/trunk/gui/wxpython/mapdisp/frame.py
   grass/trunk/gui/wxpython/mapdisp/mapwindow.py
   grass/trunk/gui/wxpython/mapdisp/statusbar.py
   grass/trunk/gui/wxpython/web_services/dialogs.py
Log:
wxGUI: remove wxUpdateProgress event completely, gUpdateMap partly

Modified: grass/trunk/gui/wxpython/core/render.py
===================================================================
--- grass/trunk/gui/wxpython/core/render.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/core/render.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -35,13 +35,15 @@
 import wx
 
 from grass.script import core as grass
+from grass.pydispatch.signal import Signal
 
 from core          import utils
-from core.ws       import RenderWMSMgr, wxUpdateProgressBar
+from core.ws       import RenderWMSMgr
 from core.gcmd     import GException, GError, RunCommand
 from core.debug    import Debug
 from core.settings import UserSettings
 
+
 USE_GPNMCOMP = True
 
 class Layer(object):
@@ -257,11 +259,9 @@
             raise GException(_("Unsupported map layer type '%s'") % ltype)
         
         if ltype == 'wms' and not isinstance(self.renderMgr, RenderWMSMgr):
-            self.renderMgr = RenderWMSMgr(receiver = self.Map.GetReceiver(),
-                                          layer = self, 
-                                          Map = self.Map, 
-                                          mapfile = self.mapfile, 
-                                          maskfile = self.maskfile)
+            self.renderMgr = RenderWMSMgr(layer=self, 
+                                          mapfile=self.mapfile, 
+                                          maskfile=self.maskfile)
         elif self.type == 'wms' and ltype != 'wms':
             self.renderMgr = None
         
@@ -398,10 +398,10 @@
         # setting some initial env. variables
         self._initGisEnv() # g.gisenv
         self.GetWindow()
+        
+        # info to report progress
+        self.progressInfo = None
 
-        # receiver of events
-        self.receiver = None
-
         # GRASS environment variable (for rendering)
         self.env = {"GRASS_BACKGROUNDCOLOR" : "FFFFFF",
                "GRASS_PNG_COMPRESSION" : "0",
@@ -418,6 +418,9 @@
 
         # is some layer being downloaded?
         self.downloading = False
+        
+        self.layerChanged = Signal('Map.layerChanged')
+        self.updateProgress = Signal('Map.updateProgress')
 
     def _runCommand(self, cmd, **kwargs):
         """!Run command in environment defined by self.gisrc if
@@ -885,9 +888,10 @@
             layers = self.layers + self.overlays
         
         self.downloading = False
-        if self.receiver:
-            event = wxUpdateProgressBar(layer = None, map = self)
-            self.receiver.GetEventHandler().ProcessEvent(event)
+
+        self.ReportProgress(layer=None)
+
+
         for layer in layers:
             # skip non-active map layers
             if not layer or not layer.active:
@@ -899,11 +903,10 @@
                     continue
 
             if layer.IsDownloading():
-                self.downloading = True     
-            if self.receiver:
-                event = wxUpdateProgressBar(layer = layer, map = self)
-                self.receiver.GetEventHandler().ProcessEvent(event) 
+                self.downloading = True 
 
+            self.ReportProgress(layer=layer)
+
             # skip map layers when rendering fails
             if not os.path.exists(layer.mapfile):
                 continue
@@ -915,7 +918,7 @@
                 opacities.append(str(layer.opacity))
             
             Debug.msg(3, "Map.Render() type=%s, layer=%s " % (layer.type, layer.name))
-        
+
         return maps, masks, opacities
         
     def GetMapsMasksAndOpacities(self, force, windres):
@@ -1045,6 +1048,11 @@
             if not layer.Render():
                 raise GException(_("Unable to render map layer <%s>.") % name)
         
+        renderMgr = layer.GetRenderMgr()
+        if renderMgr:
+            renderMgr.dataFetched.connect(self.layerChanged)
+            renderMgr.updateProgress.connect(self.ReportProgress)
+
         wx.EndBusyCursor()
         
         return layer
@@ -1349,21 +1357,54 @@
             if force or layer.forceRender:
                 layer.Render()
 
-    def GetReceiver(self):
-        """!Get event receiver"""
-        return self.receiver
-
-    def SetReceiver(self, receiver):
-        """!Set events receiver
-
-        @todo  If it will be needed to change receiver, take care of running threads.
-        """
-        self.receiver = receiver
-        for l in self.overlays + self.layers:
-            if l.GetRenderMgr():
-                l.GetRenderMgr().SetReceiver(self.receiver)
-
     def AbortAllThreads(self):
         """!Abort all layers threads e. g. donwloading data"""
         for l in self.layers + self.overlays:
             l.AbortThread()
+
+    def ReportProgress(self, layer):
+        """!Calculates progress in rendering/downloading
+        and emits signal to inform progress bar about progress.
+        """
+        if self.progressInfo is None or layer is None:
+            self.progressInfo = {'progresVal' : 0, # current progress value
+                                 'downloading' : [], # layers, which are downloading data
+                                 'rendered' : [], # already rendered layers
+                                 'range' : len(self.GetListOfLayers(active = True)) + 
+                                           len(self.GetListOfLayers(active = True, ltype = 'overlay'))}
+        else:
+            if layer not in self.progressInfo['rendered']:
+                self.progressInfo['rendered'].append(layer)
+            if layer.IsDownloading() and \
+                    layer not in self.progressInfo['downloading']:
+                self.progressInfo['downloading'].append(layer)
+            else:
+                self.progressInfo['progresVal'] += 1
+                if layer in self.progressInfo['downloading']:
+                    self.progressInfo['downloading'].remove(layer)
+            
+        # for updating statusbar text
+        stText = ''
+        first = True
+        for layer in self.progressInfo['downloading']:
+            if first:
+                stText += _("Downloading data ")
+                first = False
+            else:
+                stText += ', '
+            stText += '<%s>' % layer.GetName()
+        if stText:
+            stText += '...'
+        
+        if  self.progressInfo['range'] != len(self.progressInfo['rendered']):
+            if stText:
+                stText = _('Rendering & ') + stText
+            else:
+                stText = _('Rendering...')
+
+        self.updateProgress.emit(range=self.progressInfo['range'],
+                                 value=self.progressInfo['progresVal'],
+                                 text=stText)
+        
+
+        
\ No newline at end of file

Modified: grass/trunk/gui/wxpython/core/ws.py
===================================================================
--- grass/trunk/gui/wxpython/core/ws.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/core/ws.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -25,11 +25,9 @@
 from grass.script import core as grass
 
 from core          import utils
-from core.events   import gUpdateMap
 from core.debug    import Debug
 
 from core.gconsole import CmdThread, GStderr, EVT_CMD_DONE, EVT_CMD_OUTPUT
-from core.gcmd     import GException
 
 try:
     haveGdal = True
@@ -38,18 +36,17 @@
 except ImportError:
     haveGdal = False
 
-wxUpdateProgressBar, EVT_UPDATE_PRGBAR = NewEvent()
+from grass.pydispatch.signal import Signal
 
+
 class RenderWMSMgr(wx.EvtHandler):
     """!Fetch and prepare WMS data for rendering.
     """
-    def __init__(self, receiver, layer, Map, mapfile, maskfile):
+    def __init__(self, layer, mapfile, maskfile):
         if not haveGdal:
             sys.stderr.write(_("Unable to load GDAL Python bindings.\n"\
                                "WMS layers can not be displayed without the bindings.\n"))
-    
-        self.Map = Map
-        self.receiver = receiver
+
         self.layer = layer
 
         wx.EvtHandler.__init__(self)
@@ -71,6 +68,9 @@
         self.dstSize = {}
  
         self.Bind(EVT_CMD_OUTPUT, self.OnCmdOutput)
+        
+        self.dataFetched = Signal('RenderWMSMgr.dataFetched')
+        self.updateProgress = Signal('RenderWMSMgr.updateProgress')
 
     def __del__(self):
         grass.try_remove(self.tempMap)
@@ -160,9 +160,7 @@
             return
         self.downloading = False
         if not self.updateMap:
-            if self.receiver:
-                event = wxUpdateProgressBar(layer = self.layer, map = self.Map)
-                self.receiver.GetEventHandler().ProcessEvent(event) 
+            self.updateProgress.emit(layer=self.layer)
             self.renderedRegion = None
             self.fetched_data_cmd = None
             return
@@ -180,9 +178,7 @@
 
         self.fetched_data_cmd = self.fetching_cmd
 
-        if self.receiver:
-            event = gUpdateMap()
-            wx.PostEvent(self.receiver, event)
+        self.dataFetched.emit()
 
     def _getRegionDict(self):
         """!Parse string from GRASS_REGION env variable into dict.
@@ -247,13 +243,7 @@
         self.updateMap = False
         self.thread.abort(abortall = True)        
 
-    def SetReceiver(self, receiver):
-        """!Set events receiver
 
-        @todo  If it will be needed to change receiver, take care of running threads.
-        """        
-        self.receiver = receiver
-
 class GDALRasterMerger:
     """!Merge rasters.
 

Modified: grass/trunk/gui/wxpython/gui_core/mapwindow.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/mapwindow.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/gui_core/mapwindow.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -41,7 +41,6 @@
         self.Map = Map
         self.frame = frame
         self._giface = giface
-        self.Map.SetReceiver(self)
         
         # mouse attributes -- position on the screen, begin and end of
         # dragging, and type of drawing

Modified: grass/trunk/gui/wxpython/lmgr/frame.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/frame.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/lmgr/frame.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -1522,7 +1522,7 @@
     def OnAddWS(self, event, cmd = None):
         """!Add web services layer"""
         from web_services.dialogs import AddWSDialog
-        dlg = AddWSDialog(parent = self, gmframe = self)
+        dlg = AddWSDialog(parent = self, giface = self._giface)
         dlg.CentreOnScreen()
         x, y = dlg.GetPosition()
         dlg.SetPosition((x, y - 200))

Modified: grass/trunk/gui/wxpython/lmgr/giface.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/giface.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/lmgr/giface.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -153,7 +153,7 @@
         return LayerList(self.tree)
 
     def GetMapWindow(self):
-        return self.tree.GetMapDisplay()
+        return self.tree.GetMapDisplay().GetMapWindow()
 
     def __getattr__(self, name):
         return getattr(self._giface, name)

Modified: grass/trunk/gui/wxpython/mapdisp/frame.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/frame.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/mapdisp/frame.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -38,7 +38,6 @@
 
 from core               import globalvar
 from core.render        import Map
-from core.ws            import EVT_UPDATE_PRGBAR
 from vdigit.toolbars    import VDigitToolbar
 from mapdisp.toolbars   import MapToolbar, NvizIcons
 from mapdisp.gprint     import PrintOptions
@@ -134,6 +133,9 @@
         self.statusbarManager.AddStatusbarItem(sbRender)
         
         self.statusbarManager.Update()
+        
+        #
+        self.Map.updateProgress.connect(self.ProcessProgress)
 
         # init decoration objects
         self.decorations = {}
@@ -181,7 +183,6 @@
         #
         self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
         self.Bind(wx.EVT_CLOSE,    self.OnCloseWindow)
-        self.Bind(EVT_UPDATE_PRGBAR, self.OnUpdateProgress)
         
         #
         # Update fancy gui style
@@ -456,13 +457,6 @@
             return self._mgr.GetPane(name).IsShown()
         return False
         
-    def OnUpdateProgress(self, event):
-        """!Update progress bar info
-        """
-        self.GetProgressBar().UpdateProgress(event.layer, event.map)
-        
-        event.Skip()
-        
     def OnFocus(self, event):
         """!Change choicebook page to match display.
         """
@@ -1358,3 +1352,10 @@
         toolbar.action['id'] = vars(toolbar)["pointer"]
         toolbar.OnTool(None)
         self.OnPointer(event=None)
+
+    def ProcessProgress(self, range, value, text):
+        """!Update progress bar during rendering"""
+        bar = self.statusbarManager.GetProgressBar()
+        bar.SetRange(range)
+        bar.SetValue(value)
+        self.SetStatusText(text)

Modified: grass/trunk/gui/wxpython/mapdisp/mapwindow.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/mapwindow.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/mapdisp/mapwindow.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -38,7 +38,6 @@
 from core.settings      import UserSettings
 from core.events        import EVT_UPDATE_MAP
 from gui_core.mapwindow import MapWindow
-from core.ws            import EVT_UPDATE_PRGBAR
 from core.utils         import GetGEventAttribsForHandler
 
 try:
@@ -102,8 +101,6 @@
         self.Bind(wx.EVT_SIZE,            self.OnSize)
         self.Bind(wx.EVT_IDLE,            self.OnIdle)
         self.Bind(EVT_UPDATE_MAP,         self.OnUpdateMap)
-        if self.frame and hasattr(self.frame, 'OnUpdateProgress'):
-            self.Bind(EVT_UPDATE_PRGBAR,   self.frame.OnUpdateProgress)
 
         self._bindMouseEvents()
         
@@ -140,6 +137,8 @@
         self._buffer = wx.EmptyBitmap(max(1, self.Map.width), max(1, self.Map.height))
         
         self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None)
+        # rerender when Map reports change
+        self.Map.layerChanged.connect(lambda: self.UpdateMap())
         
         # vars for handling mouse clicks
         self.dragid   = -1

Modified: grass/trunk/gui/wxpython/mapdisp/statusbar.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/statusbar.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/mapdisp/statusbar.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -976,8 +976,6 @@
         self.widget = wx.Gauge(parent = self.statusbar, id = wx.ID_ANY,
                                range = 0, style = wx.GA_HORIZONTAL)
         self.widget.Hide()
-
-        self.maps = {}
         
     def GetRange(self):
         """!Returns progress range."""
@@ -985,90 +983,36 @@
     
     def SetRange(self, range):
         """!Sets progress range."""
-        self.widget.SetRange(range)
+        if range > 0:        
+            if self.GetRange() != range:
+                self.widget.SetRange(range)
+            self.widget.Show()
+        else:
+            self.widget.Hide()
     
     def IsShown(self):
         """!Is progress bar shown
         """
         return self.widget.IsShown()
-                
-    def UpdateProgress(self, layer, map):
-        """!Update progress"""
-        
-        if map not in self.maps or layer is None:
-            # self.map holds values needed for progress info for every Render instance in mapframe
-            self.maps[map] = {'progresVal' : 0, # current progress value
-                              'downloading' : [], # layers, which are downloading data
-                              'rendered' : [], # already rendered layers
-                              'range' : len(map.GetListOfLayers(active = True)) + 
-                                        len(map.GetListOfLayers(active = True, ltype = 'overlay'))}
-        else:
-            if layer not in self.maps[map]['rendered']:
-                self.maps[map]['rendered'].append(layer)
-            if layer.IsDownloading() and \
-                    layer not in self.maps[map]['downloading']:
-                self.maps[map]['downloading'].append(layer)
-            else:
-                self.maps[map]['progresVal'] += 1
-                if layer in self.maps[map]['downloading']:
-                    self.maps[map]['downloading'].remove(layer)
-        
-        self.Update(map)
-        self.sbManager.Update()
-        
-    def Update(self, map = None):      
-        """!Update statusbar"""
-        activeMap = self.mapFrame.GetMap()
-        if map is None:
-                map = activeMap
-        if map not in self.maps:
-            return
-        if map != activeMap:
-            return
 
-        # update progress bar
-        if self.maps[map]['range'] == self.maps[map]['progresVal']:
-            self.widget.Hide()
+    def SetValue(self, value):
+        if value > self.GetRange():
             return
-        elif self.maps[map]['range'] > 0:
-            if self.widget.GetRange() != self.maps[map]['range']:
-                self.widget.SetRange(self.maps[map]['range'])
-            self.widget.Show()
-        else:
-            return
-        
-        self.widget.SetValue(self.maps[map]['progresVal'])
-        
-        # update statusbar text
-        stText = ''
-        first = True
-        for layer in self.maps[map]['downloading']:
-            if first:
-                stText += _("Downloading data ")
-                first = False
-            else:
-                stText += ', '
-            stText += '<%s>' % layer.GetName()
-        if stText:
-            stText += '...'
-        
-        if  self.maps[map]['range'] != len(self.maps[map]['rendered']):
-            if stText:
-                stText = _('Rendering & ') + stText
-            else:
-                stText = _('Rendering...')
+        self.widget.SetValue(value)
+        if value == self.GetRange():
+            self.widget.Hide()
 
-        self.statusbar.SetStatusText(stText, self.position)
+        wx.Yield()
 
-    def GetValue(self):
-        return self.widget.GetValue()
-    
     def GetWidget(self):
         """!Returns underlaying winget.
         
         @return widget or None if doesn't exist
         """
         return self.widget
+
+    def Update(self):
+        pass
     
 class SbGoToGCP(SbItem):
     """!SpinCtrl to select GCP to focus on

Modified: grass/trunk/gui/wxpython/web_services/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/web_services/dialogs.py	2013-07-13 16:04:08 UTC (rev 57081)
+++ grass/trunk/gui/wxpython/web_services/dialogs.py	2013-07-13 16:06:32 UTC (rev 57082)
@@ -30,8 +30,6 @@
 
 from core             import globalvar
 from core.debug       import Debug
-from core.ws          import RenderWMSMgr
-from core.events      import gUpdateMap
 from core.gcmd        import GMessage, GWarning, GError, RunCommand
 from core.utils       import GetSettingsPath, CmdToTuple, CmdTupleToList
 from core.gconsole    import CmdThread, GStderr, EVT_CMD_DONE, EVT_CMD_OUTPUT
@@ -471,7 +469,7 @@
 
 class AddWSDialog(WSDialogBase):
     """!Dialog for adding web service layer."""
-    def __init__(self, parent, gmframe, id = wx.ID_ANY,
+    def __init__(self, parent, giface, id = wx.ID_ANY,
                  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
 
         WSDialogBase.__init__(self, parent, id = wx.ID_ANY,
@@ -479,7 +477,8 @@
 
         self.SetTitle(_("Add web service layer"))
 
-        self.gmframe = gmframe
+        self.parent = parent
+        self.giface = giface
         self.btn_connect.SetDefault()
 
     def _createWidgets(self):
@@ -524,7 +523,7 @@
         if not lcmd:
             return None
 
-        ltree = self.gmframe.GetLayerTree()
+        ltree = self.giface.GetLayerTree()
 
         active_ws = self.active_ws_panel.GetWebService()
         if 'WMS' not in active_ws:
@@ -542,10 +541,10 @@
         cmd_list = ltree.GetLayerInfo(layer,'cmd')
         cmd = CmdToTuple(cmd_list)
 
-        prop_win = WSPropertiesDialog(parent = self.gmframe,
+        prop_win = WSPropertiesDialog(parent = self.parent,
+                                      giface = self.giface,
                                       id = wx.ID_ANY,
                                       layer = layer,
-                                      ltree = ltree,
                                       ws_cap_files = ws_cap_files,
                                       cmd = cmd)
 
@@ -555,15 +554,15 @@
 
 class WSPropertiesDialog(WSDialogBase):
     """!Dialog for editing web service properties."""
-    def __init__(self, parent, layer, ltree, ws_cap_files, cmd, id = wx.ID_ANY,
+    def __init__(self, parent, giface, layer, ws_cap_files, cmd, id = wx.ID_ANY,
                  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
         """
-        @param layer - layer tree item
-        @param ltree - layer tree reference
-        @param ws_cap_files - dict web service('WMS_1.1.1', 'WMS_1.3.0', 'WMTS', 'OnEarth') : cap file path
-                            - cap files, which will be parsed
-        @param cmd - cmd to which dialog widgets will be initialized if it is possible 
-                    (cmp parameters exists in parsed web service cap_file)
+        @param giface grass interface
+        @param layer layer tree item
+        @param ws_cap_files dict web service('WMS_1.1.1', 'WMS_1.3.0', 'WMTS', 'OnEarth') : cap file path
+                            cap files, which will be parsed
+        @param cmd cmd to which dialog widgets will be initialized if it is possible 
+                   (cmp parameters exists in parsed web service cap_file)
         """
 
         WSDialogBase.__init__(self, parent, id = wx.ID_ANY,
@@ -571,8 +570,8 @@
 
         self.SetTitle(_("Web service layer properties"))
 
-        self.ltree = ltree
         self.layer = layer
+        self.giface = giface
 
         # after web service panels are connected, set dialog widgets
         # according to cmd in this variable (if it is not None) 
@@ -690,19 +689,17 @@
         if 'WMS' not in active_ws:
             lcmd.append('capfile=' + self.revert_ws_cap_files[active_ws])
 
-        self.ltree.GetOptData(dcmd = lcmd, 
-                              layer = self.layer, 
-                              params = None,
-                              propwin = self)
+        self.giface.GetLayerTree().GetOptData(dcmd = lcmd, 
+                                              layer = self.layer, 
+                                              params = None,
+                                              propwin = self)
 
         #TODO use just list or tuple
         cmd = CmdToTuple(lcmd)
         self.revert_cmd = cmd
         self._setRevertCapFiles(self._getCapFiles())
 
-        display = self.ltree.GetMapDisplay().GetMapWindow()
-        event = gUpdateMap()
-        wx.PostEvent(display, event)
+        self.giface.updateMap.emit()
 
     def UpdateDialogAfterConnection(self):
         """!Connect to the server



More information about the grass-commit mailing list