X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FQuitHandler.java;h=79723cf562040d4eb5b13d271cbc9f34d1b1c533;hb=4b7d3640209c4434d569c746672cf9eed4250ace;hp=75ff0b0616d5776ca108c2c65793f8d515e73d6d;hpb=4c007a518fc7e2fdaa863f16cb715f8e45e6cfbf;p=jalview.git diff --git a/src/jalview/gui/QuitHandler.java b/src/jalview/gui/QuitHandler.java index 75ff0b0..79723cf 100644 --- a/src/jalview/gui/QuitHandler.java +++ b/src/jalview/gui/QuitHandler.java @@ -7,6 +7,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -29,39 +30,51 @@ import jalview.util.Platform; public class QuitHandler { - private static final int MIN_WAIT_FOR_SAVE = 3000; + private static final int MIN_WAIT_FOR_SAVE = 1000; private static final int MAX_WAIT_FOR_SAVE = 20000; - private static final int NON_INTERACTIVE_WAIT_CYCLES = 2; + private static boolean interactive = true; public static enum QResponse { NULL, QUIT, CANCEL_QUIT, FORCE_QUIT }; + public static enum Message + { + UNSAVED_CHANGES, UNSAVED_ALIGNMENTS + }; + + protected static Message message = Message.UNSAVED_CHANGES; + + public static void setMessage(Message m) + { + message = m; + } + private static ExecutorService executor = Executors.newFixedThreadPool(3); public static QResponse setQuitHandler() { FlatDesktop.setQuitHandler(response -> { - Callable performQuit = () -> { + Callable performQuit = () -> { response.performQuit(); - return setResponse(QResponse.QUIT); + setResponse(QResponse.QUIT); + return null; }; - Callable performForceQuit = () -> { + Callable performForceQuit = () -> { response.performQuit(); - return setResponse(QResponse.FORCE_QUIT); + setResponse(QResponse.FORCE_QUIT); + return null; }; - Callable cancelQuit = () -> { + Callable cancelQuit = () -> { response.cancelQuit(); // reset setResponse(QResponse.NULL); - // but return cancel - return QResponse.CANCEL_QUIT; + return null; }; - QResponse qresponse = getQuitResponse(true, performQuit, - performForceQuit, cancelQuit); + getQuitResponse(true, performQuit, performForceQuit, cancelQuit); }); return gotQuitResponse(); @@ -69,7 +82,7 @@ public class QuitHandler private static QResponse gotQuitResponse = QResponse.NULL; - private static QResponse setResponse(QResponse qresponse) + protected static QResponse setResponse(QResponse qresponse) { gotQuitResponse = qresponse; return qresponse; @@ -80,24 +93,25 @@ public class QuitHandler return gotQuitResponse; } - public static final Callable defaultCancelQuit = () -> { + public static final Callable defaultCancelQuit = () -> { Console.debug("QuitHandler: (default) Quit action CANCELLED by user"); // reset - setResponse(QResponse.NULL); - // and return cancel - return QResponse.CANCEL_QUIT; + setResponse(QResponse.CANCEL_QUIT); + return null; }; - public static final Callable defaultOkQuit = () -> { + public static final Callable defaultOkQuit = () -> { Console.debug("QuitHandler: (default) Quit action CONFIRMED by user"); - return setResponse(QResponse.QUIT); + setResponse(QResponse.QUIT); + return null; }; - public static final Callable defaultForceQuit = () -> { + public static final Callable defaultForceQuit = () -> { Console.debug("QuitHandler: (default) Quit action FORCED by user"); // note that shutdown hook will not be run Runtime.getRuntime().halt(0); - return setResponse(QResponse.FORCE_QUIT); // this line never reached! + setResponse(QResponse.FORCE_QUIT); // this line never reached! + return null; }; public static QResponse getQuitResponse(boolean ui) @@ -106,11 +120,8 @@ public class QuitHandler defaultCancelQuit); } - private static boolean interactive = true; - - public static QResponse getQuitResponse(boolean ui, - Callable okQuit, Callable forceQuit, - Callable cancelQuit) + public static QResponse getQuitResponse(boolean ui, Callable okQuit, + Callable forceQuit, Callable cancelQuit) { QResponse got = gotQuitResponse(); if (got != QResponse.NULL && got != QResponse.CANCEL_QUIT) @@ -147,29 +158,73 @@ public class QuitHandler if (confirmQuit) { - JvOptionPane.newOptionDialog() + String messageString = MessageManager + .getString(message == Message.UNSAVED_ALIGNMENTS + ? "label.unsaved_alignments" + : "label.unsaved_changes"); + setQuitDialog(JvOptionPane.newOptionDialog() .setResponseHandler(JOptionPane.YES_OPTION, defaultOkQuit) - .setResponseHandler(JOptionPane.NO_OPTION, defaultCancelQuit) - .showDialogOnTopAsync( - new StringBuilder(MessageManager - .getString("label.quit_jalview")) - .append("\n") - .append(MessageManager.getString( - "label.unsaved_changes")) - .toString(), - MessageManager.getString("action.quit"), - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE, null, new Object[] - { MessageManager.getString("action.quit"), - MessageManager.getString("action.cancel") }, - MessageManager.getString("action.quit"), true); + .setResponseHandler(JOptionPane.NO_OPTION, cancelQuit)); + JvOptionPane qd = getQuitDialog(); + qd.showDialogOnTopAsync( + new StringBuilder( + MessageManager.getString("label.quit_jalview")) + .append("\n").append(messageString) + .toString(), + MessageManager.getString("action.quit"), + JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, + new Object[] + { MessageManager.getString("action.quit"), + MessageManager.getString("action.cancel") }, + MessageManager.getString("action.quit"), true); } got = gotQuitResponse(); + + // check for external viewer frames + if (got != QResponse.CANCEL_QUIT) + { + int count = Desktop.instance.structureViewersStillRunningCount(); + if (count > 0) + { + String prompt = MessageManager + .formatMessage(count == 1 ? "label.confirm_quit_viewer" + : "label.confirm_quit_viewers"); + String title = MessageManager.getString( + count == 1 ? "label.close_viewer" : "label.close_viewers"); + String cancelQuitText = MessageManager + .getString("action.cancel_quit"); + 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); + + if (confirmResponse == JvOptionPane.CANCEL_OPTION) + { + // Cancel Quit + QuitHandler.setResponse(QResponse.CANCEL_QUIT); + } + else + { + // Close viewers/Leave viewers open + StructureViewerBase + .setQuitClose(confirmResponse == JvOptionPane.YES_OPTION); + } + } + + } + + got = gotQuitResponse(); + boolean wait = false; if (got == QResponse.CANCEL_QUIT) { // reset + Console.debug("Cancelling quit. Resetting response to NULL"); setResponse(QResponse.NULL); // but return cancel return QResponse.CANCEL_QUIT; @@ -179,13 +234,13 @@ public class QuitHandler if (Cache.getDefault("WAIT_FOR_SAVE", true) && BackupFiles.hasSavesInProgress()) { - QResponse waitResponse = waitQuit(interactive, okQuit, forceQuit, - cancelQuit); + waitQuit(interactive, okQuit, forceQuit, cancelQuit); + QResponse waitResponse = gotQuitResponse(); wait = waitResponse == QResponse.QUIT; } } - Callable next = null; + Callable next = null; switch (gotQuitResponse()) { case QUIT: @@ -200,7 +255,15 @@ public class QuitHandler } try { - got = executor.submit(next).get(); + executor.submit(next).get(); + got = gotQuitResponse(); + } catch (RejectedExecutionException e) + { + // QuitHander.abortQuit() probably called + // CANCEL_QUIT test will reset QuitHandler + Console.info("Quit aborted!"); + got = QResponse.NULL; + setResponse(QResponse.NULL); } catch (InterruptedException | ExecutionException e) { jalview.bin.Console @@ -208,12 +271,19 @@ public class QuitHandler } setResponse(got); + if (quitCancelled()) + { + // reset if cancelled + Console.debug("Quit cancelled"); + setResponse(QResponse.NULL); + return QResponse.CANCEL_QUIT; + } return gotQuitResponse(); } private static QResponse waitQuit(boolean interactive, - Callable okQuit, Callable forceQuit, - Callable cancelQuit) + Callable okQuit, Callable forceQuit, + Callable cancelQuit) { // check for saves in progress if (!BackupFiles.hasSavesInProgress()) @@ -241,7 +311,6 @@ public class QuitHandler int waitTime = Math.min(MAX_WAIT_FOR_SAVE, Math.max(MIN_WAIT_FOR_SAVE, size / 2)); Console.debug("Set waitForSave to " + waitTime); - QResponse waitResponse = QResponse.NULL; int iteration = 0; boolean doIterations = true; // note iterations not used in the gui now, @@ -300,8 +369,7 @@ public class QuitHandler } else { - if (!(QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT - || QuitHandler.gotQuitResponse() == QResponse.NULL)) + if (!(quitCancelled())) { for (int i = 0; i < buttons.length; i++) { @@ -373,9 +441,7 @@ public class QuitHandler } // end if interactive } // end while wait iteration loop - waitResponse = gotQuitResponse(); - - return waitResponse; + return gotQuitResponse(); }; private static String waitingForSaveMessage() @@ -400,4 +466,34 @@ public class QuitHandler .append(MessageManager.getString("label.quit_after_saving")); return messageSB.toString(); } -} \ No newline at end of file + + public static void abortQuit() + { + setResponse(QResponse.NULL); + // executor.shutdownNow(); + } + + private static JvOptionPane quitDialog = null; + + private static void setQuitDialog(JvOptionPane qd) + { + quitDialog = qd; + } + + private static JvOptionPane getQuitDialog() + { + return quitDialog; + } + + public static boolean quitCancelled() + { + return QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT + || QuitHandler.gotQuitResponse() == QResponse.NULL; + } + + public static boolean quitting() + { + return QuitHandler.gotQuitResponse() == QResponse.QUIT + || QuitHandler.gotQuitResponse() == QResponse.FORCE_QUIT; + } +}