Clover icon

Coverage Report

  1. Project Clover database Mon Sep 2 2024 17:57:51 BST
  2. Package jalview.viewmodel

File AlignmentViewport.java

 

Coverage histogram

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

Code metrics

322
738
244
1
3,292
2,242
454
0.62
3.02
244
1.86

Classes

Class Line # Actions
AlignmentViewport 90 738 454
0.749233174.9%
 

Contributing tests

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