Show hide cols and rows
[jalview.git] / src / jalview / gui / 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.gui;\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     /**\r
83      * DOCUMENT ME!\r
84      *\r
85      * @param col DOCUMENT ME!\r
86      *\r
87      * @return DOCUMENT ME!\r
88      */\r
89     public boolean contains(int col)\r
90     {\r
91         return selected.contains(new Integer(col));\r
92     }\r
93 \r
94     /**\r
95      * DOCUMENT ME!\r
96      *\r
97      * @param i DOCUMENT ME!\r
98      *\r
99      * @return DOCUMENT ME!\r
100      */\r
101     public int columnAt(int i)\r
102     {\r
103         return ((Integer) selected.elementAt(i)).intValue();\r
104     }\r
105 \r
106     /**\r
107      * DOCUMENT ME!\r
108      *\r
109      * @return DOCUMENT ME!\r
110      */\r
111     public int size()\r
112     {\r
113         return selected.size();\r
114     }\r
115 \r
116     /**\r
117      * DOCUMENT ME!\r
118      *\r
119      * @return DOCUMENT ME!\r
120      */\r
121     public int getMax()\r
122     {\r
123         int max = -1;\r
124 \r
125         for (int i = 0; i < selected.size(); i++)\r
126         {\r
127             if (columnAt(i) > max)\r
128             {\r
129                 max = columnAt(i);\r
130             }\r
131         }\r
132 \r
133         return max;\r
134     }\r
135 \r
136     /**\r
137      * DOCUMENT ME!\r
138      *\r
139      * @return DOCUMENT ME!\r
140      */\r
141     public int getMin()\r
142     {\r
143         int min = 1000000000;\r
144 \r
145         for (int i = 0; i < selected.size(); i++)\r
146         {\r
147             if (columnAt(i) < min)\r
148             {\r
149                 min = columnAt(i);\r
150             }\r
151         }\r
152 \r
153         return min;\r
154     }\r
155 \r
156 \r
157     /**\r
158      * DOCUMENT ME!\r
159      *\r
160      * @param start DOCUMENT ME!\r
161      * @param change DOCUMENT ME!\r
162      */\r
163     public void compensateForEdit(int start, int change)\r
164     {\r
165         for (int i = 0; i < size(); i++)\r
166         {\r
167             int temp = columnAt(i);\r
168 \r
169             if (temp >= start)\r
170             {\r
171                 selected.setElementAt(new Integer(temp - change), i);\r
172             }\r
173         }\r
174 \r
175         if(hiddenColumns!=null)\r
176         {\r
177           for(int i=0; i<hiddenColumns.size(); i++)\r
178           {\r
179             int[] region = (int[]) hiddenColumns.elementAt(i);\r
180             if(region[0] > start)\r
181             {\r
182               region[0] -= change;\r
183               region[1] -= change;\r
184             }\r
185             if(region[0]<0)\r
186               region[0] = 0;\r
187             if(region[1] <0)\r
188              region[1] = 0;\r
189           }\r
190         }\r
191     }\r
192 \r
193     /**\r
194      * This Method is used to return all the HiddenColumn regions\r
195      * less than the given index.\r
196      * @param end int\r
197      * @return Vector\r
198      */\r
199     public Vector getHiddenColumns()\r
200     {\r
201       return hiddenColumns;\r
202     }\r
203 \r
204     public int adjustForHiddenColumns(int column)\r
205     {\r
206       int result = column;\r
207       if (hiddenColumns != null)\r
208       {\r
209         for (int i = 0; i < hiddenColumns.size(); i++)\r
210         {\r
211           int[] region = (int[]) hiddenColumns.elementAt(i);\r
212           if (result >= region[0])\r
213           {\r
214             result += region[1] - region[0] + 1;\r
215           }\r
216         }\r
217       }\r
218       return result;\r
219     }\r
220 \r
221     /**\r
222      * Use this method to find out where a visible column is in the alignment\r
223      * when hidden columns exist\r
224      * @param hiddenColumn int\r
225      * @return int\r
226      */\r
227     public int findColumnPosition(int hiddenColumn)\r
228     {\r
229       int result = hiddenColumn;\r
230       if (hiddenColumns != null)\r
231       {\r
232         int index = 0;\r
233         int gaps = 0;\r
234         do\r
235         {\r
236           int[] region = (int[]) hiddenColumns.elementAt(index);\r
237           if (hiddenColumn > region[1])\r
238           {\r
239             result -= region[1]+1-region[0];\r
240           }\r
241           index++;\r
242         }\r
243         while (index < hiddenColumns.size());\r
244 \r
245         result -= gaps;\r
246       }\r
247 \r
248       return result;\r
249     }\r
250 \r
251     /**\r
252      * Use this method to determine where the next hiddenRegion starts\r
253     */\r
254     public int findHiddenRegionPosition(int hiddenRegion)\r
255     {\r
256       int result = 0;\r
257       if (hiddenColumns != null)\r
258       {\r
259         int index = 0;\r
260         int gaps = 0;\r
261         do\r
262         {\r
263           int[] region = (int[]) hiddenColumns.elementAt(index);\r
264           if(hiddenRegion==0)\r
265           {\r
266             return region[0];\r
267           }\r
268 \r
269             gaps +=  region[1] +1 - region[0];\r
270             result = region[1] +1;\r
271             index++;\r
272         }\r
273         while(index < hiddenRegion+1);\r
274 \r
275         result -= gaps;\r
276       }\r
277 \r
278       return result;\r
279     }\r
280 \r
281     /**\r
282      * THis method returns the rightmost limit of a\r
283      * region of an alignment with hidden columns.\r
284      * In otherwords, the next hidden column.\r
285      * @param index int\r
286      */\r
287     public int getHiddenBoundaryRight(int alPos)\r
288     {\r
289       if (hiddenColumns != null)\r
290       {\r
291         int index = 0;\r
292         do\r
293         {\r
294           int[] region = (int[]) hiddenColumns.elementAt(index);\r
295           if(alPos < region[0])\r
296             return region[0];\r
297 \r
298           index++;\r
299         }\r
300         while(index < hiddenColumns.size());\r
301       }\r
302 \r
303       return alPos;\r
304 \r
305     }\r
306     /**\r
307      * THis method returns the rightmost limit of a\r
308      * region of an alignment with hidden columns.\r
309      * In otherwords, the next hidden column.\r
310      * @param index int\r
311      */\r
312     public int getHiddenBoundaryLeft(int alPos)\r
313     {\r
314       if (hiddenColumns != null)\r
315       {\r
316         int index = hiddenColumns.size()-1;\r
317         do\r
318         {\r
319           int[] region = (int[]) hiddenColumns.elementAt(index);\r
320           if(alPos > region[1])\r
321             return region[1];\r
322 \r
323           index--;\r
324         }\r
325         while(index >-1);\r
326       }\r
327 \r
328       return alPos;\r
329 \r
330     }\r
331 \r
332 \r
333     public void hideColumns(int res, AlignViewport av)\r
334     {\r
335       if(hiddenColumns==null)\r
336         hiddenColumns = new Vector();\r
337 \r
338       // First find out range of columns to hide\r
339       int min = res, max = res+1;\r
340       while( contains(min) )\r
341       {  removeElement(min); min --;  }\r
342 \r
343       while( contains(max) )\r
344       { removeElement(max);  max ++;  }\r
345 \r
346       min++; max--;\r
347 \r
348       boolean added = false;\r
349       for(int i=0; i<hiddenColumns.size(); i++)\r
350       {\r
351         int [] region = (int[])hiddenColumns.elementAt(i);\r
352         if( max < region[0])\r
353         {\r
354           hiddenColumns.insertElementAt(new int[]{min, max}, i);\r
355           added = true;\r
356           break;\r
357         }\r
358       }\r
359 \r
360       if(!added)\r
361         hiddenColumns.addElement(new int[]{min, max});\r
362 \r
363 \r
364       av.setSelectionGroup(null);\r
365       av.hasHiddenColumns = true;\r
366     }\r
367 \r
368     public void revealAllHiddenColumns(AlignViewport av)\r
369     {\r
370       for(int i=0; i<hiddenColumns.size(); i++)\r
371       {\r
372         int [] region = (int[])hiddenColumns.elementAt(i);\r
373         for(int j=region[0]; j<region[1]; j++)\r
374         {\r
375           addElement(j);\r
376         }\r
377       }\r
378       av.hasHiddenColumns = false;\r
379       hiddenColumns = null;\r
380     }\r
381 \r
382     public void revealHiddenColumns(int res, AlignViewport av)\r
383     {\r
384       for(int i=0; i<hiddenColumns.size(); i++)\r
385       {\r
386         int [] region = (int[])hiddenColumns.elementAt(i);\r
387         if( res == region[0])\r
388         {\r
389           for (int j = region[0]; j < region[1]; j++)\r
390           {\r
391             addElement(j);\r
392           }\r
393 \r
394           hiddenColumns.remove(region);\r
395           break;\r
396         }\r
397       }\r
398 \r
399 \r
400       if(hiddenColumns.size()<1)\r
401         av.hasHiddenColumns = false;\r
402     }\r
403 \r
404     public boolean isVisible(int column)\r
405     {\r
406       for(int i=0; i<hiddenColumns.size(); i++)\r
407       {\r
408         int [] region = (int[])hiddenColumns.elementAt(i);\r
409         if( column >= region[0] && column <= region[1])\r
410         {\r
411           return false;\r
412         }\r
413       }\r
414       return true;\r
415     }\r
416 \r
417 }\r