X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FQuitHandler.java;h=1b48c6de42c0544f69fface0d45517508274d946;hb=1f346fcfa0e00be0adaa82b394e6ce8b7b9e416b;hp=bedddd1f95153e167de8cc179d14ef76ef31b5da;hpb=140b350c1bb78f0d6b46f9fcbfc523a05c32beba;p=jalview.git diff --git a/src/jalview/gui/QuitHandler.java b/src/jalview/gui/QuitHandler.java index bedddd1..1b48c6d 100644 --- a/src/jalview/gui/QuitHandler.java +++ b/src/jalview/gui/QuitHandler.java @@ -1,12 +1,33 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.gui; import java.io.File; import java.util.List; -import java.util.concurrent.Callable; +import java.util.Locale; 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; @@ -16,6 +37,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 +57,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,29 +78,17 @@ public class QuitHandler private static ExecutorService executor = Executors.newFixedThreadPool(3); - public static QResponse setQuitHandler() + public static void setQuitHandler() { FlatDesktop.setQuitHandler(response -> { - Callable performQuit = () -> { - response.performQuit(); - setResponse(QResponse.QUIT); - return null; - }; - Callable performForceQuit = () -> { - response.performQuit(); - setResponse(QResponse.FORCE_QUIT); - return null; - }; - Callable cancelQuit = () -> { - response.cancelQuit(); - // reset - setResponse(QResponse.NULL); - return 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; @@ -84,6 +96,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; } @@ -92,25 +109,22 @@ public class QuitHandler return gotQuitResponse; } - public static final Callable defaultCancelQuit = () -> { + public static final Runnable defaultCancelQuit = () -> { Console.debug("QuitHandler: (default) Quit action CANCELLED by user"); // reset setResponse(QResponse.CANCEL_QUIT); - return null; }; - public static final Callable defaultOkQuit = () -> { + public static final Runnable defaultOkQuit = () -> { Console.debug("QuitHandler: (default) Quit action CONFIRMED by user"); setResponse(QResponse.QUIT); - return null; }; - public static final Callable defaultForceQuit = () -> { + public static final Runnable defaultForceQuit = () -> { Console.debug("QuitHandler: (default) Quit action FORCED by user"); // note that shutdown hook will not be run Runtime.getRuntime().halt(0); setResponse(QResponse.FORCE_QUIT); // this line never reached! - return null; }; public static QResponse getQuitResponse(boolean ui) @@ -119,8 +133,8 @@ public class QuitHandler defaultCancelQuit); } - public static QResponse getQuitResponse(boolean ui, Callable okQuit, - Callable forceQuit, Callable cancelQuit) + public static QResponse getQuitResponse(boolean ui, Runnable okQuit, + Runnable forceQuit, Runnable cancelQuit) { QResponse got = gotQuitResponse(); if (got != QResponse.NULL && got != QResponse.CANCEL_QUIT) @@ -161,22 +175,77 @@ public class QuitHandler .getString(message == Message.UNSAVED_ALIGNMENTS ? "label.unsaved_alignments" : "label.unsaved_changes"); - JvOptionPane.newOptionDialog() + setQuitDialog(JvOptionPane.newOptionDialog() .setResponseHandler(JOptionPane.YES_OPTION, defaultOkQuit) - .setResponseHandler(JOptionPane.NO_OPTION, cancelQuit) - .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); + .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 alwaysCloseExternalViewers = Cache + .getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", "ask"); + 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 = -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) + { + // 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) { @@ -197,7 +266,7 @@ public class QuitHandler } } - Callable next = null; + Runnable next = null; switch (gotQuitResponse()) { case QUIT: @@ -214,6 +283,13 @@ public class QuitHandler { 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 @@ -221,25 +297,25 @@ public class QuitHandler } setResponse(got); - if (gotQuitResponse() == QResponse.CANCEL_QUIT) + 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) + private static QResponse waitQuit(boolean interactive, Runnable okQuit, + Runnable forceQuit, Runnable cancelQuit) { // check for saves in progress if (!BackupFiles.hasSavesInProgress()) return QResponse.QUIT; int size = 0; - AlignFrame[] afArray = Desktop.getAlignFrames(); + AlignFrame[] afArray = Desktop.getDesktopAlignFrames(); if (!(afArray == null || afArray.length == 0)) { for (int i = 0; i < afArray.length; i++) @@ -318,8 +394,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++) { @@ -419,6 +494,31 @@ public class QuitHandler public static void abortQuit() { - setResponse(QResponse.CANCEL_QUIT); + 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; } -} \ No newline at end of file +}