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