X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FColumnSelection.java;h=6fd76b23ebf02a9366c38fecce0ee565d629edc1;hb=64b79e3758bd98db1664c47205f6570b2d689ba9;hp=c891485b9303f8d0d5e618a7a7832ebcc00100a9;hpb=efa007087e99f7c7552276154b733fd184c55f74;p=jalview.git diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index c891485..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; @@ -184,9 +185,30 @@ public class ColumnSelection { 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 @@ -255,11 +277,20 @@ 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) { @@ -569,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) @@ -623,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) { @@ -642,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; } @@ -708,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(); } } @@ -771,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 }); } /** @@ -1042,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). * @@ -1412,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; @@ -1494,8 +1612,4 @@ public class ColumnSelection return false; } - public boolean isSelected(int column) - { - return selected.isSelected(column); - } }