upperCaseBold
[jalview.git] / src / jalview / appletgui / AlignViewport.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 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 \r
20 package jalview.appletgui;\r
21 \r
22 import java.util.*;\r
23 \r
24 import java.awt.*;\r
25 \r
26 import jalview.analysis.*;\r
27 import jalview.bin.*;\r
28 import jalview.datamodel.*;\r
29 import jalview.schemes.*;\r
30 \r
31 public class AlignViewport\r
32 {\r
33   int startRes;\r
34   int endRes;\r
35 \r
36   int startSeq;\r
37   int endSeq;\r
38 \r
39 \r
40   boolean cursorMode = false;\r
41 \r
42   boolean showJVSuffix = true;\r
43   boolean showText = true;\r
44   boolean showColourText = false;\r
45   boolean showBoxes = true;\r
46   boolean wrapAlignment = false;\r
47   boolean renderGaps = true;\r
48   boolean showSequenceFeatures = false;\r
49   boolean showAnnotation = true;\r
50   boolean showConservation = true;\r
51   boolean showQuality = true;\r
52   boolean showConsensus = true;\r
53   boolean upperCasebold = false;\r
54 \r
55   boolean colourAppliesToAllGroups = true;\r
56   ColourSchemeI globalColourScheme = null;\r
57   boolean conservationColourSelected = false;\r
58   boolean abovePIDThreshold = false;\r
59 \r
60   SequenceGroup selectionGroup;\r
61 \r
62   int charHeight;\r
63   int charWidth;\r
64   int wrappedWidth;\r
65 \r
66   Font font = new Font("SansSerif", Font.PLAIN, 10);\r
67   boolean validCharWidth = true;\r
68   AlignmentI alignment;\r
69 \r
70   ColumnSelection colSel = new ColumnSelection();\r
71 \r
72   int threshold;\r
73   int increment;\r
74 \r
75   NJTree currentTree = null;\r
76 \r
77   boolean scaleAboveWrapped = true;\r
78   boolean scaleLeftWrapped = true;\r
79   boolean scaleRightWrapped = true;\r
80 \r
81   // The following vector holds the features which are\r
82  // currently visible, in the correct order or rendering\r
83   public Hashtable featuresDisplayed;\r
84 \r
85   boolean hasHiddenColumns = false;\r
86   boolean hasHiddenRows = false;\r
87   boolean showHiddenMarkers = true;\r
88 \r
89 \r
90   public Vector vconsensus;\r
91   AlignmentAnnotation consensus;\r
92   AlignmentAnnotation conservation;\r
93   AlignmentAnnotation quality;\r
94 \r
95   boolean autocalculateConsensus = true;\r
96 \r
97   public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!\r
98 \r
99   private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);\r
100 \r
101   boolean ignoreGapsInConsensusCalculation = false;\r
102 \r
103   jalview.bin.JalviewLite applet;\r
104 \r
105   boolean MAC = false;\r
106 \r
107   public AlignViewport(AlignmentI al, JalviewLite applet)\r
108   {\r
109     this.applet = applet;\r
110     setAlignment(al);\r
111     this.startRes = 0;\r
112     this.endRes = al.getWidth() - 1;\r
113     this.startSeq = 0;\r
114     this.endSeq = al.getHeight() - 1;\r
115     setFont(font);\r
116 \r
117     if(System.getProperty("os.name").startsWith("Mac"))\r
118       MAC = true;\r
119 \r
120     if (applet != null)\r
121     {\r
122       String param = applet.getParameter("showFullId");\r
123       if (param != null)\r
124       {\r
125         showJVSuffix = Boolean.valueOf(param).booleanValue();\r
126       }\r
127 \r
128       param = applet.getParameter("showAnnotation");\r
129       if (param != null)\r
130       {\r
131         showAnnotation = Boolean.valueOf(param).booleanValue();\r
132       }\r
133 \r
134       param = applet.getParameter("showConservation");\r
135       if (param != null)\r
136       {\r
137         showConservation = Boolean.valueOf(param).booleanValue();\r
138       }\r
139 \r
140       param = applet.getParameter("showQuality");\r
141       if (param != null)\r
142       {\r
143         showQuality = Boolean.valueOf(param).booleanValue();\r
144       }\r
145 \r
146       param = applet.getParameter("showConsensus");\r
147       if (param != null)\r
148       {\r
149         showConsensus = Boolean.valueOf(param).booleanValue();\r
150       }\r
151 \r
152       param = applet.getParameter("upperCase");\r
153       if (param != null)\r
154       {\r
155         if(param.equalsIgnoreCase("bold"))\r
156           upperCasebold = true;\r
157       }\r
158 \r
159     }\r
160     // We must set conservation and consensus before setting colour,\r
161     // as Blosum and Clustal require this to be done\r
162     updateConservation();\r
163     updateConsensus();\r
164 \r
165 \r
166     if (applet != null)\r
167     {\r
168       String colour = applet.getParameter("defaultColour");\r
169 \r
170       if(colour == null)\r
171       {\r
172         colour = applet.getParameter("userDefinedColour");\r
173         if(colour !=null)\r
174           colour = "User Defined";\r
175       }\r
176 \r
177       if(colour != null)\r
178       {\r
179         globalColourScheme = ColourSchemeProperty.getColour(alignment, colour);\r
180         if (globalColourScheme != null)\r
181         {\r
182           globalColourScheme.setConsensus(vconsensus);\r
183         }\r
184       }\r
185 \r
186       if(applet.getParameter("userDefinedColour")!=null)\r
187       {\r
188         ((UserColourScheme)globalColourScheme).parseAppletParameter(\r
189             applet.getParameter("userDefinedColour"));\r
190       }\r
191 \r
192 \r
193     }\r
194   }\r
195 \r
196   public void showSequenceFeatures(boolean b)\r
197   {\r
198     showSequenceFeatures = b;\r
199   }\r
200 \r
201   public boolean getShowSequenceFeatures()\r
202   {\r
203     return showSequenceFeatures;\r
204   }\r
205 \r
206 \r
207   public void updateConservation()\r
208   {\r
209     if(alignment.isNucleotide())\r
210           return;\r
211 \r
212     Conservation cons = new jalview.analysis.Conservation("All",\r
213         jalview.schemes.ResidueProperties.propHash, 3,\r
214         alignment.getSequences(), 0,\r
215         alignment.getWidth() - 1);\r
216     cons.calculate();\r
217     cons.verdict(false, ConsPercGaps);\r
218     cons.findQuality();\r
219     int alWidth = alignment.getWidth();\r
220     Annotation[] annotations = new Annotation[alWidth];\r
221     Annotation[] qannotations = new Annotation[alWidth];\r
222     String sequence = cons.getConsSequence().getSequence();\r
223     float minR, minG, minB, maxR, maxG, maxB;\r
224     minR = 0.3f;\r
225     minG = 0.0f;\r
226     minB = 0f;\r
227     maxR = 1.0f - minR;\r
228     maxG = 0.9f - minG;\r
229     maxB = 0f - minB; // scalable range for colouring both Conservation and Quality\r
230     float min = 0f;\r
231     float max = 11f;\r
232     float qmin = cons.qualityRange[0].floatValue();\r
233     float qmax = cons.qualityRange[1].floatValue();\r
234 \r
235     for (int i = 0; i < alWidth; i++)\r
236     {\r
237       float value = 0;\r
238       try\r
239       {\r
240         value = Integer.parseInt(sequence.charAt(i) + "");\r
241       }\r
242       catch (Exception ex)\r
243       {\r
244         if (sequence.charAt(i) == '*')\r
245         {\r
246           value = 11;\r
247         }\r
248         if (sequence.charAt(i) == '+')\r
249         {\r
250           value = 10;\r
251         }\r
252       }\r
253       float vprop = value - min;\r
254       vprop /= max;\r
255 \r
256       annotations[i] = new Annotation(sequence.charAt(i) + "",\r
257                                       "", ' ', value,\r
258                                       new Color(minR + maxR * vprop,\r
259                                                 minG + maxG * vprop,\r
260                                                 minB + maxB * vprop));\r
261       // Quality calc\r
262       value = ( (Double) cons.quality.elementAt(i)).floatValue();\r
263       vprop = value - qmin;\r
264       vprop /= qmax;\r
265       qannotations[i] = new Annotation(" ",\r
266                                        String.valueOf(value), ' ', value,\r
267                                        new\r
268                                        Color(minR + maxR * vprop,\r
269                                              minG + maxG * vprop,\r
270                                              minB + maxB * vprop));\r
271     }\r
272 \r
273     if (conservation == null)\r
274     {\r
275       conservation = new AlignmentAnnotation("Conservation",\r
276                                              "Conservation of total alignment less than " +\r
277                                              ConsPercGaps + "% gaps",\r
278                                              annotations,\r
279                                              0f, // cons.qualityRange[0].floatValue(),\r
280                                              11f, // cons.qualityRange[1].floatValue()\r
281                                              AlignmentAnnotation.BAR_GRAPH);\r
282       if (showConservation)\r
283       {\r
284         alignment.addAnnotation(conservation);\r
285       }\r
286       quality = new AlignmentAnnotation("Quality",\r
287                                         "Alignment Quality based on Blosum62 scores",\r
288                                         qannotations,\r
289                                         cons.qualityRange[0].floatValue(),\r
290                                         cons.qualityRange[1].floatValue(),\r
291                                         AlignmentAnnotation.BAR_GRAPH);\r
292       if (showQuality)\r
293       {\r
294         alignment.addAnnotation(quality);\r
295       }\r
296     }\r
297     else\r
298     {\r
299       conservation.annotations = annotations;\r
300       quality.annotations = qannotations;\r
301       quality.graphMax = cons.qualityRange[1].floatValue();\r
302     }\r
303 \r
304   }\r
305 \r
306   public void updateConsensus()\r
307   {\r
308     Annotation[] annotations = new Annotation[alignment.getWidth()];\r
309 \r
310     // this routine prevents vconsensus becoming a new object each time\r
311     // consenus is calculated. Important for speed of Blosum62\r
312     // and PID colouring of alignment\r
313     if (vconsensus == null)\r
314     {\r
315       vconsensus = alignment.getAAFrequency();\r
316     }\r
317     else\r
318     {\r
319       Vector temp = alignment.getAAFrequency();\r
320       vconsensus.removeAllElements();\r
321       Enumeration e = temp.elements();\r
322       while (e.hasMoreElements())\r
323       {\r
324         vconsensus.addElement(e.nextElement());\r
325       }\r
326     }\r
327     Hashtable hash = null;\r
328     for (int i = 0; i < alignment.getWidth(); i++)\r
329     {\r
330       hash = (Hashtable) vconsensus.elementAt(i);\r
331       float value = 0;\r
332       if(ignoreGapsInConsensusCalculation)\r
333         value = ((Float)hash.get("pid_nogaps")).floatValue();\r
334       else\r
335         value = ((Float)hash.get("pid_gaps")).floatValue();\r
336 \r
337       String maxRes = hash.get("maxResidue").toString();\r
338       String mouseOver = hash.get("maxResidue") + " ";\r
339       if (maxRes.length() > 1)\r
340       {\r
341         mouseOver = "[" + maxRes + "] ";\r
342         maxRes = "+";\r
343       }\r
344 \r
345 \r
346       mouseOver += (int) value + "%";\r
347       annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);\r
348 \r
349     }\r
350 \r
351     if (consensus == null)\r
352     {\r
353       consensus = new AlignmentAnnotation("Consensus",\r
354                                           "PID", annotations, 0f, 100f, AlignmentAnnotation.BAR_GRAPH);\r
355       if (showConsensus)\r
356       {\r
357         alignment.addAnnotation(consensus);\r
358       }\r
359     }\r
360     else\r
361     {\r
362       consensus.annotations = annotations;\r
363     }\r
364 \r
365     if(globalColourScheme!=null)\r
366           globalColourScheme.setConsensus(vconsensus);\r
367 \r
368   }\r
369   /**\r
370    * get the consensus sequence as displayed under the PID consensus annotation row.\r
371    * @return consensus sequence as a new sequence object\r
372    */\r
373   /**\r
374    * get the consensus sequence as displayed under the PID consensus annotation row.\r
375    * @return consensus sequence as a new sequence object\r
376    */\r
377   public SequenceI getConsensusSeq() {\r
378     if (consensus==null)\r
379       updateConsensus();\r
380     if (consensus==null)\r
381       return null;\r
382     StringBuffer seqs=new StringBuffer();\r
383     for (int i=0; i<consensus.annotations.length; i++) {\r
384       if (consensus.annotations[i]!=null) {\r
385         if (consensus.annotations[i].description.charAt(0) == '[')\r
386           seqs.append(consensus.annotations[i].description.charAt(1));\r
387         else\r
388           seqs.append(consensus.annotations[i].displayCharacter);\r
389       }\r
390     }\r
391     SequenceI sq = new Sequence("Consensus", seqs.toString());\r
392     sq.setDescription("Percentage Identity Consensus "+((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));\r
393     return sq;\r
394   }\r
395   public SequenceGroup getSelectionGroup()\r
396   {\r
397     return selectionGroup;\r
398   }\r
399 \r
400   public void setSelectionGroup(SequenceGroup sg)\r
401   {\r
402     selectionGroup = sg;\r
403   }\r
404 \r
405   public boolean getConservationSelected()\r
406   {\r
407     return conservationColourSelected;\r
408   }\r
409 \r
410   public void setConservationSelected(boolean b)\r
411   {\r
412     conservationColourSelected = b;\r
413   }\r
414 \r
415   public boolean getAbovePIDThreshold()\r
416   {\r
417     return abovePIDThreshold;\r
418   }\r
419 \r
420   public void setAbovePIDThreshold(boolean b)\r
421   {\r
422     abovePIDThreshold = b;\r
423   }\r
424 \r
425   public int getStartRes()\r
426   {\r
427     return startRes;\r
428   }\r
429 \r
430   public int getEndRes()\r
431   {\r
432     return endRes;\r
433   }\r
434 \r
435   public int getStartSeq()\r
436   {\r
437     return startSeq;\r
438   }\r
439 \r
440   public void setGlobalColourScheme(ColourSchemeI cs)\r
441   {\r
442     globalColourScheme = cs;\r
443   }\r
444 \r
445   public ColourSchemeI getGlobalColourScheme()\r
446   {\r
447     return globalColourScheme;\r
448   }\r
449 \r
450   public void setStartRes(int res)\r
451   {\r
452     this.startRes = res;\r
453   }\r
454 \r
455   public void setStartSeq(int seq)\r
456   {\r
457     this.startSeq = seq;\r
458   }\r
459 \r
460   public void setEndRes(int res)\r
461   {\r
462     if (res > alignment.getWidth() - 1)\r
463     {\r
464       // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));\r
465       res = alignment.getWidth() - 1;\r
466     }\r
467     if (res < 0)\r
468     {\r
469       res = 0;\r
470     }\r
471     this.endRes = res;\r
472   }\r
473 \r
474   public void setEndSeq(int seq)\r
475   {\r
476     if (seq > alignment.getHeight())\r
477     {\r
478       seq = alignment.getHeight();\r
479     }\r
480     if (seq < 0)\r
481     {\r
482       seq = 0;\r
483     }\r
484     this.endSeq = seq;\r
485   }\r
486 \r
487   public int getEndSeq()\r
488   {\r
489     return endSeq;\r
490   }\r
491 \r
492   java.awt.Frame nullFrame;\r
493   public void setFont(Font f)\r
494   {\r
495     font = f;\r
496     if(nullFrame == null)\r
497     {\r
498       nullFrame = new java.awt.Frame();\r
499       nullFrame.addNotify();\r
500     }\r
501 \r
502     java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);\r
503     setCharHeight(fm.getHeight());\r
504     charWidth = fm.charWidth('M');\r
505 \r
506     if(upperCasebold)\r
507     {\r
508       Font f2 = new Font(f.getName(), Font.BOLD, f.getSize());\r
509       fm = nullFrame.getGraphics().getFontMetrics(f2);\r
510       charWidth = fm.stringWidth("MMMMMMMMMMM") / 10;\r
511     }\r
512   }\r
513 \r
514   public Font getFont()\r
515   {\r
516     return font;\r
517   }\r
518 \r
519   public int getCharWidth()\r
520   {\r
521     return charWidth;\r
522   }\r
523 \r
524   public void setCharHeight(int h)\r
525   {\r
526     this.charHeight = h;\r
527   }\r
528 \r
529   public int getCharHeight()\r
530   {\r
531     return charHeight;\r
532   }\r
533 \r
534   public void setWrappedWidth(int w)\r
535   {\r
536     this.wrappedWidth = w;\r
537   }\r
538 \r
539   public int getwrappedWidth()\r
540   {\r
541     return wrappedWidth;\r
542   }\r
543 \r
544   public AlignmentI getAlignment()\r
545   {\r
546     return alignment;\r
547   }\r
548 \r
549   public void setAlignment(AlignmentI align)\r
550   {\r
551     this.alignment = align;\r
552   }\r
553 \r
554   public void setWrapAlignment(boolean state)\r
555   {\r
556     wrapAlignment = state;\r
557   }\r
558 \r
559   public void setShowText(boolean state)\r
560   {\r
561     showText = state;\r
562   }\r
563 \r
564   public void setRenderGaps(boolean state)\r
565   {\r
566     renderGaps = state;\r
567   }\r
568 \r
569   public boolean getColourText()\r
570   {\r
571     return showColourText;\r
572   }\r
573 \r
574   public void setColourText(boolean state)\r
575   {\r
576     showColourText = state;\r
577   }\r
578 \r
579   public void setShowBoxes(boolean state)\r
580   {\r
581     showBoxes = state;\r
582   }\r
583 \r
584   public boolean getWrapAlignment()\r
585   {\r
586     return wrapAlignment;\r
587   }\r
588 \r
589   public boolean getShowText()\r
590   {\r
591     return showText;\r
592   }\r
593 \r
594   public boolean getShowBoxes()\r
595   {\r
596     return showBoxes;\r
597   }\r
598 \r
599   public char getGapCharacter()\r
600   {\r
601     return getAlignment().getGapCharacter();\r
602   }\r
603 \r
604   public void setGapCharacter(char gap)\r
605   {\r
606     if (getAlignment() != null)\r
607     {\r
608       getAlignment().setGapCharacter(gap);\r
609     }\r
610   }\r
611 \r
612   public void setThreshold(int thresh)\r
613   {\r
614     threshold = thresh;\r
615   }\r
616 \r
617   public int getThreshold()\r
618   {\r
619     return threshold;\r
620   }\r
621 \r
622   public void setIncrement(int inc)\r
623   {\r
624     increment = inc;\r
625   }\r
626 \r
627   public int getIncrement()\r
628   {\r
629     return increment;\r
630   }\r
631 \r
632   public void setHiddenColumns(ColumnSelection colsel)\r
633   {\r
634     this.colSel = colsel;\r
635     if(colSel.getHiddenColumns()!=null)\r
636       hasHiddenColumns = true;\r
637   }\r
638 \r
639   public ColumnSelection getColumnSelection()\r
640   {\r
641     return colSel;\r
642   }\r
643 \r
644   public void resetSeqLimits(int height)\r
645   {\r
646     setEndSeq(height / getCharHeight());\r
647   }\r
648 \r
649   public void setCurrentTree(NJTree tree)\r
650   {\r
651     currentTree = tree;\r
652   }\r
653 \r
654   public NJTree getCurrentTree()\r
655   {\r
656     return currentTree;\r
657   }\r
658 \r
659   public void setColourAppliesToAllGroups(boolean b)\r
660   {\r
661     colourAppliesToAllGroups = b;\r
662   }\r
663 \r
664   public boolean getColourAppliesToAllGroups()\r
665   {\r
666     return colourAppliesToAllGroups;\r
667   }\r
668 \r
669   public boolean getShowJVSuffix()\r
670   {\r
671     return showJVSuffix;\r
672   }\r
673 \r
674   public void setShowJVSuffix(boolean b)\r
675   {\r
676     showJVSuffix = b;\r
677   }\r
678 \r
679   public boolean getShowAnnotation()\r
680   {\r
681     return showAnnotation;\r
682   }\r
683 \r
684   public void setShowAnnotation(boolean b)\r
685   {\r
686     showAnnotation = b;\r
687   }\r
688 \r
689   public boolean getScaleAboveWrapped()\r
690   {\r
691     return scaleAboveWrapped;\r
692   }\r
693 \r
694   public boolean getScaleLeftWrapped()\r
695   {\r
696     return scaleLeftWrapped;\r
697   }\r
698 \r
699   public boolean getScaleRightWrapped()\r
700   {\r
701     return scaleRightWrapped;\r
702   }\r
703 \r
704   public void setScaleAboveWrapped(boolean b)\r
705   {\r
706     scaleAboveWrapped = b;\r
707   }\r
708 \r
709   public void setScaleLeftWrapped(boolean b)\r
710   {\r
711     scaleLeftWrapped = b;\r
712   }\r
713 \r
714   public void setScaleRightWrapped(boolean b)\r
715   {\r
716     scaleRightWrapped = b;\r
717   }\r
718 \r
719   public void setIgnoreGapsConsensus(boolean b)\r
720   {\r
721     ignoreGapsInConsensusCalculation = b;\r
722     updateConsensus();\r
723     if (globalColourScheme!=null)\r
724     {\r
725       globalColourScheme.setThreshold(globalColourScheme.getThreshold(),\r
726           ignoreGapsInConsensusCalculation);\r
727 \r
728     }\r
729   }\r
730 \r
731   /**\r
732    * Property change listener for changes in alignment\r
733    *\r
734    * @param listener DOCUMENT ME!\r
735    */\r
736   public void addPropertyChangeListener(\r
737       java.beans.PropertyChangeListener listener)\r
738   {\r
739       changeSupport.addPropertyChangeListener(listener);\r
740   }\r
741 \r
742   /**\r
743    * DOCUMENT ME!\r
744    *\r
745    * @param listener DOCUMENT ME!\r
746    */\r
747   public void removePropertyChangeListener(\r
748       java.beans.PropertyChangeListener listener)\r
749   {\r
750       changeSupport.removePropertyChangeListener(listener);\r
751   }\r
752 \r
753   /**\r
754    * Property change listener for changes in alignment\r
755    *\r
756    * @param prop DOCUMENT ME!\r
757    * @param oldvalue DOCUMENT ME!\r
758    * @param newvalue DOCUMENT ME!\r
759    */\r
760   public void firePropertyChange(String prop, Object oldvalue, Object newvalue)\r
761   {\r
762       changeSupport.firePropertyChange(prop, oldvalue, newvalue);\r
763   }\r
764 \r
765 \r
766 \r
767   public boolean getIgnoreGapsConsensus()\r
768   {\r
769     return ignoreGapsInConsensusCalculation;\r
770   }\r
771   public void hideSelectedColumns()\r
772   {\r
773     if (colSel.size() < 1)\r
774       return;\r
775 \r
776     colSel.hideSelectedColumns();\r
777     setSelectionGroup(null);\r
778 \r
779     hasHiddenColumns = true;\r
780   }\r
781 \r
782   public void invertColumnSelection()\r
783   {\r
784     int column;\r
785     for (int i = 0; i < alignment.getWidth(); i++)\r
786     {\r
787       column = i;\r
788 \r
789       if (colSel.contains(column))\r
790         colSel.removeElement(column);\r
791       else\r
792         colSel.addElement(column);\r
793 \r
794     }\r
795   }\r
796 \r
797 \r
798   public void hideColumns(int start, int end)\r
799   {\r
800     if(start==end)\r
801       colSel.hideColumns(start);\r
802     else\r
803       colSel.hideColumns(start, end);\r
804 \r
805     hasHiddenColumns = true;\r
806   }\r
807 \r
808   public void hideAllSelectedSeqs()\r
809   {\r
810     if (selectionGroup == null)\r
811       return;\r
812 \r
813     SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);\r
814 \r
815     hideSequence(seqs);\r
816 \r
817     setSelectionGroup(null);\r
818   }\r
819 \r
820   public void hideSequence(SequenceI [] seq)\r
821   {\r
822     if(seq!=null)\r
823     {\r
824       for (int i = 0; i < seq.length; i++)\r
825         alignment.getHiddenSequences().hideSequence(seq[i]);\r
826 \r
827       hasHiddenRows = true;\r
828       firePropertyChange("alignment", null, alignment.getSequences());\r
829     }\r
830   }\r
831 \r
832   public void showColumn(int col)\r
833   {\r
834     colSel.revealHiddenColumns(col);\r
835     if(colSel.getHiddenColumns()==null)\r
836       hasHiddenColumns = false;\r
837   }\r
838 \r
839   public void showAllHiddenColumns()\r
840   {\r
841     colSel.revealAllHiddenColumns();\r
842     hasHiddenColumns = false;\r
843   }\r
844 \r
845   public void showAllHiddenSeqs()\r
846   {\r
847     if(alignment.getHiddenSequences().getSize()>0)\r
848     {\r
849       if(selectionGroup==null)\r
850       {\r
851         selectionGroup = new SequenceGroup();\r
852         selectionGroup.setEndRes(alignment.getWidth()-1);\r
853       }\r
854       Vector tmp = alignment.getHiddenSequences().showAll();\r
855       for(int t=0; t<tmp.size(); t++)\r
856       {\r
857         selectionGroup.addSequence(\r
858             (SequenceI)tmp.elementAt(t), false\r
859             );\r
860       }\r
861       firePropertyChange("alignment", null, alignment.getSequences());\r
862       hasHiddenRows = false;\r
863     }\r
864   }\r
865 \r
866   public int adjustForHiddenSeqs(int alignmentIndex)\r
867   {\r
868     return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);\r
869   }\r
870 \r
871   /**\r
872    * This method returns the a new SequenceI [] with\r
873    * the selection sequence and start and end points adjusted\r
874    * @return String[]\r
875    */\r
876   public SequenceI[] getSelectionAsNewSequence()\r
877   {\r
878     SequenceI[] sequences;\r
879 \r
880     if (selectionGroup == null)\r
881       sequences = alignment.getSequencesArray();\r
882     else\r
883       sequences = selectionGroup.getSelectionAsNewSequences(alignment);\r
884 \r
885     return sequences;\r
886   }\r
887 \r
888   /**\r
889    * This method returns the visible alignment as text, as\r
890    * seen on the GUI, ie if columns are hidden they will not\r
891    * be returned in the result.\r
892    * Use this for calculating trees, PCA, redundancy etc on views\r
893    * which contain hidden columns.\r
894    * @return String[]\r
895    */\r
896   public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)\r
897   {\r
898     CigarArray selection=null;\r
899     SequenceI [] seqs= null;\r
900     int i, iSize;\r
901     int start = 0, end = 0;\r
902     if(selectedRegionOnly && selectionGroup!=null)\r
903     {\r
904       iSize = selectionGroup.getSize(false);\r
905       seqs = selectionGroup.getSequencesInOrder(alignment);\r
906       start = selectionGroup.getStartRes();\r
907       end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor\r
908     }\r
909     else\r
910     {\r
911       iSize = alignment.getHeight();\r
912       seqs = alignment.getSequencesArray();\r
913       end = alignment.getWidth()-1;\r
914     }\r
915     SeqCigar[] selseqs = new SeqCigar[iSize];\r
916     for(i=0; i<iSize; i++)\r
917     {\r
918       selseqs[i] = new SeqCigar(seqs[i], start, end);\r
919     }\r
920     selection=new CigarArray(selseqs);\r
921     // now construct the CigarArray operations\r
922     if (hasHiddenColumns) {\r
923       Vector regions = colSel.getHiddenColumns();\r
924       int [] region;\r
925       int hideStart, hideEnd;\r
926       int last=start;\r
927       for (int j = 0; last<end & j < regions.size(); j++)\r
928       {\r
929         region = (int[]) regions.elementAt(j);\r
930         hideStart = region[0];\r
931         hideEnd = region[1];\r
932         // edit hidden regions to selection range\r
933         if(hideStart<last) {\r
934           if (hideEnd > last)\r
935           {\r
936             hideStart = last;\r
937           } else\r
938             continue;\r
939         }\r
940 \r
941         if (hideStart>end)\r
942           break;\r
943 \r
944         if (hideEnd>end)\r
945           hideEnd=end;\r
946 \r
947         if (hideStart>hideEnd)\r
948           break;\r
949         /**\r
950          * form operations...\r
951          */\r
952         if (last<hideStart)\r
953           selection.addOperation(CigarArray.M, hideStart-last);\r
954         selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);\r
955         last = hideEnd+1;\r
956       }\r
957       // Final match if necessary.\r
958       if (last<end)\r
959         selection.addOperation(CigarArray.M, end-last+1);\r
960     } else {\r
961       selection.addOperation(CigarArray.M, end-start+1);\r
962     }\r
963     return selection;\r
964   }\r
965   /**\r
966    * return a compact representation of the current alignment selection to\r
967    * pass to an analysis function\r
968    * @param selectedOnly boolean true to just return the selected view\r
969    * @return AlignmentView\r
970    */\r
971   jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {\r
972     // JBPNote:\r
973     // this is here because the AlignmentView constructor modifies the CigarArray\r
974     // object. Refactoring of Cigar and alignment view representation should\r
975     // be done to remove redundancy.\r
976     CigarArray aligview = getViewAsCigars(selectedOnly);\r
977     if (aligview!=null)\r
978       return new AlignmentView(aligview);\r
979     return null;\r
980   }\r
981   /**\r
982    * This method returns the visible alignment as text, as\r
983    * seen on the GUI, ie if columns are hidden they will not\r
984    * be returned in the result.\r
985    * Use this for calculating trees, PCA, redundancy etc on views\r
986    * which contain hidden columns.\r
987    * @return String[]\r
988    */\r
989   public String [] getViewAsString(boolean selectedRegionOnly)\r
990   {\r
991     String [] selection = null;\r
992     SequenceI [] seqs= null;\r
993     int i, iSize;\r
994     int start = 0, end = 0;\r
995     if(selectedRegionOnly && selectionGroup!=null)\r
996     {\r
997       iSize = selectionGroup.getSize(false);\r
998       seqs = selectionGroup.getSequencesInOrder(alignment);\r
999       start = selectionGroup.getStartRes();\r
1000       end = selectionGroup.getEndRes()+1;\r
1001     }\r
1002     else\r
1003     {\r
1004       iSize = alignment.getHeight();\r
1005       seqs = alignment.getSequencesArray();\r
1006       end = alignment.getWidth();\r
1007     }\r
1008 \r
1009     selection = new String[iSize];\r
1010 \r
1011 \r
1012     for(i=0; i<iSize; i++)\r
1013     {\r
1014       if (hasHiddenColumns)\r
1015       {\r
1016            StringBuffer visibleSeq = new StringBuffer();\r
1017            Vector regions = colSel.getHiddenColumns();\r
1018 \r
1019            int blockStart = start, blockEnd=end;\r
1020            int [] region;\r
1021            int hideStart, hideEnd;\r
1022 \r
1023            for (int j = 0; j < regions.size(); j++)\r
1024            {\r
1025              region = (int[]) regions.elementAt(j);\r
1026              hideStart = region[0];\r
1027              hideEnd = region[1];\r
1028 \r
1029              if(hideStart < start)\r
1030              {\r
1031                continue;\r
1032              }\r
1033 \r
1034              blockStart = Math.min(blockStart, hideEnd+1);\r
1035              blockEnd = Math.min(blockEnd, hideStart);\r
1036 \r
1037              if(blockStart>blockEnd)\r
1038              {\r
1039                 break;\r
1040              }\r
1041 \r
1042 \r
1043              visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));\r
1044 \r
1045              blockStart = hideEnd+1;\r
1046              blockEnd = end;\r
1047            }\r
1048 \r
1049            if(end>blockStart)\r
1050              visibleSeq.append(seqs[i].getSequence(blockStart, end));\r
1051 \r
1052            selection[i] = visibleSeq.toString();\r
1053       }\r
1054       else\r
1055       {\r
1056         selection[i] = seqs[i].getSequence(start, end);\r
1057       }\r
1058     }\r
1059 \r
1060     return selection;\r
1061   }\r
1062 \r
1063   public boolean getShowHiddenMarkers()\r
1064   {\r
1065     return showHiddenMarkers;\r
1066   }\r
1067 \r
1068   public void setShowHiddenMarkers(boolean show)\r
1069   {\r
1070     showHiddenMarkers = show;\r
1071   }\r
1072 \r
1073 \r
1074 }\r