[GRASS-SVN] r66917 - in grass/trunk: gui/wxpython gui/wxpython/lmgr gui/wxpython/xml lib/init

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Nov 24 13:56:53 PST 2015


Author: martinl
Date: 2015-11-24 13:56:53 -0800 (Tue, 24 Nov 2015)
New Revision: 66917

Modified:
   grass/trunk/gui/wxpython/lmgr/frame.py
   grass/trunk/gui/wxpython/wxgui.py
   grass/trunk/gui/wxpython/xml/toolboxes.xml
   grass/trunk/gui/wxpython/xml/wxgui_items.xml
   grass/trunk/lib/init/grass.py
Log:
wxGUI: add experimental option to exit GRASS shell from GUI session


Modified: grass/trunk/gui/wxpython/lmgr/frame.py
===================================================================
--- grass/trunk/gui/wxpython/lmgr/frame.py	2015-11-24 21:54:25 UTC (rev 66916)
+++ grass/trunk/gui/wxpython/lmgr/frame.py	2015-11-24 21:56:53 UTC (rev 66917)
@@ -84,9 +84,10 @@
     commands, tree widget page for managing map layers.
     """
     def __init__(self, parent, id = wx.ID_ANY, title = None,
-                 workspace = None,
+                 workspace = None, shellPid = None,
                  size = globalvar.GM_WINDOW_SIZE, style = wx.DEFAULT_FRAME_STYLE, **kwargs):
         self.parent    = parent
+        self._shellPid = shellPid         # process id of shell running on the background
         if title:
             self.baseTitle = title
         else:
@@ -2203,6 +2204,9 @@
 
     def OnCloseWindow(self, event):
         """Cleanup when wxGUI is quitted"""
+        self._closeWindow()
+        
+    def _closeWindow(self):
         # save command protocol if actived
         if self.goutput.btnCmdProtocol.GetValue():
             self.goutput.CmdProtocolSave()
@@ -2250,10 +2254,19 @@
         self.OnDisplayCloseAll()
         
         self.notebookLayers.DeleteAllPages()
-        
         self._auimgr.UnInit()
         self.Destroy()
         
+    def OnCloseWindowExitGRASS(self, event):
+        """Close wxGUI and exit GRASS shell."""
+        self._closeWindow()
+        if self._shellPid:
+            Debug.msg(1, "Exiting shell with pid={}".format(self._shellPid))
+            import signal
+            os.kill(self._shellPid, signal.SIGTERM)
+        else:
+            grass.warning(_("Unable to exit GRASS shell: unknown PID"))
+        
     def MsgNoLayerSelected(self):
         """Show dialog message 'No layer selected'"""
         wx.MessageBox(parent = self,

Modified: grass/trunk/gui/wxpython/wxgui.py
===================================================================
--- grass/trunk/gui/wxpython/wxgui.py	2015-11-24 21:54:25 UTC (rev 66916)
+++ grass/trunk/gui/wxpython/wxgui.py	2015-11-24 21:56:53 UTC (rev 66917)
@@ -35,13 +35,15 @@
 
 
 class GMApp(wx.App):
-    def __init__(self, workspace = None):
+    def __init__(self, workspace=None, shellPid=None):
         """ Main GUI class.
 
         :param workspace: path to the workspace file
+        :param shellPid: process id of shell running on background
         """
         self.workspaceFile = workspace
-
+        self._shellPid = shellPid
+        
         # call parent class initializer
         wx.App.__init__(self, False)
 
@@ -77,8 +79,8 @@
 
         # create and show main frame
         from lmgr.frame import GMFrame
-        mainframe = GMFrame(parent = None, id = wx.ID_ANY,
-                            workspace = self.workspaceFile)
+        mainframe = GMFrame(parent=None, id=wx.ID_ANY,
+                            workspace=self.workspaceFile, shellPid=self._shellPid)
 
         mainframe.Show()
         self.SetTopWindow(mainframe)
@@ -97,20 +99,26 @@
 
 def process_opt(opts, args):
     """ Process command-line arguments"""
-    workspaceFile = None
+    workspaceFile = shellPid = None
     for o, a in opts:
         if o in ("-h", "--help"):
             printHelp()
 
-        if o in ("-w", "--workspace"):
+        elif o in ("-w", "--workspace"):
             if a != '':
                 workspaceFile = str(a)
             else:
                 workspaceFile = args.pop(0)
 
-    return (workspaceFile,)
+        elif o in ("-p", "--pid"):
+            if a != '':
+                shellPid = int(a)
+            else:
+                shellPid = int(args.pop(0))
 
+    return (workspaceFile, shellPid)
 
+
 def main(argv = None):
 
     if argv is None:
@@ -118,18 +126,17 @@
     try:
         try:
             opts, args = getopt.getopt(argv[1:], "hw:",
-                                       ["help", "workspace"])
+                                       ["help", "workspace", "pid"])
         except getopt.error as msg:
             raise Usage(msg)
-
     except Usage as err:
         print >> sys.stderr, err.msg
         print >> sys.stderr, "for help use --help"
         printHelp()
-
-    workspaceFile = process_opt(opts, args)[0]
-
-    app = GMApp(workspaceFile)
+    
+    workspaceFile, shellPid = process_opt(opts, args)
+    app = GMApp(workspaceFile, shellPid)
+    
     # suppress wxPython logs
     q = wx.LogNull()
     set_raise_on_error(True)

Modified: grass/trunk/gui/wxpython/xml/toolboxes.xml
===================================================================
--- grass/trunk/gui/wxpython/xml/toolboxes.xml	2015-11-24 21:54:25 UTC (rev 66916)
+++ grass/trunk/gui/wxpython/xml/toolboxes.xml	2015-11-24 21:56:53 UTC (rev 66917)
@@ -41,6 +41,7 @@
       <separator/>
       <wxgui-item name="LaunchScript"/>
       <separator/>
+      <wxgui-item name="CloseGUI"/>
       <wxgui-item name="Quit"/>
     </items>
   </toolbox>

Modified: grass/trunk/gui/wxpython/xml/wxgui_items.xml
===================================================================
--- grass/trunk/gui/wxpython/xml/wxgui_items.xml	2015-11-24 21:54:25 UTC (rev 66916)
+++ grass/trunk/gui/wxpython/xml/wxgui_items.xml	2015-11-24 21:56:53 UTC (rev 66917)
@@ -62,10 +62,16 @@
     <handler>OnRunScript</handler>
     <description>Launches script file.</description>
   </wxgui-item>
+  <wxgui-item name="CloseGUI">
+    <label>Close GUI</label>
+    <handler>OnCloseWindow</handler>
+    <description>Quit wxGUI session.</description>
+    <shortcut>Ctrl+W</shortcut>
+  </wxgui-item>
   <wxgui-item name="Quit">
-    <label>Exit GUI</label>
-    <handler>OnCloseWindow</handler>
-    <description>Quit the GRASS wxGUI session.</description>
+    <label>Quit GRASS GIS</label>
+    <handler>OnCloseWindowExitGRASS</handler>
+    <description>Quit wxGUI session and exit GRASS shell.</description>
     <shortcut>Ctrl+Q</shortcut>
     <wx-id>ID_EXIT</wx-id>
   </wxgui-item>

Modified: grass/trunk/lib/init/grass.py
===================================================================
--- grass/trunk/lib/init/grass.py	2015-11-24 21:54:25 UTC (rev 66916)
+++ grass/trunk/lib/init/grass.py	2015-11-24 21:56:53 UTC (rev 66917)
@@ -1338,7 +1338,7 @@
     return returncode
 
 
-def start_gui(grass_gui):
+def start_gui(grass_gui, shell_pid=None):
     """Start specified GUI
 
     :param grass_gui: GUI name (allowed values: 'wxpython')
@@ -1348,9 +1348,14 @@
     
     # Check for gui interface
     if grass_gui == "wxpython":
-        Popen([os.getenv('GRASS_PYTHON'), wxpath("wxgui.py")])
+        cmd = [os.getenv('GRASS_PYTHON'), wxpath("wxgui.py")]
+        if shell_pid:
+            cmd.append('--pid')
+            cmd.append(str(shell_pid))
+        
+        Popen(cmd)
 
-
+    
 def clear_screen():
     """Clear terminal"""
     if windows:
@@ -1456,10 +1461,11 @@
     f.close()
     writefile(tcshrc, readfile(cshrc))
 
-    exit_val = call([gpath("etc", "run"), os.getenv('SHELL')])
-
+    process = Popen([gpath("etc", "run"), os.getenv('SHELL')])
+    
     os.environ['HOME'] = userhome
-    return exit_val
+    
+    return process
 
 
 def bash_startup(location, location_name, grass_env_file):
@@ -1512,29 +1518,27 @@
     f.write("export HOME=\"%s\"\n" % userhome) # restore user home path
 
     f.close()
-
-    exit_val = call([gpath("etc", "run"), os.getenv('SHELL')])
-
+    
+    process = Popen([gpath("etc", "run"), os.getenv('SHELL')])
+    
     os.environ['HOME'] = userhome
-    return exit_val
+    
+    return process
 
 
 def default_startup(location, location_name):
     if windows:
         os.environ['PS1'] = "GRASS %s> " % (grass_version)
         # "$ETC/run" doesn't work at all???
-        exit_val = subprocess.call([os.getenv('SHELL')])
+        process = subprocess.Popen([os.getenv('SHELL')])
         # TODO: is there a difference between this and clean_temp?
         # TODO: why this is missing in the other startups?
         cleanup_dir(os.path.join(location, ".tmp"))  # remove GUI session files from .tmp
     else:
         os.environ['PS1'] = "GRASS %s (%s):\\w > " % (grass_version, location_name)
-        exit_val = call([gpath("etc", "run"), os.getenv('SHELL')])
+        process = Popen([gpath("etc", "run"), os.getenv('SHELL')])
 
-    # TODO: this seems to be inconsistent, the other two are no fataling
-    if exit_val != 0:
-        fatal(_("Failed to start shell '%s'") % os.getenv('SHELL'))
-    return exit_val
+    return process
 
 
 def done_message():
@@ -1875,7 +1879,6 @@
         clean_temp()
         sys.exit(0)
     else:
-        start_gui(grass_gui)
         clear_screen()
         show_banner()
         say_hello()
@@ -1885,14 +1888,23 @@
             message(_("Launching <%s> GUI in the background, please wait...")
                     % grass_gui)
         if sh in ['csh', 'tcsh']:
-            csh_startup(mapset_settings.full_mapset, mapset_settings.location,
-                        mapset_settings.mapset, grass_env_file)
+            shell_process = csh_startup(mapset_settings.full_mapset,
+                                        mapset_settings.location,
+                                        mapset_settings.mapset,
+                                        grass_env_file)
         elif sh in ['bash', 'msh', 'cygwin']:
-            bash_startup(mapset_settings.full_mapset, mapset_settings.location,
-                         grass_env_file)
+            shell_process = bash_startup(mapset_settings.full_mapset,
+                                         mapset_settings.location,
+                                         grass_env_file)
         else:
-            default_startup(mapset_settings.full_mapset,
-                            mapset_settings.location)
+            shell_process = default_startup(mapset_settings.full_mapset,
+                                            mapset_settings.location)
+
+        start_gui(grass_gui, shell_process.pid)
+        exit_val = shell_process.wait()
+        if exit_val != 0:
+            warning(_("Failed to start shell '%s'") % os.getenv('SHELL'))
+        
         # here we are at the end of grass session
         clear_screen()
         # TODO: can we just register this atexit?



More information about the grass-commit mailing list