X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FColumnSelection.java;h=6fd76b23ebf02a9366c38fecce0ee565d629edc1;hb=884952b9d0bf7e07ff8c8f70ed1601bfe20ac554;hp=97955701204e99265fb89dde14d7149077bf2fa1;hpb=dd85e0fbce881a3c71ad20026311a28a10eb12de;p=jalview.git diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 9795570..6fd76b2 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -20,6 +20,7 @@ */ package jalview.datamodel; +import jalview.util.Comparison; import jalview.util.ShiftList; import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; @@ -169,9 +170,45 @@ public class ColumnSelection // lastly update the bitfield all at once selected.or(mask); } + + public boolean isSelected(int column) + { + return selected.get(column); + } + + public int getMaxColumn() + { + return selected.length() - 1; + } + + public int getMinColumn() + { + return selected.get(0) ? 0 : selected.nextSetBit(0); + } + + /** + * @return a series of selection intervals along the range + */ + public List getRanges() + { + List rlist = new ArrayList(); + 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 @@ -231,7 +268,8 @@ public class ColumnSelection /** * 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 getSelected() { @@ -239,15 +277,24 @@ public class ColumnSelection } /** + * @return list of int arrays containing start and end column position for + * runs of selected columns ordered from right to left. + */ + public List 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; } /** @@ -265,17 +312,11 @@ public class ColumnSelection */ public int getMax() { - int max = -1; - - for (int sel : getSelected()) + if (selected.isEmpty()) { - if (sel > max) - { - max = sel; - } + return -1; } - - return max; + return selected.getMaxColumn(); } /** @@ -285,17 +326,11 @@ public class ColumnSelection */ public int getMin() { - int min = 1000000000; - - for (int sel : getSelected()) + if (selected.isEmpty()) { - if (sel < min) - { - min = sel; - } + return 1000000000; } - - return min; + return selected.getMinColumn(); } /** @@ -565,7 +600,7 @@ public class ColumnSelection * 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) @@ -619,6 +654,10 @@ public class ColumnSelection /** * 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) { @@ -638,7 +677,7 @@ public class ColumnSelection gaps += region[1] + 1 - region[0]; result = region[1] + 1; index++; - } while (index < hiddenRegion + 1); + } while (index <= hiddenRegion); result -= gaps; } @@ -704,10 +743,13 @@ public class ColumnSelection 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(); } } @@ -767,7 +809,7 @@ public class ColumnSelection /* * remaining case is that the new range follows everything else */ - hiddenColumns.addElement(new int[] { start, end }); + hiddenColumns.addElement(new int[] { start, end }); } /** @@ -1038,6 +1080,84 @@ public class ColumnSelection } /** + * 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 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). * @@ -1408,6 +1528,8 @@ public class ColumnSelection 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; @@ -1489,4 +1611,5 @@ public class ColumnSelection } while (count < annotations.length); return false; } + }