JAL-3811 document SHOW_JWS2_SERVICES user preference and provide new menu option...
[jalview.git] / src / jalview / gui / AlignFrame.java
index 61a6af6..9013416 100644 (file)
  */
 package jalview.gui;
 
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterJob;
+import java.beans.PropertyChangeEvent;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JEditorPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
 import jalview.analysis.AlignmentSorter;
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.CrossRef;
@@ -90,7 +138,9 @@ import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemes;
 import jalview.schemes.ResidueColourScheme;
 import jalview.schemes.TCoffeeColourScheme;
+import jalview.util.HttpUtils;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.ViewportRanges;
 import jalview.ws.DBRefFetcher;
@@ -100,53 +150,6 @@ import jalview.ws.jws2.Jws2Discoverer;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.StringSelection;
-import java.awt.datatransfer.Transferable;
-import java.awt.dnd.DnDConstants;
-import java.awt.dnd.DropTargetDragEvent;
-import java.awt.dnd.DropTargetDropEvent;
-import java.awt.dnd.DropTargetEvent;
-import java.awt.dnd.DropTargetListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.print.PageFormat;
-import java.awt.print.PrinterJob;
-import java.beans.PropertyChangeEvent;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Vector;
-
-import javax.swing.ButtonGroup;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JEditorPane;
-import javax.swing.JInternalFrame;
-import javax.swing.JLayeredPane;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
 /**
  * DOCUMENT ME!
  * 
@@ -536,7 +539,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           }
           if (viewport.cursorMode)
           {
-            alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
+            alignPanel.getSeqPanel().moveCursor(0, 1,
+                    evt.isShiftDown() && !evt.isAltDown());
           }
           break;
 
@@ -547,9 +551,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           }
           if (viewport.cursorMode)
           {
-            alignPanel.getSeqPanel().moveCursor(0, -1,evt.isShiftDown());
+            alignPanel.getSeqPanel().moveCursor(0, -1,
+                    evt.isShiftDown() && !evt.isAltDown());
           }
-
           break;
 
         case KeyEvent.VK_LEFT:
@@ -1034,7 +1038,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         Desktop.instance.closeAssociatedWindows();
 
         FileLoader loader = new FileLoader();
-        DataSourceType protocol = fileName.startsWith("http:")
+        DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
                 ? DataSourceType.URL
                 : DataSourceType.FILE;
         loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
@@ -1044,7 +1048,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         Rectangle bounds = this.getBounds();
 
         FileLoader loader = new FileLoader();
-        DataSourceType protocol = fileName.startsWith("http:")
+        DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
                 ? DataSourceType.URL
                 : DataSourceType.FILE;
         AlignFrame newframe = loader.LoadFileWaitTillLoaded(fileName,
@@ -1091,7 +1095,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void save_actionPerformed(ActionEvent e)
   {
     if (fileName == null || (currentFileFormat == null)
-            || fileName.startsWith("http"))
+            || HttpUtils.startsWithHttpOrHttps(fileName))
     {
       saveAs_actionPerformed(null);
     }
@@ -1168,7 +1172,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
       statusBar.setText(MessageManager.formatMessage(
               "label.successfully_saved_to_file_in_format", new Object[]
-              { fileName, format }));
+              { file, format }));
 
     }
     else
@@ -1197,39 +1201,66 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       else
       {
         // create backupfiles object and get new temp filename destination
+        Cache.log.trace("ALIGNFRAME making backupfiles object for " + file);
         BackupFiles backupfiles = new BackupFiles(file);
 
         try
         {
-          PrintWriter out = new PrintWriter(
-                  new FileWriter(backupfiles.getTempFilePath()));
+          String tempFilePath = backupfiles.getTempFilePath();
+          Cache.log.trace(
+                  "ALIGNFRAME setting PrintWriter to " + tempFilePath);
+          PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
+
+          Cache.log.trace(
+                  "ALIGNFRAME about to write to temp file " + tempFilePath);
 
           out.print(output);
+          Cache.log.trace("ALIGNFRAME about to close file");
           out.close();
+          Cache.log.trace("ALIGNFRAME closed file");
           this.setTitle(file);
           statusBar.setText(MessageManager.formatMessage(
                   "label.successfully_saved_to_file_in_format", new Object[]
-                  { fileName, format.getName() }));
+                  { file, format.getName() }));
+        } catch (IOException e)
+        {
+          success = false;
+          Cache.log.error(
+                  "ALIGNFRAME Something happened writing the temp file");
+          Cache.log.error(e.getMessage());
+          Cache.log.debug(Cache.getStackTraceString(e));
+
         } catch (Exception ex)
         {
           success = false;
-          ex.printStackTrace();
+          Cache.log.error(
+                  "ALIGNFRAME Something unexpected happened writing the temp file");
+          Cache.log.error(ex.getMessage());
+          Cache.log.debug(Cache.getStackTraceString(ex));
         }
 
         backupfiles.setWriteSuccess(success);
+        Cache.log.debug("ALIGNFRAME writing temp file was "
+                + (success ? "" : "NOT ") + "successful");
         // do the backup file roll and rename the temp file to actual file
+        Cache.log.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
         success = backupfiles.rollBackupsAndRenameTempFile();
+        Cache.log.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
+                + (success ? "" : "un") + "successfully");
 
       }
     }
 
     if (!success)
     {
-      JvOptionPane.showInternalMessageDialog(this, MessageManager
-              .formatMessage("label.couldnt_save_file", new Object[]
-              { fileName }),
-              MessageManager.getString("label.error_saving_file"),
-              JvOptionPane.WARNING_MESSAGE);
+      if (!Platform.isHeadless())
+      {
+        JvOptionPane.showInternalMessageDialog(this, MessageManager
+                .formatMessage("label.couldnt_save_file", new Object[]
+                { file }),
+                MessageManager.getString("label.error_saving_file"),
+                JvOptionPane.WARNING_MESSAGE);
+      }
     }
 
     return success;
@@ -1719,10 +1750,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   /**
-   * DOCUMENT ME!
+   * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
+   * or the sequence under cursor in keyboard mode
    * 
    * @param up
-   *          DOCUMENT ME!
+   *          or down (if !up)
    */
   public void moveSelectedSequences(boolean up)
   {
@@ -1730,8 +1762,25 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     if (sg == null)
     {
+      if (viewport.cursorMode)
+      {
+        sg = new SequenceGroup();
+        sg.addSequence(viewport.getAlignment().getSequenceAt(
+                alignPanel.getSeqPanel().seqCanvas.cursorY), false);
+      }
+      else
+      {
+        return;
+      }
+    }
+
+    if (sg.getSize() < 1)
+    {
       return;
     }
+
+    // TODO: JAL-3733 - add an event to the undo buffer for this !
+
     viewport.getAlignment().moveSelectedSequencesByOne(sg,
             viewport.getHiddenRepSequences(), up);
     alignPanel.paintAlignment(true, false);
@@ -2687,15 +2736,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   /**
-   * DOCUMENT ME!
+   * Opens a Finder dialog
    * 
    * @param e
-   *          DOCUMENT ME!
    */
   @Override
   public void findMenuItem_actionPerformed(ActionEvent e)
   {
-    new Finder();
+    new Finder(alignPanel);
   }
 
   /**
@@ -2736,8 +2784,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     if (viewport.getViewName() == null)
     {
-      viewport.setViewName(MessageManager
-              .getString("label.view_name_original"));
+      viewport.setViewName(
+              MessageManager.getString("label.view_name_original"));
     }
 
     /*
@@ -3366,8 +3414,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
      * otherwise set the chosen colour scheme (or null for 'None')
      */
     ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
-            viewport,
-            viewport.getAlignment(), viewport.getHiddenRepSequences());
+            viewport, viewport.getAlignment(),
+            viewport.getHiddenRepSequences());
     changeColour(cs);
   }
 
@@ -4126,9 +4174,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                   webService.add(me.webServiceNoServices);
                 }
                 // TODO: move into separate menu builder class.
-                boolean new_sspred = false;
-                if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
                 {
+                  // logic for 2.11.1.4 is
+                  // always look to see if there is a discover. if there isn't
+                  // we can't show any Jws2 services
+                  // if there are services available, show them - regardless of
+                  // the 'show JWS2 preference'
+                  // if the discoverer is running then say so
+                  // otherwise offer to trigger discovery if 'show JWS2' is not
+                  // enabled
                   Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
                   if (jws2servs != null)
                   {
@@ -4145,8 +4199,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                           }
                         }
                       }
-
                     }
+
                     if (jws2servs.isRunning())
                     {
                       JMenuItem tm = new JMenuItem(
@@ -4154,6 +4208,26 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                       tm.setEnabled(false);
                       webService.add(tm);
                     }
+                    else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
+                    {
+                      JMenuItem enableJws2 = new JMenuItem(
+                              "Discover Web Services");
+                      enableJws2.setToolTipText(
+                              "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
+                      enableJws2.setEnabled(true);
+                      enableJws2.addActionListener(new ActionListener()
+                      {
+
+                        @Override
+                        public void actionPerformed(ActionEvent e)
+                        {
+                          // start service discoverer, but ignore preference
+                          Desktop.instance.startServiceDiscovery(false,
+                                  true);
+                        }
+                      });
+                      webService.add(enableJws2);
+                    }
                   }
                 }
                 build_urlServiceMenu(me.webService);
@@ -5694,6 +5768,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   private Rectangle lastFeatureSettingsBounds = null;
+
   @Override
   public void setFeatureSettingsGeometry(Rectangle bounds)
   {