JAL-2439 Out-by-one in setting endRes/endSeq
[jalview.git] / src / jalview / viewmodel / ViewportPositionProps.java
index 4f67cc6..61dd18c 100644 (file)
  */
 package jalview.viewmodel;
 
-import jalview.api.ViewStyleI;
-import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.SequenceCollectionI;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
 
 /**
  * Supplies and updates viewport properties relating to position such as: start
- * and end residues and sequences, hidden column/row adjustments, ratio of
- * viewport to alignment etc
+ * and end residues and sequences
  */
 public class ViewportPositionProps extends ViewportProperties
 {
@@ -52,31 +40,16 @@ public class ViewportPositionProps extends ViewportProperties
   // end sequence of viewport
   private int endSeq;
 
-  // character height
-  private int charHeight;
-
-  // character width
-  private int charWidth;
-
   // alignment
   private AlignmentI al;
 
-  // viewstyle
-  private ViewStyleI viewstyle;
-
-  // hidden column data
-  protected ColumnSelection colSel = new ColumnSelection();
-
-  private long colselhash = -1;
-
-  // hidden sequence data
-  private Map<SequenceI, SequenceCollectionI> hiddenRepSequences;
-
   /**
    * Constructor
-   * @param alignment TODO
+   * 
+   * @param alignment
+   *          the viewport's alignment
    */
-  public ViewportPositionProps(AlignmentI alignment, ViewStyleI vstyle)
+  public ViewportPositionProps(AlignmentI alignment)
   {
     // initial values of viewport settings
     this.startRes = 0;
@@ -84,17 +57,6 @@ public class ViewportPositionProps extends ViewportProperties
     this.startSeq = 0;
     this.endSeq = alignment.getHeight() - 1;
     this.al = alignment;
-    this.viewstyle = vstyle;
-  }
-
-  public void setCharHeight(int h)
-  {
-    viewstyle.setCharHeight(h);
-  }
-
-  public void setCharWidth(int w)
-  {
-    viewstyle.setCharWidth(w);
   }
 
   // ways to update values
@@ -104,21 +66,27 @@ public class ViewportPositionProps extends ViewportProperties
   // ways to supply positional information
 
   /**
-   * Get alignment width
+   * Get alignment width in cols, including hidden cols
    */
-  public int getAlignmentWidthInCols()
+  public int getAbsoluteAlignmentWidth()
   {
     return al.getWidth();
   }
 
   /**
-   * Get alignment height
+   * Get alignment height in rows, including hidden rows
    */
-  public int getAlignmentHeightInRows()
+  public int getAbsoluteAlignmentHeight()
   {
-    return al.getHeight();
+    return al.getHeight() + al.getHiddenSequences().getSize();
   }
 
+  /**
+   * Set first residue visible in the viewport
+   * 
+   * @param res
+   *          residue position
+   */
   public void setStartRes(int res)
   {
     if (res > al.getWidth() - 1)
@@ -132,24 +100,36 @@ public class ViewportPositionProps extends ViewportProperties
     this.startRes = res;
   }
 
+  /**
+   * Set last residue visible in the viewport
+   * 
+   * @param res
+   *          residue position
+   */
   public void setEndRes(int res)
   {
-    if (res > al.getWidth() - 1)
+    if (res >= al.getWidth())
     {
       res = al.getWidth() - 1;
     }
-    else if (res < 0)
+    else if (res < 1)
     {
-      res = 0;
+      res = 1;
     }
     this.endRes = res;
   }
 
+  /**
+   * Set the first sequence visible in the viewport
+   * 
+   * @param seq
+   *          sequence position
+   */
   public void setStartSeq(int seq)
   {
-    if (seq > al.getHeight())
+    if (seq > al.getHeight() - 1)
     {
-      seq = al.getHeight();
+      seq = al.getHeight() - 1;
     }
     else if (seq < 0)
     {
@@ -158,15 +138,21 @@ public class ViewportPositionProps extends ViewportProperties
     this.startSeq = seq;
   }
 
+  /**
+   * Set the last sequence visible in the viewport
+   * 
+   * @param seq
+   *          sequence position
+   */
   public void setEndSeq(int seq)
   {
-    if (seq > al.getHeight())
+    if (seq >= al.getHeight())
     {
-      seq = al.getHeight();
+      seq = al.getHeight() - 1;
     }
-    else if (seq < 0)
+    else if (seq < 1)
     {
-      seq = 0;
+      seq = 1;
     }
     this.endSeq = seq;
   }
@@ -202,451 +188,4 @@ public class ViewportPositionProps extends ViewportProperties
   {
     return endSeq;
   }
-  /**
-   * Get start residue of viewport
-   */
-  public int getStartRes(boolean countHidden)
-  {
-    if (countHidden)
-    {
-      return 0; // av.getColumnSelection().adjustForHiddenColumns(startRes);
-    }
-    else
-    {
-      return startRes;
-    }
-  }
-
-  /**
-   * Convert distance x in viewport pixels to a distance in number of residues
-   * 
-   * @param x
-   *          number of pixels
-   * @return number of residues
-   */
-  public int convertPixelsToResidues(int x)
-  {
-    return Math.round((float) x / viewstyle.getCharWidth());
-  }
-
-  /**
-   * Convert distance y in viewport pixels to a distance in number of sequences
-   * 
-   * @param y
-   *          number of pixels
-   * @return number of sequences
-   */
-  public int convertPixelsToSequences(int y)
-  {
-    return Math.round((float) y / viewstyle.getCharHeight());
-  }
-  
-  /**
-   * Convert number of sequences s to a height in viewport pixels
-   * 
-   * @param s
-   *          number of sequences
-   * @return number of pixels
-   */
-  public int convertSequencesToPixels(int s)
-  {
-    return (s * viewstyle.getCharHeight());
-  }
-
-  /**
-   * Convert number of residues r to a width in viewport pixels
-   * 
-   * @param r
-   *          number of residues
-   * @return number of pixels
-   */
-  public int convertResiduesToPixels(int r)
-  {
-    return (r * viewstyle.getCharWidth());
-  }
-
-  public void setHiddenColumns(ColumnSelection colsel)
-  {
-    this.colSel = colsel;
-  }
-
-  public ColumnSelection getColumnSelection()
-  {
-    return colSel;
-  }
-
-  public void setColumnSelection(ColumnSelection colSel)
-  {
-    this.colSel = colSel;
-    if (colSel != null)
-    {
-      // updateHiddenColumns(); - does nothing
-    }
-    isColSelChanged(true);
-  }
-
-  public boolean hasHiddenColumns()
-  {
-    return colSel != null && colSel.hasHiddenColumns();
-  }
-
-  /**
-   * checks current colsel against record of last hash value, and optionally
-   * updates record.
-   * 
-   * @param b
-   *          update the record of last hash value
-   * @return true if colsel changed since last call (when b is true)
-   */
-  public boolean isColSelChanged(boolean b)
-  {
-    int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
-    if (hc != -1 && hc != colselhash)
-    {
-      if (b)
-      {
-        colselhash = hc;
-      }
-      return true;
-    }
-    return false;
-  }
-
-  public void hideColumns(int start, int end)
-  {
-    if (start == end)
-    {
-      colSel.hideColumns(start);
-    }
-    else
-    {
-      colSel.hideColumns(start, end);
-    }
-    isColSelChanged(true);
-  }
-
-  public void showColumn(int col)
-  {
-    colSel.revealHiddenColumns(col);
-    isColSelChanged(true);
-  }
-
-  public void showAllHiddenColumns()
-  {
-    colSel.revealAllHiddenColumns();
-    isColSelChanged(true);
-  }
-
-  public void invertColumnSelection()
-  {
-    colSel.invertColumnSelection(0, al.getWidth());
-  }
-
-  public List<int[]> getVisibleRegionBoundaries(int min, int max)
-  {
-    ArrayList<int[]> regions = new ArrayList<int[]>();
-    int start = min;
-    int end = max;
-
-    do
-    {
-      if (hasHiddenColumns())
-      {
-        if (start == 0)
-        {
-          start = colSel.adjustForHiddenColumns(start);
-        }
-
-        end = colSel.getHiddenBoundaryRight(start);
-        if (start == end)
-        {
-          end = max;
-        }
-        if (end > max)
-        {
-          end = max;
-        }
-      }
-
-      regions.add(new int[] { start, end });
-
-      if (hasHiddenColumns())
-      {
-        start = colSel.adjustForHiddenColumns(end);
-        start = colSel.getHiddenBoundaryLeft(start) + 1;
-      }
-    } while (end < max);
-
-    int[][] startEnd = new int[regions.size()][2];
-
-    return regions;
-  }
-
-  /**
-   * synthesize a column selection if none exists so it covers the given
-   * selection group. if wholewidth is false, no column selection is made if the
-   * selection group covers the whole alignment width.
-   * 
-   * @param sg
-   * @param wholewidth
-   */
-  public void expandColSelection(SequenceGroup sg, boolean wholewidth)
-  {
-    int sgs, sge;
-    if (sg != null && (sgs = sg.getStartRes()) >= 0
-            && sg.getStartRes() <= (sge = sg.getEndRes()))
-    {
-      if (!wholewidth && al.getWidth() == (1 + sge - sgs))
-      {
-        // do nothing
-        return;
-      }
-      if (colSel == null)
-      {
-        colSel = new ColumnSelection();
-      }
-      for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
-      {
-        colSel.addElement(cspos);
-      }
-    }
-  }
-
-  public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
-          boolean selectedOnly, SequenceGroup selectionGroup)
-  {
-    ArrayList<AlignmentAnnotation> ala = new ArrayList<AlignmentAnnotation>();
-    AlignmentAnnotation[] aa;
-    if ((aa = al.getAlignmentAnnotation()) != null)
-    {
-      for (AlignmentAnnotation annot : aa)
-      {
-        AlignmentAnnotation clone = new AlignmentAnnotation(annot);
-        if (selectedOnly && selectionGroup != null)
-        {
-          colSel.makeVisibleAnnotation(selectionGroup.getStartRes(),
-                  selectionGroup.getEndRes(), clone);
-        }
-        else
-        {
-          colSel.makeVisibleAnnotation(clone);
-        }
-        ala.add(clone);
-      }
-    }
-    return ala;
-  }
-
-  public String[] getVisibleSequenceStrings(int start, int end,
-          SequenceI[] seqs)
-  {
-    return colSel.getVisibleSequenceStrings(start, end, seqs);
-  }
-
-  /**
-   * Set visibility for any annotations for the given sequence.
-   * 
-   * @param sequenceI
-   */
-  protected void setSequenceAnnotationsVisible(SequenceI sequenceI,
-          boolean visible)
-  {
-    AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
-    if (anns != null)
-    {
-      for (AlignmentAnnotation ann : anns)
-      {
-        if (ann.sequenceRef == sequenceI)
-        {
-          ann.visible = visible;
-        }
-      }
-    }
-  }
-
-  public void setHiddenRepSequences(
-          Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
-  {
-    this.hiddenRepSequences = hiddenRepSequences;
-  }
-
-  public Map<SequenceI, SequenceCollectionI> getHiddenRepSequences()
-  {
-    return hiddenRepSequences;
-  }
-
-  // common hide/show seq stuff
-  public SequenceGroup showAllHiddenSeqs(SequenceGroup selectionGroup)
-  {
-    if (al.getHiddenSequences().getSize() > 0)
-    {
-      if (selectionGroup == null)
-      {
-        selectionGroup = new SequenceGroup();
-        selectionGroup.setEndRes(al.getWidth() - 1);
-      }
-      List<SequenceI> tmp = al.getHiddenSequences().showAll(
-              hiddenRepSequences);
-      for (SequenceI seq : tmp)
-      {
-        selectionGroup.addSequence(seq, false);
-        setSequenceAnnotationsVisible(seq, true);
-      }
-
-      hiddenRepSequences = null;
-
-      firePropertyChange("alignment", null, al.getSequences());
-      // used to set hasHiddenRows/hiddenRepSequences here, after the property
-      // changed event
-      sendSelection();
-    }
-  }
-
-  public void showSequence(int index, SequenceGroup selectionGroup)
-  {
-    List<SequenceI> tmp = al.getHiddenSequences().showSequence(index,
-            hiddenRepSequences);
-    if (tmp.size() > 0)
-    {
-      if (selectionGroup == null)
-      {
-        selectionGroup = new SequenceGroup();
-        selectionGroup.setEndRes(al.getWidth() - 1);
-      }
-
-      for (SequenceI seq : tmp)
-      {
-        selectionGroup.addSequence(seq, false);
-        setSequenceAnnotationsVisible(seq, true);
-      }
-      firePropertyChange("alignment", null, al.getSequences());
-      sendSelection();
-    }
-  }
-
-  public void hideAllSelectedSeqs(SequenceGroup selectionGroup)
-  {
-    if (selectionGroup == null || selectionGroup.getSize() < 1)
-    {
-      return;
-    }
-
-    SequenceI[] seqs = selectionGroup.getSequencesInOrder(al);
-
-    hideSequence(seqs);
-
-    setSelectionGroup(null);
-  }
-
-  public void hideSequence(SequenceI[] seq)
-  {
-    if (seq != null)
-    {
-      for (int i = 0; i < seq.length; i++)
-      {
-        al.getHiddenSequences().hideSequence(seq[i]);
-        setSequenceAnnotationsVisible(seq[i], false);
-      }
-      firePropertyChange("alignment", null, al.getSequences());
-    }
-  }
-
-  /**
-   * Hides the specified sequence, or the sequences it represents
-   * 
-   * @param sequence
-   *          the sequence to hide, or keep as representative
-   * @param representGroup
-   *          if true, hide the current selection group except for the
-   *          representative sequence
-   */
-  public void hideSequences(SequenceI sequence, boolean representGroup,
-          SequenceGroup selectionGroup)
-  {
-    if (selectionGroup == null || selectionGroup.getSize() < 1)
-    {
-      hideSequence(new SequenceI[] { sequence });
-      return;
-    }
-
-    if (representGroup)
-    {
-      hideRepSequences(sequence, selectionGroup);
-      setSelectionGroup(null);
-      return;
-    }
-
-    int gsize = selectionGroup.getSize();
-    SequenceI[] hseqs = selectionGroup.getSequences().toArray(
-            new SequenceI[gsize]);
-
-    hideSequence(hseqs);
-    setSelectionGroup(null);
-    sendSelection();
-  }
-
-  public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
-  {
-    int sSize = sg.getSize();
-    if (sSize < 2)
-    {
-      return;
-    }
-
-    if (hiddenRepSequences == null)
-    {
-      hiddenRepSequences = new Hashtable<SequenceI, SequenceCollectionI>();
-    }
-
-    hiddenRepSequences.put(repSequence, sg);
-
-    // Hide all sequences except the repSequence
-    SequenceI[] seqs = new SequenceI[sSize - 1];
-    int index = 0;
-    for (int i = 0; i < sSize; i++)
-    {
-      if (sg.getSequenceAt(i) != repSequence)
-      {
-        if (index == sSize - 1)
-        {
-          return;
-        }
-
-        seqs[index++] = sg.getSequenceAt(i);
-      }
-    }
-    sg.setSeqrep(repSequence); // note: not done in 2.7applet
-    sg.setHidereps(true); // note: not done in 2.7applet
-    hideSequence(seqs);
-
-  }
-
-  /**
-   * 
-   * @param seq
-   * @return true if there are sequences represented by this sequence that are
-   *         currently hidden
-   */
-  public boolean isHiddenRepSequence(SequenceI seq)
-  {
-    return (hiddenRepSequences != null && hiddenRepSequences
-            .containsKey(seq));
-  }
-
-  /**
-   * 
-   * @param seq
-   * @return null or a sequence group containing the sequences that seq
-   *         represents
-   */
-  public SequenceGroup getRepresentedSequences(SequenceI seq)
-  {
-    return (SequenceGroup) (hiddenRepSequences == null ? null
-            : hiddenRepSequences.get(seq));
-  }
-
-  public int adjustForHiddenSeqs(int alignmentIndex)
-  {
-    return al.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);
-  }
 }