JAL-1620 version bump and release notes
[jalview.git] / src / jalview / appletgui / FeatureRenderer.java
old mode 100755 (executable)
new mode 100644 (file)
index 2f6fc1b..6024872
@@ -1,20 +1,22 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
- * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1)
+ * Copyright (C) 2014 The Jalview Authors
  * 
- * This program 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 2
- * of the License, or (at your option) any later version.
+ * This file is part of Jalview.
  * 
- * This program 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.
+ * 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 
+ * PURPOSE.  See the GNU General Public License for more details.
  * 
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 package jalview.appletgui;
 
@@ -24,10 +26,10 @@ import java.awt.*;
 
 import java.awt.event.*;
 
-import jalview.appletgui.FeatureSettings.MyCheckbox;
 import jalview.datamodel.*;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.GraduatedColor;
+import jalview.util.MessageManager;
 
 /**
  * DOCUMENT ME!
@@ -35,7 +37,7 @@ import jalview.schemes.GraduatedColor;
  * @author $author$
  * @version $Revision$
  */
-public class FeatureRenderer
+public class FeatureRenderer implements jalview.api.FeatureRenderer
 {
   AlignViewport av;
 
@@ -85,6 +87,25 @@ public class FeatureRenderer
     featureGroups = fr.featureGroups;
     featureColours = fr.featureColours;
     transparency = fr.transparency;
+    if (av != null && fr.av != null && fr.av != av)
+    {
+      if (fr.av.featuresDisplayed != null)
+      {
+        if (av.featuresDisplayed == null)
+        {
+          av.featuresDisplayed = new Hashtable();
+        }
+        else
+        {
+          av.featuresDisplayed.clear();
+        }
+        Enumeration en = fr.av.featuresDisplayed.keys();
+        while (en.hasMoreElements())
+        {
+          av.featuresDisplayed.put(en.nextElement(), Boolean.TRUE);
+        }
+      }
+    }
   }
 
   static String lastFeatureAdded;
@@ -98,81 +119,93 @@ public class FeatureRenderer
   boolean deleteFeature = false;
 
   FeatureColourPanel colourPanel;
-  class FeatureColourPanel extends Panel {
-    String label="";
-    
+
+  class FeatureColourPanel extends Panel
+  {
+    String label = "";
+
     private Color maxCol;
-    private boolean isColourByLabel,isGcol;
+
+    private boolean isColourByLabel, isGcol;
+
     /**
      * render a feature style in the amend feature dialog box
      */
     public void updateColor(Object newcol)
     {
-      
-      Color bg,col=null;
-      GraduatedColor gcol=null;
+
+      Color bg, col = null;
+      GraduatedColor gcol = null;
       String vlabel = "";
       if (newcol instanceof Color)
       {
-        isGcol=false;
+        isGcol = false;
         col = (Color) newcol;
         gcol = null;
       }
       else if (newcol instanceof GraduatedColor)
       {
-        isGcol=true;
+        isGcol = true;
         gcol = (GraduatedColor) newcol;
         col = null;
       }
       else
       {
-        throw new Error("Invalid color for MyCheckBox");
+        throw new Error(MessageManager.getString("error.invalid_colour_for_mycheckbox"));
       }
       if (col != null)
       {
-        setBackground(bg=col);
+        setBackground(bg = col);
       }
       else
       {
-        if (gcol.getThreshType()!=AnnotationColourGradient.NO_THRESHOLD)
+        if (gcol.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
         {
-          vlabel += " "+((gcol.getThreshType()==AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)" : "(<)");
+          vlabel += " "
+                  + ((gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)"
+                          : "(<)");
         }
-        if (isColourByLabel=gcol.isColourByLabel()) {
-          setBackground(bg=Color.white);
+        if (isColourByLabel = gcol.isColourByLabel())
+        {
+          setBackground(bg = Color.white);
           vlabel += " (by Label)";
-        } else {
-          setBackground(bg=gcol.getMinColor());
+        }
+        else
+        {
+          setBackground(bg = gcol.getMinColor());
           maxCol = gcol.getMaxColor();
         }
       }
-      label=vlabel;
+      label = vlabel;
       setBackground(bg);
       repaint();
     }
-    FeatureColourPanel() {
+
+    FeatureColourPanel()
+    {
       super(null);
     }
-    public void paint(Graphics g) 
+
+    public void paint(Graphics g)
     {
       Dimension d = getSize();
-      if (isGcol) {
-      if (isColourByLabel)
-      {
-        g.setColor(Color.white);
-        g.fillRect(d.width/2, 0,d.width/2, d.height);
-        g.setColor(Color.black); 
-        Font f=new Font("Verdana", Font.PLAIN,
-                10);
-        g.setFont(f);
-        g.drawString("Label", 0, 0);
-      }
-      else
+      if (isGcol)
       {
-        g.setColor(maxCol);
-        g.fillRect(d.width/2, 0,d.width/2, d.height);
-        
-      }
+        if (isColourByLabel)
+        {
+          g.setColor(Color.white);
+          g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+          g.setColor(Color.black);
+          Font f = new Font("Verdana", Font.PLAIN, 10);
+          g.setFont(f);
+          g.drawString(MessageManager.getString("label.label"), 0, 0);
+        }
+        else
+        {
+          g.setColor(maxCol);
+          g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+
+        }
       }
     }
 
@@ -197,7 +230,7 @@ public class FeatureRenderer
     final FeatureRenderer fr = this;
 
     Panel panel = new Panel(new GridLayout(3, 1));
-    
+
     featureIndex = 0; // feature to be amended.
     Panel tmp;
 
@@ -320,8 +353,8 @@ public class FeatureRenderer
       }
     }
 
-    String title = newFeatures ? "Create New Sequence Feature(s)"
-            : "Amend/Delete Features for " + sequences[0].getName();
+    String title = newFeatures ? MessageManager.getString("label.create_new_sequence_features")
+            : MessageManager.formatMessage("label.amend_delete_features", new String[]{sequences[0].getName()});
 
     final JVDialog dialog = new JVDialog(ap.alignFrame, title, true, 385,
             240);
@@ -335,7 +368,7 @@ public class FeatureRenderer
     }
     else
     {
-      dialog.ok.setLabel("Amend");
+      dialog.ok.setLabel(MessageManager.getString("label.amend"));
       dialog.buttonPanel.add(deleteButton, 1);
       deleteButton.addActionListener(new ActionListener()
       {
@@ -364,18 +397,21 @@ public class FeatureRenderer
     dialog.setResizable(true);
     // TODO: render the graduated color in the box.
     colourPanel.addMouseListener(new java.awt.event.MouseAdapter()
+    {
+      public void mousePressed(java.awt.event.MouseEvent evt)
       {
-        public void mousePressed(java.awt.event.MouseEvent evt)
+        if (!colourPanel.isGcol)
         {
-          if (!colourPanel.isGcol) 
-          {
-            new UserDefinedColours(fr, ap.alignFrame);
-          } else {
-            FeatureColourChooser fcc = new FeatureColourChooser(ap.alignFrame, name.getText());
-            dialog.transferFocus();
-          }
+          new UserDefinedColours(fr, ap.alignFrame);
         }
-      });
+        else
+        {
+          FeatureColourChooser fcc = new FeatureColourChooser(
+                  ap.alignFrame, name.getText());
+          dialog.transferFocus();
+        }
+      }
+    });
     dialog.setVisible(true);
 
     jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();
@@ -402,7 +438,8 @@ public class FeatureRenderer
         sf.type = lastFeatureAdded;
         sf.featureGroup = lastFeatureGroupAdded;
         sf.description = lastDescriptionAdded;
-        if (!colourPanel.isGcol) {
+        if (!colourPanel.isGcol)
+        {
           // update colour - otherwise its already done.
           setColour(sf.type, colourPanel.getBackground());
         }
@@ -446,13 +483,14 @@ public class FeatureRenderer
         }
 
         col = colourPanel.getBackground();
-        //setColour(lastFeatureAdded, fcol);
+        // setColour(lastFeatureAdded, fcol);
 
         if (lastFeatureGroupAdded != null)
         {
           featureGroups.put(lastFeatureGroupAdded, new Boolean(true));
         }
-        if (fcol instanceof Color) {
+        if (fcol instanceof Color)
+        {
           setColour(lastFeatureAdded, fcol);
         }
         av.featuresDisplayed.put(lastFeatureAdded,
@@ -472,7 +510,7 @@ public class FeatureRenderer
       }
     }
     // refresh the alignment and the feature settings dialog
-    if (av.featureSettings!=null)
+    if (av.featureSettings != null)
     {
       av.featureSettings.refreshTable();
     }
@@ -645,16 +683,16 @@ public class FeatureRenderer
         else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
         {
 
-          renderFeature(g, seq, seq
-                  .findIndex(sequenceFeatures[sfindex].begin) - 1, seq
-                  .findIndex(sequenceFeatures[sfindex].begin) - 1,
+          renderFeature(g, seq,
+                  seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                  seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
                   getColour(sequenceFeatures[sfindex])
                   // new Color(((Integer) av.featuresDisplayed
                   // .get(sequenceFeatures[sfindex].type)).intValue())
                   , start, end, y1);
-          renderFeature(g, seq, seq
-                  .findIndex(sequenceFeatures[sfindex].end) - 1, seq
-                  .findIndex(sequenceFeatures[sfindex].end) - 1,
+          renderFeature(g, seq,
+                  seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                  seq.findIndex(sequenceFeatures[sfindex].end) - 1,
                   getColour(sequenceFeatures[sfindex])
                   // new Color(((Integer) av.featuresDisplayed
                   // .get(sequenceFeatures[sfindex].type)).intValue())
@@ -664,10 +702,11 @@ public class FeatureRenderer
         else
         {
           if (showFeature(sequenceFeatures[sfindex]))
-          {          renderFeature(g, seq, seq
-                  .findIndex(sequenceFeatures[sfindex].begin) - 1, seq
-                  .findIndex(sequenceFeatures[sfindex].end) - 1,
-                  getColour(sequenceFeatures[sfindex]), start, end, y1);
+          {
+            renderFeature(g, seq,
+                    seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+                    seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+                    getColour(sequenceFeatures[sfindex]), start, end, y1);
           }
         }
 
@@ -731,6 +770,20 @@ public class FeatureRenderer
 
   Hashtable minmax = null;
 
+  /**
+   * Called when alignment in associated view has new/modified features to
+   * discover and display.
+   * 
+   */
+  public void featuresAdded()
+  {
+    lastSeq = null;
+    findAllFeatures();
+  }
+
+  /**
+   * find all features on the alignment
+   */
   void findAllFeatures()
   {
     jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
@@ -738,10 +791,10 @@ public class FeatureRenderer
     av.featuresDisplayed = new Hashtable();
     Vector allfeatures = new Vector();
     minmax = new Hashtable();
-
-    for (int i = 0; i < av.alignment.getHeight(); i++)
+    AlignmentI alignment = av.getAlignment();
+    for (int i = 0; i < alignment.getHeight(); i++)
     {
-      SequenceFeature[] features = av.alignment.getSequenceAt(i)
+      SequenceFeature[] features = alignment.getSequenceAt(i)
               .getSequenceFeatures();
 
       if (features == null)
@@ -761,8 +814,8 @@ public class FeatureRenderer
         {
           if (getColour(features[index].getType()) == null)
           {
-            featureColours.put(features[index].getType(), ucs
-                    .createColourFromName(features[index].getType()));
+            featureColours.put(features[index].getType(),
+                    ucs.createColourFromName(features[index].getType()));
           }
 
           av.featuresDisplayed.put(features[index].getType(), new Integer(
@@ -848,9 +901,9 @@ public class FeatureRenderer
         return ((GraduatedColor) fc).getMaxColor();
       }
     }
-    throw new Error("Implementation Error: Unrecognised render object "
-            + fc.getClass() + " for features of type " + featureType);
+    throw new Error(MessageManager.formatMessage("error.implementation_error_unrecognised_render_object_for_features_type", new String[]{fc.getClass().getCanonicalName(),featureType}));
   }
+
   /**
    * 
    * @param sequenceFeature
@@ -862,7 +915,11 @@ public class FeatureRenderer
     if (fc instanceof GraduatedColor)
     {
       return ((GraduatedColor) fc).isColored(sequenceFeature);
-    } else { return true; }
+    }
+    else
+    {
+      return true;
+    }
   }
 
   /**
@@ -925,7 +982,7 @@ public class FeatureRenderer
       for (int i = 0; i < data.length; i++)
       {
         String type = data[i][0].toString();
-        setColour(type,  data[i][1]);
+        setColour(type, data[i][1]);
         if (((Boolean) data[i][2]).booleanValue())
         {
           av.featuresDisplayed.put(type, new Integer(getColour(type)
@@ -1011,9 +1068,9 @@ public class FeatureRenderer
       for (int i = 0; i < toset.length; i++)
       {
         Object st = featureGroups.get(toset[i]);
+        featureGroups.put(toset[i], new Boolean(visible));
         if (st != null)
         {
-          featureGroups.put(toset[i], new Boolean(visible));
           rdrw = rdrw || (visible != ((Boolean) st).booleanValue());
         }
       }
@@ -1037,6 +1094,8 @@ public class FeatureRenderer
     }
   }
 
+  ArrayList<String> hiddenGroups = new ArrayList<String>();
+
   /**
    * analyse alignment for groups and hash tables (used to be embedded in
    * FeatureSettings.setTableData)
@@ -1050,29 +1109,34 @@ public class FeatureRenderer
     {
       featureGroups = new Hashtable();
     }
-    Vector allFeatures = new Vector();
-    Vector allGroups = new Vector();
+    hiddenGroups = new ArrayList<String>();
+    hiddenGroups.addAll(featureGroups.keySet());
+    ArrayList allFeatures = new ArrayList();
+    ArrayList allGroups = new ArrayList();
     SequenceFeature[] tmpfeatures;
     String group;
-    for (int i = 0; i < av.alignment.getHeight(); i++)
+    AlignmentI alignment = av.getAlignment();
+    for (int i = 0; i < alignment.getHeight(); i++)
     {
-      if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
+      if (alignment.getSequenceAt(i).getSequenceFeatures() == null)
       {
         continue;
       }
 
       alignmentHasFeatures = true;
 
-      tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
+      tmpfeatures = alignment.getSequenceAt(i).getSequenceFeatures();
       int index = 0;
       while (index < tmpfeatures.length)
       {
         if (tmpfeatures[index].getFeatureGroup() != null)
         {
           group = tmpfeatures[index].featureGroup;
+          // Remove group from the hiddenGroup list
+          hiddenGroups.remove(group);
           if (!allGroups.contains(group))
           {
-            allGroups.addElement(group);
+            allGroups.add(group);
 
             boolean visible = true;
             if (featureGroups.containsKey(group))
@@ -1088,7 +1152,7 @@ public class FeatureRenderer
 
         if (!allFeatures.contains(tmpfeatures[index].getType()))
         {
-          allFeatures.addElement(tmpfeatures[index].getType());
+          allFeatures.add(tmpfeatures[index].getType());
         }
         index++;
       }
@@ -1117,16 +1181,17 @@ public class FeatureRenderer
     Vector allFeatures = new Vector();
     SequenceFeature[] tmpfeatures;
     String group;
-    for (int i = 0; i < av.alignment.getHeight(); i++)
+    AlignmentI alignment = av.getAlignment();
+    for (int i = 0; i < alignment.getHeight(); i++)
     {
-      if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
+      if (alignment.getSequenceAt(i).getSequenceFeatures() == null)
       {
         continue;
       }
 
       alignmentHasFeatures = true;
 
-      tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
+      tmpfeatures = alignment.getSequenceAt(i).getSequenceFeatures();
       int index = 0;
       while (index < tmpfeatures.length)
       {