From 69f09dd6dbf67c00c27fdcfecbbcc932e7eac6a9 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Fri, 2 Sep 2022 17:26:06 +0100 Subject: [PATCH] JAL-1988 Added a saves in progress check for quit --- resources/lang/Messages.properties | 2 + resources/lang/Messages_es.properties | 2 + src/jalview/io/BackupFiles.java | 31 ++++++++++--- src/jalview/jbgui/APQHandlers.java | 46 +------------------ src/jalview/jbgui/QuitHandler.java | 78 +++++++++++++++++++++++---------- 5 files changed, 87 insertions(+), 72 deletions(-) diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 3843ddb..6125bb5 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -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... diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index d0bfd65..e375bad 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -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 diff --git a/src/jalview/io/BackupFiles.java b/src/jalview/io/BackupFiles.java index 05a1ac4..529e1b2 100644 --- a/src/jalview/io/BackupFiles.java +++ b/src/jalview/io/BackupFiles.java @@ -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 savesInProgress = new ArrayList<>(); + private static List 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 savesInProgressFiles() + { + List 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(); diff --git a/src/jalview/jbgui/APQHandlers.java b/src/jalview/jbgui/APQHandlers.java index 1a7e971..12ce1ba 100644 --- a/src/jalview/jbgui/APQHandlers.java +++ b/src/jalview/jbgui/APQHandlers.java @@ -20,13 +20,9 @@ */ 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. diff --git a/src/jalview/jbgui/QuitHandler.java b/src/jalview/jbgui/QuitHandler.java index 56e23aa..15cc37a 100644 --- a/src/jalview/jbgui/QuitHandler.java +++ b/src/jalview/jbgui/QuitHandler.java @@ -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; + } + } -- 1.7.10.2