瀏覽代碼

wxGUI: save database, location and mapset to workspace and switch it when opening it (closes https://trac.osgeo.org/grass/ticket/3575)

It is no longer possible to just open workspace in a different mapset
than the one where it was saved. However, when session element is not
present (deleted or older gxw file) no mapset switching is performed.
Older versions of GRASS GIS simply ignore the session element.

An error message is given when mapset does not exist and options to
proceed or not are given with some details (can be improved by
diagnostics from grass.py if moved to library).


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@73348 15284696-431f-4ddb-bdfa-cd5b030d7da7
Vaclav Petras 6 年之前
父節點
當前提交
053eaa89d5
共有 3 個文件被更改,包括 82 次插入2 次删除
  1. 35 0
      gui/wxpython/core/workspace.py
  2. 41 1
      gui/wxpython/lmgr/frame.py
  3. 6 1
      gui/wxpython/xml/grass-gxw.dtd

+ 35 - 0
gui/wxpython/core/workspace.py

@@ -29,6 +29,14 @@ from nviz.main import NvizSettings
 from grass.script import core as gcore
 from grass.script import core as gcore
 
 
 
 
+def get_database_location_mapset():
+    """Returns GRASS database, location, and mapset as a tuple"""
+    gisenv = gcore.gisenv()
+    return (gisenv['GISDBASE'],
+            gisenv['LOCATION_NAME'],
+            gisenv['MAPSET'])
+
+
 class ProcessWorkspaceFile:
 class ProcessWorkspaceFile:
 
 
     def __init__(self, tree):
     def __init__(self, tree):
@@ -95,6 +103,9 @@ class ProcessWorkspaceFile:
 
 
     def __processFile(self):
     def __processFile(self):
         """Process workspace file"""
         """Process workspace file"""
+
+        self.__processSession()
+        
         #
         #
         # layer manager
         # layer manager
         #
         #
@@ -177,6 +188,17 @@ class ProcessWorkspaceFile:
             # process nviz_state
             # process nviz_state
             self.__processNvizState(display)
             self.__processNvizState(display)
 
 
+    def __processSession(self):
+        session = self.root.find('session')
+        if session is None:
+            self.database = None
+            self.location = None
+            self.mapset = None
+            return
+        self.database = self.__filterValue(self.__getNodeText(session, 'database'))
+        self.location = self.__filterValue(self.__getNodeText(session, 'location'))
+        self.mapset = self.__filterValue(self.__getNodeText(session, 'mapset'))
+
     def __processLayers(self, node, inGroup=-1):
     def __processLayers(self, node, inGroup=-1):
         """Process layers/groups of selected display
         """Process layers/groups of selected display
 
 
@@ -813,6 +835,19 @@ class WriteWorkspaceFile(object):
 
 
         self.indent = + 4
         self.indent = + 4
 
 
+        database, location, mapset = get_database_location_mapset()
+
+        file.write('{indent}<session>\n'.format(indent=' ' * self.indent))
+        self.indent += 4
+        file.write('{indent}<database>{database}</database>\n'.format(
+            indent=' ' * self.indent, database=database))
+        file.write('{indent}<location>{location}</location>\n'.format(
+            indent=' ' * self.indent, location=location))
+        file.write('{indent}<mapset>{mapset}</mapset>\n'.format(
+            indent=' ' * self.indent, mapset=mapset))
+        self.indent -= 4
+        file.write('{indent}</session>\n'.format(indent=' ' * self.indent))
+
         # layer manager
         # layer manager
         windowPos = self.lmgr.GetPosition()
         windowPos = self.lmgr.GetPosition()
         windowSize = self.lmgr.GetSize()
         windowSize = self.lmgr.GetSize()

+ 41 - 1
gui/wxpython/lmgr/frame.py

@@ -1375,6 +1375,41 @@ class GMFrame(wx.Frame):
         self.workspaceFile = filename
         self.workspaceFile = filename
         self._setTitle()
         self._setTitle()
 
 
+    def _tryToSwitchMapsetFromWorkspaceFile(self, gxwXml):
+        returncode, errors = RunCommand('g.mapset',
+                      dbase=gxwXml.database,
+                      location=gxwXml.location,
+                      mapset=gxwXml.mapset,
+                      getErrorMsg=True,
+                      )
+        if returncode != 0:
+            # TODO: use the function from grass.py
+            reason = _("Most likely the database, location or mapset"
+                       " does not exist")
+            details = errors
+            message = _("Unable to change to location and mapset"
+                        " specified in the workspace.\n"
+                        "Reason: {reason}\nDetails: {details}\n\n"
+                        "Do you want to proceed with opening"
+                        " the workspace anyway?"
+                        ).format(**locals())
+            dlg = wx.MessageDialog(
+                parent=self, message=message, caption=_(
+                    "Proceed with opening of the workspace?"),
+                style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
+            dlg.CenterOnParent()
+            if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
+                return False
+        else:
+            # TODO: copy from ChangeLocation function
+            GMessage(
+                parent=self,
+                message=_("Current location is <%(loc)s>.\n"
+                          "Current mapset is <%(mapset)s>.") %
+                          {'loc': gxwXml.location,
+                           'mapset': gxwXml.mapset})
+        return True
+
     def LoadWorkspaceFile(self, filename):
     def LoadWorkspaceFile(self, filename):
         """Load layer tree definition stored in GRASS Workspace XML file (gxw)
         """Load layer tree definition stored in GRASS Workspace XML file (gxw)
 
 
@@ -1393,8 +1428,13 @@ class GMFrame(wx.Frame):
                     "Reading workspace file <%s> failed.\n"
                     "Reading workspace file <%s> failed.\n"
                     "Invalid file, unable to parse XML document.") %
                     "Invalid file, unable to parse XML document.") %
                 filename)
                 filename)
-            return
+            return False
+
+        if gxwXml.database and gxwXml.location and gxwXml.mapset:
+            if not self._tryToSwitchMapsetFromWorkspaceFile(gxwXml):
+                return False
 
 
+        # the really busy part starts here (mapset change is fast)
         busy = wx.BusyInfo(_("Please wait, loading workspace..."),
         busy = wx.BusyInfo(_("Please wait, loading workspace..."),
                            parent=self)
                            parent=self)
         wx.Yield()
         wx.Yield()

+ 6 - 1
gui/wxpython/xml/grass-gxw.dtd

@@ -14,7 +14,12 @@
 
 
 <!ELEMENT grass-gxw (gxw)>
 <!ELEMENT grass-gxw (gxw)>
 
 
-<!ELEMENT gxw (layer_manager?, display*)>
+<!ELEMENT gxw (session?, layer_manager?, display*)>
+
+<!ELEMENT session (database, location, mapset)>
+<!ELEMENT database (#PCDATA)>
+<!ELEMENT location (#PCDATA)>
+<!ELEMENT mapset (#PCDATA)>
 
 
 <!--    a layer_manager defines properties of Layer Manager
 <!--    a layer_manager defines properties of Layer Manager
 	GUI component
 	GUI component