JAL-2371 create a default ResidueShader when constructing the viewport
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index abb8f63..cdf0758 100644 (file)
@@ -35,6 +35,7 @@ import jalview.datamodel.AlignmentView;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SearchResultsI;
@@ -51,6 +52,7 @@ import jalview.structure.VamsasSource;
 import jalview.util.Comparison;
 import jalview.util.MapList;
 import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
 import jalview.viewmodel.styles.ViewStyle;
 import jalview.workers.AlignCalcManager;
 import jalview.workers.ComplementConsensusThread;
@@ -78,6 +80,8 @@ import java.util.Map;
 public abstract class AlignmentViewport implements AlignViewportI,
         CommandListener, VamsasSource
 {
+  final protected ViewportRanges ranges;
+
   protected ViewStyleI viewStyle = new ViewStyle();
 
   /**
@@ -93,6 +97,17 @@ public abstract class AlignmentViewport implements AlignViewportI,
   protected Deque<CommandI> redoList = new ArrayDeque<CommandI>();
 
   /**
+   * alignment displayed in the viewport. Please use get/setter
+   */
+  protected AlignmentI alignment;
+
+  public AlignmentViewport(AlignmentI al)
+  {
+    setAlignment(al);
+    ranges = new ViewportRanges(al);
+  }
+
+  /**
    * @param name
    * @see jalview.api.ViewStyleI#setFontName(java.lang.String)
    */
@@ -552,10 +567,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
     viewStyle.setSeqNameItalics(default1);
   }
 
-  /**
-   * alignment displayed in the viewport. Please use get/setter
-   */
-  protected AlignmentI alignment;
+
 
   @Override
   public AlignmentI getAlignment()
@@ -597,7 +609,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   protected boolean ignoreGapsInConsensusCalculation = false;
 
-  protected ResidueShaderI residueShading;
+  protected ResidueShaderI residueShading = new ResidueShader();
 
   @Override
   public void setGlobalColourScheme(ColourSchemeI cs)
@@ -626,9 +638,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
     if (cs != null)
     {
-      // if (getConservationSelected() || getAbovePIDThreshold()
-      // || cs instanceof PIDColourScheme
-      // || cs instanceof Blosum62ColourScheme)
       if (getConservationSelected())
       {
         residueShading.setConservation(hconservation);
@@ -675,6 +684,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   protected AlignmentAnnotation complementConsensus;
 
+  protected AlignmentAnnotation gapcounts;
+
   protected AlignmentAnnotation strucConsensus;
 
   protected AlignmentAnnotation conservation;
@@ -777,6 +788,12 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
+  public AlignmentAnnotation getAlignmentGapAnnotation()
+  {
+    return gapcounts;
+  }
+
+  @Override
   public AlignmentAnnotation getComplementConsensusAnnotation()
   {
     return complementConsensus;
@@ -1076,7 +1093,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   /**
-   * Set the selection group for this window.
+   * Set the selection group for this window. Also sets the current alignment as
+   * the context for the group, if it does not already have one.
    * 
    * @param sg
    *          - group holding references to sequences in this alignment view
@@ -1086,11 +1104,16 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public void setSelectionGroup(SequenceGroup sg)
   {
     selectionGroup = sg;
+    if (sg != null && sg.getContext() == null)
+    {
+      sg.setContext(alignment);
+    }
   }
 
-  public void setHiddenColumns(ColumnSelection colsel)
+  public void setHiddenColumns(HiddenColumns hidden)
   {
-    this.colSel = colsel;
+    this.alignment.setHiddenColumns(hidden);
+    // this.colSel = colsel;
   }
 
   @Override
@@ -1137,7 +1160,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
   @Override
   public boolean hasHiddenColumns()
   {
-    return colSel != null && colSel.hasHiddenColumns();
+    return colSel != null
+            && alignment.getHiddenColumns().hasHiddenColumns();
   }
 
   public void updateHiddenColumns()
@@ -1272,6 +1296,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   protected boolean showConsensus = true;
 
+  protected boolean showOccupancy = true;
+
   private Map<SequenceI, Color> sequenceColours = new HashMap<SequenceI, Color>();
 
   protected SequenceAnnotationOrder sortAnnotationsBy = null;
@@ -1283,15 +1309,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   private boolean followHighlight = true;
 
-  // TODO private with getters and setters?
-  public int startRes;
-
-  public int endRes;
-
-  public int startSeq;
-
-  public int endSeq;
-
   /**
    * Property change listener for changes in alignment
    * 
@@ -1341,7 +1358,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
       return;
     }
 
-    colSel.hideSelectedColumns();
+    colSel.hideSelectedColumns(alignment);
     setSelectionGroup(null);
     isColSelChanged(true);
   }
@@ -1350,24 +1367,24 @@ public abstract class AlignmentViewport implements AlignViewportI,
   {
     if (start == end)
     {
-      colSel.hideColumns(start);
+      colSel.hideSelectedColumns(start, alignment.getHiddenColumns());
     }
     else
     {
-      colSel.hideColumns(start, end);
+      alignment.getHiddenColumns().hideColumns(start, end);
     }
     isColSelChanged(true);
   }
 
   public void showColumn(int col)
   {
-    colSel.revealHiddenColumns(col);
+    alignment.getHiddenColumns().revealHiddenColumns(col, colSel);
     isColSelChanged(true);
   }
 
   public void showAllHiddenColumns()
   {
-    colSel.revealAllHiddenColumns();
+    alignment.getHiddenColumns().revealAllHiddenColumns(colSel);
     isColSelChanged(true);
   }
 
@@ -1589,7 +1606,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   @Override
   public void invertColumnSelection()
   {
-    colSel.invertColumnSelection(0, alignment.getWidth());
+    colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
   }
 
   @Override
@@ -1637,7 +1654,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   @Override
   public CigarArray getViewAsCigars(boolean selectedRegionOnly)
   {
-    return new CigarArray(alignment, colSel,
+    return new CigarArray(alignment, alignment.getHiddenColumns(),
             (selectedRegionOnly ? selectionGroup : null));
   }
 
@@ -1652,8 +1669,10 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public jalview.datamodel.AlignmentView getAlignmentView(
           boolean selectedOnly, boolean markGroups)
   {
-    return new AlignmentView(alignment, colSel, selectionGroup,
-            colSel != null && colSel.hasHiddenColumns(), selectedOnly,
+    return new AlignmentView(alignment, alignment.getHiddenColumns(),
+            selectionGroup, alignment.getHiddenColumns() != null
+                    && alignment.getHiddenColumns().hasHiddenColumns(),
+            selectedOnly,
             markGroups);
   }
 
@@ -1697,9 +1716,11 @@ public abstract class AlignmentViewport implements AlignViewportI,
     }
 
     selection = new String[iSize];
-    if (colSel != null && colSel.hasHiddenColumns())
+    if (alignment.getHiddenColumns() != null
+            && alignment.getHiddenColumns().hasHiddenColumns())
     {
-      selection = colSel.getVisibleSequenceStrings(start, end, seqs);
+      selection = alignment.getHiddenColumns().getVisibleSequenceStrings(
+              start, end, seqs);
     }
     else
     {
@@ -1721,14 +1742,15 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
     do
     {
-      if (colSel != null && colSel.hasHiddenColumns())
+      HiddenColumns hidden = alignment.getHiddenColumns();
+      if (hidden != null && hidden.hasHiddenColumns())
       {
         if (start == 0)
         {
-          start = colSel.adjustForHiddenColumns(start);
+          start = hidden.adjustForHiddenColumns(start);
         }
 
-        end = colSel.getHiddenBoundaryRight(start);
+        end = hidden.getHiddenBoundaryRight(start);
         if (start == end)
         {
           end = max;
@@ -1741,10 +1763,10 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
       regions.add(new int[] { start, end });
 
-      if (colSel != null && colSel.hasHiddenColumns())
+      if (hidden != null && hidden.hasHiddenColumns())
       {
-        start = colSel.adjustForHiddenColumns(end);
-        start = colSel.getHiddenBoundaryLeft(start) + 1;
+        start = hidden.adjustForHiddenColumns(end);
+        start = hidden.getHiddenBoundaryLeft(start) + 1;
       }
     } while (end < max);
 
@@ -1766,12 +1788,13 @@ public abstract class AlignmentViewport implements AlignViewportI,
         AlignmentAnnotation clone = new AlignmentAnnotation(annot);
         if (selectedOnly && selectionGroup != null)
         {
-          colSel.makeVisibleAnnotation(selectionGroup.getStartRes(),
+          alignment.getHiddenColumns().makeVisibleAnnotation(
+                  selectionGroup.getStartRes(),
                   selectionGroup.getEndRes(), clone);
         }
         else
         {
-          colSel.makeVisibleAnnotation(clone);
+          alignment.getHiddenColumns().makeVisibleAnnotation(clone);
         }
         ala.add(clone);
       }
@@ -1887,19 +1910,21 @@ public abstract class AlignmentViewport implements AlignViewportI,
       {
         initRNAStructure();
       }
-      consensus = new AlignmentAnnotation("Consensus", "PID",
+      consensus = new AlignmentAnnotation("Consensus",
+              MessageManager.getString("label.consensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
       initConsensus(consensus);
+      initGapCounts();
 
       initComplementConsensus();
     }
   }
 
   /**
-   * If this is a protein alignment and there are mappings to cDNA, add the cDNA
-   * consensus annotation.
+   * If this is a protein alignment and there are mappings to cDNA, adds the
+   * cDNA consensus annotation and returns true, else returns false.
    */
-  public void initComplementConsensus()
+  public boolean initComplementConsensus()
   {
     if (!alignment.isNucleotide())
     {
@@ -1923,12 +1948,16 @@ public abstract class AlignmentViewport implements AlignViewportI,
         if (doConsensus)
         {
           complementConsensus = new AlignmentAnnotation("cDNA Consensus",
-                  "PID for cDNA", new Annotation[1], 0f, 100f,
+                  MessageManager
+                          .getString("label.complement_consensus_descr"),
+                  new Annotation[1], 0f, 100f,
                   AlignmentAnnotation.BAR_GRAPH);
           initConsensus(complementConsensus);
+          return true;
         }
       }
     }
+    return false;
   }
 
   private void initConsensus(AlignmentAnnotation aa)
@@ -1942,6 +1971,25 @@ public abstract class AlignmentViewport implements AlignViewportI,
     }
   }
 
+  // these should be extracted from the view model - style and settings for
+  // derived annotation
+  private void initGapCounts()
+  {
+    if (showOccupancy)
+    {
+      gapcounts = new AlignmentAnnotation("Occupancy",
+              MessageManager.getString("label.occupancy_descr"),
+              new Annotation[1], 0f,
+              alignment.getHeight(), AlignmentAnnotation.BAR_GRAPH);
+      gapcounts.hasText = true;
+      gapcounts.autoCalculated = true;
+      gapcounts.scaleColLabel = true;
+      gapcounts.graph = AlignmentAnnotation.BAR_GRAPH;
+
+      alignment.addAnnotation(gapcounts);
+    }
+  }
+
   private void initConservation()
   {
     if (showConservation)
@@ -1949,8 +1997,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
       if (conservation == null)
       {
         conservation = new AlignmentAnnotation("Conservation",
-                "Conservation of total alignment less than "
-                        + getConsPercGaps() + "% gaps", new Annotation[1],
+                MessageManager.formatMessage("label.conservation_descr",
+                        getConsPercGaps()), new Annotation[1],
                 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
         conservation.hasText = true;
         conservation.autoCalculated = true;
@@ -1966,7 +2014,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
       if (quality == null)
       {
         quality = new AlignmentAnnotation("Quality",
-                "Alignment Quality based on Blosum62 scores",
+                MessageManager.getString("label.quality_descr"),
                 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
         quality.hasText = true;
         quality.autoCalculated = true;
@@ -1979,7 +2027,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
   {
     if (alignment.hasRNAStructure() && strucConsensus == null)
     {
-      strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID",
+      strucConsensus = new AlignmentAnnotation("StrucConsensus",
+              MessageManager.getString("label.strucconsensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
       strucConsensus.hasText = true;
       strucConsensus.autoCalculated = true;
@@ -2428,6 +2477,11 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public void setViewStyle(ViewStyleI settingsForView)
   {
     viewStyle = new ViewStyle(settingsForView);
+    if (residueShading != null)
+    {
+      residueShading.setConservationApplied(settingsForView
+              .isConservationColourSelected());
+    }
   }
 
   @Override
@@ -2621,6 +2675,18 @@ public abstract class AlignmentViewport implements AlignViewportI,
     viewStyle.setScaleProteinAsCdna(b);
   }
 
+  @Override
+  public boolean isProteinFontAsCdna()
+  {
+    return viewStyle.isProteinFontAsCdna();
+  }
+
+  @Override
+  public void setProteinFontAsCdna(boolean b)
+  {
+    viewStyle.setProteinFontAsCdna(b);
+  }
+
   /**
    * @return true if view should scroll to show the highlighted region of a
    *         sequence
@@ -2638,63 +2704,10 @@ public abstract class AlignmentViewport implements AlignViewportI,
     this.followHighlight = b;
   }
 
-  public int getStartRes()
-  {
-    return startRes;
-  }
-
   @Override
-  public int getEndRes()
-  {
-    return endRes;
-  }
-
-  public int getStartSeq()
-  {
-    return startSeq;
-  }
-
-  public void setStartRes(int res)
-  {
-    this.startRes = res;
-  }
-
-  public void setStartSeq(int seq)
+  public ViewportRanges getRanges()
   {
-    this.startSeq = seq;
-  }
-
-  public void setEndRes(int res)
-  {
-    if (res > alignment.getWidth() - 1)
-    {
-      // log.System.out.println(" Corrected res from " + res + " to maximum " +
-      // (alignment.getWidth()-1));
-      res = alignment.getWidth() - 1;
-    }
-    if (res < 0)
-    {
-      res = 0;
-    }
-    this.endRes = res;
-  }
-
-  public void setEndSeq(int seq)
-  {
-    if (seq > alignment.getHeight())
-    {
-      seq = alignment.getHeight();
-    }
-    if (seq < 0)
-    {
-      seq = 0;
-    }
-    this.endSeq = seq;
-  }
-
-  public int getEndSeq()
-  {
-    return endSeq;
+    return ranges;
   }
 
   /**
@@ -2734,7 +2747,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
      * locate 'middle' column (true middle if an odd number visible, left of
      * middle if an even number visible)
      */
-    int middleColumn = getStartRes() + (getEndRes() - getStartRes()) / 2;
+    int middleColumn = ranges.getStartRes()
+            + (ranges.getEndRes() - ranges.getStartRes()) / 2;
     final HiddenSequences hiddenSequences = getAlignment()
             .getHiddenSequences();
 
@@ -2744,7 +2758,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
      */
     int lastSeq = alignment.getHeight() - 1;
     List<AlignedCodonFrame> seqMappings = null;
-    for (int seqNo = getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
+    for (int seqNo = ranges.getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
     {
       sequence = getAlignment().getSequenceAt(seqNo);
       if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
@@ -2812,7 +2826,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   private boolean selectionIsDefinedGroup = false;
 
-
   @Override
   public boolean isSelectionDefinedGroup()
   {