JAL-1645 Version-Rel Version 2.9 Year-Rel 2015 Licensing glob
[jalview.git] / src / jalview / gui / AnnotationChooser.java
index bb940e8..35b6032 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9)
+ * Copyright (C) 2015 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 
+ * 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/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.gui;
 
 import jalview.datamodel.AlignmentAnnotation;
@@ -21,7 +41,6 @@ import java.util.List;
 import java.util.Map;
 
 import javax.swing.JButton;
-import javax.swing.JCheckBox;
 import javax.swing.JInternalFrame;
 import javax.swing.JLayeredPane;
 import javax.swing.JPanel;
@@ -33,6 +52,7 @@ import javax.swing.JPanel;
  * @author gmcarstairs
  *
  */
+@SuppressWarnings("serial")
 public class AnnotationChooser extends JPanel
 {
 
@@ -62,7 +82,7 @@ public class AnnotationChooser extends JPanel
 
   // currently selected 'annotation type' checkboxes
   private Map<String, String> selectedTypes = new HashMap<String, String>();
-  
+
   /**
    * Constructor.
    * 
@@ -137,7 +157,7 @@ public class AnnotationChooser extends JPanel
 
     for (final String type : annotationTypes)
     {
-      final JCheckBox check = new JCheckBox(type);
+      final Checkbox check = new Checkbox(type);
       check.setFont(CHECKBOX_FONT);
       check.addItemListener(new ItemListener()
       {
@@ -152,7 +172,7 @@ public class AnnotationChooser extends JPanel
           {
             AnnotationChooser.this.selectedTypes.remove(type);
           }
-          repaintAnnotations(false);
+          changeTypeSelected_actionPerformed(type);
         }
       });
       jp.add(check);
@@ -161,47 +181,104 @@ public class AnnotationChooser extends JPanel
   }
 
   /**
-   * Set visibility flags on annotation rows then repaint the alignment panel.
+   * Update display when scope (All/Selected sequences/Unselected) is changed.
    * <p>
-   * Optionally, update all rows, including those not in the 'apply to' scope.
-   * This makes more sense when switching between selected and unselected
-   * sequences. When selecting annotation types, or show/hide, we only apply the
-   * settings to the selected sequences.
+   * Set annotations (with one of the selected types) to the selected Show/Hide
+   * visibility, if they are in the new application scope. Set to the opposite
+   * if outside the scope.
    * <p>
    * Note this only affects sequence-specific annotations, others are left
    * unchanged.
    */
-  protected void repaintAnnotations(boolean updateAllRows)
+  protected void changeApplyTo_actionPerformed()
   {
+    setAnnotationVisibility(true);
+
+    // copied from AnnotationLabel.actionPerformed (after show/hide row)...
+    // TODO should drive this functionality into AlignmentPanel
+    ap.updateAnnotation();
+    // this.ap.annotationPanel.adjustPanelHeight();
+    // this.ap.alabels.setSize(this.ap.alabels.getSize().width,
+    // this.ap.annotationPanel.getSize().height);
+    // this.ap.validate();
+    this.ap.paintAlignment(true);
+  }
+
+  /**
+   * Update display when an annotation type is selected or deselected.
+   * <p>
+   * If the type is selected, set visibility of annotations of that type which
+   * are in the application scope (all, selected or unselected sequences).
+   * <p>
+   * If the type is unselected, set visibility to the opposite value. That is,
+   * treat select/deselect as a 'toggle' operation.
+   * 
+   * @param type
+   */
+  protected void changeTypeSelected_actionPerformed(String type)
+  {
+    boolean typeSelected = this.selectedTypes.containsKey(type);
     for (AlignmentAnnotation aa : this.ap.getAlignment()
             .getAlignmentAnnotation())
     {
-      if (aa.sequenceRef != null)
+      if (aa.sequenceRef != null && type.equals(aa.label)
+              && isInActionScope(aa))
       {
-        setAnnotationVisibility(aa, updateAllRows);
+        aa.visible = typeSelected ? this.showSelected : !this.showSelected;
       }
     }
-    // copied from AnnotationLabel.actionPerformed (after show/hide row)...
-    // TODO should drive this functionality into AlignmentPanel
     ap.updateAnnotation();
-    this.ap.annotationPanel.adjustPanelHeight();
-    this.ap.alabels.setSize(this.ap.alabels.getSize().width,
-            this.ap.annotationPanel.getSize().height);
-    this.ap.validate();
+    // // this.ap.annotationPanel.adjustPanelHeight();
+    // this.ap.alabels.setSize(this.ap.alabels.getSize().width,
+    // this.ap.annotationPanel.getSize().height);
+    // this.ap.validate();
+    this.ap.paintAlignment(true);
+  }
+
+  /**
+   * Update display on change of choice of Show or Hide
+   * <p>
+   * For annotations of any selected type, set visibility of annotations of that
+   * type which are in the application scope (all, selected or unselected
+   * sequences).
+   * 
+   * @param type
+   */
+  protected void changeShowHide_actionPerformed()
+  {
+    setAnnotationVisibility(false);
+
+    this.ap.updateAnnotation();
+    // this.ap.annotationPanel.adjustPanelHeight();
     this.ap.paintAlignment(true);
   }
 
   /**
+   * Update visibility flags on annotation rows as per the current user choices.
+   * 
+   * @param updateAllRows
+   */
+  protected void setAnnotationVisibility(boolean updateAllRows)
+  {
+    for (AlignmentAnnotation aa : this.ap.getAlignment()
+            .getAlignmentAnnotation())
+    {
+      if (aa.sequenceRef != null)
+      {
+        setAnnotationVisibility(aa, updateAllRows);
+      }
+    }
+  }
+
+  /**
    * Determine and set the visibility of the given annotation from the currently
    * selected options.
    * <p>
-   * If its sequence is in the selected application scope
-   * (all/selected/unselected sequences), then we set its visibility.
+   * Only update annotations whose type is one of the selected types.
    * <p>
-   * If the annotation type is one of those currently selected by checkbox, set
-   * its visibility to the selected value. If it is not currently selected, set
-   * it to the opposite value. So, unselecting an annotation type with 'hide'
-   * selected, will cause those annotations to be unhidden.
+   * If its sequence is in the selected application scope
+   * (all/selected/unselected sequences), then we set its visibility according
+   * to the current choice of Show or Hide.
    * <p>
    * If force update of all rows is wanted, then set rows not in the sequence
    * selection scope to the opposite visibility to those in scope.
@@ -212,22 +289,16 @@ public class AnnotationChooser extends JPanel
   protected void setAnnotationVisibility(AlignmentAnnotation aa,
           boolean updateAllRows)
   {
-    boolean setToVisible = false;
     if (this.selectedTypes.containsKey(aa.label))
     {
-      setToVisible = this.showSelected;
-    }
-    else
-    {
-      setToVisible = !this.showSelected;
-    }
-    if (isInActionScope(aa))
-    {
-      aa.visible = setToVisible;
-    }
-    else if (updateAllRows)
-    {
-      aa.visible = !setToVisible;
+      if (isInActionScope(aa))
+      {
+        aa.visible = this.showSelected;
+      }
+      else if (updateAllRows)
+      {
+        aa.visible = !this.showSelected;
+      }
     }
     // TODO force not visible if associated sequence is hidden?
     // currently hiding a sequence does not hide its annotation rows
@@ -252,6 +323,11 @@ public class AnnotationChooser extends JPanel
       // we don't care if the annotation's sequence is selected or not
       result = true;
     }
+    else if (this.sg == null)
+    {
+      // shouldn't happen - defensive programming
+      result = true;
+    }
     else if (this.sg.getSequences().contains(aa.sequenceRef))
     {
       // annotation is for a member of the selection group
@@ -279,7 +355,6 @@ public class AnnotationChooser extends JPanel
   public static List<String> getAnnotationTypes(AlignmentI alignment,
           boolean sequenceSpecificOnly)
   {
-    // stub
     List<String> result = new ArrayList<String>();
     for (AlignmentAnnotation aa : alignment.getAlignmentAnnotation())
     {
@@ -333,7 +408,7 @@ public class AnnotationChooser extends JPanel
     final boolean wholeAlignment = this.sg == null;
     JPanel applyToOptions = new JPanel(new FlowLayout(FlowLayout.LEFT));
     CheckboxGroup actingOn = new CheckboxGroup();
-    
+
     String forAll = MessageManager.getString("label.all_sequences");
     final Checkbox allSequences = new Checkbox(forAll, actingOn,
             wholeAlignment);
@@ -342,15 +417,16 @@ public class AnnotationChooser extends JPanel
       @Override
       public void itemStateChanged(ItemEvent evt)
       {
-        if (evt.getStateChange() == ItemEvent.SELECTED) {
+        if (evt.getStateChange() == ItemEvent.SELECTED)
+        {
           AnnotationChooser.this.setApplyToSelectedSequences(true);
           AnnotationChooser.this.setApplyToUnselectedSequences(true);
-          AnnotationChooser.this.repaintAnnotations(true);
+          AnnotationChooser.this.changeApplyTo_actionPerformed();
         }
       }
     });
     applyToOptions.add(allSequences);
-    
+
     String forSelected = MessageManager
             .getString("label.selected_sequences");
     final Checkbox selectedSequences = new Checkbox(forSelected, actingOn,
@@ -365,15 +441,16 @@ public class AnnotationChooser extends JPanel
         {
           AnnotationChooser.this.setApplyToSelectedSequences(true);
           AnnotationChooser.this.setApplyToUnselectedSequences(false);
-          AnnotationChooser.this.repaintAnnotations(true);
+          AnnotationChooser.this.changeApplyTo_actionPerformed();
         }
       }
     });
     applyToOptions.add(selectedSequences);
-    
+
     String exceptSelected = MessageManager
             .getString("label.except_selected_sequences");
-    final Checkbox unselectedSequences = new Checkbox(exceptSelected, actingOn, false);
+    final Checkbox unselectedSequences = new Checkbox(exceptSelected,
+            actingOn, false);
     unselectedSequences.setEnabled(!wholeAlignment);
     unselectedSequences.addItemListener(new ItemListener()
     {
@@ -384,12 +461,12 @@ public class AnnotationChooser extends JPanel
         {
           AnnotationChooser.this.setApplyToSelectedSequences(false);
           AnnotationChooser.this.setApplyToUnselectedSequences(true);
-          AnnotationChooser.this.repaintAnnotations(true);
+          AnnotationChooser.this.changeApplyTo_actionPerformed();
         }
       }
     });
     applyToOptions.add(unselectedSequences);
-    
+
     // set member variables to match the initial selection state
     this.applyToSelectedSequences = selectedSequences.getState()
             || allSequences.getState();
@@ -400,7 +477,7 @@ public class AnnotationChooser extends JPanel
   }
 
   /**
-   * Build a panel with radio buttons options to show or hide selected
+   * Build a panel with radio button options to show or hide selected
    * annotations.
    * 
    * @return
@@ -421,9 +498,10 @@ public class AnnotationChooser extends JPanel
       @Override
       public void itemStateChanged(ItemEvent evt)
       {
-        if (evt.getStateChange() == ItemEvent.SELECTED) {
+        if (evt.getStateChange() == ItemEvent.SELECTED)
+        {
           AnnotationChooser.this.setShowSelected(true);
-          AnnotationChooser.this.repaintAnnotations(false);
+          AnnotationChooser.this.changeShowHide_actionPerformed();
         }
       }
     });
@@ -443,7 +521,7 @@ public class AnnotationChooser extends JPanel
         if (evt.getStateChange() == ItemEvent.SELECTED)
         {
           AnnotationChooser.this.setShowSelected(false);
-          AnnotationChooser.this.repaintAnnotations(false);
+          AnnotationChooser.this.changeShowHide_actionPerformed();
         }
       }
     });
@@ -466,7 +544,7 @@ public class AnnotationChooser extends JPanel
   {
     JPanel jp = new JPanel();
     final Font labelFont = JvSwingUtils.getLabelFont();
-    
+
     JButton ok = new JButton(MessageManager.getString("action.ok"));
     ok.setFont(labelFont);
     ok.addActionListener(new ActionListener()
@@ -478,7 +556,7 @@ public class AnnotationChooser extends JPanel
       }
     });
     jp.add(ok);
-    
+
     JButton cancel = new JButton(MessageManager.getString("action.cancel"));
     cancel.setFont(labelFont);
     cancel.addActionListener(new ActionListener()
@@ -561,4 +639,19 @@ public class AnnotationChooser extends JPanel
     this.applyToUnselectedSequences = applyToUnselectedSequences;
   }
 
+  protected boolean isShowSelected()
+  {
+    return showSelected;
+  }
+
+  protected boolean isApplyToSelectedSequences()
+  {
+    return applyToSelectedSequences;
+  }
+
+  protected boolean isApplyToUnselectedSequences()
+  {
+    return applyToUnselectedSequences;
+  }
+
 }