Clover icon

Coverage Report

  1. Project Clover database Wed Jan 7 2026 02:49:01 GMT
  2. Package jalview.viewmodel

File AlignmentViewport.java

 

Coverage histogram

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

Code metrics

392
895
293
1
3,966
2,727
548
0.61
3.05
293
1.87

Classes

Class Line # Actions
AlignmentViewport 112 895 548
0.74303874.3%
 

Contributing tests

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