Jelajahi Sumber

wxGUI/toolboxes: store warning/error messages for later (see https://trac.osgeo.org/grass/ticket/3253)

GError and other message boxes during startup prevent
its completion unless OK is clicked quickly.
Messages are now stored and retrived later by the menu builder object.
lmgr stores them again and then shows them at the end of
init when everything is ready.

Messages (which are non-critical errors or warnings) are written as errors
to the Console output window. Console may flash during startup
but then Layers tab is shown anyway which seems like okay behavior
(careful user sees something happen but can ignore it).

Details of the exception are included into the message.


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@70461 15284696-431f-4ddb-bdfa-cd5b030d7da7
Vaclav Petras 8 tahun lalu
induk
melakukan
7e82498ebc

+ 9 - 1
gui/wxpython/core/menutree.py

@@ -46,6 +46,9 @@ import wx
 from core.treemodel import TreeModel, ModuleNode
 from core.settings import UserSettings
 from core.toolboxes import expandAddons as expAddons
+from core.toolboxes import getMessages as getToolboxMessages
+from core.toolboxes import clearMessages as clearToolboxMessages
+from core.gcmd import GError
 from core.utils import _
 
 if not os.getenv("GISBASE"):
@@ -56,7 +59,9 @@ if not os.getenv("GISBASE"):
 class MenuTreeModelBuilder:
     """Abstract menu data class"""
 
-    def __init__(self, filename, expandAddons=True):
+    # TODO: message_handler=GError is just for backwards compatibility
+    # message_handler=GError should be replaced by None
+    def __init__(self, filename, expandAddons=True, message_handler=GError):
 
         self.menustyle = UserSettings.Get(group='appearance',
                                           key='menustyle',
@@ -65,6 +70,9 @@ class MenuTreeModelBuilder:
         xmlTree = etree.parse(filename)
         if expandAddons:
             expAddons(xmlTree)
+            for message in getToolboxMessages():
+                message_handler(message)
+            clearToolboxMessages()
 
         self.model = TreeModel(ModuleNode)
         self._createModel(xmlTree)

+ 15 - 6
gui/wxpython/core/toolboxes.py

@@ -100,13 +100,21 @@ def _(string):
 # attribute translate of function _
 _.translate = None
 
+# TODO: this should be part of some reader object
+_MESSAGES = []
+
 
 def _warning(message):
     """Show warning"""
-    # TODO: enable choice between GUI and script behavior
-    # import only when really needed
-    from core.gcmd import GError
-    GError(message)
+    _MESSAGES.append("WARNING: %s" % message)
+
+
+def getMessages():
+    return _MESSAGES
+
+
+def clearMessages():
+    del _MESSAGES[:]
 
 
 def _debug(level, message):
@@ -505,9 +513,10 @@ def _removeUserToolboxesItem(root):
 def _getAddons():
     try:
         output = gcore.read_command('g.extension', quiet=True, flags='ag')
-    except CalledModuleError:
+    except CalledModuleError as error:
         _warning(_("List of addons cannot be obtained"
-                   " because g.extension failed."))
+                   " because g.extension failed."
+                   " Details: %s") % error)
         return []
 
     flist = []

+ 15 - 2
gui/wxpython/lmgr/frame.py

@@ -113,10 +113,21 @@ class GMFrame(wx.Frame):
 
         self._giface = LayerManagerGrassInterface(self)
 
+        menu_errors = []
+        def add_menu_error(message):
+            menu_errors.append(message)
+        def show_menu_errors(messages):
+            if messages:
+                self._gconsole.WriteError(
+                    _("There were some issues when loading menu"
+                      " or Modules tab:"))
+                for message in messages:
+                    self._gconsole.WriteError(message)
+
         # the main menu bar
-        self._menuTreeBuilder = LayerManagerMenuData()
+        self._menuTreeBuilder = LayerManagerMenuData(message_handler=add_menu_error)
         # the search tree and command console
-        self._moduleTreeBuilder = LayerManagerModuleTree()
+        self._moduleTreeBuilder = LayerManagerModuleTree(message_handler=add_menu_error)
         self._auimgr = wx.aui.AuiManager(self)
 
         # list of open dialogs
@@ -236,6 +247,8 @@ class GMFrame(wx.Frame):
 
         self.workspaceChanged = False
 
+        show_menu_errors(menu_errors)
+
         # start with layer manager on top
         if self.currentPage:
             self.GetMapDisplay().Raise()

+ 15 - 11
gui/wxpython/lmgr/menudata.py

@@ -18,7 +18,7 @@ This program is free software under the GNU General Public License
 import os
 
 from core.menutree import MenuTreeModelBuilder
-from core.toolboxes import getMenudataFile
+from core.toolboxes import getMenudataFile, getMessages, clearMessages
 from core.globalvar import WXGUIDIR
 from core.gcmd import GError
 from core.utils import _
@@ -26,7 +26,7 @@ from core.utils import _
 
 class LayerManagerMenuData(MenuTreeModelBuilder):
 
-    def __init__(self, filename=None):
+    def __init__(self, filename=None, message_handler=GError):
         if filename:
             expandAddons = False
         else:
@@ -39,17 +39,19 @@ class LayerManagerMenuData(MenuTreeModelBuilder):
                                        fallback=fallback)
         try:
             MenuTreeModelBuilder.__init__(
-                self, filename, expandAddons=expandAddons)
+                self, filename, expandAddons=expandAddons,
+                message_handler=message_handler)
         except (ValueError, AttributeError, TypeError):
-            GError(_("Unable to parse user toolboxes XML files. "
-                     "Default main menu will be loaded."))
+            message_handler(_("Unable to parse user toolboxes XML files. "
+                              "Default main menu will be loaded."))
             fallback = os.path.join(WXGUIDIR, 'xml', 'menudata.xml')
-            MenuTreeModelBuilder.__init__(self, fallback)
+            MenuTreeModelBuilder.__init__(
+                self, fallback,  message_handler=message_handler)
 
 
 class LayerManagerModuleTree(MenuTreeModelBuilder):
 
-    def __init__(self, filename=None):
+    def __init__(self, filename=None, message_handler=GError):
         if filename:
             expandAddons = False
         else:
@@ -63,8 +65,10 @@ class LayerManagerModuleTree(MenuTreeModelBuilder):
         # TODO: try-except useless?
         try:
             MenuTreeModelBuilder.__init__(
-                self, filename, expandAddons=expandAddons)
+                self, filename, expandAddons=expandAddons,
+                message_handler=message_handler)
         except (ValueError, AttributeError, TypeError):
-            GError(_("Unable to parse user toolboxes XML files. "
-                     "Default module tree will be loaded."))
-            MenuTreeModelBuilder.__init__(self, fallback)
+            error_handler(_("Unable to parse user toolboxes XML files. "
+                            "Default module tree will be loaded."))
+            MenuTreeModelBuilder.__init__(
+                self, fallback, message_handler=message_handler)