JAL-4125 Fixed non-closing external viewers, also added options for default behaviour...
authorBen Soares <b.soares@dundee.ac.uk>
Fri, 26 May 2023 15:45:37 +0000 (16:45 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Fri, 26 May 2023 15:45:37 +0000 (16:45 +0100)
src/jalview/bin/Jalview.java
src/jalview/gui/Desktop.java
src/jalview/gui/QuitHandler.java

index 615e318..8fa4ac7 100755 (executable)
@@ -53,6 +53,7 @@ import java.util.stream.Collectors;
 
 import javax.swing.JDialog;
 import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
 import javax.swing.JOptionPane;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
@@ -78,6 +79,7 @@ import jalview.gui.Desktop;
 import jalview.gui.PromptUserConfig;
 import jalview.gui.QuitHandler;
 import jalview.gui.QuitHandler.QResponse;
+import jalview.gui.StructureViewerBase;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
 import jalview.io.DataSourceType;
@@ -444,11 +446,26 @@ public class Jalview
       public void run()
       {
         Console.debug("Running shutdown hook");
+        QuitHandler.startForceQuit();
+        boolean closeExternal = Cache
+                .getDefault("DEFAULT_CLOSE_EXTERNAL_VIEWERS", false)
+                || Cache.getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false);
+        StructureViewerBase.setQuitClose(closeExternal);
+        for (JInternalFrame frame : Desktop.desktop.getAllFrames())
+        {
+          if (frame instanceof StructureViewerBase)
+          {
+            ((StructureViewerBase) frame).closeViewer(closeExternal);
+          }
+        }
+
         if (QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT)
         {
           // Got to here by a SIGTERM signal.
           // Note we will not actually cancel the quit from here -- it's too
-          // late -- but we can wait for saving files.
+          // late -- but we can wait for saving files and close external viewers
+          // if configured.
+          // Close viewers/Leave viewers open
           Console.debug("Checking for saving files");
           QuitHandler.getQuitResponse(false);
         }
index 8eebfc1..6f2faae 100644 (file)
@@ -1610,7 +1610,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
     }
     Jalview.setCurrentAlignFrame(null);
-    System.out.println("ALL CLOSED");
+    jalview.bin.Console.info("ALL CLOSED");
 
     /*
      * reset state of singleton objects as appropriate (clear down session state
index 5d628ff..ad7684e 100644 (file)
@@ -2,6 +2,7 @@ package jalview.gui;
 
 import java.io.File;
 import java.util.List;
+import java.util.Locale;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -16,6 +17,7 @@ import javax.swing.JOptionPane;
 import javax.swing.JTextPane;
 
 import com.formdev.flatlaf.extras.FlatDesktop;
+import com.formdev.flatlaf.extras.FlatDesktop.QuitResponse;
 
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.Cache;
@@ -35,6 +37,8 @@ public class QuitHandler
 
   private static boolean interactive = true;
 
+  private static QuitResponse flatlafResponse = null;
+
   public static enum QResponse
   {
     NULL, QUIT, CANCEL_QUIT, FORCE_QUIT
@@ -54,26 +58,17 @@ public class QuitHandler
 
   private static ExecutorService executor = Executors.newFixedThreadPool(3);
 
-  public static QResponse setQuitHandler()
+  public static void setQuitHandler()
   {
     FlatDesktop.setQuitHandler(response -> {
-      Runnable performQuit = () -> {
-        response.performQuit();
-        setResponse(QResponse.QUIT);
-      };
-      Runnable performForceQuit = () -> {
-        response.performQuit();
-        setResponse(QResponse.FORCE_QUIT);
-      };
-      Runnable cancelQuit = () -> {
-        response.cancelQuit();
-        // reset
-        setResponse(QResponse.NULL);
-      };
-      getQuitResponse(true, performQuit, performForceQuit, cancelQuit);
+      flatlafResponse = response;
+      Desktop.instance.desktopQuit();
     });
+  }
 
-    return gotQuitResponse();
+  public static void startForceQuit()
+  {
+    setResponse(QResponse.FORCE_QUIT);
   }
 
   private static QResponse gotQuitResponse = QResponse.NULL;
@@ -81,6 +76,11 @@ public class QuitHandler
   protected static QResponse setResponse(QResponse qresponse)
   {
     gotQuitResponse = qresponse;
+    if ((qresponse == QResponse.CANCEL_QUIT || qresponse == QResponse.NULL)
+            && flatlafResponse != null)
+    {
+      flatlafResponse.cancelQuit();
+    }
     return qresponse;
   }
 
@@ -162,8 +162,7 @@ public class QuitHandler
       qd.showDialogOnTopAsync(
               new StringBuilder(
                       MessageManager.getString("label.quit_jalview"))
-                              .append("\n").append(messageString)
-                              .toString(),
+                      .append("\n").append(messageString).toString(),
               MessageManager.getString("action.quit"),
               JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
               new Object[]
@@ -180,6 +179,8 @@ public class QuitHandler
       int count = Desktop.instance.structureViewersStillRunningCount();
       if (count > 0)
       {
+        String alwaysCloseExternalViewers = Cache
+                .getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", "ask");
         String prompt = MessageManager
                 .formatMessage(count == 1 ? "label.confirm_quit_viewer"
                         : "label.confirm_quit_viewers");
@@ -190,11 +191,22 @@ public class QuitHandler
         String[] buttonsText = { MessageManager.getString("action.yes"),
             MessageManager.getString("action.no"), cancelQuitText };
 
-        int confirmResponse = JvOptionPane.showOptionDialog(
-                Desktop.instance, prompt, title,
-                JvOptionPane.YES_NO_CANCEL_OPTION,
-                JvOptionPane.WARNING_MESSAGE, null, buttonsText,
-                cancelQuit);
+        int confirmResponse = -1;
+        if (alwaysCloseExternalViewers == null || "ask".equals(
+                alwaysCloseExternalViewers.toLowerCase(Locale.ROOT)))
+        {
+          confirmResponse = JvOptionPane.showOptionDialog(Desktop.instance,
+                  prompt, title, JvOptionPane.YES_NO_CANCEL_OPTION,
+                  JvOptionPane.WARNING_MESSAGE, null, buttonsText,
+                  cancelQuit);
+        }
+        else
+        {
+          confirmResponse = Cache
+                  .getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false)
+                          ? JvOptionPane.YES_OPTION
+                          : JvOptionPane.NO_OPTION;
+        }
 
         if (confirmResponse == JvOptionPane.CANCEL_OPTION)
         {