/*
* list of selected columns (ordered by selection order, not column order)
*/
- private List<Integer> order = new ArrayList<Integer>();
+ private List<Integer> order;
+
+ /*
+ * an unmodifiable view of the selected columns list
+ */
+ private List<Integer> _uorder;
/**
* bitfield for column selection - allows quick lookup
*/
- private BitSet selected = new BitSet();
+ private BitSet selected;
+
+ /**
+ * Constructor
+ */
+ IntList()
+ {
+ order = new ArrayList<Integer>();
+ _uorder = Collections.unmodifiableList(order);
+ selected = new BitSet();
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param other
+ */
+ IntList(IntList other)
+ {
+ this();
+ if (other != null)
+ {
+ int j = other.size();
+ for (int i = 0; i < j; i++)
+ {
+ add(other.elementAt(i));
+ }
+ }
+ }
/**
* adds a new column i to the selection - only if i is not already selected
*
* @param i
*/
- public void add(int i)
+ void add(int i)
{
if (!selected.get(i))
{
}
}
- public void clear()
+ void clear()
{
order.clear();
selected.clear();
}
- public void remove(int col)
+ void remove(int col)
{
Integer colInt = new Integer(col);
}
}
- public boolean contains(Integer colInt)
+ boolean contains(Integer colInt)
{
return selected.get(colInt);
}
- public boolean isEmpty()
+ boolean isEmpty()
{
return order.isEmpty();
}
- public List<Integer> getList()
+ /**
+ * Returns a read-only view of the selected columns list
+ *
+ * @return
+ */
+ List<Integer> getList()
{
- return order;
+ return _uorder;
}
- public int size()
+ int size()
{
return order.size();
}
* @param i
* @return
*/
- public int elementAt(int i)
+ int elementAt(int i)
{
return order.get(i);
}
* @param change
* - delta for shift
*/
- public void compensateForEdits(int start, int change)
+ void compensateForEdits(int start, int change)
{
BitSet mask = new BitSet();
for (int i = 0; i < order.size(); i++)
selected.or(mask);
}
- public boolean isSelected(int column)
+ boolean isSelected(int column)
{
return selected.get(column);
}
- public int getMaxColumn()
+ int getMaxColumn()
{
return selected.length() - 1;
}
- public int getMinColumn()
+ int getMinColumn()
{
return selected.get(0) ? 0 : selected.nextSetBit(0);
}
/**
* @return a series of selection intervals along the range
*/
- public List<int[]> getRanges()
+ List<int[]> getRanges()
{
List<int[]> rlist = new ArrayList<int[]>();
if (selected.isEmpty())
}
/**
- * Returns a list of selected columns. The list contains no duplicates but is
- * not necessarily ordered. It also may include columns hidden from the
- * current view
+ * Returns a read-only view of the (possibly empty) list of selected columns
+ * <p>
+ * The list contains no duplicates but is not necessarily ordered. It also may
+ * include columns hidden from the current view. To modify (for example sort)
+ * the list, you should first make a copy.
+ * <p>
+ * The list is not thread-safe: iterating over it could result in
+ * ConcurrentModificationException if it is modified by another thread.
*/
public List<Integer> getSelected()
{
{
if (copy != null)
{
- if (copy.selection != null)
- {
- selection = new IntList();
- for (int i = 0, j = copy.selection.size(); i < j; i++)
- {
- selection.add(copy.selection.elementAt(i));
- }
- }
+ selection = new IntList(copy.selection);
if (copy.hiddenColumns != null)
{
hiddenColumns = new Vector<int[]>(copy.hiddenColumns.size());
SequenceI[] seqs)
{
int i, iSize = seqs.length;
- String selection[] = new String[iSize];
+ String selections[] = new String[iSize];
if (hiddenColumns != null && hiddenColumns.size() > 0)
{
for (i = 0; i < iSize; i++)
visibleSeq.append(seqs[i].getSequence(blockStart, end));
}
- selection[i] = visibleSeq.toString();
+ selections[i] = visibleSeq.toString();
}
}
else
{
for (i = 0; i < iSize; i++)
{
- selection[i] = seqs[i].getSequenceAsString(start, end);
+ selections[i] = seqs[i].getSequenceAsString(start, end);
}
}
- return selection;
+ return selections;
}
/**
*/
public int[] locateVisibleBoundsOfSequence(SequenceI seq)
{
- int fpos=seq.getStart(),lpos= seq.getEnd();
+ 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 true;
}
+ /**
+ * Updates the column selection depending on the parameters, and returns true
+ * if any change was made to the selection
+ *
+ * @param markedColumns
+ * a set identifying marked columns (base 0)
+ * @param startCol
+ * the first column of the range to operate over (base 0)
+ * @param endCol
+ * the last column of the range to operate over (base 0)
+ * @param invert
+ * if true, deselect marked columns and select unmarked
+ * @param extendCurrent
+ * if true, extend rather than replacing the current column selection
+ * @param toggle
+ * if true, toggle the selection state of marked columns
+ *
+ * @return
+ */
+ public boolean markColumns(BitSet markedColumns, int startCol,
+ int endCol, boolean invert, boolean extendCurrent, boolean toggle)
+ {
+ boolean changed = false;
+ if (!extendCurrent && !toggle)
+ {
+ changed = !this.isEmpty();
+ clear();
+ }
+ if (invert)
+ {
+ // invert only in the currently selected sequence region
+ int i = markedColumns.nextClearBit(startCol);
+ int ibs = markedColumns.nextSetBit(startCol);
+ while (i >= startCol && i <= endCol)
+ {
+ if (ibs < 0 || i < ibs)
+ {
+ changed = true;
+ if (toggle && contains(i))
+ {
+ removeElement(i++);
+ }
+ else
+ {
+ addElement(i++);
+ }
+ }
+ else
+ {
+ i = markedColumns.nextClearBit(ibs);
+ ibs = markedColumns.nextSetBit(i);
+ }
+ }
+ }
+ else
+ {
+ int i = markedColumns.nextSetBit(startCol);
+ while (i >= startCol && i <= endCol)
+ {
+ changed = true;
+ if (toggle && contains(i))
+ {
+ removeElement(i);
+ }
+ else
+ {
+ addElement(i);
+ }
+ i = markedColumns.nextSetBit(i + 1);
+ }
+ }
+ return changed;
+ }
+
}