JAL-845 first working linked edit protein -> cDNA
[jalview.git] / src / jalview / gui / SeqPanel.java
index 94d5ca8..2c9b7f6 100644 (file)
@@ -1,36 +1,60 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
- * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 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.
+ * 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 <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
-
 package jalview.gui;
 
-import java.util.*;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.commands.EditCommand.Edit;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.SequenceAnnotationReport;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.SelectionListener;
+import jalview.structure.SelectionSource;
+import jalview.structure.SequenceListener;
+import jalview.structure.StructureSelectionManager;
+import jalview.structure.VamsasSource;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
 import java.util.List;
+import java.util.Vector;
 
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import jalview.commands.*;
-import jalview.datamodel.*;
-import jalview.io.SequenceAnnotationReport;
-import jalview.schemes.*;
-import jalview.structure.*;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.ToolTipManager;
 
 /**
  * DOCUMENT ME!
@@ -92,7 +116,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   private final SequenceAnnotationReport seqARep;
 
-  StringBuffer tooltipText = new StringBuffer("<html>");
+  StringBuffer tooltipText = new StringBuffer();
 
   String tmpString;
 
@@ -242,7 +266,9 @@ public class SeqPanel extends JPanel implements MouseListener,
                         .containsKey(features[i].featureGroup)
                 && !((Boolean) seqCanvas.fr.featureGroups
                         .get(features[i].featureGroup)).booleanValue())
+        {
           continue;
+        }
 
         if ((features[i].getBegin() <= res)
                 && (features[i].getEnd() >= res))
@@ -258,22 +284,33 @@ public class SeqPanel extends JPanel implements MouseListener,
     return features;
   }
 
+  /**
+   * When all of a sequence of edits are complete, put the resulting edit list
+   * on the history stack (undo list), and reset flags for editing in progress.
+   */
   void endEditing()
   {
-    if (editCommand != null && editCommand.getSize() > 0)
+    try
+    {
+      if (editCommand != null && editCommand.getSize() > 0)
+      {
+        ap.alignFrame.addHistoryItem(editCommand);
+        av.firePropertyChange("alignment", null, av.getAlignment()
+                .getSequences());
+      }
+    } finally
     {
-      ap.alignFrame.addHistoryItem(editCommand);
-      av.firePropertyChange("alignment", null, av.getAlignment()
-              .getSequences());
+      /*
+       * Tidy up come what may...
+       */
+      startseq = -1;
+      lastres = -1;
+      editingSeqs = false;
+      groupEditing = false;
+      keyboardNo1 = null;
+      keyboardNo2 = null;
+      editCommand = null;
     }
-
-    startseq = -1;
-    lastres = -1;
-    editingSeqs = false;
-    groupEditing = false;
-    keyboardNo1 = null;
-    keyboardNo2 = null;
-    editCommand = null;
   }
 
   void setCursorRow()
@@ -517,29 +554,34 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   int getKeyboardNo1()
   {
-    try {
-    if (keyboardNo1 != null) 
+    try
     {
-      int value = Integer.parseInt(keyboardNo1.toString());
-      keyboardNo1 = null;
-      return value;
-    }
+      if (keyboardNo1 != null)
+      {
+        int value = Integer.parseInt(keyboardNo1.toString());
+        keyboardNo1 = null;
+        return value;
+      }
     } catch (Exception x)
-    {}
+    {
+    }
     keyboardNo1 = null;
     return 1;
   }
 
   int getKeyboardNo2()
   {
-    try {
-    if (keyboardNo2!=null){
-      int value = Integer.parseInt(keyboardNo2.toString());
-      keyboardNo2 = null;
-      return value;
-    }
+    try
+    {
+      if (keyboardNo2 != null)
+      {
+        int value = Integer.parseInt(keyboardNo2.toString());
+        keyboardNo2 = null;
+        return value;
+      }
     } catch (Exception x)
-    {}
+    {
+    }
     keyboardNo2 = null;
     return 1;
   }
@@ -621,7 +663,6 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   String lastMessage;
 
-  @Override
   public void mouseOverSequence(SequenceI sequence, int index, int pos)
   {
     String tmp = sequence.hashCode() + " " + index + " " + pos;
@@ -648,6 +689,10 @@ public class SeqPanel extends JPanel implements MouseListener,
   }
 
   @Override
+  public VamsasSource getVamsasSource()
+  {
+    return this.ap == null ? null : this.ap.av;
+  }
   public void updateColours(SequenceI seq, int index)
   {
     System.out.println("update the seqPanel colours");
@@ -687,7 +732,9 @@ public class SeqPanel extends JPanel implements MouseListener,
 
     pos = setStatusMessage(sequence, res, seq);
     if (ssm != null && pos > -1)
+    {
       mouseOverSequence(sequence, res, pos);
+    }
 
     tooltipText.setLength(6); // Cuts the buffer back to <html>
 
@@ -698,11 +745,6 @@ public class SeqPanel extends JPanel implements MouseListener,
       {
         if (groups[g].getStartRes() <= res && groups[g].getEndRes() >= res)
         {
-          if (tooltipText.length() > 6)
-          {
-            tooltipText.append("<br>");
-          }
-
           if (!groups[g].getName().startsWith("JTreeGroup")
                   && !groups[g].getName().startsWith("JGroup"))
           {
@@ -734,11 +776,13 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
     else
     {
-      tooltipText.append("</html>");
       if (lastTooltip == null
               || !lastTooltip.equals(tooltipText.toString()))
       {
-        setToolTipText(tooltipText.toString());
+        String formatedTooltipText = JvSwingUtils.wrapTooltip(true,
+                tooltipText.toString());
+        // String formatedTooltipText = tooltipText.toString();
+        setToolTipText(formatedTooltipText);
         lastTooltip = tooltipText.toString();
       }
 
@@ -935,13 +979,13 @@ public class SeqPanel extends JPanel implements MouseListener,
       }
     }
 
-    StringBuffer message = new StringBuffer();
+    StringBuilder message = new StringBuilder(64);
     if (groupEditing)
     {
       message.append("Edit group:");
       if (editCommand == null)
       {
-        editCommand = new EditCommand("Edit Group");
+        editCommand = new EditCommand(MessageManager.getString("action.edit_group"));
       }
     }
     else
@@ -954,7 +998,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       }
       if (editCommand == null)
       {
-        editCommand = new EditCommand("Edit " + label);
+        editCommand = new EditCommand(MessageManager.formatMessage("label.edit_params", new String[]{label}));
       }
     }
 
@@ -1160,8 +1204,8 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, groupSeqs,
-                  startres, startres - lastres, av.getAlignment(), true);
+          appendEdit(Action.INSERT_GAP, groupSeqs, startres, startres
+                  - lastres);
         }
       }
       else
@@ -1176,8 +1220,8 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.DELETE_GAP, groupSeqs,
-                  startres, lastres - startres, av.getAlignment(), true);
+          appendEdit(Action.DELETE_GAP, groupSeqs, startres, lastres
+                  - startres);
         }
 
       }
@@ -1198,8 +1242,8 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, new SequenceI[]
-          { seq }, lastres, startres - lastres, av.getAlignment(), true);
+          appendEdit(Action.INSERT_GAP, new SequenceI[]
+          { seq }, lastres, startres - lastres);
         }
       }
       else
@@ -1211,7 +1255,7 @@ public class SeqPanel extends JPanel implements MouseListener,
           {
             for (int j = lastres; j > startres; j--)
             {
-              if (!jalview.util.Comparison.isGap(seq.getCharAt(startres)))
+              if (!Comparison.isGap(seq.getCharAt(startres)))
               {
                 endEditing();
                 break;
@@ -1226,7 +1270,7 @@ public class SeqPanel extends JPanel implements MouseListener,
             int max = 0;
             for (int m = startres; m < lastres; m++)
             {
-              if (!jalview.util.Comparison.isGap(seq.getCharAt(m)))
+              if (!Comparison.isGap(seq.getCharAt(m)))
               {
                 break;
               }
@@ -1235,9 +1279,8 @@ public class SeqPanel extends JPanel implements MouseListener,
 
             if (max > 0)
             {
-              editCommand.appendEdit(EditCommand.DELETE_GAP,
-                      new SequenceI[]
-                      { seq }, startres, max, av.getAlignment(), true);
+              appendEdit(Action.DELETE_GAP, new SequenceI[]
+              { seq }, startres, max);
             }
           }
         }
@@ -1253,8 +1296,8 @@ public class SeqPanel extends JPanel implements MouseListener,
           }
           else
           {
-            editCommand.appendEdit(EditCommand.INSERT_NUC, new SequenceI[]
-            { seq }, lastres, startres - lastres, av.getAlignment(), true);
+            appendEdit(Action.INSERT_NUC, new SequenceI[]
+            { seq }, lastres, startres - lastres);
           }
         }
       }
@@ -1289,22 +1332,37 @@ public class SeqPanel extends JPanel implements MouseListener,
       }
     }
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, blankColumn, 1,
-            av.getAlignment(), true);
+    appendEdit(Action.DELETE_GAP, seq, blankColumn, 1);
+
+    appendEdit(Action.INSERT_GAP, seq, j, 1);
+
+  }
+
+  /**
+   * Helper method to add and perform one edit action.
+   * 
+   * @param action
+   * @param seq
+   * @param pos
+   * @param count
+   */
+  protected void appendEdit(Action action, SequenceI[] seq, int pos,
+          int count)
+  {
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, j, 1,
-            av.getAlignment(), true);
+    final Edit edit = new EditCommand().new Edit(action, seq, pos, count,
+            av.getAlignment().getGapCharacter());
 
+    editCommand.appendEdit(edit, av.getAlignment(),
+            true, null);
   }
 
   void deleteChar(int j, SequenceI[] seq, int fixedColumn)
   {
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, j, 1,
-            av.getAlignment(), true);
+    appendEdit(Action.DELETE_GAP, seq, j, 1);
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, fixedColumn, 1,
-            av.getAlignment(), true);
+    appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1);
   }
 
   /**
@@ -1429,9 +1487,10 @@ public class SeqPanel extends JPanel implements MouseListener,
 
     if (av.wrapAlignment && seq > av.getAlignment().getHeight())
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop,
-              "Cannot edit annotations in wrapped view.",
-              "Wrapped view - no edit", JOptionPane.WARNING_MESSAGE);
+      JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+              .getString("label.cannot_edit_annotations_in_wrapped_view"),
+              MessageManager.getString("label.wrapped_view_no_edit"),
+              JOptionPane.WARNING_MESSAGE);
       return;
     }