X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FDesktop.java;h=fc360477c8d3879ab9e84172046b8e5e8495c7b4;hb=a69afbfd46b6defc7e7b7dd15f67a3d6dbad2559;hp=647971e7ac8dfd21a4968128b42e6ea37feb125e;hpb=b9bde68b87a581a1f21e47cb19839791a192134a;p=jalview.git diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 647971e..fc36047 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -24,6 +24,7 @@ import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.bin.Jalview; +import jalview.io.BackupFiles; import jalview.io.DataSourceType; import jalview.io.FileFormat; import jalview.io.FileFormatException; @@ -36,6 +37,7 @@ import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; import jalview.jbgui.GSplitFrame; import jalview.jbgui.GStructureViewer; +import jalview.project.Jalview2XML; import jalview.structure.StructureSelectionManager; import jalview.urls.IdOrgSettings; import jalview.util.ImageMaker; @@ -60,13 +62,16 @@ import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; -import java.awt.desktop.AboutEvent; +import java.awt.desktop.QuitStrategy; +/* not importing directly. Calling classes with full name in try block to allow Java 1.8 runtime import java.awt.desktop.AboutHandler; import java.awt.desktop.PreferencesEvent; import java.awt.desktop.PreferencesHandler; import java.awt.desktop.QuitEvent; import java.awt.desktop.QuitHandler; import java.awt.desktop.QuitResponse; +import java.awt.desktop.QuitStrategy; +*/ import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; @@ -151,6 +156,8 @@ public class Desktop extends jalview.jbgui.GDesktop private static final String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES"; + private static final String CONFIRM_KEYBOARD_QUIT = "CONFIRM_KEYBOARD_QUIT"; + public static HashMap savingFiles = new HashMap<>(); private JalviewChangeSupport changeSupport = new JalviewChangeSupport(); @@ -162,6 +169,8 @@ public class Desktop extends jalview.jbgui.GDesktop private File projectFile; + private static boolean setAPQHandlers = false; + /** * @param listener * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener) @@ -354,63 +363,135 @@ public class Desktop extends jalview.jbgui.GDesktop doConfigureStructurePrefs(); setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION")); - // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - /* comments - * galore - * to - * change the line numbers - */ - /* if (!Platform.isAMac()) { // this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } else + { + this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + } */ - // { - // this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - java.awt.Desktop hdesktop = java.awt.Desktop.getDesktop(); - hdesktop.setAboutHandler(new AboutHandler() + // flagging this test to avoid unnecessary reflection + if (!setAPQHandlers) { - @Override - public void handleAbout(AboutEvent e) - { - aboutMenuItem_actionPerformed(null); - } - }); - hdesktop.setPreferencesHandler(new PreferencesHandler() - { - @Override - public void handlePreferences(PreferencesEvent e) - { - preferences_actionPerformed(null); - } - }); - hdesktop.setQuitHandler(new QuitHandler() - { - @Override - public void handleQuitRequestWith(QuitEvent e, QuitResponse r) + // see if the Quit, About and Preferences handlers are available + Class desktopClass = java.awt.Desktop.class; + java.awt.Desktop hdesktop = java.awt.Desktop.getDesktop(); + + try { - int n = JOptionPane.showConfirmDialog(null, - MessageManager.getString("label.quit_jalview"), - MessageManager.getString("action.quit"), - JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, - null); - if (n == JOptionPane.OK_OPTION) + Float specversion = Float.parseFloat( + System.getProperty("java.specification.version")); + + if (specversion >= 9) { - System.out.println("Shortcut Quit confirmed by user"); - quit(); + if (Platform.isAMac()) + { + if (desktopClass.getDeclaredMethod("setAboutHandler", + new Class[] + { java.awt.desktop.AboutHandler.class }) != null) + { + + hdesktop.setAboutHandler(new java.awt.desktop.AboutHandler() + { + @Override + public void handleAbout(java.awt.desktop.AboutEvent e) + { + aboutMenuItem_actionPerformed(null); + } + }); + + } + + if (desktopClass.getDeclaredMethod("setPreferencesHandler", + new Class[] + { java.awt.desktop.PreferencesHandler.class }) != null) + { + + hdesktop.setPreferencesHandler( + new java.awt.desktop.PreferencesHandler() + { + @Override + public void handlePreferences( + java.awt.desktop.PreferencesEvent e) + { + preferences_actionPerformed(null); + } + }); + + } + + if (desktopClass.getDeclaredMethod("setQuitHandler", + new Class[] + { java.awt.desktop.QuitHandler.class }) != null) + { + + hdesktop.setQuitHandler(new java.awt.desktop.QuitHandler() + { + @Override + public void handleQuitRequestWith( + java.awt.desktop.QuitEvent e, + java.awt.desktop.QuitResponse r) + { + boolean confirmQuit = jalview.bin.Cache + .getDefault(CONFIRM_KEYBOARD_QUIT, true); + int n; + if (confirmQuit) + { + n = JOptionPane.showConfirmDialog(null, + MessageManager.getString("label.quit_jalview"), + MessageManager.getString("action.quit"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.PLAIN_MESSAGE, null); + } + else + { + n = JOptionPane.OK_OPTION; + } + if (n == JOptionPane.OK_OPTION) + { + System.out.println("Shortcut Quit confirmed by user"); + quit(); + r.performQuit(); // probably won't reach this line, but just + // in + // case + } + else + { + r.cancelQuit(); + System.out.println("Shortcut Quit cancelled by user"); + } + } + }); + hdesktop.setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS); + + } + } } else { - System.out.println("Shortcut Quit cancelled by user"); + System.out.println( + "Not going to try setting APQ Handlers as java.spec.version is " + + specversion); } + + } catch (Exception e) + { + System.out.println( + "Exception when looking for About, Preferences, Quit Handlers"); + e.printStackTrace(); + } catch (Throwable t) + { + System.out.println( + "Throwable when looking for About, Preferences, Quit Handlers"); + t.printStackTrace(); } - }); - // } + setAPQHandlers = true; + } addWindowListener(new WindowAdapter() { @@ -1049,7 +1130,7 @@ public class Desktop extends jalview.jbgui.GDesktop KeyStroke ctrlWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK); KeyStroke cmdWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, - Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); + Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()); InputMap inputMap = frame .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); @@ -1163,7 +1244,7 @@ public class Desktop extends jalview.jbgui.GDesktop { String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT"); JalviewFileChooser chooser = JalviewFileChooser - .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat); + .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat, true); chooser.setFileView(new JalviewFileView()); chooser.setDialogTitle( @@ -1328,8 +1409,8 @@ public class Desktop extends jalview.jbgui.GDesktop @Override public void quit() { - System.out.println("********** Desktop.quit()"); - System.out.println(savingFiles.toString()); + //System.out.println("********** Desktop.quit()"); + //System.out.println(savingFiles.toString()); Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); jalview.bin.Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + ""); @@ -1678,28 +1759,49 @@ public class Desktop extends jalview.jbgui.GDesktop } /** - * DOCUMENT ME! - * - * @param e - * DOCUMENT ME! + * Shows a file chooser dialog and writes out the current session as a Jalview + * project file */ @Override - public void saveState_actionPerformed(ActionEvent e) + public void saveState_actionPerformed() { - JalviewFileChooser chooser = new JalviewFileChooser("jvp", - "Jalview Project"); + saveState_actionPerformed(false); + } - chooser.setFileView(new JalviewFileView()); - chooser.setDialogTitle(MessageManager.getString("label.save_state")); + public void saveState_actionPerformed(boolean saveAs) + { + java.io.File projectFile = getProjectFile(); + // autoSave indicates we already have a file and don't need to ask + boolean autoSave = projectFile != null && !saveAs + && BackupFiles.getEnabled(); - int value = chooser.showSaveDialog(this); + // System.out.println("autoSave="+autoSave+", projectFile='"+projectFile+"', + // saveAs="+saveAs+", Backups + // "+(BackupFiles.getEnabled()?"enabled":"disabled")); - if (value == JalviewFileChooser.APPROVE_OPTION) + boolean approveSave = false; + if (!autoSave) { - final Desktop me = this; - final java.io.File choice = chooser.getSelectedFile(); - setProjectFile(choice); + JalviewFileChooser chooser = new JalviewFileChooser("jvp", + "Jalview Project"); + + chooser.setFileView(new JalviewFileView()); + chooser.setDialogTitle(MessageManager.getString("label.save_state")); + int value = chooser.showSaveDialog(this); + + if (value == JalviewFileChooser.APPROVE_OPTION) + { + projectFile = chooser.getSelectedFile(); + setProjectFile(projectFile); + approveSave = true; + } + } + + if (approveSave || autoSave) + { + final Desktop me = this; + final java.io.File chosenFile = projectFile; new Thread(new Runnable() { @Override @@ -1708,38 +1810,47 @@ public class Desktop extends jalview.jbgui.GDesktop // TODO: refactor to Jalview desktop session controller action. setProgressBar(MessageManager.formatMessage( "label.saving_jalview_project", new Object[] - { choice.getName() }), choice.hashCode()); + { chosenFile.getName() }), chosenFile.hashCode()); jalview.bin.Cache.setProperty("LAST_DIRECTORY", - choice.getParent()); + chosenFile.getParent()); // TODO catch and handle errors for savestate // TODO prevent user from messing with the Desktop whilst we're saving try { - new Jalview2XML().saveState(choice); + BackupFiles backupfiles = new BackupFiles(chosenFile); + + new Jalview2XML().saveState(backupfiles.getTempFile()); + + backupfiles.setWriteSuccess(true); + backupfiles.rollBackupsAndRenameTempFile(); } catch (OutOfMemoryError oom) { - new OOMWarning( - "Whilst saving current state to " + choice.getName(), - oom); + new OOMWarning("Whilst saving current state to " + + chosenFile.getName(), oom); } catch (Exception ex) { - Cache.log.error( - "Problems whilst trying to save to " + choice.getName(), - ex); + Cache.log.error("Problems whilst trying to save to " + + chosenFile.getName(), ex); JvOptionPane.showMessageDialog(me, MessageManager.formatMessage( "label.error_whilst_saving_current_state_to", new Object[] - { choice.getName() }), + { chosenFile.getName() }), MessageManager.getString("label.couldnt_save_project"), JvOptionPane.WARNING_MESSAGE); } - setProgressBar(null, choice.hashCode()); + setProgressBar(null, chosenFile.hashCode()); } }).start(); } } + @Override + public void saveAsState_actionPerformed(ActionEvent e) + { + saveState_actionPerformed(true); + } + private void setProjectFile(File choice) { this.projectFile = choice; @@ -1751,20 +1862,19 @@ public class Desktop extends jalview.jbgui.GDesktop } /** - * DOCUMENT ME! - * - * @param e - * DOCUMENT ME! + * Shows a file chooser dialog and tries to read in the selected file as a + * Jalview project */ @Override - public void loadState_actionPerformed(ActionEvent e) + public void loadState_actionPerformed() { + final String[] suffix = new String[] { "jvp", "jar" }; + final String[] desc = new String[] { "Jalview Project", + "Jalview Project (old)" }; JalviewFileChooser chooser = new JalviewFileChooser( - Cache.getProperty("LAST_DIRECTORY"), new String[] - { "jvp", "jar" }, - new String[] - { "Jalview Project", "Jalview Project (old)" }, - "Jalview Project"); + Cache.getProperty("LAST_DIRECTORY"), suffix, desc, + "Jalview Project", true, true); // last two booleans: allFiles, + // allowBackupFiles chooser.setFileView(new JalviewFileView()); chooser.setDialogTitle(MessageManager.getString("label.restore_state")); @@ -2768,7 +2878,7 @@ public class Desktop extends jalview.jbgui.GDesktop { getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, - Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), + Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()), "Quit"); getRootPane().getActionMap().put("Quit", new AbstractAction() { @@ -2825,18 +2935,18 @@ public class Desktop extends jalview.jbgui.GDesktop progressBarHandlers = new Hashtable<>(); } - if (progressBars.get(new Long(id)) != null) + if (progressBars.get(Long.valueOf(id)) != null) { - JPanel panel = progressBars.remove(new Long(id)); - if (progressBarHandlers.contains(new Long(id))) + JPanel panel = progressBars.remove(Long.valueOf(id)); + if (progressBarHandlers.contains(Long.valueOf(id))) { - progressBarHandlers.remove(new Long(id)); + progressBarHandlers.remove(Long.valueOf(id)); } removeProgressPanel(panel); } else { - progressBars.put(new Long(id), addProgressPanel(message)); + progressBars.put(Long.valueOf(id), addProgressPanel(message)); } } @@ -2851,13 +2961,13 @@ public class Desktop extends jalview.jbgui.GDesktop final IProgressIndicatorHandler handler) { if (progressBarHandlers == null - || !progressBars.containsKey(new Long(id))) + || !progressBars.containsKey(Long.valueOf(id))) { throw new Error(MessageManager.getString( "error.call_setprogressbar_before_registering_handler")); } - progressBarHandlers.put(new Long(id), handler); - final JPanel progressPanel = progressBars.get(new Long(id)); + progressBarHandlers.put(Long.valueOf(id), handler); + final JPanel progressPanel = progressBars.get(Long.valueOf(id)); if (handler.canCancel()) { JButton cancel = new JButton(