*/
package jalview.datamodel;
+import jalview.util.Comparison;
import jalview.util.ShiftList;
import jalview.viewmodel.annotationfilter.AnnotationFilterParameter;
import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField;
selected.or(mask);
}
+ public boolean isSelected(int column)
+ {
+ return selected.get(column);
+ }
+
public int getMaxColumn()
{
return selected.length() - 1;
{
return selected.get(0) ? 0 : selected.nextSetBit(0);
}
+
+ /**
+ * @return a series of selection intervals along the range
+ */
+ public List<int[]> getRanges()
+ {
+ List<int[]> rlist = new ArrayList<int[]>();
+ if (selected.isEmpty())
+ {
+ return rlist;
+ }
+ int next = selected.nextSetBit(0), clear = -1;
+ while (next != -1)
+ {
+ clear = selected.nextClearBit(next);
+ rlist.add(new int[] { next, clear - 1 });
+ next = selected.nextSetBit(clear);
+ }
+ return rlist;
+ }
}
IntList selected = new IntList();
+
/*
* list of hidden column [start, end] ranges; the list is maintained in
* ascending start column order
/**
* Returns a list of selected columns. The list contains no duplicates but is
- * not necessarily ordered.
+ * not necessarily ordered. It also may include columns hidden from the
+ * current view
*/
public List<Integer> getSelected()
{
}
/**
+ * @return list of int arrays containing start and end column position for
+ * runs of selected columns ordered from right to left.
+ */
+ public List<int[]> getSelectedRanges()
+ {
+ return selected.getRanges();
+ }
+
+ /**
*
* @param col
* index to search for in column selection
*
- * @return true if Integer(col) is in selection.
+ * @return true if col is selected
*/
public boolean contains(int col)
{
- return selected.contains(new Integer(col));
+ return (col > -1) ? selected.isSelected(col) : false;
}
/**
* Return absolute column index for a visible column index
*
* @param column
- * int column index in alignment view
+ * int column index in alignment view (count from zero)
* @return alignment column index for column
*/
public int adjustForHiddenColumns(int column)
/**
* Use this method to determine where the next hiddenRegion starts
+ *
+ * @param hiddenRegion
+ * index of hidden region (counts from 0)
+ * @return column number in visible view
*/
public int findHiddenRegionPosition(int hiddenRegion)
{
gaps += region[1] + 1 - region[0];
result = region[1] + 1;
index++;
- } while (index < hiddenRegion + 1);
+ } while (index <= hiddenRegion);
result -= gaps;
}
public void hideSelectedColumns()
{
- while (!selected.isEmpty())
+ synchronized (selected)
{
- int column = selected.elementAt(0);
- hideColumns(column);
+ for (int[] selregions : selected.getRanges())
+ {
+ hideColumns(selregions[0], selregions[1]);
+ }
+ selected.clear();
}
}
/*
* remaining case is that the new range follows everything else
*/
- hiddenColumns.addElement(new int[] { start, end });
+ hiddenColumns.addElement(new int[] { start, end });
}
/**
}
/**
+ * Locate the first and last position visible for this sequence. if seq isn't
+ * visible then return the position of the left and right of the hidden
+ * boundary region, and the corresponding alignment column indices for the
+ * extent of the sequence
+ *
+ * @param seq
+ * @return int[] { visible start, visible end, first seqpos, last seqpos,
+ * alignment index for seq start, alignment index for seq end }
+ */
+ public int[] locateVisibleBoundsOfSequence(SequenceI seq)
+ {
+ int fpos=seq.getStart(),lpos= seq.getEnd();
+ int start = 0;
+
+ if (hiddenColumns == null || hiddenColumns.size() == 0)
+ {
+ int ifpos = seq.findIndex(fpos) - 1, ilpos = seq.findIndex(lpos) - 1;
+ return new int[] { ifpos, ilpos, fpos, lpos, ifpos, ilpos };
+ }
+
+ // Simply walk along the sequence whilst watching for hidden column
+ // boundaries
+ List<int[]> regions = getHiddenColumns();
+ int spos = fpos, lastvispos = -1, rcount = 0, hideStart = seq
+ .getLength(), hideEnd = -1;
+ int visPrev = 0, visNext = 0, firstP = -1, lastP = -1;
+ boolean foundStart = false;
+ for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd()
+ && p < pLen; p++)
+ {
+ if (!Comparison.isGap(seq.getCharAt(p)))
+ {
+ // keep track of first/last column
+ // containing sequence data regardless of visibility
+ if (firstP == -1)
+ {
+ firstP = p;
+ }
+ lastP = p;
+ // update hidden region start/end
+ while (hideEnd < p && rcount < regions.size())
+ {
+ int[] region = regions.get(rcount++);
+ visPrev = visNext;
+ visNext += region[0] - visPrev;
+ hideStart = region[0];
+ hideEnd = region[1];
+ }
+ if (hideEnd < p)
+ {
+ hideStart = seq.getLength();
+ }
+ // update visible boundary for sequence
+ if (p < hideStart)
+ {
+ if (!foundStart)
+ {
+ fpos = spos;
+ start = p;
+ foundStart = true;
+ }
+ lastvispos = p;
+ lpos = spos;
+ }
+ // look for next sequence position
+ spos++;
+ }
+ }
+ if (foundStart)
+ {
+ return new int[] { findColumnPosition(start),
+ findColumnPosition(lastvispos), fpos, lpos, firstP, lastP };
+ }
+ // otherwise, sequence was completely hidden
+ return new int[] { visPrev, visNext, 0, 0, firstP, lastP };
+ }
+
+ /**
* delete any columns in alignmentAnnotation that are hidden (including
* sequence associated annotation).
*
public boolean filterAnnotations(Annotation[] annotations,
AnnotationFilterParameter filterParams)
{
+ // JBPNote - this method needs to be refactored to become independent of
+ // viewmodel package
this.revealAllHiddenColumns();
this.clear();
int count = 0;
} while (count < annotations.length);
return false;
}
+
}