X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FColumnSelection.java;h=b87cd2b06a95f10bd02cd94b22a0d4095d5cd5c7;hb=865a855a4ca87eadb3e5ff284ed32ed307d9c34b;hp=546ba1a7dbe4443e0e40da5929f4d07585b6dea5;hpb=153dd62dc91da13ae732600e6ea55ddbe15eab39;p=jalview.git diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 546ba1a..b87cd2b 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -1,1114 +1,1259 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6) - * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle - * - * This file is part of Jalview. - * - * Jalview is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * Jalview is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Jalview. If not, see . - */ -package jalview.datamodel; - -import java.util.*; - -import jalview.util.*; - -/** - * NOTE: Columns are zero based. - */ -public class ColumnSelection -{ - Vector selected = new Vector(); - - // Vector of int [] {startCol, endCol} - Vector hiddenColumns; - - /** - * Add a column to the selection - * - * @param col - * index of column - */ - public void addElement(int col) - { - Integer column = new Integer(col); - if (!selected.contains(column)) - { - selected.addElement(column); - } - } - - /** - * clears column selection - */ - public void clear() - { - selected.removeAllElements(); - } - - /** - * removes col from selection - * - * @param col - * index of column to be removed - */ - public void removeElement(int col) - { - Integer colInt = new Integer(col); - - if (selected.contains(colInt)) - { - selected.removeElement(colInt); - } - } - - /** - * removes a range of columns from the selection - * - * @param start - * int - first column in range to be removed - * @param end - * int - last col - */ - public void removeElements(int start, int end) - { - Integer colInt; - for (int i = start; i < end; i++) - { - colInt = new Integer(i); - if (selected.contains(colInt)) - { - selected.removeElement(colInt); - } - } - } - - /** - * - * @return Vector containing selected columns as Integers - */ - public Vector getSelected() - { - return selected; - } - - /** - * - * @param col - * index to search for in column selection - * - * @return true if Integer(col) is in selection. - */ - public boolean contains(int col) - { - return selected.contains(new Integer(col)); - } - - /** - * Column number at position i in selection - * - * @param i - * index into selected columns - * - * @return column number in alignment - */ - public int columnAt(int i) - { - return ((Integer) selected.elementAt(i)).intValue(); - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public int size() - { - return selected.size(); - } - - /** - * rightmost selected column - * - * @return rightmost column in alignment that is selected - */ - public int getMax() - { - int max = -1; - - for (int i = 0; i < selected.size(); i++) - { - if (columnAt(i) > max) - { - max = columnAt(i); - } - } - - return max; - } - - /** - * Leftmost column in selection - * - * @return column index of leftmost column in selection - */ - public int getMin() - { - int min = 1000000000; - - for (int i = 0; i < selected.size(); i++) - { - if (columnAt(i) < min) - { - min = columnAt(i); - } - } - - return min; - } - - /** - * propagate shift in alignment columns to column selection - * - * @param start - * beginning of edit - * @param left - * shift in edit (+ve for removal, or -ve for inserts) - */ - public Vector compensateForEdit(int start, int change) - { - Vector deletedHiddenColumns = null; - for (int i = 0; i < size(); i++) - { - int temp = columnAt(i); - - if (temp >= start) - { - selected.setElementAt(new Integer(temp - change), i); - } - } - - if (hiddenColumns != null) - { - deletedHiddenColumns = new Vector(); - int hSize = hiddenColumns.size(); - for (int i = 0; i < hSize; i++) - { - int[] region = (int[]) hiddenColumns.elementAt(i); - if (region[0] > start && start + change > region[1]) - { - deletedHiddenColumns.addElement(hiddenColumns.elementAt(i)); - - hiddenColumns.removeElementAt(i); - i--; - hSize--; - continue; - } - - if (region[0] > start) - { - region[0] -= change; - region[1] -= change; - } - - if (region[0] < 0) - { - region[0] = 0; - } - - } - - this.revealHiddenColumns(0); - } - - return deletedHiddenColumns; - } - - /** - * propagate shift in alignment columns to column selection special version of - * compensateForEdit - allowing for edits within hidden regions - * - * @param start - * beginning of edit - * @param left - * shift in edit (+ve for removal, or -ve for inserts) - */ - private void compensateForDelEdits(int start, int change) - { - for (int i = 0; i < size(); i++) - { - int temp = columnAt(i); - - if (temp >= start) - { - selected.setElementAt(new Integer(temp - change), i); - } - } - - if (hiddenColumns != null) - { - for (int i = 0; i < hiddenColumns.size(); i++) - { - int[] region = (int[]) hiddenColumns.elementAt(i); - if (region[0] >= start) - { - region[0] -= change; - } - if (region[1] >= start) - { - region[1] -= change; - } - if (region[1] < region[0]) - { - hiddenColumns.removeElementAt(i--); - } - - if (region[0] < 0) - { - region[0] = 0; - } - if (region[1] < 0) - { - region[1] = 0; - } - } - } - } - - /** - * Adjust hidden column boundaries based on a series of column additions or - * deletions in visible regions. - * - * @param shiftrecord - * @return - */ - public ShiftList compensateForEdits(ShiftList shiftrecord) - { - if (shiftrecord != null) - { - Vector shifts = shiftrecord.shifts; - if (shifts != null && shifts.size() > 0) - { - int shifted = 0; - for (int i = 0, j = shifts.size(); i < j; i++) - { - int[] sh = (int[]) shifts.elementAt(i); - // compensateForEdit(shifted+sh[0], sh[1]); - compensateForDelEdits(shifted + sh[0], sh[1]); - shifted -= sh[1]; - } - } - return shiftrecord.getInverse(); - } - return null; - } - - /** - * removes intersection of position,length ranges in deletions from the - * start,end regions marked in intervals. - * - * @param deletions - * @param intervals - * @return - */ - private boolean pruneIntervalVector(Vector deletions, Vector intervals) - { - boolean pruned = false; - int i = 0, j = intervals.size() - 1, s = 0, t = deletions.size() - 1; - int hr[] = (int[]) intervals.elementAt(i); - int sr[] = (int[]) deletions.elementAt(s); - while (i <= j && s <= t) - { - boolean trailinghn = hr[1] >= sr[0]; - if (!trailinghn) - { - if (i < j) - { - hr = (int[]) intervals.elementAt(++i); - } - else - { - i++; - } - continue; - } - int endshift = sr[0] + sr[1]; // deletion ranges - -ve means an insert - if (endshift < hr[0] || endshift < sr[0]) - { // leadinghc disjoint or not a deletion - if (s < t) - { - sr = (int[]) deletions.elementAt(++s); - } - else - { - s++; - } - continue; - } - boolean leadinghn = hr[0] >= sr[0]; - boolean leadinghc = hr[0] < endshift; - boolean trailinghc = hr[1] < endshift; - if (leadinghn) - { - if (trailinghc) - { // deleted hidden region. - intervals.removeElementAt(i); - pruned = true; - j--; - if (i <= j) - { - hr = (int[]) intervals.elementAt(i); - } - continue; - } - if (leadinghc) - { - hr[0] = endshift; // clip c terminal region - leadinghn = !leadinghn; - pruned = true; - } - } - if (!leadinghn) - { - if (trailinghc) - { - if (trailinghn) - { - hr[1] = sr[0] - 1; - pruned = true; - } - } - else - { - // sr contained in hr - if (s < t) - { - sr = (int[]) deletions.elementAt(++s); - } - else - { - s++; - } - continue; - } - } - } - return pruned; // true if any interval was removed or modified by - // operations. - } - - private boolean pruneColumnList(Vector deletion, Vector list) - { - int s = 0, t = deletion.size(); - int[] sr = (int[]) list.elementAt(s++); - boolean pruned = false; - int i = 0, j = list.size(); - while (i < j && s <= t) - { - int c = ((Integer) list.elementAt(i++)).intValue(); - if (sr[0] <= c) - { - if (sr[1] + sr[0] >= c) - { // sr[1] -ve means inseriton. - list.removeElementAt(--i); - j--; - } - else - { - if (s < t) - { - sr = (int[]) deletion.elementAt(s); - } - s++; - } - } - } - return pruned; - } - - /** - * remove any hiddenColumns or selected columns and shift remaining based on a - * series of position, range deletions. - * - * @param deletions - */ - public void pruneDeletions(ShiftList deletions) - { - if (deletions != null) - { - Vector shifts = deletions.shifts; - if (shifts != null && shifts.size() > 0) - { - // delete any intervals intersecting. - if (hiddenColumns != null) - { - pruneIntervalVector(shifts, hiddenColumns); - if (hiddenColumns != null && hiddenColumns.size() == 0) - { - hiddenColumns = null; - } - } - if (selected != null && selected.size() > 0) - { - pruneColumnList(shifts, selected); - if (selected != null && selected.size() == 0) - { - selected = null; - } - } - // and shift the rest. - this.compensateForEdits(deletions); - } - } - } - - /** - * This Method is used to return all the HiddenColumn regions less than the - * given index. - * - * @param end - * int - * @return Vector - */ - public Vector getHiddenColumns() - { - return hiddenColumns; - } - - /** - * Return absolute column index for a visible column index - * - * @param column - * int column index in alignment view - * @return alignment column index for column - */ - public int adjustForHiddenColumns(int column) - { - int result = column; - if (hiddenColumns != null) - { - for (int i = 0; i < hiddenColumns.size(); i++) - { - int[] region = (int[]) hiddenColumns.elementAt(i); - if (result >= region[0]) - { - result += region[1] - region[0] + 1; - } - } - } - return result; - } - - /** - * Use this method to find out where a column will appear in the visible alignment when - * hidden columns exist. If the column is not visible, then the left-most visible column will always be returned. - * - * @param hiddenColumn - * int - * @return int - */ - public int findColumnPosition(int hiddenColumn) - { - int result = hiddenColumn; - if (hiddenColumns != null) - { - int index = 0; - int[] region; - do - { - region = (int[]) hiddenColumns.elementAt(index++); - if (hiddenColumn > region[1]) - { - result -= region[1] + 1 - region[0]; - } - } while ((hiddenColumn > region[1]) && (index < hiddenColumns.size())); - if (hiddenColumn>region[0] && hiddenColumn