JAL-1683 replace year/version strings with tokens in source
[jalview.git] / src / jalview / gui / SeqPanel.java
index 8d81f8c..1cc8715 100644 (file)
@@ -1,39 +1,61 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
- * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
- *
+ * 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
+ * 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 <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.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.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!
- *
+ * 
  * @author $author$
  * @version $Revision: 1.130 $
  */
@@ -88,8 +110,10 @@ public class SeqPanel extends JPanel implements MouseListener,
   StringBuffer keyboardNo2;
 
   java.net.URL linkImageURL;
+
   private final SequenceAnnotationReport seqARep;
-  StringBuffer tooltipText = new StringBuffer("<html>");
+
+  StringBuffer tooltipText = new StringBuffer();
 
   String tmpString;
 
@@ -99,7 +123,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * Creates a new SeqPanel object.
-   *
+   * 
    * @param avp
    *          DOCUMENT ME!
    * @param p
@@ -108,7 +132,7 @@ public class SeqPanel extends JPanel implements MouseListener,
   public SeqPanel(AlignViewport av, AlignmentPanel ap)
   {
     linkImageURL = getClass().getResource("/images/link.gif");
-    seqARep=new SequenceAnnotationReport(linkImageURL.toString());
+    seqARep = new SequenceAnnotationReport(linkImageURL.toString());
     ToolTipManager.sharedInstance().registerComponent(this);
     ToolTipManager.sharedInstance().setInitialDelay(0);
     ToolTipManager.sharedInstance().setDismissDelay(10000);
@@ -126,7 +150,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       addMouseMotionListener(this);
       addMouseListener(this);
       addMouseWheelListener(this);
-      ssm = StructureSelectionManager.getStructureSelectionManager(Desktop.instance);
+      ssm = av.getStructureSelectionManager();
       ssm.addStructureViewerListener(this);
       ssm.addSelectionListener(this);
     }
@@ -171,10 +195,11 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
     else
     {
-      if (x>seqCanvas.getWidth()+seqCanvas.getWidth())
+      if (x > seqCanvas.getWidth() + seqCanvas.getWidth())
       {
-        // make sure we calculate relative to visible alignment, rather than right-hand gutter
-        x = seqCanvas.getX()+seqCanvas.getWidth();
+        // make sure we calculate relative to visible alignment, rather than
+        // right-hand gutter
+        x = seqCanvas.getX() + seqCanvas.getWidth();
       }
       res = (x / av.getCharWidth()) + av.getStartRes();
     }
@@ -206,54 +231,18 @@ public class SeqPanel extends JPanel implements MouseListener,
 
       y -= hgap;
 
-      seq = Math.min((y % cHeight) / av.getCharHeight(),
-              av.getAlignment().getHeight() - 1);
+      seq = Math.min((y % cHeight) / av.getCharHeight(), av.getAlignment()
+              .getHeight() - 1);
     }
     else
     {
-      seq = Math.min((y / av.getCharHeight()) + av.getStartSeq(),
-              av.getAlignment().getHeight() - 1);
+      seq = Math.min((y / av.getCharHeight()) + av.getStartSeq(), av
+              .getAlignment().getHeight() - 1);
     }
 
     return seq;
   }
 
-  SequenceFeature[] findFeaturesAtRes(SequenceI sequence, int res)
-  {
-    Vector tmp = new Vector();
-    SequenceFeature[] features = sequence.getSequenceFeatures();
-    if (features != null)
-    {
-      for (int i = 0; i < features.length; i++)
-      {
-        if (av.featuresDisplayed == null
-                || !av.featuresDisplayed.containsKey(features[i].getType()))
-        {
-          continue;
-        }
-
-        if (features[i].featureGroup != null
-                && seqCanvas.fr.featureGroups != null
-                && seqCanvas.fr.featureGroups
-                        .containsKey(features[i].featureGroup)
-                && !((Boolean) seqCanvas.fr.featureGroups
-                        .get(features[i].featureGroup)).booleanValue())
-          continue;
-
-        if ((features[i].getBegin() <= res)
-                && (features[i].getEnd() >= res))
-        {
-          tmp.addElement(features[i]);
-        }
-      }
-    }
-
-    features = new SequenceFeature[tmp.size()];
-    tmp.copyInto(features);
-
-    return features;
-  }
-
   void endEditing()
   {
     if (editCommand != null && editCommand.getSize() > 0)
@@ -300,10 +289,9 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   void setCursorPosition()
   {
-    SequenceI sequence = av.getAlignment().getSequenceAt(
-            seqCanvas.cursorY);
+    SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
 
-    seqCanvas.cursorX = sequence.findIndex(getKeyboardNo1() - 1);
+    seqCanvas.cursorX = sequence.findIndex(getKeyboardNo1()) - 1;
     scrollToVisible();
   }
 
@@ -311,7 +299,8 @@ public class SeqPanel extends JPanel implements MouseListener,
   {
     seqCanvas.cursorX += dx;
     seqCanvas.cursorY += dy;
-    if (av.hasHiddenColumns() && !av.getColumnSelection().isVisible(seqCanvas.cursorX))
+    if (av.hasHiddenColumns()
+            && !av.getColumnSelection().isVisible(seqCanvas.cursorX))
     {
       int original = seqCanvas.cursorX - dx;
       int maxWidth = av.getAlignment().getWidth();
@@ -395,8 +384,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   void setSelectionAreaAtCursor(boolean topLeft)
   {
-    SequenceI sequence = av.getAlignment().getSequenceAt(
-            seqCanvas.cursorY);
+    SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
 
     if (av.getSelectionGroup() != null)
     {
@@ -486,12 +474,13 @@ public class SeqPanel extends JPanel implements MouseListener,
     endEditing();
   }
 
-  void insertNucAtCursor(boolean group,String nuc){
-         groupEditing = group;
-           startseq = seqCanvas.cursorY;
-           lastres = seqCanvas.cursorX;
-           editSequence(false, true, seqCanvas.cursorX + getKeyboardNo1());
-           endEditing();
+  void insertNucAtCursor(boolean group, String nuc)
+  {
+    groupEditing = group;
+    startseq = seqCanvas.cursorY;
+    lastres = seqCanvas.cursorX;
+    editSequence(false, true, seqCanvas.cursorX + getKeyboardNo1());
+    endEditing();
   }
 
   void numberPressed(char value)
@@ -513,31 +502,41 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   int getKeyboardNo1()
   {
-    if (keyboardNo1 == null)
-      return 1;
-    else
+    try
+    {
+      if (keyboardNo1 != null)
+      {
+        int value = Integer.parseInt(keyboardNo1.toString());
+        keyboardNo1 = null;
+        return value;
+      }
+    } catch (Exception x)
     {
-      int value = Integer.parseInt(keyboardNo1.toString());
-      keyboardNo1 = null;
-      return value;
     }
+    keyboardNo1 = null;
+    return 1;
   }
 
   int getKeyboardNo2()
   {
-    if (keyboardNo2 == null)
-      return 1;
-    else
+    try
+    {
+      if (keyboardNo2 != null)
+      {
+        int value = Integer.parseInt(keyboardNo2.toString());
+        keyboardNo2 = null;
+        return value;
+      }
+    } catch (Exception x)
     {
-      int value = Integer.parseInt(keyboardNo2.toString());
-      keyboardNo2 = null;
-      return value;
     }
+    keyboardNo2 = null;
+    return 1;
   }
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param evt
    *          DOCUMENT ME!
    */
@@ -558,7 +557,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param evt
    *          DOCUMENT ME!
    */
@@ -632,7 +631,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     {
       if (ap.scrollToPosition(results, false))
       {
-      seqCanvas.revalidate();
+        seqCanvas.revalidate();
       }
     }
     seqCanvas.highlightSearchResults(results);
@@ -647,7 +646,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param evt
    *          DOCUMENT ME!
    */
@@ -678,7 +677,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>
 
@@ -689,11 +690,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"))
           {
@@ -709,14 +705,14 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
 
     // use aa to see if the mouse pointer is on a
-    if (av.showSequenceFeatures)
+    if (av.isShowSequenceFeatures())
     {
       int rpos;
-      SequenceFeature[] features = findFeaturesAtRes(
+      List<SequenceFeature> features = ap.getFeatureRenderer().findFeaturesAtRes(
               sequence.getDatasetSequence(),
               rpos = sequence.findPosition(res));
-      seqARep.appendFeatures(tooltipText,  rpos, features,
-              this.ap.seqPanel.seqCanvas.fr.minmax);
+      seqARep.appendFeatures(tooltipText, rpos, features,
+              this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
     }
     if (tooltipText.length() == 6) // <html></html>
     {
@@ -725,11 +721,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();
       }
 
@@ -761,12 +759,11 @@ public class SeqPanel extends JPanel implements MouseListener,
     return lastp = p;
   }
 
-
   String lastTooltip;
 
   /**
    * Set status message in alignment panel
-   *
+   * 
    * @param sequence
    *          aligned sequence object
    * @param res
@@ -814,7 +811,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param evt
    *          DOCUMENT ME!
    */
@@ -892,11 +889,11 @@ public class SeqPanel extends JPanel implements MouseListener,
     if ((res < av.getAlignment().getWidth()) && (res < lastres))
     {
       // dragLeft, delete gap
-      editSequence(false, false,res);
+      editSequence(false, false, res);
     }
     else
     {
-      editSequence(true, false,res);
+      editSequence(true, false, res);
     }
 
     mouseDragging = true;
@@ -906,8 +903,9 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
   }
 
-  //TODO: Make it more clever than many booleans
-  synchronized void editSequence(boolean insertGap, boolean editSeq, int startres)
+  // TODO: Make it more clever than many booleans
+  synchronized void editSequence(boolean insertGap, boolean editSeq,
+          int startres)
   {
     int fixedLeft = -1;
     int fixedRight = -1;
@@ -932,7 +930,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       message.append("Edit group:");
       if (editCommand == null)
       {
-        editCommand = new EditCommand("Edit Group");
+        editCommand = new EditCommand(MessageManager.getString("action.edit_group"));
       }
     }
     else
@@ -945,7 +943,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}));
       }
     }
 
@@ -1084,8 +1082,8 @@ public class SeqPanel extends JPanel implements MouseListener,
         {
           if (sg.getSize() == av.getAlignment().getHeight())
           {
-            if ((av.hasHiddenColumns() && startres < av.getColumnSelection()
-                    .getHiddenBoundaryRight(startres)))
+            if ((av.hasHiddenColumns() && startres < av
+                    .getColumnSelection().getHiddenBoundaryRight(startres)))
             {
               endEditing();
               return;
@@ -1094,7 +1092,8 @@ public class SeqPanel extends JPanel implements MouseListener,
             int alWidth = av.getAlignment().getWidth();
             if (av.hasHiddenRows())
             {
-              int hwidth = av.getAlignment().getHiddenSequences().getWidth();
+              int hwidth = av.getAlignment().getHiddenSequences()
+                      .getWidth();
               if (hwidth > alWidth)
               {
                 alWidth = hwidth;
@@ -1150,7 +1149,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, groupSeqs,
+          editCommand.appendEdit(Action.INSERT_GAP, groupSeqs,
                   startres, startres - lastres, av.getAlignment(), true);
         }
       }
@@ -1166,7 +1165,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.DELETE_GAP, groupSeqs,
+          editCommand.appendEdit(Action.DELETE_GAP, groupSeqs,
                   startres, lastres - startres, av.getAlignment(), true);
         }
 
@@ -1188,61 +1187,65 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, new SequenceI[]
+          editCommand.appendEdit(Action.INSERT_GAP, new SequenceI[]
           { seq }, lastres, startres - lastres, av.getAlignment(), true);
-         }
+        }
       }
       else
       {
-       if(!editSeq){
-        // dragging to the left
-        if (fixedColumns && fixedRight != -1)
+        if (!editSeq)
         {
-          for (int j = lastres; j > startres; j--)
+          // dragging to the left
+          if (fixedColumns && fixedRight != -1)
           {
-            if (!jalview.util.Comparison.isGap(seq.getCharAt(startres)))
+            for (int j = lastres; j > startres; j--)
             {
-              endEditing();
-              break;
+              if (!jalview.util.Comparison.isGap(seq.getCharAt(startres)))
+              {
+                endEditing();
+                break;
+              }
+              deleteChar(startres, new SequenceI[]
+              { seq }, fixedRight);
+            }
+          }
+          else
+          {
+            // could be a keyboard edit trying to delete none gaps
+            int max = 0;
+            for (int m = startres; m < lastres; m++)
+            {
+              if (!jalview.util.Comparison.isGap(seq.getCharAt(m)))
+              {
+                break;
+              }
+              max++;
+            }
+
+            if (max > 0)
+            {
+              editCommand.appendEdit(Action.DELETE_GAP,
+                      new SequenceI[]
+                      { seq }, startres, max, av.getAlignment(), true);
             }
-            deleteChar(startres, new SequenceI[]
-            { seq }, fixedRight);
           }
         }
         else
-        {
-          // could be a keyboard edit trying to delete none gaps
-          int max = 0;
-          for (int m = startres; m < lastres; m++)
+        {// insertGap==false AND editSeq==TRUE;
+          if (fixedColumns && fixedRight != -1)
           {
-            if (!jalview.util.Comparison.isGap(seq.getCharAt(m)))
+            for (int j = lastres; j < startres; j++)
             {
-              break;
+              insertChar(j, new SequenceI[]
+              { seq }, fixedRight);
             }
-            max++;
           }
-
-          if (max > 0)
+          else
           {
-            editCommand.appendEdit(EditCommand.DELETE_GAP, new SequenceI[]
-            { seq }, startres, max, av.getAlignment(), true);
+            editCommand.appendEdit(Action.INSERT_NUC, new SequenceI[]
+            { seq }, lastres, startres - lastres, av.getAlignment(), true);
           }
         }
-       }else{//insertGap==false AND editSeq==TRUE;
-               if (fixedColumns && fixedRight != -1)
-            {
-              for (int j = lastres; j < startres; j++)
-              {
-                insertChar(j, new SequenceI[]
-                { seq }, fixedRight);
-              }
-              }
-            else
-            {
-              editCommand.appendEdit(EditCommand.INSERT_NUC, new SequenceI[]
-              { seq }, lastres, startres - lastres, av.getAlignment(), true);
-             }
-       }
       }
     }
 
@@ -1275,27 +1278,27 @@ public class SeqPanel extends JPanel implements MouseListener,
       }
     }
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, blankColumn, 1,
+    editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1,
             av.getAlignment(), true);
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, j, 1, av.getAlignment(),
-            true);
+    editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1,
+            av.getAlignment(), true);
 
   }
 
   void deleteChar(int j, SequenceI[] seq, int fixedColumn)
   {
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, j, 1, av.getAlignment(),
-            true);
+    editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1,
+            av.getAlignment(), true);
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, fixedColumn, 1,
+    editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1,
             av.getAlignment(), true);
   }
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param e
    *          DOCUMENT ME!
    */
@@ -1316,7 +1319,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param e
    *          DOCUMENT ME!
    */
@@ -1348,21 +1351,21 @@ public class SeqPanel extends JPanel implements MouseListener,
         av.setSelectionGroup(null);
       }
 
-      SequenceFeature[] features = findFeaturesAtRes(
+      List<SequenceFeature> features = seqCanvas.getFeatureRenderer().findFeaturesAtRes(
               sequence.getDatasetSequence(),
               sequence.findPosition(findRes(evt)));
 
-      if (features != null && features.length > 0)
+      if (features != null && features.size()> 0)
       {
         SearchResults highlight = new SearchResults();
-        highlight.addResult(sequence, features[0].getBegin(),
-                features[0].getEnd());
+        highlight.addResult(sequence, features.get(0).getBegin(),
+                features.get(0).getEnd());
         seqCanvas.highlightSearchResults(highlight);
       }
-      if (features != null && features.length > 0)
+      if (features != null && features.size()> 0)
       {
         seqCanvas.getFeatureRenderer().amendFeatures(new SequenceI[]
-        { sequence }, features, false, ap);
+        { sequence }, features.toArray(new SequenceFeature[features.size()]), false, ap);
 
         seqCanvas.highlightSearchResults(null);
       }
@@ -1378,8 +1381,10 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (e.isShiftDown())
       {
         ap.scrollRight(true);
-        
-      } else {
+
+      }
+      else
+      {
         ap.scrollUp(false);
       }
     }
@@ -1388,7 +1393,9 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (e.isShiftDown())
       {
         ap.scrollRight(false);
-      } else {
+      }
+      else
+      {
         ap.scrollUp(true);
       }
     }
@@ -1397,7 +1404,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param evt
    *          DOCUMENT ME!
    */
@@ -1411,9 +1418,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;
     }
 
@@ -1472,16 +1480,16 @@ public class SeqPanel extends JPanel implements MouseListener,
 
     if (javax.swing.SwingUtilities.isRightMouseButton(evt))
     {
-      SequenceFeature[] allFeatures = findFeaturesAtRes(
+      List<SequenceFeature> allFeatures = ap.getFeatureRenderer().findFeaturesAtRes(
               sequence.getDatasetSequence(), sequence.findPosition(res));
       Vector links = new Vector();
-      for (int i = 0; i < allFeatures.length; i++)
+      for (SequenceFeature sf:allFeatures)
       {
-        if (allFeatures[i].links != null)
+        if (sf.links != null)
         {
-          for (int j = 0; j < allFeatures[i].links.size(); j++)
+          for (int j = 0; j < sf.links.size(); j++)
           {
-            links.addElement(allFeatures[i].links.elementAt(j));
+            links.addElement(sf.links.elementAt(j));
           }
         }
       }
@@ -1542,7 +1550,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param evt
    *          DOCUMENT ME!
    */
@@ -1557,8 +1565,8 @@ public class SeqPanel extends JPanel implements MouseListener,
                                        // state
     if (stretchGroup.cs != null)
     {
-      stretchGroup.cs.alignmentChanged(
-                stretchGroup,av.getHiddenRepSequences());
+      stretchGroup.cs.alignmentChanged(stretchGroup,
+              av.getHiddenRepSequences());
 
       if (stretchGroup.cs.conservationApplied())
       {
@@ -1582,7 +1590,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   /**
    * DOCUMENT ME!
-   *
+   * 
    * @param evt
    *          DOCUMENT ME!
    */
@@ -1648,7 +1656,8 @@ public class SeqPanel extends JPanel implements MouseListener,
       dragDirection = -1;
     }
 
-    while ((y != oldSeq) && (oldSeq > -1) && (y < av.getAlignment().getHeight()))
+    while ((y != oldSeq) && (oldSeq > -1)
+            && (y < av.getAlignment().getHeight()))
     {
       // This routine ensures we don't skip any sequences, as the
       // selection is quite slow.
@@ -1792,7 +1801,8 @@ public class SeqPanel extends JPanel implements MouseListener,
     // shared between viewports.
     if (av == source
             || !av.followSelection
-            || (av.isSelectionGroupChanged(false) || av.isColSelChanged(false))
+            || (av.isSelectionGroupChanged(false) || av
+                    .isColSelChanged(false))
             || (source instanceof AlignViewport && ((AlignViewport) source)
                     .getSequenceSetId().equals(av.getSequenceSetId())))
     {
@@ -1806,7 +1816,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     // if (!av.isSelectionGroupChanged(false))
     {
       SequenceGroup sgroup = null;
-      if (seqsel != null && seqsel.getSize()>0)
+      if (seqsel != null && seqsel.getSize() > 0)
       {
         if (av.getAlignment() == null)
         {
@@ -1844,7 +1854,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         if (av.getColumnSelection() != null)
         {
           av.getColumnSelection().clear();
-          repaint=true;
+          repaint = true;
         }
       }
       else
@@ -1862,8 +1872,10 @@ public class SeqPanel extends JPanel implements MouseListener,
       av.isColSelChanged(true);
       repaint = true;
     }
-    if (copycolsel && av.hasHiddenColumns()
-            && (av.getColumnSelection() == null || av.getColumnSelection().getHiddenColumns() == null))
+    if (copycolsel
+            && av.hasHiddenColumns()
+            && (av.getColumnSelection() == null || av.getColumnSelection()
+                    .getHiddenColumns() == null))
     {
       System.err.println("Bad things");
     }