JAL-1988 JAL-3772 Moving packages to somewhere more obvious (jbgui -> gui)
[jalview.git] / src / jalview / jbgui / QuitHandler.java
diff --git a/src/jalview/jbgui/QuitHandler.java b/src/jalview/jbgui/QuitHandler.java
deleted file mode 100644 (file)
index 7b5be98..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-package jalview.jbgui;
-
-import java.io.File;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.JTextPane;
-
-import com.formdev.flatlaf.extras.FlatDesktop;
-
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-import jalview.bin.Console;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.gui.Desktop;
-import jalview.gui.JvOptionPane;
-import jalview.io.BackupFiles;
-import jalview.project.Jalview2XML;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-
-public class QuitHandler
-{
-  private static final int MIN_WAIT_FOR_SAVE = 3000;
-
-  private static final int MAX_WAIT_FOR_SAVE = 20000;
-
-  private static final int NON_INTERACTIVE_WAIT_CYCLES = 2;
-
-  public static enum QResponse
-  {
-    NULL, QUIT, CANCEL_QUIT, FORCE_QUIT
-  };
-
-  private static ExecutorService executor = Executors.newFixedThreadPool(3);
-
-  public static QResponse setQuitHandler()
-  {
-    FlatDesktop.setQuitHandler(response -> {
-      Callable<QResponse> performQuit = () -> {
-        response.performQuit();
-        return setResponse(QResponse.QUIT);
-      };
-      Callable<QResponse> performForceQuit = () -> {
-        response.performQuit();
-        return setResponse(QResponse.FORCE_QUIT);
-      };
-      Callable<QResponse> cancelQuit = () -> {
-        response.cancelQuit();
-        // reset
-        setResponse(QResponse.NULL);
-        // but return cancel
-        return QResponse.CANCEL_QUIT;
-      };
-      QResponse qresponse = getQuitResponse(true, performQuit,
-              performForceQuit, cancelQuit);
-    });
-
-    return gotQuitResponse();
-  }
-
-  private static QResponse gotQuitResponse = QResponse.NULL;
-
-  private static QResponse setResponse(QResponse qresponse)
-  {
-    gotQuitResponse = qresponse;
-    return qresponse;
-  }
-
-  public static QResponse gotQuitResponse()
-  {
-    return gotQuitResponse;
-  }
-
-  public static final Callable<QResponse> defaultCancelQuit = () -> {
-    Console.debug("QuitHandler: (default) Quit action CANCELLED by user");
-    // reset
-    setResponse(QResponse.NULL);
-    // and return cancel
-    return QResponse.CANCEL_QUIT;
-  };
-
-  public static final Callable<QResponse> defaultOkQuit = () -> {
-    Console.debug("QuitHandler: (default) Quit action CONFIRMED by user");
-    return setResponse(QResponse.QUIT);
-  };
-
-  public static final Callable<QResponse> 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!
-  };
-
-  public static QResponse getQuitResponse(boolean ui)
-  {
-    return getQuitResponse(ui, defaultOkQuit, defaultForceQuit,
-            defaultCancelQuit);
-  }
-
-  private static boolean interactive = true;
-
-  public static QResponse getQuitResponse(boolean ui,
-          Callable<QResponse> okQuit, Callable<QResponse> forceQuit,
-          Callable<QResponse> cancelQuit)
-  {
-    QResponse got = gotQuitResponse();
-    if (got != QResponse.NULL && got != QResponse.CANCEL_QUIT)
-    {
-      // quit has already been selected, continue with calling quit method
-      return got;
-    }
-
-    interactive = ui && !Platform.isHeadless();
-    // confirm quit if needed and wanted
-    boolean confirmQuit = true;
-
-    if (!interactive)
-    {
-      Console.debug("Non interactive quit -- not confirming");
-      confirmQuit = false;
-    }
-    else if (Jalview2XML.allSavedUpToDate())
-    {
-      Console.debug("Nothing changed -- not confirming quit");
-      confirmQuit = false;
-    }
-    else
-    {
-      confirmQuit = jalview.bin.Cache
-              .getDefault(jalview.gui.Desktop.CONFIRM_KEYBOARD_QUIT, true);
-      Console.debug("Jalview property '"
-              + jalview.gui.Desktop.CONFIRM_KEYBOARD_QUIT
-              + "' is/defaults to " + confirmQuit + " -- "
-              + (confirmQuit ? "" : "not ") + "confirming quit");
-    }
-    got = confirmQuit ? QResponse.NULL : QResponse.QUIT;
-    setResponse(got);
-
-    if (confirmQuit)
-    {
-      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);
-    }
-
-    got = gotQuitResponse();
-    boolean wait = false;
-    if (got == QResponse.CANCEL_QUIT)
-    {
-      // reset
-      setResponse(QResponse.NULL);
-      // but return cancel
-      return QResponse.CANCEL_QUIT;
-    }
-    else if (got == QResponse.QUIT)
-    {
-      if (Cache.getDefault("WAIT_FOR_SAVE", true)
-              && BackupFiles.hasSavesInProgress())
-      {
-        QResponse waitResponse = waitQuit(interactive, okQuit, forceQuit,
-                cancelQuit);
-        wait = waitResponse == QResponse.QUIT;
-      }
-    }
-
-    Callable<QResponse> next = null;
-    switch (gotQuitResponse())
-    {
-    case QUIT:
-      next = okQuit;
-      break;
-    case FORCE_QUIT: // not actually an option at this stage
-      next = forceQuit;
-      break;
-    default:
-      next = cancelQuit;
-      break;
-    }
-    try
-    {
-      got = executor.submit(next).get();
-    } catch (InterruptedException | ExecutionException e)
-    {
-      jalview.bin.Console
-              .debug("Exception during quit handling (final choice)", e);
-    }
-    setResponse(got);
-
-    return gotQuitResponse();
-  }
-
-  private static QResponse waitQuit(boolean interactive,
-          Callable<QResponse> okQuit, Callable<QResponse> forceQuit,
-          Callable<QResponse> cancelQuit)
-  {
-    // check for saves in progress
-    if (!BackupFiles.hasSavesInProgress())
-      return QResponse.QUIT;
-
-    int size = 0;
-    AlignFrame[] afArray = Desktop.getAlignFrames();
-    if (!(afArray == null || afArray.length == 0))
-    {
-      for (int i = 0; i < afArray.length; i++)
-      {
-        AlignFrame af = afArray[i];
-        List<? extends AlignmentViewPanel> avpList = af.getAlignPanels();
-        for (AlignmentViewPanel avp : avpList)
-        {
-          AlignmentI a = avp.getAlignment();
-          List<SequenceI> sList = a.getSequences();
-          for (SequenceI s : sList)
-          {
-            size += s.getLength();
-          }
-        }
-      }
-    }
-    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,
-                                 // only one pass without the "Wait" button
-    while (doIterations && BackupFiles.hasSavesInProgress()
-            && iteration++ < (interactive ? 100 : 5))
-    {
-      // future that returns a Boolean when all files are saved
-      CompletableFuture<Boolean> filesAllSaved = new CompletableFuture<>();
-
-      // callback as each file finishes saving
-      for (CompletableFuture<Boolean> cf : BackupFiles
-              .savesInProgressCompletableFutures(false))
-      {
-        // if this is the last one then complete filesAllSaved
-        cf.whenComplete((ret, e) -> {
-          if (!BackupFiles.hasSavesInProgress())
-          {
-            filesAllSaved.complete(true);
-          }
-        });
-      }
-      try
-      {
-        filesAllSaved.get(waitTime, TimeUnit.MILLISECONDS);
-      } catch (InterruptedException | ExecutionException e1)
-      {
-        Console.debug(
-                "Exception whilst waiting for files to save before quit",
-                e1);
-      } catch (TimeoutException e2)
-      {
-        // this Exception to be expected
-      }
-
-      if (interactive && BackupFiles.hasSavesInProgress())
-      {
-        boolean showForceQuit = iteration > 0; // iteration > 1 to not show
-                                               // force quit the first time
-        JFrame parent = new JFrame();
-        JButton[] buttons = { new JButton(), new JButton() };
-        JvOptionPane waitDialog = JvOptionPane.newOptionDialog();
-        JTextPane messagePane = new JTextPane();
-        messagePane.setBackground(waitDialog.getBackground());
-        messagePane.setBorder(null);
-        messagePane.setText(waitingForSaveMessage());
-        // callback as each file finishes saving
-        for (CompletableFuture<Boolean> cf : BackupFiles
-                .savesInProgressCompletableFutures(false))
-        {
-          cf.whenComplete((ret, e) -> {
-            if (BackupFiles.hasSavesInProgress())
-            {
-              // update the list of saving files as they save too
-              messagePane.setText(waitingForSaveMessage());
-            }
-            else
-            {
-              if (!(QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT
-                      || QuitHandler.gotQuitResponse() == QResponse.NULL))
-              {
-                for (int i = 0; i < buttons.length; i++)
-                {
-                  Console.debug("DISABLING BUTTON " + buttons[i].getText());
-                  buttons[i].setEnabled(false);
-                  buttons[i].setVisible(false);
-                }
-                // if this is the last one then close the dialog
-                messagePane.setText(new StringBuilder()
-                        .append(MessageManager.getString("label.all_saved"))
-                        .append("\n")
-                        .append(MessageManager
-                                .getString("label.quitting_bye"))
-                        .toString());
-                messagePane.setEditable(false);
-                try
-                {
-                  Thread.sleep(1500);
-                } catch (InterruptedException e1)
-                {
-                }
-                parent.dispose();
-              }
-            }
-          });
-        }
-
-        String[] options;
-        int dialogType = -1;
-        if (showForceQuit)
-        {
-          options = new String[2];
-          options[0] = MessageManager.getString("action.force_quit");
-          options[1] = MessageManager.getString("action.cancel_quit");
-          dialogType = JOptionPane.YES_NO_OPTION;
-          waitDialog.setResponseHandler(JOptionPane.YES_OPTION, forceQuit)
-                  .setResponseHandler(JOptionPane.NO_OPTION, cancelQuit);
-        }
-        else
-        {
-          options = new String[1];
-          options[0] = MessageManager.getString("action.cancel_quit");
-          dialogType = JOptionPane.YES_OPTION;
-          waitDialog.setResponseHandler(JOptionPane.YES_OPTION, cancelQuit);
-        }
-        waitDialog.showDialogOnTopAsync(parent, messagePane,
-                MessageManager.getString("label.wait_for_save"), dialogType,
-                JOptionPane.WARNING_MESSAGE, null, options,
-                MessageManager.getString("action.cancel_quit"), true,
-                buttons);
-
-        parent.dispose();
-        final QResponse thisWaitResponse = gotQuitResponse();
-        switch (thisWaitResponse)
-        {
-        case QUIT: // wait -- do another iteration
-          break;
-        case FORCE_QUIT:
-          doIterations = false;
-          break;
-        case CANCEL_QUIT:
-          doIterations = false;
-          break;
-        case NULL: // already cancelled
-          doIterations = false;
-          break;
-        default:
-        }
-      } // end if interactive
-
-    } // end while wait iteration loop
-    waitResponse = gotQuitResponse();
-
-    return waitResponse;
-  };
-
-  private static String waitingForSaveMessage()
-  {
-    StringBuilder messageSB = new StringBuilder();
-
-    messageSB.append(MessageManager.getString("label.save_in_progress"));
-    List<File> files = BackupFiles.savesInProgressFiles(false);
-    boolean any = files.size() > 0;
-    if (any)
-    {
-      for (File file : files)
-      {
-        messageSB.append("\n\u2022 ").append(file.getName());
-      }
-    }
-    else
-    {
-      messageSB.append(MessageManager.getString("label.unknown"));
-    }
-    messageSB.append("\n\n")
-            .append(MessageManager.getString("label.quit_after_saving"));
-    return messageSB.toString();
-  }
-}
\ No newline at end of file