Clover icon

Coverage Report

  1. Project Clover database Mon Nov 11 2024 20:42:03 GMT
  2. Package jalview.viewmodel

File AlignmentViewport.java

 

Coverage histogram

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

Code metrics

338
774
252
1
3,444
2,344
469
0.61
3.07
252
1.86

Classes

Class Line # Actions
AlignmentViewport 91 774 469
0.7565982375.7%
 

Contributing tests

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