Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.viewmodel

File AlignmentViewport.java

 

Coverage histogram

../../img/srcFileCovDistChart8.png
20% of files have more coverage

Code metrics

300
676
227
1
3,081
2,069
423
0.63
2.98
227
1.86

Classes

Class Line # Actions
AlignmentViewport 83 676 423
0.7497921675%
 

Contributing tests

This file is covered by 210 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.viewmodel;
22   
23    import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
24    import jalview.analysis.Conservation;
25    import jalview.analysis.TreeModel;
26    import jalview.api.AlignCalcManagerI;
27    import jalview.api.AlignExportSettingsI;
28    import jalview.api.AlignViewportI;
29    import jalview.api.AlignmentViewPanel;
30    import jalview.api.FeaturesDisplayedI;
31    import jalview.api.ViewStyleI;
32    import jalview.commands.CommandI;
33    import jalview.datamodel.AlignedCodonFrame;
34    import jalview.datamodel.AlignmentAnnotation;
35    import jalview.datamodel.AlignmentExportData;
36    import jalview.datamodel.AlignmentI;
37    import jalview.datamodel.AlignmentView;
38    import jalview.datamodel.Annotation;
39    import jalview.datamodel.ColumnSelection;
40    import jalview.datamodel.HiddenColumns;
41    import jalview.datamodel.HiddenSequences;
42    import jalview.datamodel.ProfilesI;
43    import jalview.datamodel.SearchResultsI;
44    import jalview.datamodel.Sequence;
45    import jalview.datamodel.SequenceCollectionI;
46    import jalview.datamodel.SequenceGroup;
47    import jalview.datamodel.SequenceI;
48    import jalview.renderer.ResidueShader;
49    import jalview.renderer.ResidueShaderI;
50    import jalview.schemes.ColourSchemeI;
51    import jalview.structure.CommandListener;
52    import jalview.structure.StructureSelectionManager;
53    import jalview.structure.VamsasSource;
54    import jalview.util.Comparison;
55    import jalview.util.MapList;
56    import jalview.util.MappingUtils;
57    import jalview.util.MessageManager;
58    import jalview.viewmodel.styles.ViewStyle;
59    import jalview.workers.AlignCalcManager;
60    import jalview.workers.ComplementConsensusThread;
61    import jalview.workers.ConsensusThread;
62    import jalview.workers.StrucConsensusThread;
63   
64    import java.awt.Color;
65    import java.beans.PropertyChangeSupport;
66    import java.util.ArrayDeque;
67    import java.util.ArrayList;
68    import java.util.BitSet;
69    import java.util.Deque;
70    import java.util.HashMap;
71    import java.util.Hashtable;
72    import java.util.Iterator;
73    import java.util.List;
74    import java.util.Map;
75   
76    /**
77    * base class holding visualization and analysis attributes and common logic for
78    * an active alignment view displayed in the GUI
79    *
80    * @author jimp
81    *
82    */
 
83    public abstract class AlignmentViewport
84    implements AlignViewportI, CommandListener, VamsasSource
85    {
86    protected ViewportRanges ranges;
87   
88    protected ViewStyleI viewStyle = new ViewStyle();
89   
90    /**
91    * A viewport that hosts the cDna view of this (protein), or vice versa (if
92    * set).
93    */
94    AlignViewportI codingComplement = null;
95   
96    FeaturesDisplayedI featuresDisplayed = null;
97   
98    protected Deque<CommandI> historyList = new ArrayDeque<>();
99   
100    protected Deque<CommandI> redoList = new ArrayDeque<>();
101   
102    /**
103    * alignment displayed in the viewport. Please use get/setter
104    */
105    protected AlignmentI alignment;
106   
 
107  294 toggle public AlignmentViewport(AlignmentI al)
108    {
109  294 setAlignment(al);
110  294 ranges = new ViewportRanges(al);
111    }
112   
113    /**
114    * @param name
115    * @see jalview.api.ViewStyleI#setFontName(java.lang.String)
116    */
 
117  0 toggle @Override
118    public void setFontName(String name)
119    {
120  0 viewStyle.setFontName(name);
121    }
122   
123    /**
124    * @param style
125    * @see jalview.api.ViewStyleI#setFontStyle(int)
126    */
 
127  0 toggle @Override
128    public void setFontStyle(int style)
129    {
130  0 viewStyle.setFontStyle(style);
131    }
132   
133    /**
134    * @param size
135    * @see jalview.api.ViewStyleI#setFontSize(int)
136    */
 
137  0 toggle @Override
138    public void setFontSize(int size)
139    {
140  0 viewStyle.setFontSize(size);
141    }
142   
143    /**
144    * @return
145    * @see jalview.api.ViewStyleI#getFontStyle()
146    */
 
147  0 toggle @Override
148    public int getFontStyle()
149    {
150  0 return viewStyle.getFontStyle();
151    }
152   
153    /**
154    * @return
155    * @see jalview.api.ViewStyleI#getFontName()
156    */
 
157  0 toggle @Override
158    public String getFontName()
159    {
160  0 return viewStyle.getFontName();
161    }
162   
163    /**
164    * @return
165    * @see jalview.api.ViewStyleI#getFontSize()
166    */
 
167  0 toggle @Override
168    public int getFontSize()
169    {
170  0 return viewStyle.getFontSize();
171    }
172   
173    /**
174    * @param upperCasebold
175    * @see jalview.api.ViewStyleI#setUpperCasebold(boolean)
176    */
 
177  0 toggle @Override
178    public void setUpperCasebold(boolean upperCasebold)
179    {
180  0 viewStyle.setUpperCasebold(upperCasebold);
181    }
182   
183    /**
184    * @return
185    * @see jalview.api.ViewStyleI#isUpperCasebold()
186    */
 
187  0 toggle @Override
188    public boolean isUpperCasebold()
189    {
190  0 return viewStyle.isUpperCasebold();
191    }
192   
193    /**
194    * @return
195    * @see jalview.api.ViewStyleI#isSeqNameItalics()
196    */
 
197  904 toggle @Override
198    public boolean isSeqNameItalics()
199    {
200  904 return viewStyle.isSeqNameItalics();
201    }
202   
203    /**
204    * @param colourByReferenceSeq
205    * @see jalview.api.ViewStyleI#setColourByReferenceSeq(boolean)
206    */
 
207  10 toggle @Override
208    public void setColourByReferenceSeq(boolean colourByReferenceSeq)
209    {
210  10 viewStyle.setColourByReferenceSeq(colourByReferenceSeq);
211    }
212   
213    /**
214    * @param b
215    * @see jalview.api.ViewStyleI#setColourAppliesToAllGroups(boolean)
216    */
 
217  445 toggle @Override
218    public void setColourAppliesToAllGroups(boolean b)
219    {
220  445 viewStyle.setColourAppliesToAllGroups(b);
221    }
222   
223    /**
224    * @return
225    * @see jalview.api.ViewStyleI#getColourAppliesToAllGroups()
226    */
 
227  614 toggle @Override
228    public boolean getColourAppliesToAllGroups()
229    {
230  614 return viewStyle.getColourAppliesToAllGroups();
231    }
232   
233    /**
234    * @return
235    * @see jalview.api.ViewStyleI#getAbovePIDThreshold()
236    */
 
237  590 toggle @Override
238    public boolean getAbovePIDThreshold()
239    {
240  590 return viewStyle.getAbovePIDThreshold();
241    }
242   
243    /**
244    * @param inc
245    * @see jalview.api.ViewStyleI#setIncrement(int)
246    */
 
247  70 toggle @Override
248    public void setIncrement(int inc)
249    {
250  70 viewStyle.setIncrement(inc);
251    }
252   
253    /**
254    * @return
255    * @see jalview.api.ViewStyleI#getIncrement()
256    */
 
257  0 toggle @Override
258    public int getIncrement()
259    {
260  0 return viewStyle.getIncrement();
261    }
262   
263    /**
264    * @param b
265    * @see jalview.api.ViewStyleI#setConservationSelected(boolean)
266    */
 
267  78 toggle @Override
268    public void setConservationSelected(boolean b)
269    {
270  78 viewStyle.setConservationSelected(b);
271    }
272   
273    /**
274    * @param show
275    * @see jalview.api.ViewStyleI#setShowHiddenMarkers(boolean)
276    */
 
277  0 toggle @Override
278    public void setShowHiddenMarkers(boolean show)
279    {
280  0 viewStyle.setShowHiddenMarkers(show);
281    }
282   
283    /**
284    * @return
285    * @see jalview.api.ViewStyleI#getShowHiddenMarkers()
286    */
 
287  5802 toggle @Override
288    public boolean getShowHiddenMarkers()
289    {
290  5802 return viewStyle.getShowHiddenMarkers();
291    }
292   
293    /**
294    * @param b
295    * @see jalview.api.ViewStyleI#setScaleRightWrapped(boolean)
296    */
 
297  8 toggle @Override
298    public void setScaleRightWrapped(boolean b)
299    {
300  8 viewStyle.setScaleRightWrapped(b);
301    }
302   
303    /**
304    * @param b
305    * @see jalview.api.ViewStyleI#setScaleLeftWrapped(boolean)
306    */
 
307  10 toggle @Override
308    public void setScaleLeftWrapped(boolean b)
309    {
310  10 viewStyle.setScaleLeftWrapped(b);
311    }
312   
313    /**
314    * @param b
315    * @see jalview.api.ViewStyleI#setScaleAboveWrapped(boolean)
316    */
 
317  8 toggle @Override
318    public void setScaleAboveWrapped(boolean b)
319    {
320  8 viewStyle.setScaleAboveWrapped(b);
321    }
322   
323    /**
324    * @return
325    * @see jalview.api.ViewStyleI#getScaleLeftWrapped()
326    */
 
327  708 toggle @Override
328    public boolean getScaleLeftWrapped()
329    {
330  708 return viewStyle.getScaleLeftWrapped();
331    }
332   
333    /**
334    * @return
335    * @see jalview.api.ViewStyleI#getScaleAboveWrapped()
336    */
 
337  566 toggle @Override
338    public boolean getScaleAboveWrapped()
339    {
340  566 return viewStyle.getScaleAboveWrapped();
341    }
342   
343    /**
344    * @return
345    * @see jalview.api.ViewStyleI#getScaleRightWrapped()
346    */
 
347  964 toggle @Override
348    public boolean getScaleRightWrapped()
349    {
350  964 return viewStyle.getScaleRightWrapped();
351    }
352   
353    /**
354    * @param b
355    * @see jalview.api.ViewStyleI#setAbovePIDThreshold(boolean)
356    */
 
357  79 toggle @Override
358    public void setAbovePIDThreshold(boolean b)
359    {
360  79 viewStyle.setAbovePIDThreshold(b);
361    }
362   
363    /**
364    * @param thresh
365    * @see jalview.api.ViewStyleI#setThreshold(int)
366    */
 
367  91 toggle @Override
368    public void setThreshold(int thresh)
369    {
370  91 viewStyle.setThreshold(thresh);
371    }
372   
373    /**
374    * @return
375    * @see jalview.api.ViewStyleI#getThreshold()
376    */
 
377  0 toggle @Override
378    public int getThreshold()
379    {
380  0 return viewStyle.getThreshold();
381    }
382   
383    /**
384    * @return
385    * @see jalview.api.ViewStyleI#getShowJVSuffix()
386    */
 
387  11008 toggle @Override
388    public boolean getShowJVSuffix()
389    {
390  11008 return viewStyle.getShowJVSuffix();
391    }
392   
393    /**
394    * @param b
395    * @see jalview.api.ViewStyleI#setShowJVSuffix(boolean)
396    */
 
397  72 toggle @Override
398    public void setShowJVSuffix(boolean b)
399    {
400  72 viewStyle.setShowJVSuffix(b);
401    }
402   
403    /**
404    * @param state
405    * @see jalview.api.ViewStyleI#setWrapAlignment(boolean)
406    */
 
407  81 toggle @Override
408    public void setWrapAlignment(boolean state)
409    {
410  81 viewStyle.setWrapAlignment(state);
411  81 ranges.setWrappedMode(state);
412    }
413   
414    /**
415    * @param state
416    * @see jalview.api.ViewStyleI#setShowText(boolean)
417    */
 
418  70 toggle @Override
419    public void setShowText(boolean state)
420    {
421  70 viewStyle.setShowText(state);
422    }
423   
424    /**
425    * @param state
426    * @see jalview.api.ViewStyleI#setRenderGaps(boolean)
427    */
 
428  70 toggle @Override
429    public void setRenderGaps(boolean state)
430    {
431  70 viewStyle.setRenderGaps(state);
432    }
433   
434    /**
435    * @return
436    * @see jalview.api.ViewStyleI#getColourText()
437    */
 
438  264375 toggle @Override
439    public boolean getColourText()
440    {
441  264375 return viewStyle.getColourText();
442    }
443   
444    /**
445    * @param state
446    * @see jalview.api.ViewStyleI#setColourText(boolean)
447    */
 
448  70 toggle @Override
449    public void setColourText(boolean state)
450    {
451  70 viewStyle.setColourText(state);
452    }
453   
454    /**
455    * @return
456    * @see jalview.api.ViewStyleI#getWrapAlignment()
457    */
 
458  8502 toggle @Override
459    public boolean getWrapAlignment()
460    {
461  8502 return viewStyle.getWrapAlignment();
462    }
463   
464    /**
465    * @return
466    * @see jalview.api.ViewStyleI#getShowText()
467    */
 
468  264796 toggle @Override
469    public boolean getShowText()
470    {
471  264796 return viewStyle.getShowText();
472    }
473   
474    /**
475    * @return
476    * @see jalview.api.ViewStyleI#getWrappedWidth()
477    */
 
478  0 toggle @Override
479    public int getWrappedWidth()
480    {
481  0 return viewStyle.getWrappedWidth();
482    }
483   
484    /**
485    * @param w
486    * @see jalview.api.ViewStyleI#setWrappedWidth(int)
487    */
 
488  111 toggle @Override
489    public void setWrappedWidth(int w)
490    {
491  111 viewStyle.setWrappedWidth(w);
492    }
493   
494    /**
495    * @return
496    * @see jalview.api.ViewStyleI#getCharHeight()
497    */
 
498  69190 toggle @Override
499    public int getCharHeight()
500    {
501  69190 return viewStyle.getCharHeight();
502    }
503   
504    /**
505    * @param h
506    * @see jalview.api.ViewStyleI#setCharHeight(int)
507    */
 
508  368 toggle @Override
509    public void setCharHeight(int h)
510    {
511  368 viewStyle.setCharHeight(h);
512    }
513   
514    /**
515    * @return
516    * @see jalview.api.ViewStyleI#getCharWidth()
517    */
 
518  924728 toggle @Override
519    public int getCharWidth()
520    {
521  924728 return viewStyle.getCharWidth();
522    }
523   
524    /**
525    * @param w
526    * @see jalview.api.ViewStyleI#setCharWidth(int)
527    */
 
528  371 toggle @Override
529    public void setCharWidth(int w)
530    {
531  371 viewStyle.setCharWidth(w);
532    }
533   
534    /**
535    * @return
536    * @see jalview.api.ViewStyleI#getShowBoxes()
537    */
 
538  267815 toggle @Override
539    public boolean getShowBoxes()
540    {
541  267815 return viewStyle.getShowBoxes();
542    }
543   
544    /**
545    * @return
546    * @see jalview.api.ViewStyleI#getShowUnconserved()
547    */
 
548  262808 toggle @Override
549    public boolean getShowUnconserved()
550    {
551  262808 return viewStyle.getShowUnconserved();
552    }
553   
554    /**
555    * @param showunconserved
556    * @see jalview.api.ViewStyleI#setShowUnconserved(boolean)
557    */
 
558  70 toggle @Override
559    public void setShowUnconserved(boolean showunconserved)
560    {
561  70 viewStyle.setShowUnconserved(showunconserved);
562    }
563   
564    /**
565    * @param default1
566    * @see jalview.api.ViewStyleI#setSeqNameItalics(boolean)
567    */
 
568  0 toggle @Override
569    public void setSeqNameItalics(boolean default1)
570    {
571  0 viewStyle.setSeqNameItalics(default1);
572    }
573   
 
574  79829 toggle @Override
575    public AlignmentI getAlignment()
576    {
577  79830 return alignment;
578    }
579   
 
580  0 toggle @Override
581    public char getGapCharacter()
582    {
583  0 return alignment.getGapCharacter();
584    }
585   
586    protected String sequenceSetID;
587   
588    /**
589    * probably unused indicator that view is of a dataset rather than an
590    * alignment
591    */
592    protected boolean isDataset = false;
593   
 
594  0 toggle public void setDataset(boolean b)
595    {
596  0 isDataset = b;
597    }
598   
 
599  267 toggle public boolean isDataset()
600    {
601  267 return isDataset;
602    }
603   
604    private Map<SequenceI, SequenceCollectionI> hiddenRepSequences;
605   
606    protected ColumnSelection colSel = new ColumnSelection();
607   
608    public boolean autoCalculateConsensus = true;
609   
610    protected boolean autoCalculateStrucConsensus = true;
611   
612    protected boolean ignoreGapsInConsensusCalculation = false;
613   
614    protected ResidueShaderI residueShading = new ResidueShader();
615   
 
616  187 toggle @Override
617    public void setGlobalColourScheme(ColourSchemeI cs)
618    {
619    // TODO: logic refactored from AlignFrame changeColour -
620    // TODO: autorecalc stuff should be changed to rely on the worker system
621    // check to see if we should implement a changeColour(cs) method rather than
622    // put the logic in here
623    // - means that caller decides if they want to just modify state and defer
624    // calculation till later or to do all calculations in thread.
625    // via changecolour
626   
627    /*
628    * only instantiate alignment colouring once, thereafter update it;
629    * this means that any conservation or PID threshold settings
630    * persist when the alignment colour scheme is changed
631    */
632  187 if (residueShading == null)
633    {
634  0 residueShading = new ResidueShader(viewStyle);
635    }
636  187 residueShading.setColourScheme(cs);
637   
638    // TODO: do threshold and increment belong in ViewStyle or ResidueShader?
639    // ...problem: groups need these, but do not currently have a ViewStyle
640   
641  187 if (cs != null)
642    {
643  56 if (getConservationSelected())
644    {
645  15 residueShading.setConservation(hconservation);
646    }
647    /*
648    * reset conservation flag in case just set to false if
649    * Conservation was null (calculation still in progress)
650    */
651  56 residueShading.setConservationApplied(getConservationSelected());
652  56 residueShading.alignmentChanged(alignment, hiddenRepSequences);
653    }
654   
655    /*
656    * if 'apply colour to all groups' is selected... do so
657    * (but don't transfer any colour threshold settings to groups)
658    */
659  187 if (getColourAppliesToAllGroups())
660    {
661  29 for (SequenceGroup sg : getAlignment().getGroups())
662    {
663    /*
664    * retain any colour thresholds per group while
665    * changing choice of colour scheme (JAL-2386)
666    */
667  6 sg.setColourScheme(
668  6 cs == null ? null : cs.getInstance(this, sg));
669  6 if (cs != null)
670    {
671  5 sg.getGroupColourScheme().alignmentChanged(sg,
672    hiddenRepSequences);
673    }
674    }
675    }
676    }
677   
 
678  822 toggle @Override
679    public ColourSchemeI getGlobalColourScheme()
680    {
681  822 return residueShading == null ? null : residueShading.getColourScheme();
682    }
683   
 
684  268763 toggle @Override
685    public ResidueShaderI getResidueShading()
686    {
687  268763 return residueShading;
688    }
689   
690    protected AlignmentAnnotation consensus;
691   
692    protected AlignmentAnnotation complementConsensus;
693   
694    protected AlignmentAnnotation gapcounts;
695   
696    protected AlignmentAnnotation strucConsensus;
697   
698    protected AlignmentAnnotation conservation;
699   
700    protected AlignmentAnnotation quality;
701   
702    protected AlignmentAnnotation[] groupConsensus;
703   
704    protected AlignmentAnnotation[] groupConservation;
705   
706    /**
707    * results of alignment consensus analysis for visible portion of view
708    */
709    protected ProfilesI hconsensus = null;
710   
711    /**
712    * results of cDNA complement consensus visible portion of view
713    */
714    protected Hashtable<String, Object>[] hcomplementConsensus = null;
715   
716    /**
717    * results of secondary structure base pair consensus for visible portion of
718    * view
719    */
720    protected Hashtable<String, Object>[] hStrucConsensus = null;
721   
722    protected Conservation hconservation = null;
723   
 
724  497 toggle @Override
725    public void setConservation(Conservation cons)
726    {
727  497 hconservation = cons;
728    }
729   
730    /**
731    * percentage gaps allowed in a column before all amino acid properties should
732    * be considered unconserved
733    */
734    int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
735   
 
736  988 toggle @Override
737    public int getConsPercGaps()
738    {
739  988 return ConsPercGaps;
740    }
741   
 
742  459 toggle @Override
743    public void setSequenceConsensusHash(ProfilesI hconsensus)
744    {
745  459 this.hconsensus = hconsensus;
746    }
747   
 
748  4 toggle @Override
749    public void setComplementConsensusHash(
750    Hashtable<String, Object>[] hconsensus)
751    {
752  4 this.hcomplementConsensus = hconsensus;
753    }
754   
 
755  1226 toggle @Override
756    public ProfilesI getSequenceConsensusHash()
757    {
758  1226 return hconsensus;
759    }
760   
 
761  685 toggle @Override
762    public Hashtable<String, Object>[] getComplementConsensusHash()
763    {
764  685 return hcomplementConsensus;
765    }
766   
 
767  684 toggle @Override
768    public Hashtable<String, Object>[] getRnaStructureConsensusHash()
769    {
770  684 return hStrucConsensus;
771    }
772   
 
773  3 toggle @Override
774    public void setRnaStructureConsensusHash(
775    Hashtable<String, Object>[] hStrucConsensus)
776    {
777  3 this.hStrucConsensus = hStrucConsensus;
778   
779    }
780   
 
781  854 toggle @Override
782    public AlignmentAnnotation getAlignmentQualityAnnot()
783    {
784  854 return quality;
785    }
786   
 
787  1069 toggle @Override
788    public AlignmentAnnotation getAlignmentConservationAnnotation()
789    {
790  1069 return conservation;
791    }
792   
 
793  2404 toggle @Override
794    public AlignmentAnnotation getAlignmentConsensusAnnotation()
795    {
796  2404 return consensus;
797    }
798   
 
799  1427 toggle @Override
800    public AlignmentAnnotation getAlignmentGapAnnotation()
801    {
802  1427 return gapcounts;
803    }
804   
 
805  693 toggle @Override
806    public AlignmentAnnotation getComplementConsensusAnnotation()
807    {
808  693 return complementConsensus;
809    }
810   
 
811  684 toggle @Override
812    public AlignmentAnnotation getAlignmentStrucConsensusAnnotation()
813    {
814  684 return strucConsensus;
815    }
816   
817    protected AlignCalcManagerI calculator = new AlignCalcManager();
818   
819    /**
820    * trigger update of conservation annotation
821    */
 
822  443 toggle public void updateConservation(final AlignmentViewPanel ap)
823    {
824    // see note in mantis : issue number 8585
825  443 if (alignment.isNucleotide()
826    || (conservation == null && quality == null)
827    || !autoCalculateConsensus)
828    {
829  22 return;
830    }
831  421 if (calculator.getRegisteredWorkersOfClass(
832    jalview.workers.ConservationThread.class) == null)
833    {
834  238 calculator.registerWorker(
835    new jalview.workers.ConservationThread(this, ap));
836    }
837    }
838   
839    /**
840    * trigger update of consensus annotation
841    */
 
842  453 toggle public void updateConsensus(final AlignmentViewPanel ap)
843    {
844    // see note in mantis : issue number 8585
845  453 if (consensus == null || !autoCalculateConsensus)
846    {
847  0 return;
848    }
849  453 if (calculator
850    .getRegisteredWorkersOfClass(ConsensusThread.class) == null)
851    {
852  244 calculator.registerWorker(new ConsensusThread(this, ap));
853    }
854   
855    /*
856    * A separate thread to compute cDNA consensus for a protein alignment
857    * which has mapping to cDNA
858    */
859  453 final AlignmentI al = this.getAlignment();
860  453 if (!al.isNucleotide() && al.getCodonFrames() != null
861    && !al.getCodonFrames().isEmpty())
862    {
863    /*
864    * fudge - check first for protein-to-nucleotide mappings
865    * (we don't want to do this for protein-to-protein)
866    */
867  4 boolean doConsensus = false;
868  4 for (AlignedCodonFrame mapping : al.getCodonFrames())
869    {
870    // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
871  4 MapList[] mapLists = mapping.getdnaToProt();
872    // mapLists can be empty if project load has not finished resolving seqs
873  4 if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
874    {
875  4 doConsensus = true;
876  4 break;
877    }
878    }
879  4 if (doConsensus)
880    {
881  4 if (calculator.getRegisteredWorkersOfClass(
882    ComplementConsensusThread.class) == null)
883    {
884  4 calculator
885    .registerWorker(new ComplementConsensusThread(this, ap));
886    }
887    }
888    }
889    }
890   
891    // --------START Structure Conservation
 
892  450 toggle public void updateStrucConsensus(final AlignmentViewPanel ap)
893    {
894  450 if (autoCalculateStrucConsensus && strucConsensus == null
895    && alignment.isNucleotide() && alignment.hasRNAStructure())
896    {
897    // secondary structure has been added - so init the consensus line
898  0 initRNAStructure();
899    }
900   
901    // see note in mantis : issue number 8585
902  450 if (strucConsensus == null || !autoCalculateStrucConsensus)
903    {
904  447 return;
905    }
906  3 if (calculator.getRegisteredWorkersOfClass(
907    StrucConsensusThread.class) == null)
908    {
909  2 calculator.registerWorker(new StrucConsensusThread(this, ap));
910    }
911    }
912   
 
913  455 toggle public boolean isCalcInProgress()
914    {
915  455 return calculator.isWorking();
916    }
917   
 
918  3016 toggle @Override
919    public boolean isCalculationInProgress(
920    AlignmentAnnotation alignmentAnnotation)
921    {
922  3016 if (!alignmentAnnotation.autoCalculated)
923    {
924  0 return false;
925    }
926  3016 if (calculator.workingInvolvedWith(alignmentAnnotation))
927    {
928    // System.err.println("grey out ("+alignmentAnnotation.label+")");
929  113 return true;
930    }
931  2903 return false;
932    }
933   
 
934  396 toggle public void setAlignment(AlignmentI align)
935    {
936  396 this.alignment = align;
937    }
938   
939    /**
940    * Clean up references when this viewport is closed
941    */
 
942  102 toggle @Override
943    public void dispose()
944    {
945    /*
946    * defensively null out references to large objects in case
947    * this object is not garbage collected (as if!)
948    */
949  102 consensus = null;
950  102 complementConsensus = null;
951  102 strucConsensus = null;
952  102 conservation = null;
953  102 quality = null;
954  102 groupConsensus = null;
955  102 groupConservation = null;
956  102 hconsensus = null;
957  102 hconservation = null;
958  102 hcomplementConsensus = null;
959  102 gapcounts = null;
960  102 calculator = null;
961  102 residueShading = null; // may hold a reference to Consensus
962  102 changeSupport = null;
963  102 ranges = null;
964  102 currentTree = null;
965  102 selectionGroup = null;
966  102 setAlignment(null);
967    }
968   
 
969  1471 toggle @Override
970    public boolean isClosed()
971    {
972    // TODO: check that this isClosed is only true after panel is closed, not
973    // before it is fully constructed.
974  1471 return alignment == null;
975    }
976   
 
977  1620 toggle @Override
978    public AlignCalcManagerI getCalcManager()
979    {
980  1620 return calculator;
981    }
982   
983    /**
984    * should conservation rows be shown for groups
985    */
986    protected boolean showGroupConservation = false;
987   
988    /**
989    * should consensus rows be shown for groups
990    */
991    protected boolean showGroupConsensus = false;
992   
993    /**
994    * should consensus profile be rendered by default
995    */
996    protected boolean showSequenceLogo = false;
997   
998    /**
999    * should consensus profile be rendered normalised to row height
1000    */
1001    protected boolean normaliseSequenceLogo = false;
1002   
1003    /**
1004    * should consensus histograms be rendered by default
1005    */
1006    protected boolean showConsensusHistogram = true;
1007   
1008    /**
1009    * @return the showConsensusProfile
1010    */
 
1011  1726 toggle @Override
1012    public boolean isShowSequenceLogo()
1013    {
1014  1726 return showSequenceLogo;
1015    }
1016   
1017    /**
1018    * @param showSequenceLogo
1019    * the new value
1020    */
 
1021  70 toggle public void setShowSequenceLogo(boolean showSequenceLogo)
1022    {
1023  70 if (showSequenceLogo != this.showSequenceLogo)
1024    {
1025    // TODO: decouple settings setting from calculation when refactoring
1026    // annotation update method from alignframe to viewport
1027  16 this.showSequenceLogo = showSequenceLogo;
1028  16 calculator.updateAnnotationFor(ConsensusThread.class);
1029  16 calculator.updateAnnotationFor(ComplementConsensusThread.class);
1030  16 calculator.updateAnnotationFor(StrucConsensusThread.class);
1031    }
1032  70 this.showSequenceLogo = showSequenceLogo;
1033    }
1034   
1035    /**
1036    * @param showConsensusHistogram
1037    * the showConsensusHistogram to set
1038    */
 
1039  70 toggle public void setShowConsensusHistogram(boolean showConsensusHistogram)
1040    {
1041  70 this.showConsensusHistogram = showConsensusHistogram;
1042    }
1043   
1044    /**
1045    * @return the showGroupConservation
1046    */
 
1047  565 toggle public boolean isShowGroupConservation()
1048    {
1049  565 return showGroupConservation;
1050    }
1051   
1052    /**
1053    * @param showGroupConservation
1054    * the showGroupConservation to set
1055    */
 
1056  70 toggle public void setShowGroupConservation(boolean showGroupConservation)
1057    {
1058  70 this.showGroupConservation = showGroupConservation;
1059    }
1060   
1061    /**
1062    * @return the showGroupConsensus
1063    */
 
1064  565 toggle public boolean isShowGroupConsensus()
1065    {
1066  565 return showGroupConsensus;
1067    }
1068   
1069    /**
1070    * @param showGroupConsensus
1071    * the showGroupConsensus to set
1072    */
 
1073  70 toggle public void setShowGroupConsensus(boolean showGroupConsensus)
1074    {
1075  70 this.showGroupConsensus = showGroupConsensus;
1076    }
1077   
1078    /**
1079    *
1080    * @return flag to indicate if the consensus histogram should be rendered by
1081    * default
1082    */
 
1083  1246 toggle @Override
1084    public boolean isShowConsensusHistogram()
1085    {
1086  1246 return this.showConsensusHistogram;
1087    }
1088   
1089    /**
1090    * when set, updateAlignment will always ensure sequences are of equal length
1091    */
1092    private boolean padGaps = false;
1093   
1094    /**
1095    * when set, alignment should be reordered according to a newly opened tree
1096    */
1097    public boolean sortByTree = false;
1098   
1099    /**
1100    *
1101    *
1102    * @return null or the currently selected sequence region
1103    */
 
1104  11182 toggle @Override
1105    public SequenceGroup getSelectionGroup()
1106    {
1107  11182 return selectionGroup;
1108    }
1109   
1110    /**
1111    * Set the selection group for this window. Also sets the current alignment as
1112    * the context for the group, if it does not already have one.
1113    *
1114    * @param sg
1115    * - group holding references to sequences in this alignment view
1116    *
1117    */
 
1118  141 toggle @Override
1119    public void setSelectionGroup(SequenceGroup sg)
1120    {
1121  141 selectionGroup = sg;
1122  141 if (sg != null && sg.getContext() == null)
1123    {
1124  33 sg.setContext(alignment);
1125    }
1126    }
1127   
 
1128  1 toggle public void setHiddenColumns(HiddenColumns hidden)
1129    {
1130  1 this.alignment.setHiddenColumns(hidden);
1131    }
1132   
 
1133  1468 toggle @Override
1134    public ColumnSelection getColumnSelection()
1135    {
1136  1468 return colSel;
1137    }
1138   
 
1139  13 toggle @Override
1140    public void setColumnSelection(ColumnSelection colSel)
1141    {
1142  13 this.colSel = colSel;
1143  13 if (colSel != null)
1144    {
1145  13 updateHiddenColumns();
1146    }
1147  13 isColSelChanged(true);
1148    }
1149   
1150    /**
1151    *
1152    * @return
1153    */
 
1154  32 toggle @Override
1155    public Map<SequenceI, SequenceCollectionI> getHiddenRepSequences()
1156    {
1157  32 return hiddenRepSequences;
1158    }
1159   
 
1160  0 toggle @Override
1161    public void setHiddenRepSequences(
1162    Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
1163    {
1164  0 this.hiddenRepSequences = hiddenRepSequences;
1165    }
1166   
 
1167  0 toggle @Override
1168    public boolean hasSelectedColumns()
1169    {
1170  0 ColumnSelection columnSelection = getColumnSelection();
1171  0 return columnSelection != null && columnSelection.hasSelectedColumns();
1172    }
1173   
 
1174  3204 toggle @Override
1175    public boolean hasHiddenColumns()
1176    {
1177  3204 return alignment.getHiddenColumns() != null
1178    && alignment.getHiddenColumns().hasHiddenColumns();
1179    }
1180   
 
1181  13 toggle public void updateHiddenColumns()
1182    {
1183    // this method doesn't really do anything now. But - it could, since a
1184    // column Selection could be in the process of modification
1185    // hasHiddenColumns = colSel.hasHiddenColumns();
1186    }
1187   
 
1188  1734 toggle @Override
1189    public boolean hasHiddenRows()
1190    {
1191  1734 return alignment.getHiddenSequences().getSize() > 0;
1192    }
1193   
1194    protected SequenceGroup selectionGroup;
1195   
 
1196  70 toggle public void setSequenceSetId(String newid)
1197    {
1198  70 if (sequenceSetID != null)
1199    {
1200  70 System.err.println(
1201    "Warning - overwriting a sequenceSetId for a viewport!");
1202    }
1203  70 sequenceSetID = new String(newid);
1204    }
1205   
 
1206  2732 toggle @Override
1207    public String getSequenceSetId()
1208    {
1209  2732 if (sequenceSetID == null)
1210    {
1211  168 sequenceSetID = alignment.hashCode() + "";
1212    }
1213   
1214  2732 return sequenceSetID;
1215    }
1216   
1217    /**
1218    * unique viewId for synchronizing state (e.g. with stored Jalview Project)
1219    *
1220    */
1221    protected String viewId = null;
1222   
 
1223  123 toggle @Override
1224    public String getViewId()
1225    {
1226  123 if (viewId == null)
1227    {
1228  16 viewId = this.getSequenceSetId() + "." + this.hashCode() + "";
1229    }
1230  123 return viewId;
1231    }
1232   
 
1233  73 toggle public void setIgnoreGapsConsensus(boolean b, AlignmentViewPanel ap)
1234    {
1235  73 ignoreGapsInConsensusCalculation = b;
1236  73 if (ap != null)
1237    {
1238  3 updateConsensus(ap);
1239  3 if (residueShading != null)
1240    {
1241  3 residueShading.setThreshold(residueShading.getThreshold(),
1242    ignoreGapsInConsensusCalculation);
1243    }
1244    }
1245   
1246    }
1247   
1248    private long sgrouphash = -1, colselhash = -1;
1249   
1250    /**
1251    * checks current SelectionGroup against record of last hash value, and
1252    * updates record.
1253    *
1254    * @param b
1255    * update the record of last hash value
1256    *
1257    * @return true if SelectionGroup changed since last call (when b is true)
1258    */
 
1259  173 toggle public boolean isSelectionGroupChanged(boolean b)
1260    {
1261  173 int hc = (selectionGroup == null || selectionGroup.getSize() == 0) ? -1
1262    : selectionGroup.hashCode();
1263  173 if (hc != -1 && hc != sgrouphash)
1264    {
1265  7 if (b)
1266    {
1267  7 sgrouphash = hc;
1268    }
1269  7 return true;
1270    }
1271  166 return false;
1272    }
1273   
1274    /**
1275    * checks current colsel against record of last hash value, and optionally
1276    * updates record.
1277    *
1278    * @param b
1279    * update the record of last hash value
1280    * @return true if colsel changed since last call (when b is true)
1281    */
 
1282  180 toggle public boolean isColSelChanged(boolean b)
1283    {
1284  180 int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
1285  180 if (hc != -1 && hc != colselhash)
1286    {
1287  17 if (b)
1288    {
1289  17 colselhash = hc;
1290    }
1291  17 return true;
1292    }
1293  163 return false;
1294    }
1295   
 
1296  1213 toggle @Override
1297    public boolean isIgnoreGapsConsensus()
1298    {
1299  1213 return ignoreGapsInConsensusCalculation;
1300    }
1301   
1302    // property change stuff
1303    // JBPNote Prolly only need this in the applet version.
1304    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
1305    this);
1306   
1307    protected boolean showConservation = true;
1308   
1309    protected boolean showQuality = true;
1310   
1311    protected boolean showConsensus = true;
1312   
1313    protected boolean showOccupancy = true;
1314   
1315    private Map<SequenceI, Color> sequenceColours = new HashMap<>();
1316   
1317    protected SequenceAnnotationOrder sortAnnotationsBy = null;
1318   
1319    protected boolean showAutocalculatedAbove;
1320   
1321    /**
1322    * when set, view will scroll to show the highlighted position
1323    */
1324    private boolean followHighlight = true;
1325   
1326    /**
1327    * Property change listener for changes in alignment
1328    *
1329    * @param listener
1330    * DOCUMENT ME!
1331    */
 
1332  276 toggle public void addPropertyChangeListener(
1333    java.beans.PropertyChangeListener listener)
1334    {
1335  276 changeSupport.addPropertyChangeListener(listener);
1336    }
1337   
1338    /**
1339    * DOCUMENT ME!
1340    *
1341    * @param listener
1342    * DOCUMENT ME!
1343    */
 
1344  110 toggle public void removePropertyChangeListener(
1345    java.beans.PropertyChangeListener listener)
1346    {
1347  110 if (changeSupport != null)
1348    {
1349  109 changeSupport.removePropertyChangeListener(listener);
1350    }
1351    }
1352   
1353    /**
1354    * Property change listener for changes in alignment
1355    *
1356    * @param prop
1357    * DOCUMENT ME!
1358    * @param oldvalue
1359    * DOCUMENT ME!
1360    * @param newvalue
1361    * DOCUMENT ME!
1362    */
 
1363  55 toggle public void firePropertyChange(String prop, Object oldvalue,
1364    Object newvalue)
1365    {
1366  55 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1367    }
1368   
1369    // common hide/show column stuff
1370   
 
1371  6 toggle public void hideSelectedColumns()
1372    {
1373  6 if (colSel.isEmpty())
1374    {
1375  2 return;
1376    }
1377   
1378  4 colSel.hideSelectedColumns(alignment);
1379  4 setSelectionGroup(null);
1380  4 isColSelChanged(true);
1381    }
1382   
 
1383  71 toggle public void hideColumns(int start, int end)
1384    {
1385  71 if (start == end)
1386    {
1387  2 colSel.hideSelectedColumns(start, alignment.getHiddenColumns());
1388    }
1389    else
1390    {
1391  69 alignment.getHiddenColumns().hideColumns(start, end);
1392    }
1393  71 isColSelChanged(true);
1394    }
1395   
 
1396  1 toggle public void showColumn(int col)
1397    {
1398  1 alignment.getHiddenColumns().revealHiddenColumns(col, colSel);
1399  1 isColSelChanged(true);
1400    }
1401   
 
1402  5 toggle public void showAllHiddenColumns()
1403    {
1404  5 alignment.getHiddenColumns().revealAllHiddenColumns(colSel);
1405  5 isColSelChanged(true);
1406    }
1407   
1408    // common hide/show seq stuff
 
1409  1 toggle public void showAllHiddenSeqs()
1410    {
1411  1 int startSeq = ranges.getStartSeq();
1412  1 int endSeq = ranges.getEndSeq();
1413   
1414  1 if (alignment.getHiddenSequences().getSize() > 0)
1415    {
1416  1 if (selectionGroup == null)
1417    {
1418  0 selectionGroup = new SequenceGroup();
1419  0 selectionGroup.setEndRes(alignment.getWidth() - 1);
1420    }
1421  1 List<SequenceI> tmp = alignment.getHiddenSequences()
1422    .showAll(hiddenRepSequences);
1423  1 for (SequenceI seq : tmp)
1424    {
1425  2 selectionGroup.addSequence(seq, false);
1426  2 setSequenceAnnotationsVisible(seq, true);
1427    }
1428   
1429  1 hiddenRepSequences = null;
1430   
1431  1 ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
1432   
1433  1 firePropertyChange("alignment", null, alignment.getSequences());
1434    // used to set hasHiddenRows/hiddenRepSequences here, after the property
1435    // changed event
1436  1 sendSelection();
1437    }
1438    }
1439   
 
1440  2 toggle public void showSequence(int index)
1441    {
1442  2 int startSeq = ranges.getStartSeq();
1443  2 int endSeq = ranges.getEndSeq();
1444   
1445  2 List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(index,
1446    hiddenRepSequences);
1447  2 if (tmp.size() > 0)
1448    {
1449  2 if (selectionGroup == null)
1450    {
1451  2 selectionGroup = new SequenceGroup();
1452  2 selectionGroup.setEndRes(alignment.getWidth() - 1);
1453    }
1454   
1455  2 for (SequenceI seq : tmp)
1456    {
1457  3 selectionGroup.addSequence(seq, false);
1458  3 setSequenceAnnotationsVisible(seq, true);
1459    }
1460   
1461  2 ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
1462   
1463  2 firePropertyChange("alignment", null, alignment.getSequences());
1464  2 sendSelection();
1465    }
1466    }
1467   
 
1468  0 toggle public void hideAllSelectedSeqs()
1469    {
1470  0 if (selectionGroup == null || selectionGroup.getSize() < 1)
1471    {
1472  0 return;
1473    }
1474   
1475  0 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1476   
1477  0 hideSequence(seqs);
1478   
1479  0 setSelectionGroup(null);
1480    }
1481   
 
1482  51 toggle public void hideSequence(SequenceI[] seq)
1483    {
1484    /*
1485    * cache offset to first visible sequence
1486    */
1487  51 int startSeq = ranges.getStartSeq();
1488   
1489  51 if (seq != null)
1490    {
1491  246 for (int i = 0; i < seq.length; i++)
1492    {
1493  195 alignment.getHiddenSequences().hideSequence(seq[i]);
1494  195 setSequenceAnnotationsVisible(seq[i], false);
1495    }
1496  51 ranges.setStartSeq(startSeq);
1497  51 firePropertyChange("alignment", null, alignment.getSequences());
1498    }
1499    }
1500   
1501    /**
1502    * Hides the specified sequence, or the sequences it represents
1503    *
1504    * @param sequence
1505    * the sequence to hide, or keep as representative
1506    * @param representGroup
1507    * if true, hide the current selection group except for the
1508    * representative sequence
1509    */
 
1510  3 toggle public void hideSequences(SequenceI sequence, boolean representGroup)
1511    {
1512  3 if (selectionGroup == null || selectionGroup.getSize() < 1)
1513    {
1514  0 hideSequence(new SequenceI[] { sequence });
1515  0 return;
1516    }
1517   
1518  3 if (representGroup)
1519    {
1520  3 hideRepSequences(sequence, selectionGroup);
1521  3 setSelectionGroup(null);
1522  3 return;
1523    }
1524   
1525  0 int gsize = selectionGroup.getSize();
1526  0 SequenceI[] hseqs = selectionGroup.getSequences()
1527    .toArray(new SequenceI[gsize]);
1528   
1529  0 hideSequence(hseqs);
1530  0 setSelectionGroup(null);
1531  0 sendSelection();
1532    }
1533   
1534    /**
1535    * Set visibility for any annotations for the given sequence.
1536    *
1537    * @param sequenceI
1538    */
 
1539  200 toggle protected void setSequenceAnnotationsVisible(SequenceI sequenceI,
1540    boolean visible)
1541    {
1542  200 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
1543  200 if (anns != null)
1544    {
1545  200 for (AlignmentAnnotation ann : anns)
1546    {
1547  1018 if (ann.sequenceRef == sequenceI)
1548    {
1549  0 ann.visible = visible;
1550    }
1551    }
1552    }
1553    }
1554   
 
1555  5 toggle public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1556    {
1557  5 int sSize = sg.getSize();
1558  5 if (sSize < 2)
1559    {
1560  0 return;
1561    }
1562   
1563  5 if (hiddenRepSequences == null)
1564    {
1565  5 hiddenRepSequences = new Hashtable<>();
1566    }
1567   
1568  5 hiddenRepSequences.put(repSequence, sg);
1569   
1570    // Hide all sequences except the repSequence
1571  5 SequenceI[] seqs = new SequenceI[sSize - 1];
1572  5 int index = 0;
1573  16 for (int i = 0; i < sSize; i++)
1574    {
1575  11 if (sg.getSequenceAt(i) != repSequence)
1576    {
1577  6 if (index == sSize - 1)
1578    {
1579  0 return;
1580    }
1581   
1582  6 seqs[index++] = sg.getSequenceAt(i);
1583    }
1584    }
1585  5 sg.setSeqrep(repSequence); // note: not done in 2.7applet
1586  5 sg.setHidereps(true); // note: not done in 2.7applet
1587  5 hideSequence(seqs);
1588   
1589    }
1590   
1591    /**
1592    *
1593    * @return null or the current reference sequence
1594    */
 
1595  0 toggle public SequenceI getReferenceSeq()
1596    {
1597  0 return alignment.getSeqrep();
1598    }
1599   
1600    /**
1601    * @param seq
1602    * @return true iff seq is the reference for the alignment
1603    */
 
1604  4620 toggle public boolean isReferenceSeq(SequenceI seq)
1605    {
1606  4620 return alignment.getSeqrep() == seq;
1607    }
1608   
1609    /**
1610    *
1611    * @param seq
1612    * @return true if there are sequences represented by this sequence that are
1613    * currently hidden
1614    */
 
1615  4669 toggle public boolean isHiddenRepSequence(SequenceI seq)
1616    {
1617  4669 return (hiddenRepSequences != null
1618    && hiddenRepSequences.containsKey(seq));
1619    }
1620   
1621    /**
1622    *
1623    * @param seq
1624    * @return null or a sequence group containing the sequences that seq
1625    * represents
1626    */
 
1627  2 toggle public SequenceGroup getRepresentedSequences(SequenceI seq)
1628    {
1629  2 return (SequenceGroup) (hiddenRepSequences == null ? null
1630    : hiddenRepSequences.get(seq));
1631    }
1632   
 
1633  0 toggle @Override
1634    public int adjustForHiddenSeqs(int alignmentIndex)
1635    {
1636  0 return alignment.getHiddenSequences()
1637    .adjustForHiddenSeqs(alignmentIndex);
1638    }
1639   
 
1640  0 toggle @Override
1641    public void invertColumnSelection()
1642    {
1643  0 colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
1644  0 isColSelChanged(true);
1645    }
1646   
 
1647  1 toggle @Override
1648    public SequenceI[] getSelectionAsNewSequence()
1649    {
1650  1 SequenceI[] sequences;
1651    // JBPNote: Need to test jalviewLite.getSelectedSequencesAsAlignmentFrom -
1652    // this was the only caller in the applet for this method
1653    // JBPNote: in applet, this method returned references to the alignment
1654    // sequences, and it did not honour the presence/absence of annotation
1655    // attached to the alignment (probably!)
1656  1 if (selectionGroup == null || selectionGroup.getSize() == 0)
1657    {
1658  1 sequences = alignment.getSequencesArray();
1659  1 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
1660  2 for (int i = 0; i < sequences.length; i++)
1661    {
1662    // construct new sequence with subset of visible annotation
1663  1 sequences[i] = new Sequence(sequences[i], annots);
1664    }
1665    }
1666    else
1667    {
1668  0 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1669    }
1670   
1671  1 return sequences;
1672    }
1673   
 
1674  28 toggle @Override
1675    public SequenceI[] getSequenceSelection()
1676    {
1677  28 SequenceI[] sequences = null;
1678  28 if (selectionGroup != null)
1679    {
1680  4 sequences = selectionGroup.getSequencesInOrder(alignment);
1681    }
1682  28 if (sequences == null)
1683    {
1684  24 sequences = alignment.getSequencesArray();
1685    }
1686  28 return sequences;
1687    }
1688   
 
1689  17 toggle @Override
1690    public jalview.datamodel.AlignmentView getAlignmentView(
1691    boolean selectedOnly)
1692    {
1693  17 return getAlignmentView(selectedOnly, false);
1694    }
1695   
 
1696  18 toggle @Override
1697    public jalview.datamodel.AlignmentView getAlignmentView(
1698    boolean selectedOnly, boolean markGroups)
1699    {
1700  18 return new AlignmentView(alignment, alignment.getHiddenColumns(),
1701    selectionGroup,
1702    alignment.getHiddenColumns() != null
1703    && alignment.getHiddenColumns().hasHiddenColumns(),
1704    selectedOnly, markGroups);
1705    }
1706   
 
1707  24 toggle @Override
1708    public String[] getViewAsString(boolean selectedRegionOnly)
1709    {
1710  24 return getViewAsString(selectedRegionOnly, true);
1711    }
1712   
 
1713  24 toggle @Override
1714    public String[] getViewAsString(boolean selectedRegionOnly,
1715    boolean exportHiddenSeqs)
1716    {
1717  24 String[] selection = null;
1718  24 SequenceI[] seqs = null;
1719  24 int i, iSize;
1720  24 int start = 0, end = 0;
1721  24 if (selectedRegionOnly && selectionGroup != null)
1722    {
1723  0 iSize = selectionGroup.getSize();
1724  0 seqs = selectionGroup.getSequencesInOrder(alignment);
1725  0 start = selectionGroup.getStartRes();
1726  0 end = selectionGroup.getEndRes() + 1;
1727    }
1728    else
1729    {
1730  24 if (hasHiddenRows() && exportHiddenSeqs)
1731    {
1732  0 AlignmentI fullAlignment = alignment.getHiddenSequences()
1733    .getFullAlignment();
1734  0 iSize = fullAlignment.getHeight();
1735  0 seqs = fullAlignment.getSequencesArray();
1736  0 end = fullAlignment.getWidth();
1737    }
1738    else
1739    {
1740  24 iSize = alignment.getHeight();
1741  24 seqs = alignment.getSequencesArray();
1742  24 end = alignment.getWidth();
1743    }
1744    }
1745   
1746  24 selection = new String[iSize];
1747  24 if (alignment.getHiddenColumns() != null
1748    && alignment.getHiddenColumns().hasHiddenColumns())
1749    {
1750  206 for (i = 0; i < iSize; i++)
1751    {
1752  188 Iterator<int[]> blocks = alignment.getHiddenColumns()
1753    .getVisContigsIterator(start, end + 1, false);
1754  188 selection[i] = seqs[i].getSequenceStringFromIterator(blocks);
1755    }
1756    }
1757    else
1758    {
1759  36 for (i = 0; i < iSize; i++)
1760    {
1761  30 selection[i] = seqs[i].getSequenceAsString(start, end);
1762    }
1763   
1764    }
1765  24 return selection;
1766    }
1767   
 
1768  0 toggle @Override
1769    public List<int[]> getVisibleRegionBoundaries(int min, int max)
1770    {
1771  0 ArrayList<int[]> regions = new ArrayList<>();
1772  0 int start = min;
1773  0 int end = max;
1774   
1775  0 do
1776    {
1777  0 HiddenColumns hidden = alignment.getHiddenColumns();
1778  0 if (hidden != null && hidden.hasHiddenColumns())
1779    {
1780  0 if (start == 0)
1781    {
1782  0 start = hidden.visibleToAbsoluteColumn(start);
1783    }
1784   
1785  0 end = hidden.getNextHiddenBoundary(false, start);
1786  0 if (start == end)
1787    {
1788  0 end = max;
1789    }
1790  0 if (end > max)
1791    {
1792  0 end = max;
1793    }
1794    }
1795   
1796  0 regions.add(new int[] { start, end });
1797   
1798  0 if (hidden != null && hidden.hasHiddenColumns())
1799    {
1800  0 start = hidden.visibleToAbsoluteColumn(end);
1801  0 start = hidden.getNextHiddenBoundary(true, start) + 1;
1802    }
1803  0 } while (end < max);
1804   
1805    // int[][] startEnd = new int[regions.size()][2];
1806   
1807  0 return regions;
1808    }
1809   
 
1810  1 toggle @Override
1811    public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
1812    boolean selectedOnly)
1813    {
1814  1 ArrayList<AlignmentAnnotation> ala = new ArrayList<>();
1815  1 AlignmentAnnotation[] aa;
1816  ? if ((aa = alignment.getAlignmentAnnotation()) != null)
1817    {
1818  1 for (AlignmentAnnotation annot : aa)
1819    {
1820  4 AlignmentAnnotation clone = new AlignmentAnnotation(annot);
1821  4 if (selectedOnly && selectionGroup != null)
1822    {
1823  4 clone.makeVisibleAnnotation(
1824    selectionGroup.getStartRes(), selectionGroup.getEndRes(),
1825    alignment.getHiddenColumns());
1826    }
1827    else
1828    {
1829  0 clone.makeVisibleAnnotation(alignment.getHiddenColumns());
1830    }
1831  4 ala.add(clone);
1832    }
1833    }
1834  1 return ala;
1835    }
1836   
 
1837  871 toggle @Override
1838    public boolean isPadGaps()
1839    {
1840  871 return padGaps;
1841    }
1842   
 
1843  294 toggle @Override
1844    public void setPadGaps(boolean padGaps)
1845    {
1846  294 this.padGaps = padGaps;
1847    }
1848   
1849    /**
1850    * apply any post-edit constraints and trigger any calculations needed after
1851    * an edit has been performed on the alignment
1852    *
1853    * @param ap
1854    */
 
1855  208 toggle @Override
1856    public void alignmentChanged(AlignmentViewPanel ap)
1857    {
1858  208 if (isPadGaps())
1859    {
1860  0 alignment.padGaps();
1861    }
1862  208 if (autoCalculateConsensus)
1863    {
1864  208 updateConsensus(ap);
1865    }
1866  208 if (hconsensus != null && autoCalculateConsensus)
1867    {
1868  201 updateConservation(ap);
1869    }
1870  208 if (autoCalculateStrucConsensus)
1871    {
1872  208 updateStrucConsensus(ap);
1873    }
1874   
1875    // Reset endRes of groups if beyond alignment width
1876  208 int alWidth = alignment.getWidth();
1877  208 List<SequenceGroup> groups = alignment.getGroups();
1878  208 if (groups != null)
1879    {
1880  208 for (SequenceGroup sg : groups)
1881    {
1882  171 if (sg.getEndRes() > alWidth)
1883    {
1884  0 sg.setEndRes(alWidth - 1);
1885    }
1886    }
1887    }
1888   
1889  208 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
1890    {
1891  0 selectionGroup.setEndRes(alWidth - 1);
1892    }
1893   
1894  208 updateAllColourSchemes();
1895  208 calculator.restartWorkers();
1896    // alignment.adjustSequenceAnnotations();
1897    }
1898   
1899    /**
1900    * reset scope and do calculations for all applied colourschemes on alignment
1901    */
 
1902  208 toggle void updateAllColourSchemes()
1903    {
1904  208 ResidueShaderI rs = residueShading;
1905  208 if (rs != null)
1906    {
1907  208 rs.alignmentChanged(alignment, hiddenRepSequences);
1908   
1909  208 rs.setConsensus(hconsensus);
1910  208 if (rs.conservationApplied())
1911    {
1912  3 rs.setConservation(Conservation.calculateConservation("All",
1913    alignment.getSequences(), 0, alignment.getWidth(), false,
1914    getConsPercGaps(), false));
1915    }
1916    }
1917   
1918  208 for (SequenceGroup sg : alignment.getGroups())
1919    {
1920  171 if (sg.cs != null)
1921    {
1922  171 sg.cs.alignmentChanged(sg, hiddenRepSequences);
1923    }
1924  171 sg.recalcConservation();
1925    }
1926    }
1927   
 
1928  294 toggle protected void initAutoAnnotation()
1929    {
1930    // TODO: add menu option action that nulls or creates consensus object
1931    // depending on if the user wants to see the annotation or not in a
1932    // specific alignment
1933   
1934  294 if (hconsensus == null && !isDataset)
1935    {
1936  294 if (!alignment.isNucleotide())
1937    {
1938  248 initConservation();
1939  248 initQuality();
1940    }
1941    else
1942    {
1943  46 initRNAStructure();
1944    }
1945  294 consensus = new AlignmentAnnotation("Consensus",
1946    MessageManager.getString("label.consensus_descr"),
1947    new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
1948  294 initConsensus(consensus);
1949  294 initGapCounts();
1950   
1951  294 initComplementConsensus();
1952    }
1953    }
1954   
1955    /**
1956    * If this is a protein alignment and there are mappings to cDNA, adds the
1957    * cDNA consensus annotation and returns true, else returns false.
1958    */
 
1959  300 toggle public boolean initComplementConsensus()
1960    {
1961  300 if (!alignment.isNucleotide())
1962    {
1963  253 final List<AlignedCodonFrame> codonMappings = alignment
1964    .getCodonFrames();
1965  253 if (codonMappings != null && !codonMappings.isEmpty())
1966    {
1967  4 boolean doConsensus = false;
1968  4 for (AlignedCodonFrame mapping : codonMappings)
1969    {
1970    // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
1971  4 MapList[] mapLists = mapping.getdnaToProt();
1972    // mapLists can be empty if project load has not finished resolving
1973    // seqs
1974  4 if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
1975    {
1976  4 doConsensus = true;
1977  4 break;
1978    }
1979    }
1980  4 if (doConsensus)
1981    {
1982  4 complementConsensus = new AlignmentAnnotation("cDNA Consensus",
1983    MessageManager
1984    .getString("label.complement_consensus_descr"),
1985    new Annotation[1], 0f, 100f,
1986    AlignmentAnnotation.BAR_GRAPH);
1987  4 initConsensus(complementConsensus);
1988  4 return true;
1989    }
1990    }
1991    }
1992  296 return false;
1993    }
1994   
 
1995  298 toggle private void initConsensus(AlignmentAnnotation aa)
1996    {
1997  298 aa.hasText = true;
1998  298 aa.autoCalculated = true;
1999   
2000  298 if (showConsensus)
2001    {
2002  297 alignment.addAnnotation(aa);
2003    }
2004    }
2005   
2006    // these should be extracted from the view model - style and settings for
2007    // derived annotation
 
2008  294 toggle private void initGapCounts()
2009    {
2010  294 if (showOccupancy)
2011    {
2012  292 gapcounts = new AlignmentAnnotation("Occupancy",
2013    MessageManager.getString("label.occupancy_descr"),
2014    new Annotation[1], 0f, alignment.getHeight(),
2015    AlignmentAnnotation.BAR_GRAPH);
2016  292 gapcounts.hasText = true;
2017  292 gapcounts.autoCalculated = true;
2018  292 gapcounts.scaleColLabel = true;
2019  292 gapcounts.graph = AlignmentAnnotation.BAR_GRAPH;
2020   
2021  292 alignment.addAnnotation(gapcounts);
2022    }
2023    }
2024   
 
2025  248 toggle private void initConservation()
2026    {
2027  248 if (showConservation)
2028    {
2029  247 if (conservation == null)
2030    {
2031  247 conservation = new AlignmentAnnotation("Conservation",
2032    MessageManager.formatMessage("label.conservation_descr",
2033    getConsPercGaps()),
2034    new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
2035  247 conservation.hasText = true;
2036  247 conservation.autoCalculated = true;
2037  247 alignment.addAnnotation(conservation);
2038    }
2039    }
2040    }
2041   
 
2042  248 toggle private void initQuality()
2043    {
2044  248 if (showQuality)
2045    {
2046  248 if (quality == null)
2047    {
2048  248 quality = new AlignmentAnnotation("Quality",
2049    MessageManager.getString("label.quality_descr"),
2050    new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
2051  248 quality.hasText = true;
2052  248 quality.autoCalculated = true;
2053  248 alignment.addAnnotation(quality);
2054    }
2055    }
2056    }
2057   
 
2058  46 toggle private void initRNAStructure()
2059    {
2060  46 if (alignment.hasRNAStructure() && strucConsensus == null)
2061    {
2062  2 strucConsensus = new AlignmentAnnotation("StrucConsensus",
2063    MessageManager.getString("label.strucconsensus_descr"),
2064    new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
2065  2 strucConsensus.hasText = true;
2066  2 strucConsensus.autoCalculated = true;
2067   
2068  2 if (showConsensus)
2069    {
2070  2 alignment.addAnnotation(strucConsensus);
2071    }
2072    }
2073    }
2074   
2075    /*
2076    * (non-Javadoc)
2077    *
2078    * @see jalview.api.AlignViewportI#calcPanelHeight()
2079    */
 
2080  1745 toggle @Override
2081    public int calcPanelHeight()
2082    {
2083    // setHeight of panels
2084  1745 AlignmentAnnotation[] anns = getAlignment().getAlignmentAnnotation();
2085  1744 int height = 0;
2086  1745 int charHeight = getCharHeight();
2087  1745 if (anns != null)
2088    {
2089  1745 BitSet graphgrp = new BitSet();
2090  1744 for (AlignmentAnnotation aa : anns)
2091    {
2092  9362 if (aa == null)
2093    {
2094  0 System.err.println("Null annotation row: ignoring.");
2095  0 continue;
2096    }
2097  9362 if (!aa.visible)
2098    {
2099  1141 continue;
2100    }
2101  8221 if (aa.graphGroup > -1)
2102    {
2103  270 if (graphgrp.get(aa.graphGroup))
2104    {
2105  135 continue;
2106    }
2107    else
2108    {
2109  135 graphgrp.set(aa.graphGroup);
2110    }
2111    }
2112  8087 aa.height = 0;
2113   
2114  8085 if (aa.hasText)
2115    {
2116  7385 aa.height += charHeight;
2117    }
2118   
2119  8086 if (aa.hasIcons)
2120    {
2121  334 aa.height += 16;
2122    }
2123   
2124  8087 if (aa.graph > 0)
2125    {
2126  7453 aa.height += aa.graphHeight;
2127    }
2128   
2129  8086 if (aa.height == 0)
2130    {
2131  147 aa.height = 20;
2132    }
2133   
2134  8086 height += aa.height;
2135    }
2136    }
2137  1745 if (height == 0)
2138    {
2139    // set minimum
2140  0 height = 20;
2141    }
2142  1745 return height;
2143    }
2144   
 
2145  115 toggle @Override
2146    public void updateGroupAnnotationSettings(boolean applyGlobalSettings,
2147    boolean preserveNewGroupSettings)
2148    {
2149  115 boolean updateCalcs = false;
2150  115 boolean conv = isShowGroupConservation();
2151  115 boolean cons = isShowGroupConsensus();
2152  115 boolean showprf = isShowSequenceLogo();
2153  115 boolean showConsHist = isShowConsensusHistogram();
2154  115 boolean normLogo = isNormaliseSequenceLogo();
2155   
2156    /**
2157    * TODO reorder the annotation rows according to group/sequence ordering on
2158    * alignment
2159    */
2160    // boolean sortg = true;
2161   
2162    // remove old automatic annotation
2163    // add any new annotation
2164   
2165    // intersect alignment annotation with alignment groups
2166   
2167  115 AlignmentAnnotation[] aan = alignment.getAlignmentAnnotation();
2168  115 List<SequenceGroup> oldrfs = new ArrayList<>();
2169  115 if (aan != null)
2170    {
2171  928 for (int an = 0; an < aan.length; an++)
2172    {
2173  813 if (aan[an].autoCalculated && aan[an].groupRef != null)
2174    {
2175  0 oldrfs.add(aan[an].groupRef);
2176  0 alignment.deleteAnnotation(aan[an], false);
2177    }
2178    }
2179    }
2180  115 if (alignment.getGroups() != null)
2181    {
2182  115 for (SequenceGroup sg : alignment.getGroups())
2183    {
2184  52 updateCalcs = false;
2185  52 if (applyGlobalSettings
2186    || (!preserveNewGroupSettings && !oldrfs.contains(sg)))
2187    {
2188    // set defaults for this group's conservation/consensus
2189  9 sg.setshowSequenceLogo(showprf);
2190  9 sg.setShowConsensusHistogram(showConsHist);
2191  9 sg.setNormaliseSequenceLogo(normLogo);
2192    }
2193  52 if (conv)
2194    {
2195  0 updateCalcs = true;
2196  0 alignment.addAnnotation(sg.getConservationRow(), 0);
2197    }
2198  52 if (cons)
2199    {
2200  24 updateCalcs = true;
2201  24 alignment.addAnnotation(sg.getConsensus(), 0);
2202    }
2203    // refresh the annotation rows
2204  52 if (updateCalcs)
2205    {
2206  24 sg.recalcConservation();
2207    }
2208    }
2209    }
2210  115 oldrfs.clear();
2211    }
2212   
 
2213  11338 toggle @Override
2214    public boolean isDisplayReferenceSeq()
2215    {
2216  11338 return alignment.hasSeqrep() && viewStyle.isDisplayReferenceSeq();
2217    }
2218   
 
2219  10 toggle @Override
2220    public void setDisplayReferenceSeq(boolean displayReferenceSeq)
2221    {
2222  10 viewStyle.setDisplayReferenceSeq(displayReferenceSeq);
2223    }
2224   
 
2225  5 toggle @Override
2226    public boolean isColourByReferenceSeq()
2227    {
2228  5 return alignment.hasSeqrep() && viewStyle.isColourByReferenceSeq();
2229    }
2230   
 
2231  9189 toggle @Override
2232    public Color getSequenceColour(SequenceI seq)
2233    {
2234  9189 Color sqc = sequenceColours.get(seq);
2235  9189 return (sqc == null ? Color.white : sqc);
2236    }
2237   
 
2238  1051 toggle @Override
2239    public void setSequenceColour(SequenceI seq, Color col)
2240    {
2241  1051 if (col == null)
2242    {
2243  0 sequenceColours.remove(seq);
2244    }
2245    else
2246    {
2247  1051 sequenceColours.put(seq, col);
2248    }
2249    }
2250   
 
2251  4 toggle @Override
2252    public void updateSequenceIdColours()
2253    {
2254  4 for (SequenceGroup sg : alignment.getGroups())
2255    {
2256  5 if (sg.idColour != null)
2257    {
2258  0 for (SequenceI s : sg.getSequences(getHiddenRepSequences()))
2259    {
2260  0 sequenceColours.put(s, sg.idColour);
2261    }
2262    }
2263    }
2264    }
2265   
 
2266  0 toggle @Override
2267    public void clearSequenceColours()
2268    {
2269  0 sequenceColours.clear();
2270    }
2271   
 
2272  780 toggle @Override
2273    public AlignViewportI getCodingComplement()
2274    {
2275  780 return this.codingComplement;
2276    }
2277   
2278    /**
2279    * Set this as the (cDna/protein) complement of the given viewport. Also
2280    * ensures the reverse relationship is set on the given viewport.
2281    */
 
2282  6 toggle @Override
2283    public void setCodingComplement(AlignViewportI av)
2284    {
2285  6 if (this == av)
2286    {
2287  0 System.err.println("Ignoring recursive setCodingComplement request");
2288    }
2289    else
2290    {
2291  6 this.codingComplement = av;
2292    // avoid infinite recursion!
2293  6 if (av.getCodingComplement() != this)
2294    {
2295  3 av.setCodingComplement(this);
2296    }
2297    }
2298    }
2299   
 
2300  22 toggle @Override
2301    public boolean isNucleotide()
2302    {
2303  22 return getAlignment() == null ? false : getAlignment().isNucleotide();
2304    }
2305   
 
2306  61297 toggle @Override
2307    public FeaturesDisplayedI getFeaturesDisplayed()
2308    {
2309  61297 return featuresDisplayed;
2310    }
2311   
 
2312  78 toggle @Override
2313    public void setFeaturesDisplayed(FeaturesDisplayedI featuresDisplayedI)
2314    {
2315  78 featuresDisplayed = featuresDisplayedI;
2316    }
2317   
 
2318  83 toggle @Override
2319    public boolean areFeaturesDisplayed()
2320    {
2321  83 return featuresDisplayed != null
2322    && featuresDisplayed.getRegisteredFeaturesCount() > 0;
2323    }
2324   
2325    /**
2326    * set the flag
2327    *
2328    * @param b
2329    * features are displayed if true
2330    */
 
2331  117 toggle @Override
2332    public void setShowSequenceFeatures(boolean b)
2333    {
2334  117 viewStyle.setShowSequenceFeatures(b);
2335    }
2336   
 
2337  11372 toggle @Override
2338    public boolean isShowSequenceFeatures()
2339    {
2340  11372 return viewStyle.isShowSequenceFeatures();
2341    }
2342   
 
2343  0 toggle @Override
2344    public void setShowSequenceFeaturesHeight(boolean selected)
2345    {
2346  0 viewStyle.setShowSequenceFeaturesHeight(selected);
2347    }
2348   
 
2349  0 toggle @Override
2350    public boolean isShowSequenceFeaturesHeight()
2351    {
2352  0 return viewStyle.isShowSequenceFeaturesHeight();
2353    }
2354   
 
2355  437 toggle @Override
2356    public void setShowAnnotation(boolean b)
2357    {
2358  437 viewStyle.setShowAnnotation(b);
2359    }
2360   
 
2361  2363 toggle @Override
2362    public boolean isShowAnnotation()
2363    {
2364  2363 return viewStyle.isShowAnnotation();
2365    }
2366   
 
2367  8578 toggle @Override
2368    public boolean isRightAlignIds()
2369    {
2370  8578 return viewStyle.isRightAlignIds();
2371    }
2372   
 
2373  364 toggle @Override
2374    public void setRightAlignIds(boolean rightAlignIds)
2375    {
2376  364 viewStyle.setRightAlignIds(rightAlignIds);
2377    }
2378   
 
2379  702 toggle @Override
2380    public boolean getConservationSelected()
2381    {
2382  702 return viewStyle.getConservationSelected();
2383    }
2384   
 
2385  70 toggle @Override
2386    public void setShowBoxes(boolean state)
2387    {
2388  70 viewStyle.setShowBoxes(state);
2389    }
2390   
2391    /**
2392    * @return
2393    * @see jalview.api.ViewStyleI#getTextColour()
2394    */
 
2395  447696 toggle @Override
2396    public Color getTextColour()
2397    {
2398  447696 return viewStyle.getTextColour();
2399    }
2400   
2401    /**
2402    * @return
2403    * @see jalview.api.ViewStyleI#getTextColour2()
2404    */
 
2405  29 toggle @Override
2406    public Color getTextColour2()
2407    {
2408  29 return viewStyle.getTextColour2();
2409    }
2410   
2411    /**
2412    * @return
2413    * @see jalview.api.ViewStyleI#getThresholdTextColour()
2414    */
 
2415  264375 toggle @Override
2416    public int getThresholdTextColour()
2417    {
2418  264375 return viewStyle.getThresholdTextColour();
2419    }
2420   
2421    /**
2422    * @return
2423    * @see jalview.api.ViewStyleI#isConservationColourSelected()
2424    */
 
2425  0 toggle @Override
2426    public boolean isConservationColourSelected()
2427    {
2428  0 return viewStyle.isConservationColourSelected();
2429    }
2430   
2431    /**
2432    * @return
2433    * @see jalview.api.ViewStyleI#isRenderGaps()
2434    */
 
2435  1428 toggle @Override
2436    public boolean isRenderGaps()
2437    {
2438  1428 return viewStyle.isRenderGaps();
2439    }
2440   
2441    /**
2442    * @return
2443    * @see jalview.api.ViewStyleI#isShowColourText()
2444    */
 
2445  421 toggle @Override
2446    public boolean isShowColourText()
2447    {
2448  421 return viewStyle.isShowColourText();
2449    }
2450   
2451    /**
2452    * @param conservationColourSelected
2453    * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean)
2454    */
 
2455  0 toggle @Override
2456    public void setConservationColourSelected(
2457    boolean conservationColourSelected)
2458    {
2459  0 viewStyle.setConservationColourSelected(conservationColourSelected);
2460    }
2461   
2462    /**
2463    * @param showColourText
2464    * @see jalview.api.ViewStyleI#setShowColourText(boolean)
2465    */
 
2466  0 toggle @Override
2467    public void setShowColourText(boolean showColourText)
2468    {
2469  0 viewStyle.setShowColourText(showColourText);
2470    }
2471   
2472    /**
2473    * @param textColour
2474    * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color)
2475    */
 
2476  70 toggle @Override
2477    public void setTextColour(Color textColour)
2478    {
2479  70 viewStyle.setTextColour(textColour);
2480    }
2481   
2482    /**
2483    * @param thresholdTextColour
2484    * @see jalview.api.ViewStyleI#setThresholdTextColour(int)
2485    */
 
2486  70 toggle @Override
2487    public void setThresholdTextColour(int thresholdTextColour)
2488    {
2489  70 viewStyle.setThresholdTextColour(thresholdTextColour);
2490    }
2491   
2492    /**
2493    * @param textColour2
2494    * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color)
2495    */
 
2496  70 toggle @Override
2497    public void setTextColour2(Color textColour2)
2498    {
2499  70 viewStyle.setTextColour2(textColour2);
2500    }
2501   
 
2502  111 toggle @Override
2503    public ViewStyleI getViewStyle()
2504    {
2505  111 return new ViewStyle(viewStyle);
2506    }
2507   
 
2508  71 toggle @Override
2509    public void setViewStyle(ViewStyleI settingsForView)
2510    {
2511  71 viewStyle = new ViewStyle(settingsForView);
2512  71 if (residueShading != null)
2513    {
2514  71 residueShading.setConservationApplied(
2515    settingsForView.isConservationColourSelected());
2516    }
2517    }
2518   
 
2519  0 toggle @Override
2520    public boolean sameStyle(ViewStyleI them)
2521    {
2522  0 return viewStyle.sameStyle(them);
2523    }
2524   
2525    /**
2526    * @return
2527    * @see jalview.api.ViewStyleI#getIdWidth()
2528    */
 
2529  1653 toggle @Override
2530    public int getIdWidth()
2531    {
2532  1653 return viewStyle.getIdWidth();
2533    }
2534   
2535    /**
2536    * @param i
2537    * @see jalview.api.ViewStyleI#setIdWidth(int)
2538    */
 
2539  247 toggle @Override
2540    public void setIdWidth(int i)
2541    {
2542  247 viewStyle.setIdWidth(i);
2543    }
2544   
2545    /**
2546    * @return
2547    * @see jalview.api.ViewStyleI#isCentreColumnLabels()
2548    */
 
2549  421 toggle @Override
2550    public boolean isCentreColumnLabels()
2551    {
2552  421 return viewStyle.isCentreColumnLabels();
2553    }
2554   
2555    /**
2556    * @param centreColumnLabels
2557    * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean)
2558    */
 
2559  364 toggle @Override
2560    public void setCentreColumnLabels(boolean centreColumnLabels)
2561    {
2562  364 viewStyle.setCentreColumnLabels(centreColumnLabels);
2563    }
2564   
2565    /**
2566    * @param showdbrefs
2567    * @see jalview.api.ViewStyleI#setShowDBRefs(boolean)
2568    */
 
2569  364 toggle @Override
2570    public void setShowDBRefs(boolean showdbrefs)
2571    {
2572  364 viewStyle.setShowDBRefs(showdbrefs);
2573    }
2574   
2575    /**
2576    * @return
2577    * @see jalview.api.ViewStyleI#isShowDBRefs()
2578    */
 
2579  450 toggle @Override
2580    public boolean isShowDBRefs()
2581    {
2582  450 return viewStyle.isShowDBRefs();
2583    }
2584   
2585    /**
2586    * @return
2587    * @see jalview.api.ViewStyleI#isShowNPFeats()
2588    */
 
2589  450 toggle @Override
2590    public boolean isShowNPFeats()
2591    {
2592  450 return viewStyle.isShowNPFeats();
2593    }
2594   
2595    /**
2596    * @param shownpfeats
2597    * @see jalview.api.ViewStyleI#setShowNPFeats(boolean)
2598    */
 
2599  364 toggle @Override
2600    public void setShowNPFeats(boolean shownpfeats)
2601    {
2602  364 viewStyle.setShowNPFeats(shownpfeats);
2603    }
2604   
2605    public abstract StructureSelectionManager getStructureSelectionManager();
2606   
2607    /**
2608    * Add one command to the command history list.
2609    *
2610    * @param command
2611    */
 
2612  0 toggle public void addToHistoryList(CommandI command)
2613    {
2614  0 if (this.historyList != null)
2615    {
2616  0 this.historyList.push(command);
2617  0 broadcastCommand(command, false);
2618    }
2619    }
2620   
 
2621  0 toggle protected void broadcastCommand(CommandI command, boolean undo)
2622    {
2623  0 getStructureSelectionManager().commandPerformed(command, undo,
2624    getVamsasSource());
2625    }
2626   
2627    /**
2628    * Add one command to the command redo list.
2629    *
2630    * @param command
2631    */
 
2632  0 toggle public void addToRedoList(CommandI command)
2633    {
2634  0 if (this.redoList != null)
2635    {
2636  0 this.redoList.push(command);
2637    }
2638  0 broadcastCommand(command, true);
2639    }
2640   
2641    /**
2642    * Clear the command redo list.
2643    */
 
2644  0 toggle public void clearRedoList()
2645    {
2646  0 if (this.redoList != null)
2647    {
2648  0 this.redoList.clear();
2649    }
2650    }
2651   
 
2652  47 toggle public void setHistoryList(Deque<CommandI> list)
2653    {
2654  47 this.historyList = list;
2655    }
2656   
 
2657  676 toggle public Deque<CommandI> getHistoryList()
2658    {
2659  676 return this.historyList;
2660    }
2661   
 
2662  47 toggle public void setRedoList(Deque<CommandI> list)
2663    {
2664  47 this.redoList = list;
2665    }
2666   
 
2667  676 toggle public Deque<CommandI> getRedoList()
2668    {
2669  676 return this.redoList;
2670    }
2671   
 
2672  0 toggle @Override
2673    public VamsasSource getVamsasSource()
2674    {
2675  0 return this;
2676    }
2677   
 
2678  1788 toggle public SequenceAnnotationOrder getSortAnnotationsBy()
2679    {
2680  1788 return sortAnnotationsBy;
2681    }
2682   
 
2683  0 toggle public void setSortAnnotationsBy(
2684    SequenceAnnotationOrder sortAnnotationsBy)
2685    {
2686  0 this.sortAnnotationsBy = sortAnnotationsBy;
2687    }
2688   
 
2689  1788 toggle public boolean isShowAutocalculatedAbove()
2690    {
2691  1788 return showAutocalculatedAbove;
2692    }
2693   
 
2694  241 toggle public void setShowAutocalculatedAbove(boolean showAutocalculatedAbove)
2695    {
2696  241 this.showAutocalculatedAbove = showAutocalculatedAbove;
2697    }
2698   
 
2699  3 toggle @Override
2700    public boolean isScaleProteinAsCdna()
2701    {
2702  3 return viewStyle.isScaleProteinAsCdna();
2703    }
2704   
 
2705  0 toggle @Override
2706    public void setScaleProteinAsCdna(boolean b)
2707    {
2708  0 viewStyle.setScaleProteinAsCdna(b);
2709    }
2710   
 
2711  0 toggle @Override
2712    public boolean isProteinFontAsCdna()
2713    {
2714  0 return viewStyle.isProteinFontAsCdna();
2715    }
2716   
 
2717  0 toggle @Override
2718    public void setProteinFontAsCdna(boolean b)
2719    {
2720  0 viewStyle.setProteinFontAsCdna(b);
2721    }
2722   
 
2723  70 toggle @Override
2724    public void setShowComplementFeatures(boolean b)
2725    {
2726  70 viewStyle.setShowComplementFeatures(b);
2727    }
2728   
 
2729  5165 toggle @Override
2730    public boolean isShowComplementFeatures()
2731    {
2732  5165 return viewStyle.isShowComplementFeatures();
2733    }
2734   
 
2735  70 toggle @Override
2736    public void setShowComplementFeaturesOnTop(boolean b)
2737    {
2738  70 viewStyle.setShowComplementFeaturesOnTop(b);
2739    }
2740   
 
2741  30 toggle @Override
2742    public boolean isShowComplementFeaturesOnTop()
2743    {
2744  30 return viewStyle.isShowComplementFeaturesOnTop();
2745    }
2746   
2747    /**
2748    * @return true if view should scroll to show the highlighted region of a
2749    * sequence
2750    * @return
2751    */
 
2752  35 toggle @Override
2753    public final boolean isFollowHighlight()
2754    {
2755  35 return followHighlight;
2756    }
2757   
 
2758  70 toggle @Override
2759    public final void setFollowHighlight(boolean b)
2760    {
2761  70 this.followHighlight = b;
2762    }
2763   
 
2764  11364 toggle @Override
2765    public ViewportRanges getRanges()
2766    {
2767  11364 return ranges;
2768    }
2769   
2770    /**
2771    * Helper method to populate the SearchResults with the location in the
2772    * complementary alignment to scroll to, in order to match this one.
2773    *
2774    * @param sr
2775    * the SearchResults to add to
2776    * @return the offset (below top of visible region) of the matched sequence
2777    */
 
2778  402 toggle protected int findComplementScrollTarget(SearchResultsI sr)
2779    {
2780  402 final AlignViewportI complement = getCodingComplement();
2781  402 if (complement == null || !complement.isFollowHighlight())
2782    {
2783  398 return 0;
2784    }
2785  4 boolean iAmProtein = !getAlignment().isNucleotide();
2786  4 AlignmentI proteinAlignment = iAmProtein ? getAlignment()
2787    : complement.getAlignment();
2788  4 if (proteinAlignment == null)
2789    {
2790  0 return 0;
2791    }
2792  4 final List<AlignedCodonFrame> mappings = proteinAlignment
2793    .getCodonFrames();
2794   
2795    /*
2796    * Heuristic: find the first mapped sequence (if any) with a non-gapped
2797    * residue in the middle column of the visible region. Scroll the
2798    * complementary alignment to line up the corresponding residue.
2799    */
2800  4 int seqOffset = 0;
2801  4 SequenceI sequence = null;
2802   
2803    /*
2804    * locate 'middle' column (true middle if an odd number visible, left of
2805    * middle if an even number visible)
2806    */
2807  4 int middleColumn = ranges.getStartRes()
2808    + (ranges.getEndRes() - ranges.getStartRes()) / 2;
2809  4 final HiddenSequences hiddenSequences = getAlignment()
2810    .getHiddenSequences();
2811   
2812    /*
2813    * searching to the bottom of the alignment gives smoother scrolling across
2814    * all gapped visible regions
2815    */
2816  4 int lastSeq = alignment.getHeight() - 1;
2817  4 List<AlignedCodonFrame> seqMappings = null;
2818  4 for (int seqNo = ranges
2819  6 .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
2820    {
2821  6 sequence = getAlignment().getSequenceAt(seqNo);
2822  6 if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
2823    {
2824  0 continue;
2825    }
2826  6 if (Comparison.isGap(sequence.getCharAt(middleColumn)))
2827    {
2828  2 continue;
2829    }
2830  4 seqMappings = MappingUtils.findMappingsForSequenceAndOthers(sequence,
2831    mappings,
2832    getCodingComplement().getAlignment().getSequences());
2833  4 if (!seqMappings.isEmpty())
2834    {
2835  4 break;
2836    }
2837    }
2838   
2839  4 if (sequence == null || seqMappings == null || seqMappings.isEmpty())
2840    {
2841    /*
2842    * No ungapped mapped sequence in middle column - do nothing
2843    */
2844  0 return 0;
2845    }
2846  4 MappingUtils.addSearchResults(sr, sequence,
2847    sequence.findPosition(middleColumn), seqMappings);
2848  4 return seqOffset;
2849    }
2850   
2851    /**
2852    * synthesize a column selection if none exists so it covers the given
2853    * selection group. if wholewidth is false, no column selection is made if the
2854    * selection group covers the whole alignment width.
2855    *
2856    * @param sg
2857    * @param wholewidth
2858    */
 
2859  0 toggle public void expandColSelection(SequenceGroup sg, boolean wholewidth)
2860    {
2861  0 int sgs, sge;
2862  0 if (sg != null && (sgs = sg.getStartRes()) >= 0
2863    && sg.getStartRes() <= (sge = sg.getEndRes())
2864    && !this.hasSelectedColumns())
2865    {
2866  0 if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
2867    {
2868    // do nothing
2869  0 return;
2870    }
2871  0 if (colSel == null)
2872    {
2873  0 colSel = new ColumnSelection();
2874    }
2875  0 for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
2876    {
2877  0 colSel.addElement(cspos);
2878    }
2879    }
2880    }
2881   
2882    /**
2883    * hold status of current selection group - defined on alignment or not.
2884    */
2885    private boolean selectionIsDefinedGroup = false;
2886   
 
2887  0 toggle @Override
2888    public boolean isSelectionDefinedGroup()
2889    {
2890  0 if (selectionGroup == null)
2891    {
2892  0 return false;
2893    }
2894  0 if (isSelectionGroupChanged(true))
2895    {
2896  0 selectionIsDefinedGroup = false;
2897  0 List<SequenceGroup> gps = alignment.getGroups();
2898  0 if (gps == null || gps.size() == 0)
2899    {
2900  0 selectionIsDefinedGroup = false;
2901    }
2902    else
2903    {
2904  0 selectionIsDefinedGroup = gps.contains(selectionGroup);
2905    }
2906    }
2907  0 return selectionGroup.isDefined() || selectionIsDefinedGroup;
2908    }
2909   
2910    /**
2911    * null, or currently highlighted results on this view
2912    */
2913    private SearchResultsI searchResults = null;
2914   
2915    protected TreeModel currentTree = null;
2916   
 
2917  7829 toggle @Override
2918    public boolean hasSearchResults()
2919    {
2920  7829 return searchResults != null;
2921    }
2922   
 
2923  8 toggle @Override
2924    public void setSearchResults(SearchResultsI results)
2925    {
2926  8 searchResults = results;
2927    }
2928   
 
2929  20 toggle @Override
2930    public SearchResultsI getSearchResults()
2931    {
2932  20 return searchResults;
2933    }
2934   
2935    /**
2936    * get the consensus sequence as displayed under the PID consensus annotation
2937    * row.
2938    *
2939    * @return consensus sequence as a new sequence object
2940    */
 
2941  1 toggle public SequenceI getConsensusSeq()
2942    {
2943  1 if (consensus == null)
2944    {
2945  0 updateConsensus(null);
2946    }
2947  1 if (consensus == null)
2948    {
2949  0 return null;
2950    }
2951  1 StringBuffer seqs = new StringBuffer();
2952  4 for (int i = 0; i < consensus.annotations.length; i++)
2953    {
2954  3 Annotation annotation = consensus.annotations[i];
2955  3 if (annotation != null)
2956    {
2957  3 String description = annotation.description;
2958  3 if (description != null && description.startsWith("["))
2959    {
2960    // consensus is a tie - just pick the first one
2961  1 seqs.append(description.charAt(1));
2962    }
2963    else
2964    {
2965  2 seqs.append(annotation.displayCharacter);
2966    }
2967    }
2968    }
2969   
2970  1 SequenceI sq = new Sequence("Consensus", seqs.toString());
2971  1 sq.setDescription("Percentage Identity Consensus "
2972  1 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
2973  1 return sq;
2974    }
2975   
 
2976  18 toggle @Override
2977    public void setCurrentTree(TreeModel tree)
2978    {
2979  18 currentTree = tree;
2980    }
2981   
 
2982  31 toggle @Override
2983    public TreeModel getCurrentTree()
2984    {
2985  31 return currentTree;
2986    }
2987   
 
2988  44 toggle @Override
2989    public AlignmentExportData getAlignExportData(AlignExportSettingsI options)
2990    {
2991  44 AlignmentI alignmentToExport = null;
2992  44 String[] omitHidden = null;
2993  44 alignmentToExport = null;
2994   
2995  44 if (hasHiddenColumns() && !options.isExportHiddenColumns())
2996    {
2997  0 omitHidden = getViewAsString(false,
2998    options.isExportHiddenSequences());
2999    }
3000   
3001  44 int[] alignmentStartEnd = new int[2];
3002  44 if (hasHiddenRows() && options.isExportHiddenSequences())
3003    {
3004  0 alignmentToExport = getAlignment().getHiddenSequences()
3005    .getFullAlignment();
3006    }
3007    else
3008    {
3009  44 alignmentToExport = getAlignment();
3010    }
3011  44 alignmentStartEnd = getAlignment().getHiddenColumns()
3012    .getVisibleStartAndEndIndex(alignmentToExport.getWidth());
3013  44 AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
3014    omitHidden, alignmentStartEnd);
3015  44 return ed;
3016    }
3017   
3018    /**
3019    * flag set to indicate if structure views might be out of sync with sequences
3020    * in the alignment
3021    */
3022   
3023    private boolean needToUpdateStructureViews = false;
3024   
 
3025  0 toggle @Override
3026    public boolean isUpdateStructures()
3027    {
3028  0 return needToUpdateStructureViews;
3029    }
3030   
 
3031  0 toggle @Override
3032    public void setUpdateStructures(boolean update)
3033    {
3034  0 needToUpdateStructureViews = update;
3035    }
3036   
 
3037  462 toggle @Override
3038    public boolean needToUpdateStructureViews()
3039    {
3040  462 boolean update = needToUpdateStructureViews;
3041  462 needToUpdateStructureViews = false;
3042  462 return update;
3043    }
3044   
 
3045  0 toggle @Override
3046    public void addSequenceGroup(SequenceGroup sequenceGroup)
3047    {
3048  0 alignment.addGroup(sequenceGroup);
3049   
3050  0 Color col = sequenceGroup.idColour;
3051  0 if (col != null)
3052    {
3053  0 col = col.brighter();
3054   
3055  0 for (SequenceI sq : sequenceGroup.getSequences())
3056    {
3057  0 setSequenceColour(sq, col);
3058    }
3059    }
3060   
3061  0 if (codingComplement != null)
3062    {
3063  0 SequenceGroup mappedGroup = MappingUtils
3064    .mapSequenceGroup(sequenceGroup, this, codingComplement);
3065  0 if (mappedGroup.getSequences().size() > 0)
3066    {
3067  0 codingComplement.getAlignment().addGroup(mappedGroup);
3068   
3069  0 if (col != null)
3070    {
3071  0 for (SequenceI seq : mappedGroup.getSequences())
3072    {
3073  0 codingComplement.setSequenceColour(seq, col);
3074    }
3075    }
3076    }
3077    // propagate the structure view update flag according to our own setting
3078  0 codingComplement.setUpdateStructures(needToUpdateStructureViews);
3079    }
3080    }
3081    }