Fire alignment changed if seqs hidden / revealed
[jalview.git] / src / jalview / gui / AlignViewport.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 jalview.analysis.*;\r
22 \r
23 import jalview.bin.*;\r
24 \r
25 import jalview.datamodel.*;\r
26 \r
27 import jalview.schemes.*;\r
28 \r
29 import java.awt.*;\r
30 \r
31 import java.util.*;\r
32 \r
33 \r
34 /**\r
35  * DOCUMENT ME!\r
36  *\r
37  * @author $author$\r
38  * @version $Revision$\r
39  */\r
40 public class AlignViewport\r
41 {\r
42     int startRes;\r
43     int endRes;\r
44     int startSeq;\r
45     int endSeq;\r
46     boolean showJVSuffix = true;\r
47     boolean showText = true;\r
48     boolean showColourText = false;\r
49     boolean showBoxes = true;\r
50     boolean wrapAlignment = false;\r
51     boolean renderGaps = true;\r
52     boolean showSequenceFeatures = false;\r
53     boolean showAnnotation = true;\r
54     boolean showConservation = true;\r
55     boolean showQuality = true;\r
56     boolean showIdentity = true;\r
57     boolean colourAppliesToAllGroups = true;\r
58     ColourSchemeI globalColourScheme = null;\r
59     boolean conservationColourSelected = false;\r
60     boolean abovePIDThreshold = false;\r
61     SequenceGroup selectionGroup;\r
62     int charHeight;\r
63     int charWidth;\r
64     boolean validCharWidth;\r
65     int wrappedWidth;\r
66     Font font;\r
67     AlignmentI alignment;\r
68     ColumnSelection colSel = new ColumnSelection();\r
69     int threshold;\r
70     int increment;\r
71     NJTree currentTree = null;\r
72     boolean scaleAboveWrapped = false;\r
73     boolean scaleLeftWrapped = true;\r
74     boolean scaleRightWrapped = true;\r
75     boolean hasHiddenColumns = false;\r
76     boolean hasHiddenRows = false;\r
77     boolean showHiddenMarkers = true;\r
78 \r
79     boolean cursorMode = false;\r
80 \r
81     // The following vector holds the features which are\r
82     // currently visible, in the correct order or rendering\r
83     Hashtable featuresDisplayed = null;\r
84 \r
85 \r
86     /** DOCUMENT ME!! */\r
87     public Vector vconsensus;\r
88     AlignmentAnnotation consensus;\r
89     AlignmentAnnotation conservation;\r
90     AlignmentAnnotation quality;\r
91     boolean autoCalculateConsensus = true;\r
92 \r
93     /** DOCUMENT ME!! */\r
94     public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!\r
95 \r
96     // JBPNote Prolly only need this in the applet version.\r
97     private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);\r
98 \r
99     boolean ignoreGapsInConsensusCalculation = false;\r
100 \r
101     boolean isDataset = false;\r
102 \r
103     boolean antiAlias = false;\r
104 \r
105     boolean padGaps = false;\r
106 \r
107 \r
108     public AlignViewport(AlignmentI al, boolean dataset)\r
109     {\r
110       isDataset = dataset;\r
111       setAlignment(al);\r
112       init();\r
113     }\r
114     /**\r
115      * Creates a new AlignViewport object.\r
116      *\r
117      * @param al DOCUMENT ME!\r
118      */\r
119     public AlignViewport(AlignmentI al)\r
120     {\r
121         setAlignment(al);\r
122         init();\r
123     }\r
124     /**\r
125      * Create a new AlignViewport with hidden regions\r
126      * @param al AlignmentI\r
127      * @param hiddenColumns ColumnSelection\r
128      */\r
129     public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns) {\r
130       setAlignment(al);\r
131       if (hiddenColumns!=null) {\r
132         this.colSel = hiddenColumns;\r
133         if (hiddenColumns.getHiddenColumns() != null)\r
134           hasHiddenColumns = true;\r
135       }\r
136       init();\r
137     }\r
138 \r
139     void init()\r
140     {\r
141         this.startRes = 0;\r
142         this.endRes = alignment.getWidth() - 1;\r
143         this.startSeq = 0;\r
144         this.endSeq = alignment.getHeight() - 1;\r
145 \r
146       antiAlias = Cache.getDefault("ANTI_ALIAS", false);\r
147 \r
148       showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);\r
149       showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);\r
150       showConservation = Cache.getDefault("SHOW_CONSERVATION", true);\r
151 \r
152       showQuality = Cache.getDefault("SHOW_QUALITY", true);\r
153       showIdentity = Cache.getDefault("SHOW_IDENTITY", true);\r
154 \r
155       autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);\r
156 \r
157       padGaps = Cache.getDefault("PAD_GAPS", false);\r
158 \r
159        String fontName = Cache.getDefault("FONT_NAME", "SansSerif");\r
160        String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "") ;\r
161        String fontSize = Cache.getDefault("FONT_SIZE", "10");\r
162 \r
163        int style = 0;\r
164 \r
165        if (fontStyle.equals("bold"))\r
166        {\r
167          style = 1;\r
168        }\r
169        else if (fontStyle.equals("italic"))\r
170        {\r
171          style = 2;\r
172        }\r
173 \r
174        setFont(new Font(fontName, style, Integer.parseInt(fontSize)));\r
175 \r
176 \r
177        alignment.setGapCharacter( Cache.getDefault("GAP_SYMBOL", "-").charAt(0) );\r
178 \r
179 \r
180         // We must set conservation and consensus before setting colour,\r
181         // as Blosum and Clustal require this to be done\r
182         if(vconsensus==null && !isDataset)\r
183         {\r
184           updateConservation();\r
185           updateConsensus();\r
186         }\r
187 \r
188         if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)\r
189         {\r
190           globalColourScheme = ColourSchemeProperty.getColour(alignment,\r
191               jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));\r
192 \r
193             if (globalColourScheme instanceof UserColourScheme)\r
194             {\r
195                 globalColourScheme = UserDefinedColours.loadDefaultColours();\r
196                 ((UserColourScheme)globalColourScheme).setThreshold(0, getIgnoreGapsConsensus());\r
197             }\r
198 \r
199             if (globalColourScheme != null)\r
200             {\r
201                 globalColourScheme.setConsensus(vconsensus);\r
202             }\r
203         }\r
204     }\r
205 \r
206 \r
207 \r
208     /**\r
209      * DOCUMENT ME!\r
210      *\r
211      * @param b DOCUMENT ME!\r
212      */\r
213     public void setShowSequenceFeatures(boolean b)\r
214     {\r
215         showSequenceFeatures = b;\r
216     }\r
217 \r
218     public boolean getShowSequenceFeatures()\r
219     {\r
220       return showSequenceFeatures;\r
221     }\r
222 \r
223     /**\r
224      * DOCUMENT ME!\r
225      */\r
226     public void updateConservation()\r
227     {\r
228       if(alignment.isNucleotide())\r
229           return;\r
230 \r
231       try{\r
232         Conservation cons = new jalview.analysis.Conservation("All",\r
233             jalview.schemes.ResidueProperties.propHash, 3,\r
234             alignment.getSequences(), 0, alignment.getWidth() - 1);\r
235         cons.calculate();\r
236         cons.verdict(false, ConsPercGaps);\r
237         cons.findQuality();\r
238 \r
239         int alWidth = alignment.getWidth();\r
240         Annotation[] annotations = new Annotation[alWidth];\r
241         Annotation[] qannotations = new Annotation[alWidth];\r
242         String sequence = cons.getConsSequence().getSequence();\r
243         float minR;\r
244         float minG;\r
245         float minB;\r
246         float maxR;\r
247         float maxG;\r
248         float maxB;\r
249         minR = 0.3f;\r
250         minG = 0.0f;\r
251         minB = 0f;\r
252         maxR = 1.0f - minR;\r
253         maxG = 0.9f - minG;\r
254         maxB = 0f - minB; // scalable range for colouring both Conservation and Quality\r
255 \r
256         float min = 0f;\r
257         float max = 11f;\r
258         float qmin = cons.qualityRange[0].floatValue();\r
259         float qmax = cons.qualityRange[1].floatValue();\r
260 \r
261         for (int i = 0; i < alWidth; i++)\r
262         {\r
263           float value = 0;\r
264 \r
265           try\r
266           {\r
267             value = Integer.parseInt(sequence.charAt(i) + "");\r
268           }\r
269           catch (Exception ex)\r
270           {\r
271             if (sequence.charAt(i) == '*')\r
272             {\r
273               value = 11;\r
274             }\r
275 \r
276             if (sequence.charAt(i) == '+')\r
277             {\r
278               value = 10;\r
279             }\r
280           }\r
281 \r
282           float vprop = value - min;\r
283           vprop /= max;\r
284           annotations[i] = new Annotation(sequence.charAt(i) + "",\r
285                                           String.valueOf(value), ' ', value,\r
286                                           new Color(minR + (maxR * vprop),\r
287               minG + (maxG * vprop),\r
288               minB + (maxB * vprop)));\r
289 \r
290           // Quality calc\r
291           value = ( (Double) cons.quality.get(i)).floatValue();\r
292           vprop = value - qmin;\r
293           vprop /= qmax;\r
294           qannotations[i] = new Annotation(" ", String.valueOf(value), ' ',\r
295                                            value,\r
296                                            new Color(minR + (maxR * vprop),\r
297               minG + (maxG * vprop),\r
298               minB + (maxB * vprop)));\r
299         }\r
300 \r
301         if (conservation == null)\r
302         {\r
303           conservation = new AlignmentAnnotation("Conservation",\r
304                                                  "Conservation of total alignment less than " +\r
305                                                  ConsPercGaps + "% gaps",\r
306                                                  annotations, 0f, // cons.qualityRange[0].floatValue(),\r
307                                                  11f, // cons.qualityRange[1].floatValue()\r
308                                                  AlignmentAnnotation.BAR_GRAPH);\r
309 \r
310           if (showConservation)\r
311           {\r
312             alignment.addAnnotation(conservation);\r
313           }\r
314 \r
315           quality = new AlignmentAnnotation("Quality",\r
316                                             "Alignment Quality based on Blosum62 scores",\r
317                                             qannotations,\r
318                                             cons.qualityRange[0].floatValue(),\r
319                                             cons.qualityRange[1].floatValue(),\r
320                                             AlignmentAnnotation.BAR_GRAPH);\r
321 \r
322           if (showQuality)\r
323           {\r
324             alignment.addAnnotation(quality);\r
325           }\r
326         }\r
327         else\r
328         {\r
329           conservation.annotations = annotations;\r
330           quality.annotations = qannotations;\r
331           quality.graphMax = cons.qualityRange[1].floatValue();\r
332         }\r
333       }\r
334       catch (OutOfMemoryError error)\r
335       {\r
336         javax.swing.SwingUtilities.invokeLater(new Runnable()\r
337         {\r
338           public void run()\r
339           {\r
340             javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
341                 "Out of memory calculating conservation!!"\r
342                 +\r
343                 "\nSee help files for increasing Java Virtual Machine memory."\r
344                 , "Out of memory",\r
345                 javax.swing.JOptionPane.WARNING_MESSAGE);\r
346           }\r
347         });\r
348 \r
349         System.out.println("Conservation calculation: " + error);\r
350         System.gc();\r
351 \r
352       }\r
353     }\r
354 \r
355     /**\r
356      * DOCUMENT ME!\r
357      */\r
358     public void updateConsensus()\r
359     {\r
360       try{\r
361         Annotation[] annotations = new Annotation[alignment.getWidth()];\r
362 \r
363         // this routine prevents vconsensus becoming a new object each time\r
364         // consenus is calculated. Important for speed of Blosum62\r
365         // and PID colouring of alignment\r
366         if (vconsensus == null)\r
367         {\r
368           vconsensus = alignment.getAAFrequency();\r
369         }\r
370         else\r
371         {\r
372           Vector temp = alignment.getAAFrequency();\r
373           vconsensus.clear();\r
374 \r
375           Enumeration e = temp.elements();\r
376 \r
377           while (e.hasMoreElements())\r
378           {\r
379             vconsensus.add(e.nextElement());\r
380           }\r
381         }\r
382 \r
383         Hashtable hash = null;\r
384 \r
385         for (int i = 0; i < alignment.getWidth(); i++)\r
386         {\r
387           hash = (Hashtable) vconsensus.elementAt(i);\r
388 \r
389           float value = 0;\r
390           if (ignoreGapsInConsensusCalculation)\r
391             value = ( (Float) hash.get("pid_nogaps")).floatValue();\r
392           else\r
393             value = ( (Float) hash.get("pid_gaps")).floatValue();\r
394 \r
395           String maxRes = hash.get("maxResidue").toString();\r
396           String mouseOver = hash.get("maxResidue") + " ";\r
397 \r
398           if (maxRes.length() > 1)\r
399           {\r
400             mouseOver = "[" + maxRes + "] ";\r
401             maxRes = "+";\r
402           }\r
403 \r
404           mouseOver += ( (int) value + "%");\r
405           annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);\r
406         }\r
407 \r
408         if (consensus == null)\r
409         {\r
410           consensus = new AlignmentAnnotation("Consensus", "PID",\r
411                                               annotations, 0f, 100f,AlignmentAnnotation.BAR_GRAPH);\r
412 \r
413           if (showIdentity)\r
414           {\r
415             alignment.addAnnotation(consensus);\r
416           }\r
417         }\r
418         else\r
419         {\r
420           consensus.annotations = annotations;\r
421         }\r
422 \r
423         if (globalColourScheme != null)\r
424           globalColourScheme.setConsensus(vconsensus);\r
425 \r
426       }catch(OutOfMemoryError error)\r
427       {\r
428         javax.swing.SwingUtilities.invokeLater(new Runnable()\r
429         {\r
430           public void run()\r
431           {\r
432             javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
433                 "Out of memory calc45ulating consensus!!"\r
434                 +\r
435                 "\nSee help files for increasing Java Virtual Machine memory."\r
436                 , "Out of memory",\r
437                 javax.swing.JOptionPane.WARNING_MESSAGE);\r
438           }\r
439         });\r
440 \r
441 \r
442         System.out.println("Consensus calculation: " + error);\r
443         System.gc();\r
444       }\r
445 \r
446     }\r
447 \r
448     /**\r
449      * DOCUMENT ME!\r
450      *\r
451      * @return DOCUMENT ME!\r
452      */\r
453     public SequenceGroup getSelectionGroup()\r
454     {\r
455         return selectionGroup;\r
456     }\r
457 \r
458     /**\r
459      * DOCUMENT ME!\r
460      *\r
461      * @param sg DOCUMENT ME!\r
462      */\r
463     public void setSelectionGroup(SequenceGroup sg)\r
464     {\r
465         selectionGroup = sg;\r
466     }\r
467 \r
468     /**\r
469      * DOCUMENT ME!\r
470      *\r
471      * @return DOCUMENT ME!\r
472      */\r
473     public boolean getConservationSelected()\r
474     {\r
475         return conservationColourSelected;\r
476     }\r
477 \r
478     /**\r
479      * DOCUMENT ME!\r
480      *\r
481      * @param b DOCUMENT ME!\r
482      */\r
483     public void setConservationSelected(boolean b)\r
484     {\r
485         conservationColourSelected = b;\r
486     }\r
487 \r
488     /**\r
489      * DOCUMENT ME!\r
490      *\r
491      * @return DOCUMENT ME!\r
492      */\r
493     public boolean getAbovePIDThreshold()\r
494     {\r
495         return abovePIDThreshold;\r
496     }\r
497 \r
498     /**\r
499      * DOCUMENT ME!\r
500      *\r
501      * @param b DOCUMENT ME!\r
502      */\r
503     public void setAbovePIDThreshold(boolean b)\r
504     {\r
505         abovePIDThreshold = b;\r
506     }\r
507 \r
508     /**\r
509      * DOCUMENT ME!\r
510      *\r
511      * @return DOCUMENT ME!\r
512      */\r
513     public int getStartRes()\r
514     {\r
515         return startRes;\r
516     }\r
517 \r
518     /**\r
519      * DOCUMENT ME!\r
520      *\r
521      * @return DOCUMENT ME!\r
522      */\r
523     public int getEndRes()\r
524     {\r
525         return endRes;\r
526     }\r
527 \r
528     /**\r
529      * DOCUMENT ME!\r
530      *\r
531      * @return DOCUMENT ME!\r
532      */\r
533     public int getStartSeq()\r
534     {\r
535         return startSeq;\r
536     }\r
537 \r
538     /**\r
539      * DOCUMENT ME!\r
540      *\r
541      * @param cs DOCUMENT ME!\r
542      */\r
543     public void setGlobalColourScheme(ColourSchemeI cs)\r
544     {\r
545         globalColourScheme = cs;\r
546     }\r
547 \r
548     /**\r
549      * DOCUMENT ME!\r
550      *\r
551      * @return DOCUMENT ME!\r
552      */\r
553     public ColourSchemeI getGlobalColourScheme()\r
554     {\r
555         return globalColourScheme;\r
556     }\r
557 \r
558     /**\r
559      * DOCUMENT ME!\r
560      *\r
561      * @param res DOCUMENT ME!\r
562      */\r
563     public void setStartRes(int res)\r
564     {\r
565         this.startRes = res;\r
566     }\r
567 \r
568     /**\r
569      * DOCUMENT ME!\r
570      *\r
571      * @param seq DOCUMENT ME!\r
572      */\r
573     public void setStartSeq(int seq)\r
574     {\r
575         this.startSeq = seq;\r
576     }\r
577 \r
578     /**\r
579      * DOCUMENT ME!\r
580      *\r
581      * @param res DOCUMENT ME!\r
582      */\r
583     public void setEndRes(int res)\r
584     {\r
585         if (res > (alignment.getWidth() - 1))\r
586         {\r
587             // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));\r
588             res = alignment.getWidth() - 1;\r
589         }\r
590 \r
591         if (res < 0)\r
592         {\r
593             res = 0;\r
594         }\r
595 \r
596         this.endRes = res;\r
597     }\r
598 \r
599     /**\r
600      * DOCUMENT ME!\r
601      *\r
602      * @param seq DOCUMENT ME!\r
603      */\r
604     public void setEndSeq(int seq)\r
605     {\r
606         if (seq > alignment.getHeight())\r
607         {\r
608             seq = alignment.getHeight();\r
609         }\r
610 \r
611         if (seq < 0)\r
612         {\r
613             seq = 0;\r
614         }\r
615 \r
616         this.endSeq = seq;\r
617     }\r
618 \r
619     /**\r
620      * DOCUMENT ME!\r
621      *\r
622      * @return DOCUMENT ME!\r
623      */\r
624     public int getEndSeq()\r
625     {\r
626         return endSeq;\r
627     }\r
628 \r
629     /**\r
630      * DOCUMENT ME!\r
631      *\r
632      * @param f DOCUMENT ME!\r
633      */\r
634     public void setFont(Font f)\r
635     {\r
636         font = f;\r
637 \r
638         Container c = new Container();\r
639 \r
640         java.awt.FontMetrics fm = c.getFontMetrics(font);\r
641         setCharHeight(fm.getHeight());\r
642         setCharWidth(fm.charWidth('M'));\r
643         validCharWidth = true;\r
644     }\r
645 \r
646     /**\r
647      * DOCUMENT ME!\r
648      *\r
649      * @return DOCUMENT ME!\r
650      */\r
651     public Font getFont()\r
652     {\r
653         return font;\r
654     }\r
655 \r
656     /**\r
657      * DOCUMENT ME!\r
658      *\r
659      * @param w DOCUMENT ME!\r
660      */\r
661     public void setCharWidth(int w)\r
662     {\r
663         this.charWidth = w;\r
664     }\r
665 \r
666     /**\r
667      * DOCUMENT ME!\r
668      *\r
669      * @return DOCUMENT ME!\r
670      */\r
671     public int getCharWidth()\r
672     {\r
673         return charWidth;\r
674     }\r
675 \r
676     /**\r
677      * DOCUMENT ME!\r
678      *\r
679      * @param h DOCUMENT ME!\r
680      */\r
681     public void setCharHeight(int h)\r
682     {\r
683         this.charHeight = h;\r
684     }\r
685 \r
686     /**\r
687      * DOCUMENT ME!\r
688      *\r
689      * @return DOCUMENT ME!\r
690      */\r
691     public int getCharHeight()\r
692     {\r
693         return charHeight;\r
694     }\r
695 \r
696     /**\r
697      * DOCUMENT ME!\r
698      *\r
699      * @param w DOCUMENT ME!\r
700      */\r
701     public void setWrappedWidth(int w)\r
702     {\r
703         this.wrappedWidth = w;\r
704     }\r
705 \r
706     /**\r
707      * DOCUMENT ME!\r
708      *\r
709      * @return DOCUMENT ME!\r
710      */\r
711     public int getWrappedWidth()\r
712     {\r
713         return wrappedWidth;\r
714     }\r
715 \r
716 \r
717     /**\r
718      * DOCUMENT ME!\r
719      *\r
720      * @return DOCUMENT ME!\r
721      */\r
722     public AlignmentI getAlignment()\r
723     {\r
724         return alignment;\r
725     }\r
726 \r
727     /**\r
728      * DOCUMENT ME!\r
729      *\r
730      * @param align DOCUMENT ME!\r
731      */\r
732     public void setAlignment(AlignmentI align)\r
733     {\r
734         this.alignment = align;\r
735     }\r
736 \r
737     /**\r
738      * DOCUMENT ME!\r
739      *\r
740      * @param state DOCUMENT ME!\r
741      */\r
742     public void setWrapAlignment(boolean state)\r
743     {\r
744         wrapAlignment = state;\r
745     }\r
746 \r
747     /**\r
748      * DOCUMENT ME!\r
749      *\r
750      * @param state DOCUMENT ME!\r
751      */\r
752     public void setShowText(boolean state)\r
753     {\r
754         showText = state;\r
755     }\r
756 \r
757     /**\r
758      * DOCUMENT ME!\r
759      *\r
760      * @param state DOCUMENT ME!\r
761      */\r
762     public void setRenderGaps(boolean state)\r
763     {\r
764         renderGaps = state;\r
765     }\r
766 \r
767     /**\r
768      * DOCUMENT ME!\r
769      *\r
770      * @return DOCUMENT ME!\r
771      */\r
772     public boolean getColourText()\r
773     {\r
774         return showColourText;\r
775     }\r
776 \r
777     /**\r
778      * DOCUMENT ME!\r
779      *\r
780      * @param state DOCUMENT ME!\r
781      */\r
782     public void setColourText(boolean state)\r
783     {\r
784         showColourText = state;\r
785     }\r
786 \r
787     /**\r
788      * DOCUMENT ME!\r
789      *\r
790      * @param state DOCUMENT ME!\r
791      */\r
792     public void setShowBoxes(boolean state)\r
793     {\r
794         showBoxes = state;\r
795     }\r
796 \r
797     /**\r
798      * DOCUMENT ME!\r
799      *\r
800      * @return DOCUMENT ME!\r
801      */\r
802     public boolean getWrapAlignment()\r
803     {\r
804         return wrapAlignment;\r
805     }\r
806 \r
807     /**\r
808      * DOCUMENT ME!\r
809      *\r
810      * @return DOCUMENT ME!\r
811      */\r
812     public boolean getShowText()\r
813     {\r
814         return showText;\r
815     }\r
816 \r
817     /**\r
818      * DOCUMENT ME!\r
819      *\r
820      * @return DOCUMENT ME!\r
821      */\r
822     public boolean getShowBoxes()\r
823     {\r
824         return showBoxes;\r
825     }\r
826 \r
827     /**\r
828      * DOCUMENT ME!\r
829      *\r
830      * @return DOCUMENT ME!\r
831      */\r
832     public char getGapCharacter()\r
833     {\r
834         return getAlignment().getGapCharacter();\r
835     }\r
836 \r
837     /**\r
838      * DOCUMENT ME!\r
839      *\r
840      * @param gap DOCUMENT ME!\r
841      */\r
842     public void setGapCharacter(char gap)\r
843     {\r
844         if (getAlignment() != null)\r
845         {\r
846             getAlignment().setGapCharacter(gap);\r
847         }\r
848     }\r
849 \r
850     /**\r
851      * DOCUMENT ME!\r
852      *\r
853      * @param thresh DOCUMENT ME!\r
854      */\r
855     public void setThreshold(int thresh)\r
856     {\r
857         threshold = thresh;\r
858     }\r
859 \r
860     /**\r
861      * DOCUMENT ME!\r
862      *\r
863      * @return DOCUMENT ME!\r
864      */\r
865     public int getThreshold()\r
866     {\r
867         return threshold;\r
868     }\r
869 \r
870     /**\r
871      * DOCUMENT ME!\r
872      *\r
873      * @param inc DOCUMENT ME!\r
874      */\r
875     public void setIncrement(int inc)\r
876     {\r
877         increment = inc;\r
878     }\r
879 \r
880     /**\r
881      * DOCUMENT ME!\r
882      *\r
883      * @return DOCUMENT ME!\r
884      */\r
885     public int getIncrement()\r
886     {\r
887         return increment;\r
888     }\r
889 \r
890 \r
891     /**\r
892      * DOCUMENT ME!\r
893      *\r
894      * @return DOCUMENT ME!\r
895      */\r
896     public ColumnSelection getColumnSelection()\r
897     {\r
898         return colSel;\r
899     }\r
900 \r
901 \r
902     /**\r
903      * DOCUMENT ME!\r
904      *\r
905      * @param tree DOCUMENT ME!\r
906      */\r
907     public void setCurrentTree(NJTree tree)\r
908     {\r
909         currentTree = tree;\r
910     }\r
911 \r
912     /**\r
913      * DOCUMENT ME!\r
914      *\r
915      * @return DOCUMENT ME!\r
916      */\r
917     public NJTree getCurrentTree()\r
918     {\r
919         return currentTree;\r
920     }\r
921 \r
922     /**\r
923      * DOCUMENT ME!\r
924      *\r
925      * @param b DOCUMENT ME!\r
926      */\r
927     public void setColourAppliesToAllGroups(boolean b)\r
928     {\r
929         colourAppliesToAllGroups = b;\r
930     }\r
931 \r
932     /**\r
933      * DOCUMENT ME!\r
934      *\r
935      * @return DOCUMENT ME!\r
936      */\r
937     public boolean getColourAppliesToAllGroups()\r
938     {\r
939         return colourAppliesToAllGroups;\r
940     }\r
941 \r
942     /**\r
943      * DOCUMENT ME!\r
944      *\r
945      * @return DOCUMENT ME!\r
946      */\r
947     public boolean getShowJVSuffix()\r
948     {\r
949         return showJVSuffix;\r
950     }\r
951 \r
952     /**\r
953      * DOCUMENT ME!\r
954      *\r
955      * @param b DOCUMENT ME!\r
956      */\r
957     public void setShowJVSuffix(boolean b)\r
958     {\r
959         showJVSuffix = b;\r
960     }\r
961 \r
962 \r
963     /**\r
964      * DOCUMENT ME!\r
965      *\r
966      * @return DOCUMENT ME!\r
967      */\r
968     public boolean getShowAnnotation()\r
969     {\r
970         return showAnnotation;\r
971     }\r
972 \r
973     /**\r
974      * DOCUMENT ME!\r
975      *\r
976      * @param b DOCUMENT ME!\r
977      */\r
978     public void setShowAnnotation(boolean b)\r
979     {\r
980         showAnnotation = b;\r
981     }\r
982 \r
983     /**\r
984      * DOCUMENT ME!\r
985      *\r
986      * @return DOCUMENT ME!\r
987      */\r
988     public boolean getScaleAboveWrapped()\r
989     {\r
990         return scaleAboveWrapped;\r
991     }\r
992 \r
993     /**\r
994      * DOCUMENT ME!\r
995      *\r
996      * @return DOCUMENT ME!\r
997      */\r
998     public boolean getScaleLeftWrapped()\r
999     {\r
1000         return scaleLeftWrapped;\r
1001     }\r
1002 \r
1003     /**\r
1004      * DOCUMENT ME!\r
1005      *\r
1006      * @return DOCUMENT ME!\r
1007      */\r
1008     public boolean getScaleRightWrapped()\r
1009     {\r
1010         return scaleRightWrapped;\r
1011     }\r
1012 \r
1013     /**\r
1014      * DOCUMENT ME!\r
1015      *\r
1016      * @param b DOCUMENT ME!\r
1017      */\r
1018     public void setScaleAboveWrapped(boolean b)\r
1019     {\r
1020         scaleAboveWrapped = b;\r
1021     }\r
1022 \r
1023     /**\r
1024      * DOCUMENT ME!\r
1025      *\r
1026      * @param b DOCUMENT ME!\r
1027      */\r
1028     public void setScaleLeftWrapped(boolean b)\r
1029     {\r
1030         scaleLeftWrapped = b;\r
1031     }\r
1032 \r
1033     /**\r
1034      * DOCUMENT ME!\r
1035      *\r
1036      * @param b DOCUMENT ME!\r
1037      */\r
1038     public void setScaleRightWrapped(boolean b)\r
1039     {\r
1040         scaleRightWrapped = b;\r
1041     }\r
1042 \r
1043     /**\r
1044      * Property change listener for changes in alignment\r
1045      *\r
1046      * @param listener DOCUMENT ME!\r
1047      */\r
1048     public void addPropertyChangeListener(\r
1049         java.beans.PropertyChangeListener listener)\r
1050     {\r
1051         changeSupport.addPropertyChangeListener(listener);\r
1052     }\r
1053 \r
1054     /**\r
1055      * DOCUMENT ME!\r
1056      *\r
1057      * @param listener DOCUMENT ME!\r
1058      */\r
1059     public void removePropertyChangeListener(\r
1060         java.beans.PropertyChangeListener listener)\r
1061     {\r
1062         changeSupport.removePropertyChangeListener(listener);\r
1063     }\r
1064 \r
1065     /**\r
1066      * Property change listener for changes in alignment\r
1067      *\r
1068      * @param prop DOCUMENT ME!\r
1069      * @param oldvalue DOCUMENT ME!\r
1070      * @param newvalue DOCUMENT ME!\r
1071      */\r
1072     public void firePropertyChange(String prop, Object oldvalue, Object newvalue)\r
1073     {\r
1074         changeSupport.firePropertyChange(prop, oldvalue, newvalue);\r
1075     }\r
1076 \r
1077     public void setIgnoreGapsConsensus(boolean b)\r
1078     {\r
1079       ignoreGapsInConsensusCalculation = b;\r
1080       updateConsensus();\r
1081       if(globalColourScheme!=null)\r
1082       {\r
1083         globalColourScheme.setThreshold(globalColourScheme.getThreshold(), ignoreGapsInConsensusCalculation);\r
1084       }\r
1085     }\r
1086 \r
1087     public boolean getIgnoreGapsConsensus()\r
1088     {\r
1089      return ignoreGapsInConsensusCalculation;\r
1090     }\r
1091 \r
1092     public void setDataset(boolean b)\r
1093     {\r
1094       isDataset = b;\r
1095     }\r
1096 \r
1097     public boolean isDataset()\r
1098     {\r
1099       return isDataset;\r
1100     }\r
1101 \r
1102 \r
1103     public void hideSelectedColumns()\r
1104     {\r
1105       if (colSel.size() < 1)\r
1106         return;\r
1107 \r
1108       colSel.hideSelectedColumns();\r
1109       setSelectionGroup(null);\r
1110 \r
1111       hasHiddenColumns = true;\r
1112     }\r
1113 \r
1114 \r
1115     public void hideColumns(int start, int end)\r
1116     {\r
1117       if(start==end)\r
1118         colSel.hideColumns(start);\r
1119       else\r
1120         colSel.hideColumns(start, end);\r
1121       setSelectionGroup(null);\r
1122       hasHiddenColumns = true;\r
1123     }\r
1124 \r
1125     public void hideAllSelectedSeqs()\r
1126     {\r
1127       if (selectionGroup == null)\r
1128         return;\r
1129 \r
1130       SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);\r
1131 \r
1132       for (int i = 0; i < seqs.length; i++)\r
1133       {\r
1134         alignment.getHiddenSequences().hideSequence(seqs[i]);\r
1135       }\r
1136       firePropertyChange("alignment", null, alignment.getSequences());\r
1137       hasHiddenRows = true;\r
1138       setSelectionGroup(null);\r
1139     }\r
1140 \r
1141     public void hideSequence(SequenceI seq)\r
1142     {\r
1143       if(seq!=null)\r
1144       {\r
1145         alignment.getHiddenSequences().hideSequence(seq);\r
1146         hasHiddenRows = true;\r
1147         firePropertyChange("alignment", null, alignment.getSequences());\r
1148       }\r
1149     }\r
1150 \r
1151     public void showSequence(int index)\r
1152     {\r
1153       Vector tmp = alignment.getHiddenSequences().showSequence(index);\r
1154       if(tmp.size()>0)\r
1155       {\r
1156         if(selectionGroup==null)\r
1157         {\r
1158           selectionGroup = new SequenceGroup();\r
1159           selectionGroup.setEndRes(alignment.getWidth()-1);\r
1160         }\r
1161 \r
1162         for (int t = 0; t < tmp.size(); t++)\r
1163         {\r
1164           selectionGroup.addSequence(\r
1165               (SequenceI) tmp.elementAt(t), false\r
1166               );\r
1167         }\r
1168         firePropertyChange("alignment", null, alignment.getSequences());\r
1169       }\r
1170 \r
1171       if(alignment.getHiddenSequences().getSize()<1)\r
1172         hasHiddenRows = false;\r
1173     }\r
1174 \r
1175     public void showColumn(int col)\r
1176     {\r
1177       colSel.revealHiddenColumns(col);\r
1178       if(colSel.getHiddenColumns()==null)\r
1179         hasHiddenColumns = false;\r
1180     }\r
1181 \r
1182     public void showAllHiddenColumns()\r
1183     {\r
1184       colSel.revealAllHiddenColumns();\r
1185       hasHiddenColumns = false;\r
1186     }\r
1187 \r
1188     public void showAllHiddenSeqs()\r
1189     {\r
1190       if(alignment.getHiddenSequences().getSize()>0)\r
1191       {\r
1192         if(selectionGroup==null)\r
1193         {\r
1194           selectionGroup = new SequenceGroup();\r
1195           selectionGroup.setEndRes(alignment.getWidth()-1);\r
1196         }\r
1197         Vector tmp = alignment.getHiddenSequences().showAll();\r
1198         for(int t=0; t<tmp.size(); t++)\r
1199         {\r
1200           selectionGroup.addSequence(\r
1201               (SequenceI)tmp.elementAt(t), false\r
1202               );\r
1203         }\r
1204         firePropertyChange("alignment", null, alignment.getSequences());\r
1205         hasHiddenRows = false;\r
1206       }\r
1207     }\r
1208 \r
1209     public void invertColumnSelection()\r
1210     {\r
1211       int column;\r
1212       for(int i=0; i<alignment.getWidth(); i++)\r
1213       {\r
1214         column = i;\r
1215 \r
1216         if(colSel.contains(column))\r
1217           colSel.removeElement(column);\r
1218         else\r
1219           colSel.addElement(column);\r
1220 \r
1221       }\r
1222 \r
1223     }\r
1224 \r
1225     public int adjustForHiddenSeqs(int alignmentIndex)\r
1226     {\r
1227       return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);\r
1228     }\r
1229 \r
1230     /**\r
1231      * This method returns the a new SequenceI [] with\r
1232      * the selection sequence and start and end points adjusted\r
1233      * @return String[]\r
1234      */\r
1235     public SequenceI[] getSelectionAsNewSequence()\r
1236     {\r
1237       SequenceI[] sequences;\r
1238 \r
1239       if (selectionGroup == null)\r
1240         sequences = alignment.getSequencesArray();\r
1241       else\r
1242         sequences = selectionGroup.getSelectionAsNewSequences(alignment);\r
1243 \r
1244       return sequences;\r
1245     }\r
1246 \r
1247     /**\r
1248      * This method returns the visible alignment as text, as\r
1249      * seen on the GUI, ie if columns are hidden they will not\r
1250      * be returned in the result.\r
1251      * Use this for calculating trees, PCA, redundancy etc on views\r
1252      * which contain hidden columns.\r
1253      * @return String[]\r
1254      */\r
1255     public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)\r
1256     {\r
1257       CigarArray selection=null;\r
1258       SequenceI [] seqs= null;\r
1259       int i, iSize;\r
1260       int start = 0, end = 0;\r
1261       if(selectedRegionOnly && selectionGroup!=null)\r
1262       {\r
1263         iSize = selectionGroup.getSize(false);\r
1264         seqs = selectionGroup.getSequencesInOrder(alignment);\r
1265         start = selectionGroup.getStartRes();\r
1266         end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor\r
1267       }\r
1268       else\r
1269       {\r
1270         iSize = alignment.getHeight();\r
1271         seqs = alignment.getSequencesArray();\r
1272         end = alignment.getWidth()-1;\r
1273       }\r
1274       SeqCigar[] selseqs = new SeqCigar[iSize];\r
1275       for(i=0; i<iSize; i++)\r
1276       {\r
1277         selseqs[i] = new SeqCigar(seqs[i], start, end);\r
1278       }\r
1279       selection=new CigarArray(selseqs);\r
1280       // now construct the CigarArray operations\r
1281       if (hasHiddenColumns) {\r
1282         Vector regions = colSel.getHiddenColumns();\r
1283         int [] region;\r
1284         int hideStart, hideEnd;\r
1285         int last=start;\r
1286         for (int j = 0; last<end & j < regions.size(); j++)\r
1287         {\r
1288           region = (int[]) regions.elementAt(j);\r
1289           hideStart = region[0];\r
1290           hideEnd = region[1];\r
1291           // edit hidden regions to selection range\r
1292           if(hideStart<last) {\r
1293             if (hideEnd > last)\r
1294             {\r
1295               hideStart = last;\r
1296             } else\r
1297               continue;\r
1298           }\r
1299 \r
1300           if (hideStart>end)\r
1301             break;\r
1302 \r
1303           if (hideEnd>end)\r
1304             hideEnd=end;\r
1305 \r
1306           if (hideStart>hideEnd)\r
1307             break;\r
1308           /**\r
1309            * form operations...\r
1310            */\r
1311           if (last<hideStart)\r
1312             selection.addOperation(CigarArray.M, hideStart-last);\r
1313           selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);\r
1314           last = hideEnd+1;\r
1315         }\r
1316         // Final match if necessary.\r
1317         if (last<end)\r
1318           selection.addOperation(CigarArray.M, end-last);\r
1319       } else {\r
1320         selection.addOperation(CigarArray.M, end-start);\r
1321       }\r
1322       return selection;\r
1323     }\r
1324     /**\r
1325      * return a compact representation of the current alignment selection to\r
1326      * pass to an analysis function\r
1327      * @param selectedOnly boolean true to just return the selected view\r
1328      * @return AlignmentView\r
1329      */\r
1330     jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {\r
1331       // JBPNote:\r
1332       // this is here because the AlignmentView constructor modifies the CigarArray\r
1333       // object. Refactoring of Cigar and alignment view representation should\r
1334       // be done to remove redundancy.\r
1335       CigarArray aligview = getViewAsCigars(selectedOnly);\r
1336       if (aligview!=null)\r
1337         return new AlignmentView(aligview);\r
1338       return null;\r
1339     }\r
1340     /**\r
1341      * This method returns the visible alignment as text, as\r
1342      * seen on the GUI, ie if columns are hidden they will not\r
1343      * be returned in the result.\r
1344      * Use this for calculating trees, PCA, redundancy etc on views\r
1345      * which contain hidden columns.\r
1346      * @return String[]\r
1347      */\r
1348     public String [] getViewAsString(boolean selectedRegionOnly)\r
1349     {\r
1350       String [] selection = null;\r
1351       SequenceI [] seqs= null;\r
1352       int i, iSize;\r
1353       int start = 0, end = 0;\r
1354       if(selectedRegionOnly && selectionGroup!=null)\r
1355       {\r
1356         iSize = selectionGroup.getSize(false);\r
1357         seqs = selectionGroup.getSequencesInOrder(alignment);\r
1358         start = selectionGroup.getStartRes();\r
1359         end = selectionGroup.getEndRes()+1;\r
1360       }\r
1361       else\r
1362       {\r
1363         iSize = alignment.getHeight();\r
1364         seqs = alignment.getSequencesArray();\r
1365         end = alignment.getWidth();\r
1366       }\r
1367 \r
1368       selection = new String[iSize];\r
1369 \r
1370 \r
1371       for(i=0; i<iSize; i++)\r
1372       {\r
1373         if (hasHiddenColumns)\r
1374         {\r
1375              StringBuffer visibleSeq = new StringBuffer();\r
1376              Vector regions = colSel.getHiddenColumns();\r
1377 \r
1378              int blockStart = start, blockEnd=end;\r
1379              int [] region;\r
1380              int hideStart, hideEnd;\r
1381 \r
1382              for (int j = 0; j < regions.size(); j++)\r
1383              {\r
1384                region = (int[]) regions.elementAt(j);\r
1385                hideStart = region[0];\r
1386                hideEnd = region[1];\r
1387 \r
1388                if(hideStart < start)\r
1389                {\r
1390                  continue;\r
1391                }\r
1392 \r
1393                blockStart = Math.min(blockStart, hideEnd+1);\r
1394                blockEnd = Math.min(blockEnd, hideStart);\r
1395 \r
1396                if(blockStart>blockEnd)\r
1397                {\r
1398                   break;\r
1399                }\r
1400 \r
1401 \r
1402                visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));\r
1403 \r
1404                blockStart = hideEnd+1;\r
1405                blockEnd = end;\r
1406              }\r
1407 \r
1408              if(end>blockStart)\r
1409                visibleSeq.append(seqs[i].getSequence(blockStart, end));\r
1410 \r
1411              selection[i] = visibleSeq.toString();\r
1412         }\r
1413         else\r
1414         {\r
1415           selection[i] = seqs[i].getSequence(start, end);\r
1416         }\r
1417       }\r
1418 \r
1419       return selection;\r
1420     }\r
1421 \r
1422     public boolean getShowHiddenMarkers()\r
1423     {\r
1424       return showHiddenMarkers;\r
1425     }\r
1426 \r
1427     public void setShowHiddenMarkers(boolean show)\r
1428     {\r
1429       showHiddenMarkers = show;\r
1430     }\r
1431 }\r