JAL-1264 adding show/hide annotation options to applet
[jalview.git] / src / jalview / gui / PopupMenu.java
index 0000291..174772c 100644 (file)
@@ -23,9 +23,7 @@ package jalview.gui;
 import java.awt.Color;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Hashtable;
 import java.util.LinkedHashMap;
@@ -45,6 +43,7 @@ import javax.swing.JRadioButtonMenuItem;
 
 import jalview.analysis.AAFrequency;
 import jalview.analysis.AlignmentAnnotationUtils;
+import jalview.analysis.AlignmentUtils;
 import jalview.analysis.Conservation;
 import jalview.commands.ChangeCaseCommand;
 import jalview.commands.EditCommand;
@@ -198,13 +197,15 @@ public class PopupMenu extends JPopupMenu
 
   JMenu seqHideAnnotationsMenu = new JMenu();
 
-  JMenuItem seqAddReferenceAnnotations = new JMenuItem();
+  JMenuItem seqAddReferenceAnnotations = new JMenuItem(
+          MessageManager.getString("label.add_reference_annotations"));
 
   JMenu groupShowAnnotationsMenu = new JMenu();
 
   JMenu groupHideAnnotationsMenu = new JMenu();
 
-  JMenuItem groupAddReferenceAnnotations = new JMenuItem();
+  JMenuItem groupAddReferenceAnnotations = new JMenuItem(
+          MessageManager.getString("label.add_reference_annotations"));
 
   JMenuItem sequenceFeature = new JMenuItem();
 
@@ -946,7 +947,7 @@ public class PopupMenu extends JPopupMenu
           final boolean actionIsShow)
   {
     String label = types.toString(); // [a, b, c]
-    label = label.substring(1, label.length() - 1);
+    label = label.substring(1, label.length() - 1); // a, b, c
     final JMenuItem item = new JMenuItem(label);
     item.setToolTipText(calcId);
     item.addActionListener(new java.awt.event.ActionListener()
@@ -954,41 +955,14 @@ public class PopupMenu extends JPopupMenu
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        showHideAnnotation_actionPerformed(types, forSequences, allTypes,
-                actionIsShow);
+        AlignmentUtils.showOrHideSequenceAnnotations(ap.getAlignment(), types,
+                forSequences, allTypes, actionIsShow);
+        refresh();
       }
     });
     showOrHideMenu.add(item);
   }
 
-  /**
-   * Action on selecting a list of annotation type (or the 'all types' values)
-   * to show or hide for the specified sequences.
-   * 
-   * @param types
-   * @param forSequences
-   * @param anyType
-   * @param doShow
-   */
-  protected void showHideAnnotation_actionPerformed(
-          Collection<String> types, List<SequenceI> forSequences,
-          boolean anyType, boolean doShow)
-  {
-    for (AlignmentAnnotation aa : ap.getAlignment()
-            .getAlignmentAnnotation())
-    {
-      if (anyType || types.contains(aa.label))
-      {
-        if ((aa.sequenceRef != null)
-                && forSequences.contains(aa.sequenceRef))
-        {
-          aa.visible = doShow;
-        }
-      }
-    }
-    refresh();
-  }
-
   private void buildGroupURLMenu(SequenceGroup sg, Vector groupLinks)
   {
 
@@ -1815,68 +1789,22 @@ public class PopupMenu extends JPopupMenu
   protected void configureReferenceAnnotationsMenu(
           JMenuItem menuItem, List<SequenceI> forSequences)
   {
-    menuItem.setText(MessageManager
-            .getString("label.add_reference_annotations"));
     menuItem.setEnabled(false);
-    if (forSequences == null)
-    {
-      return;
-    }
 
     /*
      * Temporary store to hold distinct calcId / type pairs for the tooltip.
      * Using TreeMap means calcIds are shown in alphabetical order.
      */
     Map<String, String> tipEntries = new TreeMap<String, String>();
-    StringBuilder tooltip = new StringBuilder(64);
-    tooltip.append(MessageManager.getString("label.add_annotations_for"));
-
-    /*
-     * For each sequence selected in the alignment, make a list of any
-     * annotations on the underlying dataset sequence which are not already on
-     * the alignment.
-     * 
-     * Build a map of { alignmentSequence, <List of annotations to add> }
-     */
-    AlignmentI al = this.ap.av.getAlignment();
     final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<SequenceI, List<AlignmentAnnotation>>();
-    for (SequenceI seq : forSequences)
-    {
-      SequenceI dataset = seq.getDatasetSequence();
-      if (dataset == null)
-      {
-        continue;
-      }
-      AlignmentAnnotation[] datasetAnnotations = dataset.getAnnotation();
-      if (datasetAnnotations == null)
-      {
-        continue;
-      }
-      final List<AlignmentAnnotation> result = new ArrayList<AlignmentAnnotation>();
-      for (AlignmentAnnotation dsann : datasetAnnotations)
-      {
-        /*
-         * Find matching annotations on the alignment.
-         */
-        final Iterable<AlignmentAnnotation> matchedAlignmentAnnotations = al
-                .findAnnotations(seq, dsann.getCalcId(),
-                        dsann.label);
-        if (!matchedAlignmentAnnotations.iterator().hasNext())
-        {
-          result.add(dsann);
-          tipEntries.put(dsann.getCalcId(), dsann.label);
-        }
-      }
-      /*
-       * Save any addable annotations for this sequence
-       */
-      if (!result.isEmpty())
-      {
-        candidates.put(seq, result);
-      }
-    }
+    AlignmentI al = this.ap.av.getAlignment();
+    AlignmentUtils.findAddableReferenceAnnotations(forSequences,
+            tipEntries, candidates, al);
     if (!candidates.isEmpty())
     {
+      StringBuilder tooltip = new StringBuilder(64);
+      tooltip.append(MessageManager.getString("label.add_annotations_for"));
+
       /*
        * Found annotations that could be added. Enable the menu item, and
        * configure its tooltip and action.
@@ -1911,40 +1839,10 @@ public class PopupMenu extends JPopupMenu
   protected void addReferenceAnnotations_actionPerformed(
           Map<SequenceI, List<AlignmentAnnotation>> candidates)
   {
-    /*
-     * Add annotations at the top of the annotation, in the same order as their
-     * related sequences.
-     */
-    for (SequenceI seq : candidates.keySet())
-    {
-      for (AlignmentAnnotation ann : candidates.get(seq))
-      {
-        AlignmentAnnotation copyAnn = new AlignmentAnnotation(ann);
-        int startRes = 0;
-        int endRes = ann.annotations.length;
-        final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup();
-        if (selectionGroup != null)
-        {
-          startRes = selectionGroup.getStartRes();
-          endRes = selectionGroup.getEndRes();
-        }
-        copyAnn.restrict(startRes, endRes);
-
-        /*
-         * Add to the sequence (sets copyAnn.datasetSequence), unless the
-         * original annotation is already on the sequence.
-         */
-        if (!seq.hasAnnotation(ann))
-        {
-          seq.addAlignmentAnnotation(copyAnn);
-        }
-        // adjust for gaps
-        copyAnn.adjustForAlignment();
-        // add to the alignment and set visible
-        this.ap.getAlignment().addAnnotation(copyAnn);
-        copyAnn.visible = true;
-      }
-    }
+    final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup();
+    final AlignmentI alignment = this.ap.getAlignment();
+    AlignmentUtils.addReferenceAnnotations(candidates, alignment,
+            selectionGroup);
     refresh();
   }