Clover icon

Coverage Report

  1. Project Clover database Wed Dec 3 2025 15:58:31 GMT
  2. Package jalview.viewmodel

File AlignmentViewport.java

 

Coverage histogram

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

Code metrics

360
818
259
1
3,567
2,451
489
0.6
3.16
259
1.89

Classes

Class Line # Actions
AlignmentViewport 92 818 489
0.7633959776.3%
 

Contributing tests

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