JAL-3485 constants for CDNA_CONSENSUS, STRUCTURE_CONSENSUS added
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index a0cbff4..268633f 100644 (file)
@@ -67,6 +67,7 @@ import java.util.BitSet;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -80,6 +81,29 @@ import java.util.Map;
 public abstract class AlignmentViewport
         implements AlignViewportI, CommandListener, VamsasSource
 {
+  /**
+   * An enum for auto-calculated annotations, with constants for the
+   * annotation's label, and the key for the property to show it or not
+   */
+  public enum AutoAnnotation
+  {
+    CONSERVATION("Conservation", "SHOW_CONSERVATION"),
+    QUALITY("Quality", "SHOW_QUALITY"),
+    CONSENSUS("Consensus", "SHOW_IDENTITY"),
+    CDNA_CONSENSUS("cDNA Consensus", null),
+    STRUCTURE_CONSENSUS("StrucConsensus", null),
+    OCCUPANCY("Occupancy", "SHOW_OCCUPANCY");
+    
+    public final String label;
+    public final String preferenceKey;
+    
+    private AutoAnnotation(String lbl, String prefKey)
+    {
+      this.label = lbl;
+      this.preferenceKey = prefKey;
+    }
+  }
+
   protected ViewportRanges ranges;
 
   protected ViewStyleI viewStyle = new ViewStyle();
@@ -661,7 +685,8 @@ public abstract class AlignmentViewport
          * retain any colour thresholds per group while
          * changing choice of colour scheme (JAL-2386)
          */
-        sg.setColourScheme(cs);
+        sg.setColourScheme(
+                cs == null ? null : cs.getInstance(this, sg));
         if (cs != null)
         {
           sg.getGroupColourScheme().alignmentChanged(sg,
@@ -1635,6 +1660,7 @@ public abstract class AlignmentViewport
   public void invertColumnSelection()
   {
     colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
+    isColSelChanged(true);
   }
 
   @Override
@@ -1740,8 +1766,12 @@ public abstract class AlignmentViewport
     if (alignment.getHiddenColumns() != null
             && alignment.getHiddenColumns().hasHiddenColumns())
     {
-      selection = alignment.getHiddenColumns()
-              .getVisibleSequenceStrings(start, end, seqs);
+      for (i = 0; i < iSize; i++)
+      {
+        Iterator<int[]> blocks = alignment.getHiddenColumns()
+                .getVisContigsIterator(start, end + 1, false);
+        selection[i] = seqs[i].getSequenceStringFromIterator(blocks);
+      }
     }
     else
     {
@@ -1768,10 +1798,10 @@ public abstract class AlignmentViewport
       {
         if (start == 0)
         {
-          start = hidden.adjustForHiddenColumns(start);
+          start = hidden.visibleToAbsoluteColumn(start);
         }
 
-        end = hidden.getHiddenBoundaryRight(start);
+        end = hidden.getNextHiddenBoundary(false, start);
         if (start == end)
         {
           end = max;
@@ -1786,8 +1816,8 @@ public abstract class AlignmentViewport
 
       if (hidden != null && hidden.hasHiddenColumns())
       {
-        start = hidden.adjustForHiddenColumns(end);
-        start = hidden.getHiddenBoundaryLeft(start) + 1;
+        start = hidden.visibleToAbsoluteColumn(end);
+        start = hidden.getNextHiddenBoundary(true, start) + 1;
       }
     } while (end < max);
 
@@ -1809,13 +1839,13 @@ public abstract class AlignmentViewport
         AlignmentAnnotation clone = new AlignmentAnnotation(annot);
         if (selectedOnly && selectionGroup != null)
         {
-          alignment.getHiddenColumns().makeVisibleAnnotation(
+          clone.makeVisibleAnnotation(
                   selectionGroup.getStartRes(), selectionGroup.getEndRes(),
-                  clone);
+                  alignment.getHiddenColumns());
         }
         else
         {
-          alignment.getHiddenColumns().makeVisibleAnnotation(clone);
+          clone.makeVisibleAnnotation(alignment.getHiddenColumns());
         }
         ala.add(clone);
       }
@@ -1931,7 +1961,7 @@ public abstract class AlignmentViewport
       {
         initRNAStructure();
       }
-      consensus = new AlignmentAnnotation("Consensus",
+      consensus = new AlignmentAnnotation(AutoAnnotation.CONSENSUS.label,
               MessageManager.getString("label.consensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
       initConsensus(consensus);
@@ -1968,7 +1998,8 @@ public abstract class AlignmentViewport
         }
         if (doConsensus)
         {
-          complementConsensus = new AlignmentAnnotation("cDNA Consensus",
+          complementConsensus = new AlignmentAnnotation(
+                  AutoAnnotation.CDNA_CONSENSUS.label,
                   MessageManager
                           .getString("label.complement_consensus_descr"),
                   new Annotation[1], 0f, 100f,
@@ -1992,13 +2023,11 @@ public abstract class AlignmentViewport
     }
   }
 
-  // these should be extracted from the view model - style and settings for
-  // derived annotation
   private void initGapCounts()
   {
     if (showOccupancy)
     {
-      gapcounts = new AlignmentAnnotation("Occupancy",
+      gapcounts = new AlignmentAnnotation(AutoAnnotation.OCCUPANCY.label,
               MessageManager.getString("label.occupancy_descr"),
               new Annotation[1], 0f, alignment.getHeight(),
               AlignmentAnnotation.BAR_GRAPH);
@@ -2017,7 +2046,8 @@ public abstract class AlignmentViewport
     {
       if (conservation == null)
       {
-        conservation = new AlignmentAnnotation("Conservation",
+        conservation = new AlignmentAnnotation(
+                AutoAnnotation.CONSERVATION.label,
                 MessageManager.formatMessage("label.conservation_descr",
                         getConsPercGaps()),
                 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
@@ -2034,7 +2064,7 @@ public abstract class AlignmentViewport
     {
       if (quality == null)
       {
-        quality = new AlignmentAnnotation("Quality",
+        quality = new AlignmentAnnotation(AutoAnnotation.QUALITY.label,
                 MessageManager.getString("label.quality_descr"),
                 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
         quality.hasText = true;
@@ -2048,7 +2078,8 @@ public abstract class AlignmentViewport
   {
     if (alignment.hasRNAStructure() && strucConsensus == null)
     {
-      strucConsensus = new AlignmentAnnotation("StrucConsensus",
+      strucConsensus = new AlignmentAnnotation(
+              AutoAnnotation.STRUCTURE_CONSENSUS.label,
               MessageManager.getString("label.strucconsensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
       strucConsensus.hasText = true;
@@ -2669,17 +2700,20 @@ public abstract class AlignmentViewport
     return sortAnnotationsBy;
   }
 
+  @Override
   public void setSortAnnotationsBy(
           SequenceAnnotationOrder sortAnnotationsBy)
   {
     this.sortAnnotationsBy = sortAnnotationsBy;
   }
 
+  @Override
   public boolean isShowAutocalculatedAbove()
   {
     return showAutocalculatedAbove;
   }
 
+  @Override
   public void setShowAutocalculatedAbove(boolean showAutocalculatedAbove)
   {
     this.showAutocalculatedAbove = showAutocalculatedAbove;
@@ -2781,7 +2815,7 @@ public abstract class AlignmentViewport
     int lastSeq = alignment.getHeight() - 1;
     List<AlignedCodonFrame> seqMappings = null;
     for (int seqNo = ranges
-            .getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
+            .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
     {
       sequence = getAlignment().getSequenceAt(seqNo);
       if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
@@ -2949,4 +2983,68 @@ public abstract class AlignmentViewport
   {
     return currentTree;
   }
+
+  /**
+   * flag set to indicate if structure views might be out of sync with sequences
+   * in the alignment
+   */
+
+  private boolean needToUpdateStructureViews = false;
+
+  @Override
+  public boolean isUpdateStructures()
+  {
+    return needToUpdateStructureViews;
+  }
+
+  @Override
+  public void setUpdateStructures(boolean update)
+  {
+    needToUpdateStructureViews = update;
+  }
+
+  @Override
+  public boolean needToUpdateStructureViews()
+  {
+    boolean update = needToUpdateStructureViews;
+    needToUpdateStructureViews = false;
+    return update;
+  }
+
+  @Override
+  public void addSequenceGroup(SequenceGroup sequenceGroup)
+  {
+    alignment.addGroup(sequenceGroup);
+
+    Color col = sequenceGroup.idColour;
+    if (col != null)
+    {
+      col = col.brighter();
+
+      for (SequenceI sq : sequenceGroup.getSequences())
+      {
+        setSequenceColour(sq, col);
+      }
+    }
+
+    if (codingComplement != null)
+    {
+      SequenceGroup mappedGroup = MappingUtils
+              .mapSequenceGroup(sequenceGroup, this, codingComplement);
+      if (mappedGroup.getSequences().size() > 0)
+      {
+        codingComplement.getAlignment().addGroup(mappedGroup);
+
+        if (col != null)
+        {
+          for (SequenceI seq : mappedGroup.getSequences())
+          {
+            codingComplement.setSequenceColour(seq, col);
+          }
+        }
+      }
+      // propagate the structure view update flag according to our own setting
+      codingComplement.setUpdateStructures(needToUpdateStructureViews);
+    }
+  }
 }