1dafcf0ccc8d881a7025baeb8e82ecad5c58a254
[jalview.git] / src / jalview / datamodel / ColumnSelection.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.datamodel;\r
20 \r
21 import java.util.*;\r
22 \r
23 /**\r
24  * NOTE: Columns are zero based.\r
25  */\r
26 public class ColumnSelection\r
27 {\r
28     Vector selected = new Vector();\r
29 \r
30     //Vector of int [] {startCol, endCol}\r
31     Vector hiddenColumns;\r
32 \r
33     /**\r
34      * DOCUMENT ME!\r
35      *\r
36      * @param col DOCUMENT ME!\r
37      */\r
38     public void addElement(int col)\r
39     {\r
40         if (!selected.contains(new Integer(col)))\r
41         {\r
42             selected.addElement(new Integer(col));\r
43         }\r
44     }\r
45 \r
46     /**\r
47      * DOCUMENT ME!\r
48      */\r
49     public void clear()\r
50     {\r
51         selected.removeAllElements();\r
52     }\r
53 \r
54     /**\r
55      * DOCUMENT ME!\r
56      *\r
57      * @param col DOCUMENT ME!\r
58      */\r
59     public void removeElement(int col)\r
60     {\r
61         Integer colInt = new Integer(col);\r
62 \r
63         if (selected.contains(colInt))\r
64         {\r
65             selected.removeElement(colInt);\r
66         }\r
67     }\r
68 \r
69     public void removeElements(int start, int end)\r
70     {\r
71       Integer colInt;\r
72       for(int i=start; i<end; i++)\r
73       {\r
74         colInt = new Integer(i);\r
75         if (selected.contains(colInt))\r
76         {\r
77             selected.removeElement(colInt);\r
78         }\r
79       }\r
80     }\r
81 \r
82     public Vector getSelected()\r
83     {\r
84       return selected;\r
85     }\r
86 \r
87     /**\r
88      * DOCUMENT ME!\r
89      *\r
90      * @param col DOCUMENT ME!\r
91      *\r
92      * @return DOCUMENT ME!\r
93      */\r
94     public boolean contains(int col)\r
95     {\r
96         return selected.contains(new Integer(col));\r
97     }\r
98 \r
99     /**\r
100      * DOCUMENT ME!\r
101      *\r
102      * @param i DOCUMENT ME!\r
103      *\r
104      * @return DOCUMENT ME!\r
105      */\r
106     public int columnAt(int i)\r
107     {\r
108         return ((Integer) selected.elementAt(i)).intValue();\r
109     }\r
110 \r
111     /**\r
112      * DOCUMENT ME!\r
113      *\r
114      * @return DOCUMENT ME!\r
115      */\r
116     public int size()\r
117     {\r
118         return selected.size();\r
119     }\r
120 \r
121     /**\r
122      * DOCUMENT ME!\r
123      *\r
124      * @return DOCUMENT ME!\r
125      */\r
126     public int getMax()\r
127     {\r
128         int max = -1;\r
129 \r
130         for (int i = 0; i < selected.size(); i++)\r
131         {\r
132             if (columnAt(i) > max)\r
133             {\r
134                 max = columnAt(i);\r
135             }\r
136         }\r
137 \r
138         return max;\r
139     }\r
140 \r
141     /**\r
142      * DOCUMENT ME!\r
143      *\r
144      * @return DOCUMENT ME!\r
145      */\r
146     public int getMin()\r
147     {\r
148         int min = 1000000000;\r
149 \r
150         for (int i = 0; i < selected.size(); i++)\r
151         {\r
152             if (columnAt(i) < min)\r
153             {\r
154                 min = columnAt(i);\r
155             }\r
156         }\r
157 \r
158         return min;\r
159     }\r
160 \r
161 \r
162     /**\r
163      * DOCUMENT ME!\r
164      *\r
165      * @param start DOCUMENT ME!\r
166      * @param change DOCUMENT ME!\r
167      */\r
168     public void compensateForEdit(int start, int change)\r
169     {\r
170         for (int i = 0; i < size(); i++)\r
171         {\r
172             int temp = columnAt(i);\r
173 \r
174             if (temp >= start)\r
175             {\r
176                 selected.setElementAt(new Integer(temp - change), i);\r
177             }\r
178         }\r
179 \r
180         if(hiddenColumns!=null)\r
181         {\r
182           for(int i=0; i<hiddenColumns.size(); i++)\r
183           {\r
184             int[] region = (int[]) hiddenColumns.elementAt(i);\r
185             if(region[0] > start)\r
186             {\r
187               region[0] -= change;\r
188               region[1] -= change;\r
189             }\r
190             if(region[0]<0)\r
191               region[0] = 0;\r
192             if(region[1] <0)\r
193              region[1] = 0;\r
194           }\r
195         }\r
196     }\r
197 \r
198     /**\r
199      * This Method is used to return all the HiddenColumn regions\r
200      * less than the given index.\r
201      * @param end int\r
202      * @return Vector\r
203      */\r
204     public Vector getHiddenColumns()\r
205     {\r
206       return hiddenColumns;\r
207     }\r
208 \r
209     public int adjustForHiddenColumns(int column)\r
210     {\r
211       int result = column;\r
212       if (hiddenColumns != null)\r
213       {\r
214         for (int i = 0; i < hiddenColumns.size(); i++)\r
215         {\r
216           int[] region = (int[]) hiddenColumns.elementAt(i);\r
217           if (result >= region[0])\r
218           {\r
219             result += region[1] - region[0] + 1;\r
220           }\r
221         }\r
222       }\r
223       return result;\r
224     }\r
225 \r
226     /**\r
227      * Use this method to find out where a visible column is in the alignment\r
228      * when hidden columns exist\r
229      * @param hiddenColumn int\r
230      * @return int\r
231      */\r
232     public int findColumnPosition(int hiddenColumn)\r
233     {\r
234       int result = hiddenColumn;\r
235       if (hiddenColumns != null)\r
236       {\r
237         int index = 0;\r
238         int gaps = 0;\r
239         do\r
240         {\r
241           int[] region = (int[]) hiddenColumns.elementAt(index);\r
242           if (hiddenColumn > region[1])\r
243           {\r
244             result -= region[1]+1-region[0];\r
245           }\r
246           index++;\r
247         }\r
248         while (index < hiddenColumns.size());\r
249 \r
250         result -= gaps;\r
251       }\r
252 \r
253       return result;\r
254     }\r
255 \r
256     /**\r
257      * Use this method to determine where the next hiddenRegion starts\r
258     */\r
259     public int findHiddenRegionPosition(int hiddenRegion)\r
260     {\r
261       int result = 0;\r
262       if (hiddenColumns != null)\r
263       {\r
264         int index = 0;\r
265         int gaps = 0;\r
266         do\r
267         {\r
268           int[] region = (int[]) hiddenColumns.elementAt(index);\r
269           if(hiddenRegion==0)\r
270           {\r
271             return region[0];\r
272           }\r
273 \r
274             gaps +=  region[1] +1 - region[0];\r
275             result = region[1] +1;\r
276             index++;\r
277         }\r
278         while(index < hiddenRegion+1);\r
279 \r
280         result -= gaps;\r
281       }\r
282 \r
283       return result;\r
284     }\r
285 \r
286     /**\r
287      * THis method returns the rightmost limit of a\r
288      * region of an alignment with hidden columns.\r
289      * In otherwords, the next hidden column.\r
290      * @param index int\r
291      */\r
292     public int getHiddenBoundaryRight(int alPos)\r
293     {\r
294       if (hiddenColumns != null)\r
295       {\r
296         int index = 0;\r
297         do\r
298         {\r
299           int[] region = (int[]) hiddenColumns.elementAt(index);\r
300           if(alPos < region[0])\r
301             return region[0];\r
302 \r
303           index++;\r
304         }\r
305         while(index < hiddenColumns.size());\r
306       }\r
307 \r
308       return alPos;\r
309 \r
310     }\r
311     /**\r
312      * THis method returns the rightmost limit of a\r
313      * region of an alignment with hidden columns.\r
314      * In otherwords, the next hidden column.\r
315      * @param index int\r
316      */\r
317     public int getHiddenBoundaryLeft(int alPos)\r
318     {\r
319       if (hiddenColumns != null)\r
320       {\r
321         int index = hiddenColumns.size()-1;\r
322         do\r
323         {\r
324           int[] region = (int[]) hiddenColumns.elementAt(index);\r
325           if(alPos > region[1])\r
326             return region[1];\r
327 \r
328           index--;\r
329         }\r
330         while(index >-1);\r
331       }\r
332 \r
333       return alPos;\r
334 \r
335     }\r
336 \r
337 \r
338 \r
339     public void hideColumns(int res)\r
340     {\r
341       if(hiddenColumns==null)\r
342         hiddenColumns = new Vector();\r
343 \r
344       // First find out range of columns to hide\r
345       int min = res, max = res+1;\r
346       while( contains(min) )\r
347       {  removeElement(min); min --;  }\r
348 \r
349       while( contains(max) )\r
350       { removeElement(max);  max ++;  }\r
351 \r
352       min++; max--;\r
353 \r
354       boolean added = false;\r
355       for(int i=0; i<hiddenColumns.size(); i++)\r
356       {\r
357         int [] region = (int[])hiddenColumns.elementAt(i);\r
358         if( max < region[0])\r
359         {\r
360           hiddenColumns.insertElementAt(new int[]{min, max}, i);\r
361           added = true;\r
362           break;\r
363         }\r
364       }\r
365 \r
366       if(!added)\r
367         hiddenColumns.addElement(new int[]{min, max});\r
368 \r
369     }\r
370 \r
371     public void revealAllHiddenColumns()\r
372     {\r
373       if(hiddenColumns!=null)\r
374       {\r
375         for (int i = 0; i < hiddenColumns.size(); i++)\r
376         {\r
377           int[] region = (int[]) hiddenColumns.elementAt(i);\r
378           for (int j = region[0]; j < region[1]; j++)\r
379           {\r
380             addElement(j);\r
381           }\r
382         }\r
383       }\r
384 \r
385       hiddenColumns = null;\r
386     }\r
387 \r
388     public void revealHiddenColumns(int res)\r
389     {\r
390       for(int i=0; i<hiddenColumns.size(); i++)\r
391       {\r
392         int [] region = (int[])hiddenColumns.elementAt(i);\r
393         if( res == region[0])\r
394         {\r
395           for (int j = region[0]; j < region[1]; j++)\r
396           {\r
397             addElement(j);\r
398           }\r
399 \r
400           hiddenColumns.removeElement(region);\r
401           break;\r
402         }\r
403       }\r
404     }\r
405 \r
406     public boolean isVisible(int column)\r
407     {\r
408       for(int i=0; i<hiddenColumns.size(); i++)\r
409       {\r
410         int [] region = (int[])hiddenColumns.elementAt(i);\r
411         if( column >= region[0] && column <= region[1])\r
412         {\r
413           return false;\r
414         }\r
415       }\r
416       return true;\r
417     }\r
418 \r
419 }\r