Clover icon

Coverage Report

  1. Project Clover database Fri Dec 6 2024 13:47:14 GMT
  2. Package jalview.viewmodel

File AlignmentViewport.java

 

Coverage histogram

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

Code metrics

346
790
258
1
3,508
2,399
479
0.61
3.06
258
1.86

Classes

Class Line # Actions
AlignmentViewport 91 790 479
0.7460545374.6%
 

Contributing tests

This file is covered by 287 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  3187 toggle @Override
211    public boolean isSeqNameItalics()
212    {
213  3187 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  6725 toggle public boolean isShowStructureProvider()
268    {
269  6725 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  7090 toggle @Override
337    public boolean getShowHiddenMarkers()
338    {
339  7090 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  1308 toggle @Override
377    public boolean getScaleLeftWrapped()
378    {
379  1308 return viewStyle.getScaleLeftWrapped();
380    }
381   
382    /**
383    * @return
384    * @see jalview.api.ViewStyleI#getScaleAboveWrapped()
385    */
 
386  913 toggle @Override
387    public boolean getScaleAboveWrapped()
388    {
389  913 return viewStyle.getScaleAboveWrapped();
390    }
391   
392    /**
393    * @return
394    * @see jalview.api.ViewStyleI#getScaleRightWrapped()
395    */
 
396  2122 toggle @Override
397    public boolean getScaleRightWrapped()
398    {
399  2122 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  48843 toggle @Override
443    public boolean getShowJVSuffix()
444    {
445  48843 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  432784 toggle @Override
494    public boolean getColourText()
495    {
496  432784 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  30632 toggle @Override
514    public boolean getWrapAlignment()
515    {
516  30632 return viewStyle.getWrapAlignment();
517    }
518   
519    /**
520    * @return
521    * @see jalview.api.ViewStyleI#getShowText()
522    */
 
523  433456 toggle @Override
524    public boolean getShowText()
525    {
526  433456 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  842 toggle @Override
544    public void setWrappedWidth(int w)
545    {
546  842 viewStyle.setWrappedWidth(w);
547    }
548   
549    /**
550    * @return
551    * @see jalview.api.ViewStyleI#getCharHeight()
552    */
 
553  115242 toggle @Override
554    public int getCharHeight()
555    {
556  115243 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  1521110 toggle @Override
574    public int getCharWidth()
575    {
576  1521110 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  471267 toggle @Override
594    public boolean getShowBoxes()
595    {
596  471269 return viewStyle.getShowBoxes();
597    }
598   
599    /**
600    * @return
601    * @see jalview.api.ViewStyleI#getShowUnconserved()
602    */
 
603  430966 toggle @Override
604    public boolean getShowUnconserved()
605    {
606  430966 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  208173 toggle @Override
630    public AlignmentI getAlignment()
631    {
632  208173 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  475538 toggle @Override
739    public ResidueShaderI getResidueShading()
740    {
741  475537 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  1016 toggle @Override
786    public void setConservation(Conservation cons)
787    {
788  1016 hconservation = cons;
789    }
790   
 
791  1469 toggle @Override
792    public List<String> getSecondaryStructureSources()
793    {
794  1469 return viewStyle.getSecondaryStructureSources();
795    }
796   
 
797  961 toggle @Override
798    public void setSecondaryStructureSources(
799    List<String> secondaryStructureSources)
800    {
801  961 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  1866 toggle @Override
826    public int getConsPercGaps()
827    {
828  1866 return ConsPercGaps;
829    }
830   
 
831  955 toggle @Override
832    public void setSequenceConsensusHash(ProfilesI hconsensus)
833    {
834  955 this.hconsensus = hconsensus;
835    }
836   
 
837  961 toggle @Override
838    public void setSequenceSSConsensusHash(
839    Map<String, ProfilesI> hSSConsensusProfileMap)
840    {
841  961 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  3430 toggle @Override
852    public ProfilesI getSequenceConsensusHash()
853    {
854  3430 return hconsensus;
855    }
856   
 
857  3436 toggle @Override
858    public Map<String, ProfilesI> getSequenceSSConsensusHash()
859    {
860  3436 return hSSConsensusProfileMap;
861    }
862   
 
863  2378 toggle @Override
864    public Hashtable<String, Object>[] getComplementConsensusHash()
865    {
866  2378 return hcomplementConsensus;
867    }
868   
 
869  2378 toggle @Override
870    public Hashtable<String, Object>[] getRnaStructureConsensusHash()
871    {
872  2378 return hStrucConsensus;
873    }
874   
 
875  4 toggle @Override
876    public void setRnaStructureConsensusHash(
877    Hashtable<String, Object>[] hStrucConsensus)
878    {
879  4 this.hStrucConsensus = hStrucConsensus;
880   
881    }
882   
 
883  1457 toggle @Override
884    public AlignmentAnnotation getAlignmentQualityAnnot()
885    {
886  1457 return quality;
887    }
888   
 
889  2340 toggle @Override
890    public AlignmentAnnotation getAlignmentConservationAnnotation()
891    {
892  2340 return conservation;
893    }
894   
 
895  5661 toggle @Override
896    public AlignmentAnnotation getAlignmentConsensusAnnotation()
897    {
898  5661 return consensus;
899    }
900   
 
901  5323 toggle @Override
902    public List<AlignmentAnnotation> getAlignmentSecondaryStructureConsensusAnnotation()
903    {
904  5323 return secondaryStructureConsensus;
905    }
906   
 
907  5841 toggle @Override
908    public AlignmentAnnotation getAlignmentGapAnnotation()
909    {
910  5841 return gapcounts;
911    }
912   
 
913  2386 toggle @Override
914    public AlignmentAnnotation getComplementConsensusAnnotation()
915    {
916  2386 return complementConsensus;
917    }
918   
 
919  2378 toggle @Override
920    public AlignmentAnnotation getAlignmentStrucConsensusAnnotation()
921    {
922  2378 return strucConsensus;
923    }
924   
925    protected AlignCalcManagerI calculator = new AlignCalcManager();
926   
927    /**
928    * trigger update of conservation annotation
929    */
 
930  1000 toggle public void updateConservation(final AlignmentViewPanel ap)
931    {
932    // see note in mantis : issue number 8585
933  1000 if (alignment.isNucleotide()
934    || (conservation == null && quality == null)
935    || !autoCalculateConsensus)
936    {
937  216 return;
938    }
939  784 if (calculator.getRegisteredWorkersOfClass(
940    jalview.workers.ConservationThread.class) == null)
941    {
942  448 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  73 for (String source : ssSources)
1014    {
1015  85 boolean ssConsensusForSourcePresent = false;
1016  85 for (AlignmentAnnotation aa : secondaryStructureConsensus)
1017    {
1018  24 if (aa.description.startsWith(source))
1019    {
1020  12 ssConsensusForSourcePresent = true;
1021  12 break;
1022    }
1023    }
1024   
1025  85 if (!ssConsensusForSourcePresent)
1026    {
1027  73 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  73 ssConsensus.hasText = true;
1037  73 ssConsensus.autoCalculated = true;
1038  73 secondaryStructureConsensus.add(ssConsensus);
1039  73 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  458 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  2735 toggle public boolean isCalcInProgress()
1081    {
1082  2735 return calculator.isWorking();
1083    }
1084   
 
1085  9353 toggle @Override
1086    public boolean isCalculationInProgress(
1087    AlignmentAnnotation alignmentAnnotation)
1088    {
1089  9353 if (!alignmentAnnotation.autoCalculated)
1090    {
1091  0 return false;
1092    }
1093  9353 if (calculator.workingInvolvedWith(alignmentAnnotation))
1094    {
1095    // jalview.bin.Console.errPrintln("grey out
1096    // ("+alignmentAnnotation.label+")");
1097  386 return true;
1098    }
1099  8967 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  3974 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  3974 return alignment == null;
1145    }
1146   
 
1147  1477 toggle @Override
1148    public AlignCalcManagerI getCalcManager()
1149    {
1150  1477 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  5125 toggle @Override
1184    public boolean isShowSequenceLogo()
1185    {
1186  5125 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  3222 toggle @Override
1280    public boolean isShowConsensusHistogram()
1281    {
1282  3222 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  26658 toggle @Override
1301    public SequenceGroup getSelectionGroup()
1302    {
1303  26658 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  4870 toggle @Override
1330    public ColumnSelection getColumnSelection()
1331    {
1332  4870 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  8768 toggle @Override
1371    public boolean hasHiddenColumns()
1372    {
1373  8768 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  4844 toggle @Override
1385    public boolean hasHiddenRows()
1386    {
1387  4844 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  4537 toggle @Override
1403    public String getSequenceSetId()
1404    {
1405  4537 if (sequenceSetID == null)
1406    {
1407  364 sequenceSetID = alignment.hashCode() + "";
1408    }
1409   
1410  4537 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  4346 toggle @Override
1494    public boolean isIgnoreGapsConsensus()
1495    {
1496  4346 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    private Map<AlignmentAnnotation, Color> annotationColours = new HashMap<>();
1517   
1518    protected SequenceAnnotationOrder sortAnnotationsBy = null;
1519   
1520    protected boolean showAutocalculatedAbove;
1521   
1522    /**
1523    * when set, view will scroll to show the highlighted position
1524    */
1525    private boolean followHighlight = true;
1526   
1527    /**
1528    * Property change listener for changes in alignment
1529    *
1530    * @param listener
1531    * DOCUMENT ME!
1532    */
 
1533  492 toggle public void addPropertyChangeListener(
1534    java.beans.PropertyChangeListener listener)
1535    {
1536  492 changeSupport.addPropertyChangeListener(listener);
1537    }
1538   
1539    /**
1540    * DOCUMENT ME!
1541    *
1542    * @param listener
1543    * DOCUMENT ME!
1544    */
 
1545  265 toggle public void removePropertyChangeListener(
1546    java.beans.PropertyChangeListener listener)
1547    {
1548  265 if (changeSupport != null)
1549    {
1550  264 changeSupport.removePropertyChangeListener(listener);
1551    }
1552    }
1553   
1554    /**
1555    * Property change listener for changes in alignment
1556    *
1557    * @param prop
1558    * DOCUMENT ME!
1559    * @param oldvalue
1560    * DOCUMENT ME!
1561    * @param newvalue
1562    * DOCUMENT ME!
1563    */
 
1564  78 toggle public void firePropertyChange(String prop, Object oldvalue,
1565    Object newvalue)
1566    {
1567  78 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1568    }
1569   
 
1570  0 toggle @Override
1571    public void notifyAlignmentChanged()
1572    {
1573  0 firePropertyChange("alignment", null, alignment);
1574    }
1575   
1576    // common hide/show column stuff
1577   
 
1578  6 toggle public void hideSelectedColumns()
1579    {
1580  6 if (colSel.isEmpty())
1581    {
1582  2 return;
1583    }
1584   
1585  4 colSel.hideSelectedColumns(alignment);
1586  4 setSelectionGroup(null);
1587  4 isColSelChanged(true);
1588    }
1589   
 
1590  71 toggle public void hideColumns(int start, int end)
1591    {
1592  71 if (start == end)
1593    {
1594  2 colSel.hideSelectedColumns(start, alignment.getHiddenColumns());
1595    }
1596    else
1597    {
1598  69 alignment.getHiddenColumns().hideColumns(start, end);
1599    }
1600  71 isColSelChanged(true);
1601    }
1602   
 
1603  1 toggle public void showColumn(int col)
1604    {
1605  1 alignment.getHiddenColumns().revealHiddenColumns(col, colSel);
1606  1 isColSelChanged(true);
1607    }
1608   
 
1609  5 toggle public void showAllHiddenColumns()
1610    {
1611  5 alignment.getHiddenColumns().revealAllHiddenColumns(colSel);
1612  5 isColSelChanged(true);
1613    }
1614   
1615    // common hide/show seq stuff
 
1616  1 toggle public void showAllHiddenSeqs()
1617    {
1618  1 int startSeq = ranges.getStartSeq();
1619  1 int endSeq = ranges.getEndSeq();
1620   
1621  1 if (alignment.getHiddenSequences().getSize() > 0)
1622    {
1623  1 if (selectionGroup == null)
1624    {
1625  0 selectionGroup = new SequenceGroup();
1626  0 selectionGroup.setEndRes(alignment.getWidth() - 1);
1627    }
1628  1 List<SequenceI> tmp = alignment.getHiddenSequences()
1629    .showAll(hiddenRepSequences);
1630  1 for (SequenceI seq : tmp)
1631    {
1632  2 selectionGroup.addSequence(seq, false);
1633  2 setSequenceAnnotationsVisible(seq, true);
1634    }
1635   
1636  1 hiddenRepSequences = null;
1637   
1638  1 ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
1639   
1640  1 firePropertyChange("alignment", null, alignment.getSequences());
1641    // used to set hasHiddenRows/hiddenRepSequences here, after the property
1642    // changed event
1643  1 sendSelection();
1644    }
1645    }
1646   
 
1647  2 toggle public void showSequence(int index)
1648    {
1649  2 int startSeq = ranges.getStartSeq();
1650  2 int endSeq = ranges.getEndSeq();
1651   
1652  2 List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(index,
1653    hiddenRepSequences);
1654  2 if (tmp.size() > 0)
1655    {
1656  2 if (selectionGroup == null)
1657    {
1658  2 selectionGroup = new SequenceGroup();
1659  2 selectionGroup.setEndRes(alignment.getWidth() - 1);
1660    }
1661   
1662  2 for (SequenceI seq : tmp)
1663    {
1664  3 selectionGroup.addSequence(seq, false);
1665  3 setSequenceAnnotationsVisible(seq, true);
1666    }
1667   
1668  2 ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
1669   
1670  2 firePropertyChange("alignment", null, alignment.getSequences());
1671  2 sendSelection();
1672    }
1673    }
1674   
 
1675  0 toggle public void hideAllSelectedSeqs()
1676    {
1677  0 if (selectionGroup == null || selectionGroup.getSize() < 1)
1678    {
1679  0 return;
1680    }
1681   
1682  0 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1683   
1684  0 hideSequence(seqs);
1685   
1686  0 setSelectionGroup(null);
1687    }
1688   
 
1689  54 toggle public void hideSequence(SequenceI[] seq)
1690    {
1691    /*
1692    * cache offset to first visible sequence
1693    */
1694  54 int startSeq = ranges.getStartSeq();
1695   
1696  54 if (seq != null)
1697    {
1698  252 for (int i = 0; i < seq.length; i++)
1699    {
1700  198 alignment.getHiddenSequences().hideSequence(seq[i]);
1701  198 setSequenceAnnotationsVisible(seq[i], false);
1702    }
1703  54 ranges.setStartSeq(startSeq);
1704  54 firePropertyChange("alignment", null, alignment.getSequences());
1705    }
1706    }
1707   
1708    /**
1709    * Hides the specified sequence, or the sequences it represents
1710    *
1711    * @param sequence
1712    * the sequence to hide, or keep as representative
1713    * @param representGroup
1714    * if true, hide the current selection group except for the
1715    * representative sequence
1716    */
 
1717  3 toggle public void hideSequences(SequenceI sequence, boolean representGroup)
1718    {
1719  3 if (selectionGroup == null || selectionGroup.getSize() < 1)
1720    {
1721  0 hideSequence(new SequenceI[] { sequence });
1722  0 return;
1723    }
1724   
1725  3 if (representGroup)
1726    {
1727  3 hideRepSequences(sequence, selectionGroup);
1728  3 setSelectionGroup(null);
1729  3 return;
1730    }
1731   
1732  0 int gsize = selectionGroup.getSize();
1733  0 SequenceI[] hseqs = selectionGroup.getSequences()
1734    .toArray(new SequenceI[gsize]);
1735   
1736  0 hideSequence(hseqs);
1737  0 setSelectionGroup(null);
1738  0 sendSelection();
1739    }
1740   
1741    /**
1742    * Set visibility for any annotations for the given sequence.
1743    *
1744    * @param sequenceI
1745    */
 
1746  203 toggle protected void setSequenceAnnotationsVisible(SequenceI sequenceI,
1747    boolean visible)
1748    {
1749  203 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
1750  203 if (anns != null)
1751    {
1752  203 for (AlignmentAnnotation ann : anns)
1753    {
1754  1033 if (ann.sequenceRef == sequenceI)
1755    {
1756  0 ann.visible = visible;
1757    }
1758    }
1759    }
1760    }
1761   
 
1762  5 toggle public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1763    {
1764  5 int sSize = sg.getSize();
1765  5 if (sSize < 2)
1766    {
1767  0 return;
1768    }
1769   
1770  5 if (hiddenRepSequences == null)
1771    {
1772  5 hiddenRepSequences = new Hashtable<>();
1773    }
1774   
1775  5 hiddenRepSequences.put(repSequence, sg);
1776   
1777    // Hide all sequences except the repSequence
1778  5 SequenceI[] seqs = new SequenceI[sSize - 1];
1779  5 int index = 0;
1780  16 for (int i = 0; i < sSize; i++)
1781    {
1782  11 if (sg.getSequenceAt(i) != repSequence)
1783    {
1784  6 if (index == sSize - 1)
1785    {
1786  0 return;
1787    }
1788   
1789  6 seqs[index++] = sg.getSequenceAt(i);
1790    }
1791    }
1792  5 sg.setSeqrep(repSequence); // note: not done in 2.7applet
1793  5 sg.setHidereps(true); // note: not done in 2.7applet
1794  5 hideSequence(seqs);
1795   
1796    }
1797   
1798    /**
1799    *
1800    * @return null or the current reference sequence
1801    */
 
1802  0 toggle public SequenceI getReferenceSeq()
1803    {
1804  0 return alignment.getSeqrep();
1805    }
1806   
1807    /**
1808    * @param seq
1809    * @return true iff seq is the reference for the alignment
1810    */
 
1811  5271 toggle public boolean isReferenceSeq(SequenceI seq)
1812    {
1813  5271 return alignment.getSeqrep() == seq;
1814    }
1815   
1816    /**
1817    *
1818    * @param seq
1819    * @return true if there are sequences represented by this sequence that are
1820    * currently hidden
1821    */
 
1822  5322 toggle public boolean isHiddenRepSequence(SequenceI seq)
1823    {
1824  5322 return (hiddenRepSequences != null
1825    && hiddenRepSequences.containsKey(seq));
1826    }
1827   
1828    /**
1829    *
1830    * @param seq
1831    * @return null or a sequence group containing the sequences that seq
1832    * represents
1833    */
 
1834  2 toggle public SequenceGroup getRepresentedSequences(SequenceI seq)
1835    {
1836  2 return (SequenceGroup) (hiddenRepSequences == null ? null
1837    : hiddenRepSequences.get(seq));
1838    }
1839   
 
1840  0 toggle @Override
1841    public int adjustForHiddenSeqs(int alignmentIndex)
1842    {
1843  0 return alignment.getHiddenSequences()
1844    .adjustForHiddenSeqs(alignmentIndex);
1845    }
1846   
 
1847  0 toggle @Override
1848    public void invertColumnSelection()
1849    {
1850  0 colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
1851  0 isColSelChanged(true);
1852    }
1853   
 
1854  4 toggle @Override
1855    public SequenceI[] getSelectionAsNewSequence()
1856    {
1857  4 SequenceI[] sequences;
1858    // JBPNote: Need to test jalviewLite.getSelectedSequencesAsAlignmentFrom -
1859    // this was the only caller in the applet for this method
1860    // JBPNote: in applet, this method returned references to the alignment
1861    // sequences, and it did not honour the presence/absence of annotation
1862    // attached to the alignment (probably!)
1863  4 if (selectionGroup == null || selectionGroup.getSize() == 0)
1864    {
1865  2 sequences = alignment.getSequencesArray();
1866  2 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
1867  4 for (int i = 0; i < sequences.length; i++)
1868    {
1869    // construct new sequence with subset of visible annotation
1870  2 sequences[i] = new Sequence(sequences[i], annots);
1871    }
1872    }
1873    else
1874    {
1875  2 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1876    }
1877   
1878  4 return sequences;
1879    }
1880   
 
1881  28 toggle @Override
1882    public SequenceI[] getSequenceSelection()
1883    {
1884  28 SequenceI[] sequences = null;
1885  28 if (selectionGroup != null)
1886    {
1887  4 sequences = selectionGroup.getSequencesInOrder(alignment);
1888    }
1889  28 if (sequences == null)
1890    {
1891  24 sequences = alignment.getSequencesArray();
1892    }
1893  28 return sequences;
1894    }
1895   
 
1896  20 toggle @Override
1897    public jalview.datamodel.AlignmentView getAlignmentView(
1898    boolean selectedOnly)
1899    {
1900  20 return getAlignmentView(selectedOnly, false);
1901    }
1902   
 
1903  21 toggle @Override
1904    public jalview.datamodel.AlignmentView getAlignmentView(
1905    boolean selectedOnly, boolean markGroups)
1906    {
1907  21 return new AlignmentView(alignment, alignment.getHiddenColumns(),
1908    selectionGroup,
1909    alignment.getHiddenColumns() != null
1910    && alignment.getHiddenColumns().hasHiddenColumns(),
1911    selectedOnly, markGroups);
1912    }
1913   
 
1914  24 toggle @Override
1915    public String[] getViewAsString(boolean selectedRegionOnly)
1916    {
1917  24 return getViewAsString(selectedRegionOnly, true);
1918    }
1919   
 
1920  24 toggle @Override
1921    public String[] getViewAsString(boolean selectedRegionOnly,
1922    boolean exportHiddenSeqs)
1923    {
1924  24 String[] selection = null;
1925  24 SequenceI[] seqs = null;
1926  24 int i, iSize;
1927  24 int start = 0, end = 0;
1928  24 if (selectedRegionOnly && selectionGroup != null)
1929    {
1930  0 iSize = selectionGroup.getSize();
1931  0 seqs = selectionGroup.getSequencesInOrder(alignment);
1932  0 start = selectionGroup.getStartRes();
1933  0 end = selectionGroup.getEndRes() + 1;
1934    }
1935    else
1936    {
1937  24 if (hasHiddenRows() && exportHiddenSeqs)
1938    {
1939  0 AlignmentI fullAlignment = alignment.getHiddenSequences()
1940    .getFullAlignment();
1941  0 iSize = fullAlignment.getHeight();
1942  0 seqs = fullAlignment.getSequencesArray();
1943  0 end = fullAlignment.getWidth();
1944    }
1945    else
1946    {
1947  24 iSize = alignment.getHeight();
1948  24 seqs = alignment.getSequencesArray();
1949  24 end = alignment.getWidth();
1950    }
1951    }
1952   
1953  24 selection = new String[iSize];
1954  24 if (alignment.getHiddenColumns() != null
1955    && alignment.getHiddenColumns().hasHiddenColumns())
1956    {
1957  206 for (i = 0; i < iSize; i++)
1958    {
1959  188 Iterator<int[]> blocks = alignment.getHiddenColumns()
1960    .getVisContigsIterator(start, end + 1, false);
1961  188 selection[i] = seqs[i].getSequenceStringFromIterator(blocks);
1962    }
1963    }
1964    else
1965    {
1966  36 for (i = 0; i < iSize; i++)
1967    {
1968  30 selection[i] = seqs[i].getSequenceAsString(start, end);
1969    }
1970   
1971    }
1972  24 return selection;
1973    }
1974   
 
1975  0 toggle @Override
1976    public List<int[]> getVisibleRegionBoundaries(int min, int max)
1977    {
1978  0 ArrayList<int[]> regions = new ArrayList<>();
1979  0 int start = min;
1980  0 int end = max;
1981   
1982  0 do
1983    {
1984  0 HiddenColumns hidden = alignment.getHiddenColumns();
1985  0 if (hidden != null && hidden.hasHiddenColumns())
1986    {
1987  0 if (start == 0)
1988    {
1989  0 start = hidden.visibleToAbsoluteColumn(start);
1990    }
1991   
1992  0 end = hidden.getNextHiddenBoundary(false, start);
1993  0 if (start == end)
1994    {
1995  0 end = max;
1996    }
1997  0 if (end > max)
1998    {
1999  0 end = max;
2000    }
2001    }
2002   
2003  0 regions.add(new int[] { start, end });
2004   
2005  0 if (hidden != null && hidden.hasHiddenColumns())
2006    {
2007  0 start = hidden.visibleToAbsoluteColumn(end);
2008  0 start = hidden.getNextHiddenBoundary(true, start) + 1;
2009    }
2010  0 } while (end < max);
2011   
2012    // int[][] startEnd = new int[regions.size()][2];
2013   
2014  0 return regions;
2015    }
2016   
 
2017  1 toggle @Override
2018    public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
2019    boolean selectedOnly)
2020    {
2021  1 ArrayList<AlignmentAnnotation> ala = new ArrayList<>();
2022  1 AlignmentAnnotation[] aa;
2023  ? if ((aa = alignment.getAlignmentAnnotation()) != null)
2024    {
2025  1 for (AlignmentAnnotation annot : aa)
2026    {
2027  4 AlignmentAnnotation clone = new AlignmentAnnotation(annot);
2028  4 if (selectedOnly && selectionGroup != null)
2029    {
2030  4 clone.makeVisibleAnnotation(selectionGroup.getStartRes(),
2031    selectionGroup.getEndRes(), alignment.getHiddenColumns());
2032    }
2033    else
2034    {
2035  0 clone.makeVisibleAnnotation(alignment.getHiddenColumns());
2036    }
2037  4 ala.add(clone);
2038    }
2039    }
2040  1 return ala;
2041    }
2042   
 
2043  1678 toggle @Override
2044    public boolean isPadGaps()
2045    {
2046  1678 return padGaps;
2047    }
2048   
 
2049  508 toggle @Override
2050    public void setPadGaps(boolean padGaps)
2051    {
2052  508 this.padGaps = padGaps;
2053    }
2054   
2055    /**
2056    * apply any post-edit constraints and trigger any calculations needed after
2057    * an edit has been performed on the alignment
2058    *
2059    * @param ap
2060    */
 
2061  549 toggle @Override
2062    public void alignmentChanged(AlignmentViewPanel ap)
2063    {
2064  549 if (isPadGaps())
2065    {
2066  310 alignment.padGaps();
2067    }
2068  549 if (autoCalculateConsensus)
2069    {
2070  549 updateConsensus(ap);
2071  549 updateSecondaryStructureConsensus(ap);
2072    }
2073  549 if (hconsensus != null && autoCalculateConsensus)
2074    {
2075  543 updateConservation(ap);
2076    }
2077  549 if (autoCalculateStrucConsensus)
2078    {
2079  549 updateStrucConsensus(ap);
2080    }
2081   
2082    // Reset endRes of groups if beyond alignment width
2083  549 int alWidth = alignment.getWidth();
2084  549 List<SequenceGroup> groups = alignment.getGroups();
2085  549 if (groups != null)
2086    {
2087  549 for (SequenceGroup sg : groups)
2088    {
2089  175 if (sg.getEndRes() > alWidth)
2090    {
2091  0 sg.setEndRes(alWidth - 1);
2092    }
2093    }
2094    }
2095   
2096  549 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
2097    {
2098  0 selectionGroup.setEndRes(alWidth - 1);
2099    }
2100   
2101  549 updateAllColourSchemes();
2102  549 calculator.restartWorkers();
2103    // alignment.adjustSequenceAnnotations();
2104    }
2105   
2106    /**
2107    * reset scope and do calculations for all applied colourschemes on alignment
2108    */
 
2109  549 toggle void updateAllColourSchemes()
2110    {
2111  549 ResidueShaderI rs = residueShading;
2112  549 if (rs != null)
2113    {
2114  549 rs.alignmentChanged(alignment, hiddenRepSequences);
2115   
2116  549 rs.setConsensus(hconsensus);
2117  549 if (rs.conservationApplied())
2118    {
2119  3 rs.setConservation(Conservation.calculateConservation("All",
2120    alignment.getSequences(), 0, alignment.getWidth(), false,
2121    getConsPercGaps(), false));
2122    }
2123    }
2124   
2125  549 for (SequenceGroup sg : alignment.getGroups())
2126    {
2127  175 if (sg.cs != null)
2128    {
2129  175 sg.cs.alignmentChanged(sg, hiddenRepSequences);
2130    }
2131  175 sg.recalcConservation();
2132    }
2133    }
2134   
 
2135  508 toggle protected void initAutoAnnotation()
2136    {
2137    // TODO: add menu option action that nulls or creates consensus object
2138    // depending on if the user wants to see the annotation or not in a
2139    // specific alignment
2140   
2141  508 if (hconsensus == null && !isDataset)
2142    {
2143  508 if (!alignment.isNucleotide())
2144    {
2145  397 initConservation();
2146  397 initQuality();
2147    }
2148    else
2149    {
2150  111 initRNAStructure();
2151    }
2152  508 consensus = new AlignmentAnnotation("Consensus",
2153    MessageManager.getString("label.consensus_descr"),
2154    new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
2155  508 setSecondaryStructureSources(alignment.getAlignmentAnnotation());
2156  508 List<String> secondaryStructureSources = getSecondaryStructureSources();
2157   
2158  508 if (secondaryStructureSources != null)
2159    {
2160   
2161  508 secondaryStructureConsensus = new ArrayList<AlignmentAnnotation>();
2162  508 for (String ssSource : secondaryStructureSources)
2163    {
2164   
2165  434 AlignmentAnnotation ssConsensus = new AlignmentAnnotation(
2166    MessageManager.getString("label.ssconsensus_label") + " "
2167    + ssSource,
2168    ssSource + " "
2169    + MessageManager
2170    .getString("label.ssconsensus_descr"),
2171    new Annotation[1], 0f, 100f,
2172    AlignmentAnnotation.BAR_GRAPH);
2173  434 secondaryStructureConsensus.add(ssConsensus);
2174    }
2175   
2176    }
2177   
2178  508 initConsensus(consensus);
2179  508 initSSConsensus(secondaryStructureConsensus);
2180  508 initGapCounts();
2181  508 initComplementConsensus();
2182    }
2183    }
2184   
2185    /**
2186    * If this is a protein alignment and there are mappings to cDNA, adds the
2187    * cDNA consensus annotation and returns true, else returns false.
2188    */
 
2189  518 toggle public boolean initComplementConsensus()
2190    {
2191  518 if (!alignment.isNucleotide())
2192    {
2193  406 final List<AlignedCodonFrame> codonMappings = alignment
2194    .getCodonFrames();
2195  406 if (codonMappings != null && !codonMappings.isEmpty())
2196    {
2197  4 boolean doConsensus = false;
2198  4 for (AlignedCodonFrame mapping : codonMappings)
2199    {
2200    // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
2201  4 MapList[] mapLists = mapping.getdnaToProt();
2202    // mapLists can be empty if project load has not finished resolving
2203    // seqs
2204  4 if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
2205    {
2206  4 doConsensus = true;
2207  4 break;
2208    }
2209    }
2210  4 if (doConsensus)
2211    {
2212  4 complementConsensus = new AlignmentAnnotation("cDNA Consensus",
2213    MessageManager
2214    .getString("label.complement_consensus_descr"),
2215    new Annotation[1], 0f, 100f,
2216    AlignmentAnnotation.BAR_GRAPH);
2217  4 initConsensus(complementConsensus);
2218  4 return true;
2219    }
2220    }
2221    }
2222  514 return false;
2223    }
2224   
 
2225  512 toggle private void initConsensus(AlignmentAnnotation aa)
2226    {
2227  512 aa.hasText = true;
2228  512 aa.autoCalculated = true;
2229   
2230  512 if (showConsensus)
2231    {
2232  511 alignment.addAnnotation(aa);
2233    }
2234    }
2235   
 
2236  508 toggle private void initSSConsensus(
2237    List<AlignmentAnnotation> secondaryStructureConsensuses)
2238    {
2239  508 if (secondaryStructureConsensuses == null)
2240    {
2241  0 return;
2242    }
2243  508 for (AlignmentAnnotation aa : secondaryStructureConsensuses)
2244    {
2245  434 aa.hasText = true;
2246  434 aa.autoCalculated = true;
2247   
2248  434 if (showSSConsensus)
2249    {
2250  0 alignment.addAnnotation(aa);
2251    }
2252   
2253    }
2254    }
2255   
2256    // these should be extracted from the view model - style and settings for
2257    // derived annotation
 
2258  508 toggle private void initGapCounts()
2259    {
2260  508 if (showOccupancy)
2261    {
2262  504 gapcounts = new AlignmentAnnotation("Occupancy",
2263    MessageManager.getString("label.occupancy_descr"),
2264    new Annotation[1], 0f, alignment.getHeight(),
2265    AlignmentAnnotation.BAR_GRAPH);
2266  504 gapcounts.hasText = true;
2267  504 gapcounts.autoCalculated = true;
2268  504 gapcounts.scaleColLabel = true;
2269  504 gapcounts.graph = AlignmentAnnotation.BAR_GRAPH;
2270   
2271  504 alignment.addAnnotation(gapcounts);
2272    }
2273    }
2274   
 
2275  397 toggle private void initConservation()
2276    {
2277  397 if (showConservation)
2278    {
2279  396 if (conservation == null)
2280    {
2281  396 conservation = new AlignmentAnnotation("Conservation",
2282    MessageManager.formatMessage("label.conservation_descr",
2283    getConsPercGaps()),
2284    new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
2285  396 conservation.hasText = true;
2286  396 conservation.autoCalculated = true;
2287  396 alignment.addAnnotation(conservation);
2288    }
2289    }
2290    }
2291   
 
2292  397 toggle private void initQuality()
2293    {
2294  397 if (showQuality)
2295    {
2296  397 if (quality == null)
2297    {
2298  397 quality = new AlignmentAnnotation("Quality",
2299    MessageManager.getString("label.quality_descr"),
2300    new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
2301  397 quality.hasText = true;
2302  397 quality.autoCalculated = true;
2303  397 alignment.addAnnotation(quality);
2304    }
2305    }
2306    }
2307   
 
2308  111 toggle private void initRNAStructure()
2309    {
2310  111 if (alignment.hasRNAStructure() && strucConsensus == null)
2311    {
2312  2 strucConsensus = new AlignmentAnnotation("StrucConsensus",
2313    MessageManager.getString("label.strucconsensus_descr"),
2314    new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
2315  2 strucConsensus.hasText = true;
2316  2 strucConsensus.autoCalculated = true;
2317   
2318  2 if (showConsensus)
2319    {
2320  2 alignment.addAnnotation(strucConsensus);
2321    }
2322    }
2323    }
2324   
2325    /*
2326    * (non-Javadoc)
2327    *
2328    * @see jalview.api.AlignViewportI#calcPanelHeight()
2329    */
 
2330  4824 toggle @Override
2331    public int calcPanelHeight()
2332    {
2333    // setHeight of panels
2334  4824 AlignmentAnnotation[] anns = getAlignment().getAlignmentAnnotation();
2335  4824 int height = 0;
2336  4824 int charHeight = getCharHeight();
2337  4824 if (anns != null)
2338    {
2339  4823 BitSet graphgrp = new BitSet();
2340  4824 for (AlignmentAnnotation aa : anns)
2341    {
2342  22509 if (aa == null)
2343    {
2344  0 jalview.bin.Console.errPrintln("Null annotation row: ignoring.");
2345  0 continue;
2346    }
2347  22508 if (!aa.visible)
2348    {
2349  1776 continue;
2350    }
2351  20732 if (aa.graphGroup > -1)
2352    {
2353  390 if (graphgrp.get(aa.graphGroup))
2354    {
2355  195 continue;
2356    }
2357    else
2358    {
2359  195 graphgrp.set(aa.graphGroup);
2360    }
2361    }
2362  20538 aa.height = 0;
2363   
2364  20536 if (aa.hasText)
2365    {
2366  18285 aa.height += charHeight;
2367    }
2368   
2369  20537 if (aa.hasIcons)
2370    {
2371  894 aa.height += 16;
2372    }
2373   
2374  20537 if (aa.graph > 0)
2375    {
2376  19150 aa.height += aa.graphHeight + 20;
2377    }
2378   
2379  20537 if (aa.height == 0)
2380    {
2381  158 aa.height = 20;
2382    }
2383   
2384  20537 height += aa.height;
2385    }
2386    }
2387  4824 if (height == 0)
2388    {
2389    // set minimum
2390  23 height = 20;
2391    }
2392  4824 return height;
2393    }
2394   
 
2395  130 toggle @Override
2396    public void updateGroupAnnotationSettings(boolean applyGlobalSettings,
2397    boolean preserveNewGroupSettings)
2398    {
2399  130 boolean updateCalcs = false;
2400  130 boolean conv = isShowGroupConservation();
2401  130 boolean cons = isShowGroupConsensus();
2402  130 boolean sscons = isShowGroupSSConsensus();
2403  130 boolean showprf = isShowSequenceLogo();
2404  130 boolean showConsHist = isShowConsensusHistogram();
2405  130 boolean normLogo = isNormaliseSequenceLogo();
2406   
2407    /**
2408    * TODO reorder the annotation rows according to group/sequence ordering on
2409    * alignment
2410    */
2411    // boolean sortg = true;
2412   
2413    // remove old automatic annotation
2414    // add any new annotation
2415   
2416    // intersect alignment annotation with alignment groups
2417   
2418  130 AlignmentAnnotation[] aan = alignment.getAlignmentAnnotation();
2419  130 List<SequenceGroup> oldrfs = new ArrayList<>();
2420  130 if (aan != null)
2421    {
2422  1021 for (int an = 0; an < aan.length; an++)
2423    {
2424  891 if (aan[an].autoCalculated && aan[an].groupRef != null)
2425    {
2426  0 oldrfs.add(aan[an].groupRef);
2427  0 alignment.deleteAnnotation(aan[an], false);
2428    }
2429    }
2430    }
2431  130 if (alignment.getGroups() != null)
2432    {
2433  130 for (SequenceGroup sg : alignment.getGroups())
2434    {
2435  56 updateCalcs = false;
2436  56 if (applyGlobalSettings
2437    || (!preserveNewGroupSettings && !oldrfs.contains(sg)))
2438    {
2439    // set defaults for this group's conservation/consensus
2440  9 sg.setshowSequenceLogo(showprf);
2441  9 sg.setShowConsensusHistogram(showConsHist);
2442  9 sg.setNormaliseSequenceLogo(normLogo);
2443    }
2444  56 if (conv)
2445    {
2446  0 updateCalcs = true;
2447  0 alignment.addAnnotation(sg.getConservationRow(), 0);
2448    }
2449  56 if (cons)
2450    {
2451  24 updateCalcs = true;
2452  24 alignment.addAnnotation(sg.getConsensus(), 0);
2453    }
2454  56 if (sscons)
2455    {
2456  0 updateCalcs = true;
2457  0 List<String> secondaryStructureSources = getSecondaryStructureSources();
2458  0 if (secondaryStructureSources != null)
2459    {
2460  0 List<AlignmentAnnotation> ssAa = sg
2461    .getSSConsensus(secondaryStructureSources);
2462  0 if (ssAa != null)
2463    {
2464  0 for (AlignmentAnnotation aa : ssAa)
2465    {
2466    // Setting annotation visibility to true for the secondary
2467    // structure consensus for all providers
2468  0 if (aa.label.contains(Constants.SS_ALL_PROVIDERS))
2469    {
2470  0 aa.visible = true;
2471    }
2472  0 alignment.addAnnotation(aa, 0);
2473    }
2474    }
2475    }
2476    }
2477    // refresh the annotation rows
2478  56 if (updateCalcs)
2479    {
2480  24 sg.recalcConservation();
2481    }
2482    }
2483    }
2484  130 oldrfs.clear();
2485    }
2486   
 
2487  26241 toggle @Override
2488    public boolean isDisplayReferenceSeq()
2489    {
2490  26241 return alignment.hasSeqrep() && viewStyle.isDisplayReferenceSeq();
2491    }
2492   
 
2493  10 toggle @Override
2494    public void setDisplayReferenceSeq(boolean displayReferenceSeq)
2495    {
2496  10 viewStyle.setDisplayReferenceSeq(displayReferenceSeq);
2497    }
2498   
 
2499  5 toggle @Override
2500    public boolean isColourByReferenceSeq()
2501    {
2502  5 return alignment.hasSeqrep() && viewStyle.isColourByReferenceSeq();
2503    }
2504   
 
2505  19447 toggle @Override
2506    public Color getSequenceColour(SequenceI seq)
2507    {
2508  19447 Color sqc = sequenceColours.get(seq);
2509  19447 return (sqc == null ? Color.white : sqc);
2510    }
2511   
 
2512  1192 toggle @Override
2513    public void setSequenceColour(SequenceI seq, Color col)
2514    {
2515  1192 if (col == null)
2516    {
2517  0 sequenceColours.remove(seq);
2518    }
2519    else
2520    {
2521  1192 sequenceColours.put(seq, col);
2522    }
2523    }
2524   
 
2525  5 toggle @Override
2526    public void updateSequenceIdColours()
2527    {
2528  5 for (SequenceGroup sg : alignment.getGroups())
2529    {
2530  5 if (sg.idColour != null)
2531    {
2532  0 for (SequenceI s : sg.getSequences(getHiddenRepSequences()))
2533    {
2534  0 sequenceColours.put(s, sg.idColour);
2535    }
2536    }
2537    }
2538    }
2539   
 
2540  0 toggle @Override
2541    public void clearSequenceColours()
2542    {
2543  0 sequenceColours.clear();
2544    }
2545   
2546   
 
2547  3124 toggle @Override
2548    public Color getAnnotationColour(AlignmentAnnotation annot)
2549    {
2550  3124 Color annotColor = annotationColours.get(annot);
2551  3124 return (annotColor == null ? Color.white : annotColor);
2552    }
2553   
 
2554  0 toggle @Override
2555    public void setAnnotationColour(AlignmentAnnotation annot, Color col)
2556    {
2557  0 if (col == null)
2558    {
2559  0 annotationColours.remove(annot);
2560    }
2561    else
2562    {
2563  0 annotationColours.put(annot, col);
2564    }
2565    }
2566   
 
2567  5 toggle @Override
2568    public void updateAnnotationColours()
2569    {
2570  5 for (SequenceGroup sg : alignment.getGroups())
2571    {
2572  5 if (sg.idColour != null)
2573    {
2574  0 for (AlignmentAnnotation annot : sg.getAlignmentAnnotation())
2575    {
2576  0 annotationColours.put(annot, sg.idColour);
2577    }
2578    }
2579    }
2580    }
2581   
 
2582  0 toggle @Override
2583    public void clearAnnotationColours()
2584    {
2585  0 annotationColours.clear();
2586    }
2587   
 
2588  0 toggle @Override
2589    public Map<AlignmentAnnotation, Color> getAnnotationColours()
2590    {
2591  0 return annotationColours;
2592    }
2593   
 
2594  0 toggle @Override
2595    public void setAnnotationColours(
2596    Map<AlignmentAnnotation, Color> annotationColours)
2597    {
2598  0 this.annotationColours = annotationColours;
2599    }
2600   
 
2601  1057 toggle @Override
2602    public AlignViewportI getCodingComplement()
2603    {
2604  1057 return this.codingComplement;
2605    }
2606   
2607    /**
2608    * Set this as the (cDna/protein) complement of the given viewport. Also
2609    * ensures the reverse relationship is set on the given viewport.
2610    */
 
2611  6 toggle @Override
2612    public void setCodingComplement(AlignViewportI av)
2613    {
2614  6 if (this == av)
2615    {
2616  0 jalview.bin.Console
2617    .errPrintln("Ignoring recursive setCodingComplement request");
2618    }
2619    else
2620    {
2621  6 this.codingComplement = av;
2622    // avoid infinite recursion!
2623  6 if (av.getCodingComplement() != this)
2624    {
2625  3 av.setCodingComplement(this);
2626    }
2627    }
2628    }
2629   
 
2630  25 toggle @Override
2631    public boolean isNucleotide()
2632    {
2633  25 return getAlignment() == null ? false : getAlignment().isNucleotide();
2634    }
2635   
 
2636  1545874 toggle @Override
2637    public FeaturesDisplayedI getFeaturesDisplayed()
2638    {
2639  1547488 return featuresDisplayed;
2640    }
2641   
 
2642  112 toggle @Override
2643    public void setFeaturesDisplayed(FeaturesDisplayedI featuresDisplayedI)
2644    {
2645  112 featuresDisplayed = featuresDisplayedI;
2646    }
2647   
 
2648  83 toggle @Override
2649    public boolean areFeaturesDisplayed()
2650    {
2651  83 return featuresDisplayed != null
2652    && featuresDisplayed.getRegisteredFeaturesCount() > 0;
2653    }
2654   
2655    /**
2656    * set the flag
2657    *
2658    * @param b
2659    * features are displayed if true
2660    */
 
2661  141 toggle @Override
2662    public void setShowSequenceFeatures(boolean b)
2663    {
2664  141 viewStyle.setShowSequenceFeatures(b);
2665    }
2666   
 
2667  459303 toggle @Override
2668    public boolean isShowSequenceFeatures()
2669    {
2670  459330 return viewStyle.isShowSequenceFeatures();
2671    }
2672   
 
2673  0 toggle @Override
2674    public void setShowSequenceFeaturesHeight(boolean selected)
2675    {
2676  0 viewStyle.setShowSequenceFeaturesHeight(selected);
2677    }
2678   
 
2679  0 toggle @Override
2680    public boolean isShowSequenceFeaturesHeight()
2681    {
2682  0 return viewStyle.isShowSequenceFeaturesHeight();
2683    }
2684   
 
2685  680 toggle @Override
2686    public void setShowAnnotation(boolean b)
2687    {
2688  680 viewStyle.setShowAnnotation(b);
2689    }
2690   
 
2691  4914 toggle @Override
2692    public boolean isShowAnnotation()
2693    {
2694  4914 return viewStyle.isShowAnnotation();
2695    }
2696   
 
2697  19268 toggle @Override
2698    public boolean isRightAlignIds()
2699    {
2700  19268 return viewStyle.isRightAlignIds();
2701    }
2702   
 
2703  593 toggle @Override
2704    public void setRightAlignIds(boolean rightAlignIds)
2705    {
2706  593 viewStyle.setRightAlignIds(rightAlignIds);
2707    }
2708   
 
2709  1040 toggle @Override
2710    public boolean getConservationSelected()
2711    {
2712  1040 return viewStyle.getConservationSelected();
2713    }
2714   
 
2715  85 toggle @Override
2716    public void setShowBoxes(boolean state)
2717    {
2718  85 viewStyle.setShowBoxes(state);
2719    }
2720   
2721    /**
2722    * @return
2723    * @see jalview.api.ViewStyleI#getTextColour()
2724    */
 
2725  736782 toggle @Override
2726    public Color getTextColour()
2727    {
2728  736782 return viewStyle.getTextColour();
2729    }
2730   
2731    /**
2732    * @return
2733    * @see jalview.api.ViewStyleI#getTextColour2()
2734    */
 
2735  46 toggle @Override
2736    public Color getTextColour2()
2737    {
2738  46 return viewStyle.getTextColour2();
2739    }
2740   
2741    /**
2742    * @return
2743    * @see jalview.api.ViewStyleI#getThresholdTextColour()
2744    */
 
2745  432784 toggle @Override
2746    public int getThresholdTextColour()
2747    {
2748  432784 return viewStyle.getThresholdTextColour();
2749    }
2750   
2751    /**
2752    * @return
2753    * @see jalview.api.ViewStyleI#isConservationColourSelected()
2754    */
 
2755  0 toggle @Override
2756    public boolean isConservationColourSelected()
2757    {
2758  0 return viewStyle.isConservationColourSelected();
2759    }
2760   
2761    /**
2762    * @return
2763    * @see jalview.api.ViewStyleI#isRenderGaps()
2764    */
 
2765  3433 toggle @Override
2766    public boolean isRenderGaps()
2767    {
2768  3433 return viewStyle.isRenderGaps();
2769    }
2770   
2771    /**
2772    * @return
2773    * @see jalview.api.ViewStyleI#isShowColourText()
2774    */
 
2775  672 toggle @Override
2776    public boolean isShowColourText()
2777    {
2778  672 return viewStyle.isShowColourText();
2779    }
2780   
2781    /**
2782    * @param conservationColourSelected
2783    * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean)
2784    */
 
2785  0 toggle @Override
2786    public void setConservationColourSelected(
2787    boolean conservationColourSelected)
2788    {
2789  0 viewStyle.setConservationColourSelected(conservationColourSelected);
2790    }
2791   
2792    /**
2793    * @param showColourText
2794    * @see jalview.api.ViewStyleI#setShowColourText(boolean)
2795    */
 
2796  0 toggle @Override
2797    public void setShowColourText(boolean showColourText)
2798    {
2799  0 viewStyle.setShowColourText(showColourText);
2800    }
2801   
2802    /**
2803    * @param textColour
2804    * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color)
2805    */
 
2806  85 toggle @Override
2807    public void setTextColour(Color textColour)
2808    {
2809  85 viewStyle.setTextColour(textColour);
2810    }
2811   
2812    /**
2813    * @param thresholdTextColour
2814    * @see jalview.api.ViewStyleI#setThresholdTextColour(int)
2815    */
 
2816  85 toggle @Override
2817    public void setThresholdTextColour(int thresholdTextColour)
2818    {
2819  85 viewStyle.setThresholdTextColour(thresholdTextColour);
2820    }
2821   
2822    /**
2823    * @param textColour2
2824    * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color)
2825    */
 
2826  85 toggle @Override
2827    public void setTextColour2(Color textColour2)
2828    {
2829  85 viewStyle.setTextColour2(textColour2);
2830    }
2831   
 
2832  143 toggle @Override
2833    public ViewStyleI getViewStyle()
2834    {
2835  143 return new ViewStyle(viewStyle);
2836    }
2837   
 
2838  86 toggle @Override
2839    public void setViewStyle(ViewStyleI settingsForView)
2840    {
2841  86 viewStyle = new ViewStyle(settingsForView);
2842  86 if (residueShading != null)
2843    {
2844  86 residueShading.setConservationApplied(
2845    settingsForView.isConservationColourSelected());
2846    }
2847    }
2848   
 
2849  0 toggle @Override
2850    public boolean sameStyle(ViewStyleI them)
2851    {
2852  0 return viewStyle.sameStyle(them);
2853    }
2854   
2855    /**
2856    * @return
2857    * @see jalview.api.ViewStyleI#getIdWidth()
2858    */
 
2859  6301 toggle @Override
2860    public int getIdWidth()
2861    {
2862  6301 return viewStyle.getIdWidth();
2863    }
2864   
2865    /**
2866    * @param i
2867    * @see jalview.api.ViewStyleI#setIdWidth(int)
2868    */
 
2869  970 toggle @Override
2870    public void setIdWidth(int i)
2871    {
2872  970 viewStyle.setIdWidth(i);
2873    }
2874   
2875    /**
2876    * @return
2877    * @see jalview.api.ViewStyleI#isCentreColumnLabels()
2878    */
 
2879  672 toggle @Override
2880    public boolean isCentreColumnLabels()
2881    {
2882  672 return viewStyle.isCentreColumnLabels();
2883    }
2884   
2885    /**
2886    * @param centreColumnLabels
2887    * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean)
2888    */
 
2889  593 toggle @Override
2890    public void setCentreColumnLabels(boolean centreColumnLabels)
2891    {
2892  593 viewStyle.setCentreColumnLabels(centreColumnLabels);
2893    }
2894   
2895    /**
2896    * @param showdbrefs
2897    * @see jalview.api.ViewStyleI#setShowDBRefs(boolean)
2898    */
 
2899  593 toggle @Override
2900    public void setShowDBRefs(boolean showdbrefs)
2901    {
2902  593 viewStyle.setShowDBRefs(showdbrefs);
2903    }
2904   
2905    /**
2906    * @return
2907    * @see jalview.api.ViewStyleI#isShowDBRefs()
2908    */
 
2909  718 toggle @Override
2910    public boolean isShowDBRefs()
2911    {
2912  718 return viewStyle.isShowDBRefs();
2913    }
2914   
2915    /**
2916    * @return
2917    * @see jalview.api.ViewStyleI#isShowNPFeats()
2918    */
 
2919  718 toggle @Override
2920    public boolean isShowNPFeats()
2921    {
2922  718 return viewStyle.isShowNPFeats();
2923    }
2924   
2925    /**
2926    * @param shownpfeats
2927    * @see jalview.api.ViewStyleI#setShowNPFeats(boolean)
2928    */
 
2929  593 toggle @Override
2930    public void setShowNPFeats(boolean shownpfeats)
2931    {
2932  593 viewStyle.setShowNPFeats(shownpfeats);
2933    }
2934   
2935    public abstract StructureSelectionManager getStructureSelectionManager();
2936   
2937    /**
2938    * Add one command to the command history list.
2939    *
2940    * @param command
2941    */
 
2942  1 toggle public void addToHistoryList(CommandI command)
2943    {
2944  1 if (this.historyList != null)
2945    {
2946  1 this.historyList.push(command);
2947  1 broadcastCommand(command, false);
2948  1 setSavedUpToDate(false);
2949  1 Jalview2XML.setStateSavedUpToDate(false);
2950    }
2951    }
2952   
 
2953  1 toggle protected void broadcastCommand(CommandI command, boolean undo)
2954    {
2955  1 getStructureSelectionManager().commandPerformed(command, undo,
2956    getVamsasSource());
2957    }
2958   
2959    /**
2960    * Add one command to the command redo list.
2961    *
2962    * @param command
2963    */
 
2964  0 toggle public void addToRedoList(CommandI command)
2965    {
2966  0 if (this.redoList != null)
2967    {
2968  0 this.redoList.push(command);
2969    }
2970  0 broadcastCommand(command, true);
2971    }
2972   
2973    /**
2974    * Clear the command redo list.
2975    */
 
2976  1 toggle public void clearRedoList()
2977    {
2978  1 if (this.redoList != null)
2979    {
2980  1 this.redoList.clear();
2981    }
2982    }
2983   
 
2984  53 toggle public void setHistoryList(Deque<CommandI> list)
2985    {
2986  53 this.historyList = list;
2987    }
2988   
 
2989  1276 toggle public Deque<CommandI> getHistoryList()
2990    {
2991  1276 return this.historyList;
2992    }
2993   
 
2994  53 toggle public void setRedoList(Deque<CommandI> list)
2995    {
2996  53 this.redoList = list;
2997    }
2998   
 
2999  1275 toggle public Deque<CommandI> getRedoList()
3000    {
3001  1275 return this.redoList;
3002    }
3003   
 
3004  1 toggle @Override
3005    public VamsasSource getVamsasSource()
3006    {
3007  1 return this;
3008    }
3009   
 
3010  5565 toggle public SequenceAnnotationOrder getSortAnnotationsBy()
3011    {
3012  5565 return sortAnnotationsBy;
3013    }
3014   
 
3015  0 toggle public void setSortAnnotationsBy(
3016    SequenceAnnotationOrder sortAnnotationsBy)
3017    {
3018  0 this.sortAnnotationsBy = sortAnnotationsBy;
3019    }
3020   
 
3021  5565 toggle public boolean isShowAutocalculatedAbove()
3022    {
3023  5565 return showAutocalculatedAbove;
3024    }
3025   
 
3026  452 toggle public void setShowAutocalculatedAbove(boolean showAutocalculatedAbove)
3027    {
3028  452 this.showAutocalculatedAbove = showAutocalculatedAbove;
3029    }
3030   
 
3031  3 toggle @Override
3032    public boolean isScaleProteinAsCdna()
3033    {
3034  3 return viewStyle.isScaleProteinAsCdna();
3035    }
3036   
 
3037  0 toggle @Override
3038    public void setScaleProteinAsCdna(boolean b)
3039    {
3040  0 viewStyle.setScaleProteinAsCdna(b);
3041    }
3042   
 
3043  0 toggle @Override
3044    public boolean isProteinFontAsCdna()
3045    {
3046  0 return viewStyle.isProteinFontAsCdna();
3047    }
3048   
 
3049  0 toggle @Override
3050    public void setProteinFontAsCdna(boolean b)
3051    {
3052  0 viewStyle.setProteinFontAsCdna(b);
3053    }
3054   
 
3055  85 toggle @Override
3056    public void setShowComplementFeatures(boolean b)
3057    {
3058  85 viewStyle.setShowComplementFeatures(b);
3059    }
3060   
 
3061  460669 toggle @Override
3062    public boolean isShowComplementFeatures()
3063    {
3064  460714 return viewStyle.isShowComplementFeatures();
3065    }
3066   
 
3067  85 toggle @Override
3068    public void setShowComplementFeaturesOnTop(boolean b)
3069    {
3070  85 viewStyle.setShowComplementFeaturesOnTop(b);
3071    }
3072   
 
3073  47 toggle @Override
3074    public boolean isShowComplementFeaturesOnTop()
3075    {
3076  47 return viewStyle.isShowComplementFeaturesOnTop();
3077    }
3078   
3079    /**
3080    * @return true if view should scroll to show the highlighted region of a
3081    * sequence
3082    * @return
3083    */
 
3084  51 toggle @Override
3085    public final boolean isFollowHighlight()
3086    {
3087  51 return followHighlight;
3088    }
3089   
 
3090  85 toggle @Override
3091    public final void setFollowHighlight(boolean b)
3092    {
3093  85 this.followHighlight = b;
3094    }
3095   
 
3096  39785 toggle @Override
3097    public ViewportRanges getRanges()
3098    {
3099  39785 return ranges;
3100    }
3101   
3102    /**
3103    * Helper method to populate the SearchResults with the location in the
3104    * complementary alignment to scroll to, in order to match this one.
3105    *
3106    * @param sr
3107    * the SearchResults to add to
3108    * @return the offset (below top of visible region) of the matched sequence
3109    */
 
3110  637 toggle protected int findComplementScrollTarget(SearchResultsI sr)
3111    {
3112  637 final AlignViewportI complement = getCodingComplement();
3113  637 if (complement == null || !complement.isFollowHighlight())
3114    {
3115  633 return 0;
3116    }
3117  4 boolean iAmProtein = !getAlignment().isNucleotide();
3118  4 AlignmentI proteinAlignment = iAmProtein ? getAlignment()
3119    : complement.getAlignment();
3120  4 if (proteinAlignment == null)
3121    {
3122  0 return 0;
3123    }
3124  4 final List<AlignedCodonFrame> mappings = proteinAlignment
3125    .getCodonFrames();
3126   
3127    /*
3128    * Heuristic: find the first mapped sequence (if any) with a non-gapped
3129    * residue in the middle column of the visible region. Scroll the
3130    * complementary alignment to line up the corresponding residue.
3131    */
3132  4 int seqOffset = 0;
3133  4 SequenceI sequence = null;
3134   
3135    /*
3136    * locate 'middle' column (true middle if an odd number visible, left of
3137    * middle if an even number visible)
3138    */
3139  4 int middleColumn = ranges.getStartRes()
3140    + (ranges.getEndRes() - ranges.getStartRes()) / 2;
3141  4 final HiddenSequences hiddenSequences = getAlignment()
3142    .getHiddenSequences();
3143   
3144    /*
3145    * searching to the bottom of the alignment gives smoother scrolling across
3146    * all gapped visible regions
3147    */
3148  4 int lastSeq = alignment.getHeight() - 1;
3149  4 List<AlignedCodonFrame> seqMappings = null;
3150  4 for (int seqNo = ranges
3151  4 .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
3152    {
3153  4 sequence = getAlignment().getSequenceAt(seqNo);
3154  4 if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
3155    {
3156  0 continue;
3157    }
3158  4 if (Comparison.isGap(sequence.getCharAt(middleColumn)))
3159    {
3160  0 continue;
3161    }
3162  4 seqMappings = MappingUtils.findMappingsForSequenceAndOthers(sequence,
3163    mappings,
3164    getCodingComplement().getAlignment().getSequences());
3165  4 if (!seqMappings.isEmpty())
3166    {
3167  4 break;
3168    }
3169    }
3170   
3171  4 if (sequence == null || seqMappings == null || seqMappings.isEmpty())
3172    {
3173    /*
3174    * No ungapped mapped sequence in middle column - do nothing
3175    */
3176  0 return 0;
3177    }
3178  4 MappingUtils.addSearchResults(sr, sequence,
3179    sequence.findPosition(middleColumn), seqMappings);
3180  4 return seqOffset;
3181    }
3182   
3183    /**
3184    * synthesize a column selection if none exists so it covers the given
3185    * selection group. if wholewidth is false, no column selection is made if the
3186    * selection group covers the whole alignment width.
3187    *
3188    * @param sg
3189    * @param wholewidth
3190    */
 
3191  0 toggle public void expandColSelection(SequenceGroup sg, boolean wholewidth)
3192    {
3193  0 int sgs, sge;
3194  0 if (sg != null && (sgs = sg.getStartRes()) >= 0
3195    && sg.getStartRes() <= (sge = sg.getEndRes())
3196    && !this.hasSelectedColumns())
3197    {
3198  0 if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
3199    {
3200    // do nothing
3201  0 return;
3202    }
3203  0 if (colSel == null)
3204    {
3205  0 colSel = new ColumnSelection();
3206    }
3207  0 for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
3208    {
3209  0 colSel.addElement(cspos);
3210    }
3211    }
3212    }
3213   
3214    /**
3215    * hold status of current selection group - defined on alignment or not.
3216    */
3217    private boolean selectionIsDefinedGroup = false;
3218   
 
3219  0 toggle @Override
3220    public boolean isSelectionDefinedGroup()
3221    {
3222  0 if (selectionGroup == null)
3223    {
3224  0 return false;
3225    }
3226  0 if (isSelectionGroupChanged(true))
3227    {
3228  0 selectionIsDefinedGroup = false;
3229  0 List<SequenceGroup> gps = alignment.getGroups();
3230  0 if (gps == null || gps.size() == 0)
3231    {
3232  0 selectionIsDefinedGroup = false;
3233    }
3234    else
3235    {
3236  0 selectionIsDefinedGroup = gps.contains(selectionGroup);
3237    }
3238    }
3239  0 return selectionGroup.isDefined() || selectionIsDefinedGroup;
3240    }
3241   
3242    /**
3243    * null, or currently highlighted results on this view
3244    */
3245    private SearchResultsI searchResults = null;
3246   
3247    protected TreeModel currentTree = null;
3248   
 
3249  12961 toggle @Override
3250    public boolean hasSearchResults()
3251    {
3252  12961 return searchResults != null;
3253    }
3254   
 
3255  7 toggle @Override
3256    public void setSearchResults(SearchResultsI results)
3257    {
3258  7 searchResults = results;
3259    }
3260   
 
3261  41 toggle @Override
3262    public SearchResultsI getSearchResults()
3263    {
3264  41 return searchResults;
3265    }
3266   
 
3267  3552 toggle @Override
3268    public ContactListI getContactList(AlignmentAnnotation _aa, int column)
3269    {
3270  3552 return alignment.getContactListFor(_aa, column);
3271    }
3272   
 
3273  139 toggle @Override
3274    public ContactMatrixI getContactMatrix(
3275    AlignmentAnnotation alignmentAnnotation)
3276    {
3277  139 return alignment.getContactMatrixFor(alignmentAnnotation);
3278    }
3279   
3280    /**
3281    * get the consensus sequence as displayed under the PID consensus annotation
3282    * row.
3283    *
3284    * @return consensus sequence as a new sequence object
3285    */
 
3286  1 toggle public SequenceI getConsensusSeq()
3287    {
3288  1 if (consensus == null)
3289    {
3290  0 updateConsensus(null);
3291    }
3292  1 if (consensus == null)
3293    {
3294  0 return null;
3295    }
3296  1 StringBuffer seqs = new StringBuffer();
3297  4 for (int i = 0; i < consensus.annotations.length; i++)
3298    {
3299  3 Annotation annotation = consensus.annotations[i];
3300  3 if (annotation != null)
3301    {
3302  3 String description = annotation.description;
3303  3 if (description != null && description.startsWith("["))
3304    {
3305    // consensus is a tie - just pick the first one
3306  1 seqs.append(description.charAt(1));
3307    }
3308    else
3309    {
3310  2 seqs.append(annotation.displayCharacter);
3311    }
3312    }
3313    }
3314   
3315  1 SequenceI sq = new Sequence("Consensus", seqs.toString());
3316  1 sq.setDescription("Percentage Identity Consensus "
3317  1 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
3318  1 return sq;
3319    }
3320   
3321    // to do jal-4386
 
3322  0 toggle public SequenceI getSSConsensusSeq()
3323    {
3324  0 if (secondaryStructureConsensus == null)
3325    {
3326  0 updateSecondaryStructureConsensus(null);
3327    }
3328  0 if (secondaryStructureConsensus == null)
3329    {
3330  0 return null;
3331    }
3332  0 StringBuffer seqs = new StringBuffer();
3333    // for (int i = 0; i < secondaryStructureConsensus.annotations.length; i++)
3334    // {
3335    // Annotation annotation = secondaryStructureConsensus.annotations[i];
3336    // if (annotation != null)
3337    // {
3338    // String description = annotation.description;
3339    // if (description != null && description.startsWith("["))
3340    // {
3341    // // consensus is a tie - just pick the first one
3342    // seqs.append(description.charAt(1));
3343    // }
3344    // else
3345    // {
3346    // seqs.append(annotation.displayCharacter);
3347    // }
3348    // }
3349    // }
3350   
3351  0 SequenceI sq = new Sequence("Sec Str Consensus", seqs.toString());
3352  0 sq.setDescription("Percentage Identity Sec Str Consensus "
3353  0 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
3354  0 return sq;
3355    }
3356   
 
3357  28 toggle @Override
3358    public void setCurrentTree(TreeModel tree)
3359    {
3360  28 currentTree = tree;
3361    }
3362   
 
3363  50 toggle @Override
3364    public TreeModel getCurrentTree()
3365    {
3366  50 return currentTree;
3367    }
3368   
 
3369  121 toggle @Override
3370    public AlignmentExportData getAlignExportData(
3371    AlignExportSettingsI options)
3372    {
3373  121 AlignmentI alignmentToExport = null;
3374  121 String[] omitHidden = null;
3375  121 alignmentToExport = null;
3376   
3377  121 if (hasHiddenColumns() && !options.isExportHiddenColumns())
3378    {
3379  0 omitHidden = getViewAsString(false,
3380    options.isExportHiddenSequences());
3381    }
3382   
3383  121 int[] alignmentStartEnd = new int[2];
3384  121 if (hasHiddenRows() && options.isExportHiddenSequences())
3385    {
3386  0 alignmentToExport = getAlignment().getHiddenSequences()
3387    .getFullAlignment();
3388    }
3389    else
3390    {
3391  121 alignmentToExport = getAlignment();
3392    }
3393  121 alignmentStartEnd = getAlignment().getHiddenColumns()
3394    .getVisibleStartAndEndIndex(alignmentToExport.getWidth());
3395  121 AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
3396    omitHidden, alignmentStartEnd);
3397  121 return ed;
3398    }
3399   
3400    /**
3401    * flag set to indicate if structure views might be out of sync with sequences
3402    * in the alignment
3403    */
3404   
3405    private boolean needToUpdateStructureViews = false;
3406   
 
3407  0 toggle @Override
3408    public boolean isUpdateStructures()
3409    {
3410  0 return needToUpdateStructureViews;
3411    }
3412   
 
3413  0 toggle @Override
3414    public void setUpdateStructures(boolean update)
3415    {
3416  0 needToUpdateStructureViews = update;
3417    }
3418   
 
3419  1750 toggle @Override
3420    public boolean needToUpdateStructureViews()
3421    {
3422  1750 boolean update = needToUpdateStructureViews;
3423  1750 needToUpdateStructureViews = false;
3424  1750 return update;
3425    }
3426   
 
3427  0 toggle @Override
3428    public void addSequenceGroup(SequenceGroup sequenceGroup)
3429    {
3430  0 alignment.addGroup(sequenceGroup);
3431   
3432  0 Color col = sequenceGroup.idColour;
3433  0 if (col != null)
3434    {
3435  0 col = col.brighter();
3436   
3437  0 for (SequenceI sq : sequenceGroup.getSequences())
3438    {
3439  0 setSequenceColour(sq, col);
3440    }
3441   
3442  0 List<AlignmentAnnotation> annotations = sequenceGroup.getAnnotationsFromTree();
3443  0 if (annotations != null) {
3444  0 for (AlignmentAnnotation annot : annotations) {
3445  0 setAnnotationColour(annot, col);
3446    }
3447    }
3448    }
3449   
3450  0 if (codingComplement != null)
3451    {
3452  0 SequenceGroup mappedGroup = MappingUtils
3453    .mapSequenceGroup(sequenceGroup, this, codingComplement);
3454  0 if (mappedGroup.getSequences().size() > 0)
3455    {
3456  0 codingComplement.getAlignment().addGroup(mappedGroup);
3457   
3458  0 if (col != null)
3459    {
3460  0 for (SequenceI seq : mappedGroup.getSequences())
3461    {
3462  0 codingComplement.setSequenceColour(seq, col);
3463    }
3464    }
3465    }
3466    // propagate the structure view update flag according to our own setting
3467  0 codingComplement.setUpdateStructures(needToUpdateStructureViews);
3468    }
3469    }
3470   
 
3471  34 toggle @Override
3472    public Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly)
3473    {
3474  34 int start = 0;
3475  34 int end = 0;
3476  34 if (selectedRegionOnly && selectionGroup != null)
3477    {
3478  4 start = selectionGroup.getStartRes();
3479  4 end = selectionGroup.getEndRes() + 1;
3480    }
3481    else
3482    {
3483  30 end = alignment.getWidth();
3484    }
3485  34 return (alignment.getHiddenColumns().getVisContigsIterator(start, end,
3486    false));
3487    }
3488   
 
3489  133 toggle public void setSavedUpToDate(boolean s)
3490    {
3491  133 setSavedUpToDate(s, QuitHandler.Message.UNSAVED_CHANGES);
3492    }
3493   
 
3494  452 toggle public void setSavedUpToDate(boolean s, QuitHandler.Message m)
3495    {
3496  452 Console.debug(
3497    "Setting " + this.getViewId() + " setSavedUpToDate to " + s);
3498  452 savedUpToDate = s;
3499  452 QuitHandler.setMessage(m);
3500    }
3501   
 
3502  4 toggle public boolean savedUpToDate()
3503    {
3504  4 Console.debug("Returning " + this.getViewId() + " savedUpToDate value: "
3505    + savedUpToDate);
3506  4 return savedUpToDate;
3507    }
3508    }