Bladeren bron

wxGUI: Ask user about shell only when present (#1219)

Introduces two new functions to check for shell presence and PID.
The environment is accessed twice now, to construct the dialog and to end the shell.

Default button is now Quit.

Shell/terminal/prompt is not just called shell because that's really what is being ended.

Updates outdated doc to new behavior. The doc described some previous state, not the current state before this change.

The section is restructured and changed to be about GUI and CLI rather than starting
otherwise it is confusing for a reader studying GUI as a primary or first-contact interface
of GRASS GIS.
Vaclav Petras 4 jaren geleden
bovenliggende
commit
50cd8fcdf4
4 gewijzigde bestanden met toevoegingen van 65 en 48 verwijderingen
  1. 21 0
      gui/wxpython/core/utils.py
  2. 20 29
      gui/wxpython/docs/wxGUI.html
  3. 21 10
      gui/wxpython/gui_core/dialogs.py
  4. 3 9
      gui/wxpython/lmgr/frame.py

+ 21 - 0
gui/wxpython/core/utils.py

@@ -1175,5 +1175,26 @@ def unregisterPid(pid):
             set='GUI_PID={0}'.format(
                 ','.join(guiPid)))
 
+
+def get_shell_pid(env=None):
+    """Get shell PID from the GIS environment or None"""
+    try:
+        shell_pid = int(grass.gisenv(env=env)['PID'])
+        return shell_pid
+    except (KeyError, ValueError) as error:
+        Debug.msg(
+            1,
+            "No PID for GRASS shell (assuming no shell running): {}".format(error)
+        )
+        return None
+
+
+def is_shell_running():
+    """Return True if a separate shell is registered in the GIS environment"""
+    if get_shell_pid() is None:
+        return False
+    return True
+
+
 if __name__ == '__main__':
     sys.exit(doc_test())

+ 20 - 29
gui/wxpython/docs/wxGUI.html

@@ -638,48 +638,32 @@ the computational region extents.
 </dl>
 
 
-<h3>Starting the graphical user interface</h3>
+<h3>Starting the GUI from command line</h3>
 
-If the wxGUI is not the default user interface, it can defined as default by
-typing at the GRASS GIS command line prompt:
+By default, the GUI is always started, but if only the command line (shell) is
+running, the GUI can be also started manually using:
 
 <div class="code"><pre>
-g.gui -u wxpython
-</pre></div>
-
-Alternatively it may be defined in GISRC file
-(<tt>$HOME/.grass7/rc</tt> on GNU/Linux, <tt>$APPDATA\GRASS7\rc</tt>
-on MS Windows) by <tt>GUI</tt> variable
-
-<div class="code"><pre>
-GUI: wxpython
+g.gui
 </pre></div>
 
-or by the environmental variable <tt>GRASS_GUI</tt>.
-<p>
-The GUI can be quit by selecting the 'File -&gt; Exit GUI' menu item.
-<!-- is &rarr; allowed? -->
-On MS Windows when GRASS is launched without an interactive command line
-this will end the entire GRASS session. In other cases the terminal
-window will remain running; type <tt>exit</tt> at the command prompt
-to end the GRASS session.
-<p>
-The GUI can be restarted from the GRASS command line prompt by typing
+If the wxGUI is not the default user interface, it can defined as default by
+typing at the GRASS GIS command line:
 
 <div class="code"><pre>
-g.gui
+g.gui -d wxpython
 </pre></div>
 
-or
+Alternatively, it may be defined in the main configuration file
+(<tt>$HOME/.grass7/rc</tt> on GNU/Linux and macOS, <tt>$APPDATA\GRASS7\rc</tt>
+on MS Windows) using the <tt>GUI</tt> variable set to <tt>wxpython</tt>
+(<tt>GUI: wxpython</tt>) or by the environmental variable <tt>GRASS_GUI</tt>.
 
-<div class="code"><pre>
-g.gui wxpython
-</pre></div>
 
-To restart with previously saved workspace file:
+To start with a previously saved workspace file:
 
 <div class="code"><pre>
-g.gui wxpython workspace=file.gxw
+g.gui workspace=file.gxw
 </pre></div>
 
 <p>
@@ -690,6 +674,13 @@ specifying the <tt>--gui</tt> switch:
 grass79 --gui
 </pre></div>
 
+<p>
+The GUI can be quit by selecting the 'File &gt; Quit GRASS GIS' menu item
+which gives options to close only GUI or to quit GRASS GIS entirely
+if GRASS GIS is running with a command line (a shell in a terminal application).
+Exiting the shell (typically by the <tt>exit</tt> command) ends the GRASS session
+including any running GUIs.
+
 
 <h3>Background information</h3>
 

+ 21 - 10
gui/wxpython/gui_core/dialogs.py

@@ -47,6 +47,7 @@ from gui_core.widgets import SingleSymbolPanel, SimpleValidator, \
     MapValidator
 from core.settings import UserSettings
 from core.debug import Debug
+from core.utils import is_shell_running
 from gui_core.wrap import Button, CheckListBox, EmptyBitmap, HyperlinkCtrl, \
     Menu, NewId, SpinCtrl, StaticBox, StaticText, TextCtrl
 
@@ -2356,18 +2357,27 @@ class QuitDialog(wx.Dialog):
                 wx.ART_QUESTION,
                 client=wx.ART_MESSAGE_BOX))
 
-        self.informLabel = StaticText(
-            parent=self.panel, id=wx.ID_ANY, label=_(
-                "Do you want to quit GRASS including shell "
-                "prompt or just close the GUI?"))
+        self._shell_running = is_shell_running()
+
+        if self._shell_running:
+            text = _(
+                "Do you want to quit GRASS GIS including shell "
+                "or just close the GUI?"
+            )
+        else:
+            text = _(
+                "Do you want to quit GRASS GIS?"
+            )
+        self.informLabel = StaticText(parent=self.panel, id=wx.ID_ANY, label=text)
         self.btnCancel = Button(parent=self.panel, id=wx.ID_CANCEL)
-        self.btnClose = Button(parent=self.panel, id=wx.ID_NO,
-                                  label=_("Close GUI"))
-        self.btnClose.SetFocus()
+        if self._shell_running:
+            self.btnClose = Button(
+                parent=self.panel, id=wx.ID_NO, label=_("Close GUI")
+            )
+            self.btnClose.Bind(wx.EVT_BUTTON, self.OnClose)
         self.btnQuit = Button(parent=self.panel, id=wx.ID_YES,
                                  label=_("Quit GRASS GIS"))
-
-        self.btnClose.Bind(wx.EVT_BUTTON, self.OnClose)
+        self.btnQuit.SetFocus()
         self.btnQuit.Bind(wx.EVT_BUTTON, self.OnQuit)
 
         self.__layout()
@@ -2378,7 +2388,8 @@ class QuitDialog(wx.Dialog):
 
         btnSizer = wx.BoxSizer(wx.HORIZONTAL)
         btnSizer.Add(self.btnCancel, flag=wx.RIGHT, border=5)
-        btnSizer.Add(self.btnClose, flag=wx.RIGHT, border=5)
+        if self._shell_running:
+            btnSizer.Add(self.btnClose, flag=wx.RIGHT, border=5)
         btnSizer.Add(self.btnQuit, flag=wx.RIGHT, border=5)
 
         bodySizer = wx.BoxSizer(wx.HORIZONTAL)

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

@@ -49,7 +49,7 @@ from startup.guiutils import (
 
 from core.gcmd import RunCommand, GError, GMessage
 from core.settings import UserSettings, GetDisplayVectSettings
-from core.utils import SetAddOnPath, GetLayerNameFromCmd, command2ltype
+from core.utils import SetAddOnPath, GetLayerNameFromCmd, command2ltype, get_shell_pid
 from gui_core.preferences import MapsetAccess, PreferencesDialog
 from lmgr.layertree import LayerTree, LMIcons
 from lmgr.menudata import LayerManagerMenuData, LayerManagerModuleTree
@@ -2567,15 +2567,9 @@ class GMFrame(wx.Frame):
 
     def _quitGRASS(self):
         """Quit GRASS terminal"""
-        try:
-            shellPid = int(grass.gisenv()['PID'])
-        except (KeyError, ValueError) as error:
-            Debug.msg(
-                1,
-                "No PID for GRASS shell (assuming no shell running): {}".format(error)
-            )
+        shellPid = get_shell_pid()
+        if shellPid is None:
             return
-
         Debug.msg(1, "Exiting shell with pid={0}".format(shellPid))
         import signal
         os.kill(shellPid, signal.SIGTERM)