JAL-1988 Added a saves in progress check for quit
authorBen Soares <bsoares@dundee.ac.uk>
Fri, 2 Sep 2022 16:26:06 +0000 (17:26 +0100)
committerBen Soares <bsoares@dundee.ac.uk>
Fri, 2 Sep 2022 16:26:06 +0000 (17:26 +0100)
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/io/BackupFiles.java
src/jalview/jbgui/APQHandlers.java
src/jalview/jbgui/QuitHandler.java

index 3843ddb..6125bb5 100644 (file)
@@ -32,7 +32,9 @@ action.load_project = Load Project
 action.save_project = Save Project
 action.save_project_as = Save Project as...
 action.quit = Quit
+action.force_quit = Force Quit
 label.quit_jalview = Quit Jalview?
+label.save_in_progress = Some files are still saving. Force quit?
 action.expand_views = Expand Views
 action.gather_views = Gather Views
 action.page_setup = Page Setup...
index d0bfd65..e375bad 100644 (file)
@@ -32,7 +32,9 @@ action.load_project = Cargar proyecto
 action.save_project = Guardar proyecto
 action.save_project_as = Guardar proyecto como...
 action.quit = Salir
+action.force_quit = Forzar la salida
 label.quit_jalview = Salir de Jalview?
+label.save_in_progress = Algunos archivos aún se están guardando. ¿Forzar la salida?
 action.expand_views = Expandir vistas
 action.gather_views = Capturar vistas
 action.page_setup = Configuración de la página
index 05a1ac4..529e1b2 100644 (file)
@@ -29,6 +29,7 @@ import java.nio.file.StandardCopyOption;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
@@ -105,27 +106,27 @@ public class BackupFiles
 
   private static final String oldTempFileSuffix = "_oldfile_tobedeleted";
 
-  private static ArrayList<File> savesInProgress = new ArrayList<>();
+  private static List<BackupFiles> savesInProgress = new ArrayList<>();
 
   private boolean addSaveInProgress()
   {
-    if (savesInProgress.contains(file))
+    if (savesInProgress.contains(this))
     {
       return false;
     }
     else
     {
-      savesInProgress.add(file);
+      savesInProgress.add(this);
       return true;
     }
   }
 
   private boolean removeSaveInProgress()
   {
-    if (savesInProgress.contains(file))
+    if (savesInProgress.contains(this))
     {
       // remove all occurrences
-      while (savesInProgress.remove(file))
+      while (savesInProgress.remove(this))
       {
       }
       return true;
@@ -136,6 +137,21 @@ public class BackupFiles
     }
   }
 
+  public static boolean hasSavesInProgress()
+  {
+    return savesInProgress.size() > 0;
+  }
+
+  public static List<File> savesInProgressFiles()
+  {
+    List<File> files = new ArrayList<>();
+    for (BackupFiles bfile : savesInProgress)
+    {
+      files.add(bfile.getFile());
+    }
+    return files;
+  }
+
   public BackupFiles(String filename)
   {
     this(new File(filename));
@@ -928,6 +944,11 @@ public class BackupFiles
     return ret;
   }
 
+  public File getFile()
+  {
+    return file;
+  }
+
   public static boolean moveFileToFile(File oldFile, File newFile)
   {
     Console.initLogger();
index 1a7e971..12ce1ba 100644 (file)
  */
 package jalview.jbgui;
 
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-
 import com.formdev.flatlaf.extras.FlatDesktop;
 import com.formdev.flatlaf.extras.FlatDesktop.Action;
 
-import jalview.util.MessageManager;
 import jalview.util.Platform;
 
 public class APQHandlers
@@ -59,47 +55,7 @@ public class APQHandlers
     }
     if (FlatDesktop.isSupported(Action.APP_QUIT_HANDLER))
     {
-      FlatDesktop.setQuitHandler(response -> {
-        boolean confirmQuit = jalview.bin.Cache.getDefault(
-                jalview.gui.Desktop.CONFIRM_KEYBOARD_QUIT, true);
-        boolean canQuit = !confirmQuit;
-        int n;
-        if (confirmQuit)
-        {
-          // ensure Jalview window is brought to front for Quit confirmation
-          // window to be visible
-
-          // this method of raising the Jalview window is broken in java
-          // jalviewDesktop.setVisible(true);
-          // jalviewDesktop.toFront();
-
-          // a better hack which works instead
-          JFrame dialogParent = new JFrame();
-          dialogParent.setAlwaysOnTop(true);
-
-          n = JOptionPane.showConfirmDialog(dialogParent,
-                  MessageManager.getString("label.quit_jalview"),
-                  MessageManager.getString("action.quit"),
-                  JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
-                  null);
-
-          dialogParent.setAlwaysOnTop(false);
-          dialogParent.dispose();
-        }
-        else
-        {
-          n = JOptionPane.OK_OPTION;
-        }
-        canQuit = (n == JOptionPane.OK_OPTION);
-        if (canQuit)
-        {
-          response.performQuit();
-        }
-        else
-        {
-          response.cancelQuit();
-        }
-      });
+      QuitHandler.setQuitHandler();
       setQuit = true;
     }
     // if we got to here, no exceptions occurred when we set the handlers.
index 56e23aa..15cc37a 100644 (file)
@@ -1,10 +1,13 @@
 package jalview.jbgui;
 
+import java.io.File;
+
 import javax.swing.JFrame;
 import javax.swing.JOptionPane;
 
 import com.formdev.flatlaf.extras.FlatDesktop;
 
+import jalview.io.BackupFiles;
 import jalview.util.MessageManager;
 
 public class QuitHandler
@@ -12,37 +15,44 @@ public class QuitHandler
   public static void setQuitHandler()
   {
     FlatDesktop.setQuitHandler(response -> {
+      // confirm quit if needed and wanted
       boolean confirmQuit = jalview.bin.Cache
               .getDefault(jalview.gui.Desktop.CONFIRM_KEYBOARD_QUIT, true);
-      boolean canQuit = !confirmQuit;
-      int n;
+      /* 
+         if undostack is empty
+           confirmQuit = false
+       */
+      int n = confirmQuit ? JOptionPane.CANCEL_OPTION
+              : JOptionPane.OK_OPTION;
+
+      // if going to confirm, do it before the save in progress check to give
+      // the save time to finish!
       if (confirmQuit)
       {
-        // ensure Jalview window is brought to front for Quit confirmation
-        // window to be visible
-
-        // this method of raising the Jalview window is broken in java
-        // jalviewDesktop.setVisible(true);
-        // jalviewDesktop.toFront();
-
-        // a better hack which works instead
-        JFrame dialogParent = new JFrame();
-        dialogParent.setAlwaysOnTop(true);
-
-        n = JOptionPane.showConfirmDialog(dialogParent,
-                MessageManager.getString("label.quit_jalview"),
+        n = frameOnTop(MessageManager.getString("label.quit_jalview"),
                 MessageManager.getString("action.quit"),
-                JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
-                null);
+                JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
 
-        dialogParent.setAlwaysOnTop(false);
-        dialogParent.dispose();
       }
-      else
+
+      if (BackupFiles.hasSavesInProgress())
       {
-        n = JOptionPane.OK_OPTION;
+        // sleep 1
+        // ...
+
+        StringBuilder messageSB = new StringBuilder(
+                MessageManager.getString("label.save_in_progress"));
+        for (File file : BackupFiles.savesInProgressFiles())
+        {
+          messageSB.append("\n");
+          messageSB.append(file.getName());
+        }
+        n = frameOnTop(messageSB.toString(),
+                MessageManager.getString("action.force_quit"),
+                JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
       }
-      canQuit = (n == JOptionPane.OK_OPTION);
+
+      boolean canQuit = (n == JOptionPane.OK_OPTION);
       if (canQuit)
       {
         response.performQuit();
@@ -54,4 +64,28 @@ public class QuitHandler
     });
   }
 
+  public static int frameOnTop(String label, String actionString,
+          int JOPTIONPANE_OPTION, int JOPTIONPANE_MESSAGETYPE)
+  {
+    // ensure Jalview window is brought to front for Quit confirmation
+    // window to be visible
+
+    // this method of raising the Jalview window is broken in java
+    // jalviewDesktop.setVisible(true);
+    // jalviewDesktop.toFront();
+
+    // a better hack which works instead
+
+    JFrame dialogParent = new JFrame();
+    dialogParent.setAlwaysOnTop(true);
+
+    int n = JOptionPane.showConfirmDialog(dialogParent, label, actionString,
+            JOPTIONPANE_OPTION, JOPTIONPANE_MESSAGETYPE);
+
+    dialogParent.setAlwaysOnTop(false);
+    dialogParent.dispose();
+
+    return n;
+  }
+
 }