JAL-1640 JAL-966 is for boolean getter on AlignViewportI
[jalview.git] / src / jalview / gui / AlignViewport.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 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 /*
22  * Jalview - A Sequence Alignment Editor and Viewer
23  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
24  *
25  * This program is free software; you can redistribute it and/or
26  * modify it under the terms of the GNU General Public License
27  * as published by the Free Software Foundation; either version 2
28  * of the License, or (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program; if not, write to the Free Software
37  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
38  */
39 package jalview.gui;
40
41 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
42 import jalview.analysis.NJTree;
43 import jalview.api.AlignViewportI;
44 import jalview.bin.Cache;
45 import jalview.commands.CommandI;
46 import jalview.datamodel.AlignmentI;
47 import jalview.datamodel.ColumnSelection;
48 import jalview.datamodel.PDBEntry;
49 import jalview.datamodel.Sequence;
50 import jalview.datamodel.SequenceGroup;
51 import jalview.datamodel.SequenceI;
52 import jalview.schemes.ColourSchemeProperty;
53 import jalview.schemes.UserColourScheme;
54 import jalview.structure.SelectionSource;
55 import jalview.structure.StructureSelectionManager;
56 import jalview.structure.VamsasSource;
57 import jalview.viewmodel.AlignmentViewport;
58 import jalview.ws.params.AutoCalcSetting;
59
60 import java.awt.Container;
61 import java.awt.Font;
62 import java.awt.Rectangle;
63 import java.util.ArrayList;
64 import java.util.Hashtable;
65 import java.util.Stack;
66 import java.util.Vector;
67
68 /**
69  * DOCUMENT ME!
70  * 
71  * @author $author$
72  * @version $Revision: 1.141 $
73  */
74 public class AlignViewport extends AlignmentViewport implements
75         SelectionSource, VamsasSource, AlignViewportI
76 {
77   int startRes;
78
79   int endRes;
80
81   int startSeq;
82
83   int endSeq;
84
85
86   SequenceAnnotationOrder sortAnnotationsBy = null;
87
88   Font font;
89
90   NJTree currentTree = null;
91
92   boolean cursorMode = false;
93
94   boolean antiAlias = false;
95
96   Rectangle explodedPosition;
97
98   String viewName;
99
100   boolean gatherViewsHere = false;
101
102   Stack<CommandI> historyList = new Stack<CommandI>();
103
104   Stack<CommandI> redoList = new Stack<CommandI>();
105
106   private AnnotationColumnChooser annotationColumnSelectionState;
107   /**
108    * Creates a new AlignViewport object.
109    * 
110    * @param al
111    *          alignment to view
112    */
113   public AlignViewport(AlignmentI al)
114   {
115     setAlignment(al);
116     init();
117   }
118
119   /**
120    * Create a new AlignViewport object with a specific sequence set ID
121    * 
122    * @param al
123    * @param seqsetid
124    *          (may be null - but potential for ambiguous constructor exception)
125    */
126   public AlignViewport(AlignmentI al, String seqsetid)
127   {
128     this(al, seqsetid, null);
129   }
130
131   public AlignViewport(AlignmentI al, String seqsetid, String viewid)
132   {
133     sequenceSetID = seqsetid;
134     viewId = viewid;
135     // TODO remove these once 2.4.VAMSAS release finished
136     if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null)
137     {
138       Cache.log.debug("Setting viewport's sequence set id : "
139               + sequenceSetID);
140     }
141     if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null)
142     {
143       Cache.log.debug("Setting viewport's view id : " + viewId);
144     }
145     setAlignment(al);
146     init();
147   }
148
149   /**
150    * Create a new AlignViewport with hidden regions
151    * 
152    * @param al
153    *          AlignmentI
154    * @param hiddenColumns
155    *          ColumnSelection
156    */
157   public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns)
158   {
159     setAlignment(al);
160     if (hiddenColumns != null)
161     {
162       colSel = hiddenColumns;
163     }
164     init();
165   }
166
167   /**
168    * New viewport with hidden columns and an existing sequence set id
169    * 
170    * @param al
171    * @param hiddenColumns
172    * @param seqsetid
173    *          (may be null)
174    */
175   public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns,
176           String seqsetid)
177   {
178     this(al, hiddenColumns, seqsetid, null);
179   }
180
181   /**
182    * New viewport with hidden columns and an existing sequence set id and viewid
183    * 
184    * @param al
185    * @param hiddenColumns
186    * @param seqsetid
187    *          (may be null)
188    * @param viewid
189    *          (may be null)
190    */
191   public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns,
192           String seqsetid, String viewid)
193   {
194     sequenceSetID = seqsetid;
195     viewId = viewid;
196     // TODO remove these once 2.4.VAMSAS release finished
197     if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null)
198     {
199       Cache.log.debug("Setting viewport's sequence set id : "
200               + sequenceSetID);
201     }
202     if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null)
203     {
204       Cache.log.debug("Setting viewport's view id : " + viewId);
205     }
206     setAlignment(al);
207     if (hiddenColumns != null)
208     {
209       colSel = hiddenColumns;
210     }
211     init();
212   }
213
214   private void applyViewProperties()
215   {
216     antiAlias = Cache.getDefault("ANTI_ALIAS", false);
217
218     viewStyle.setShowJVSuffix(Cache.getDefault("SHOW_JVSUFFIX", true));
219     setShowAnnotation(Cache.getDefault("SHOW_ANNOTATIONS", true));
220
221     setRightAlignIds(Cache.getDefault("RIGHT_ALIGN_IDS", false));
222     centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false);
223     autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
224
225     setPadGaps(Cache.getDefault("PAD_GAPS", true));
226     shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true);
227     showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP", true);
228     viewStyle.setSeqNameItalics(Cache.getDefault("ID_ITALICS", true));
229     viewStyle.setWrapAlignment(Cache.getDefault("WRAP_ALIGNMENT", false));
230     viewStyle.setShowUnconserved(Cache
231             .getDefault("SHOW_UNCONSERVED", false));
232     sortByTree = Cache.getDefault("SORT_BY_TREE", false);
233     followSelection = Cache.getDefault("FOLLOW_SELECTIONS", true);
234     sortAnnotationsBy = SequenceAnnotationOrder.valueOf(Cache.getDefault(
235             Preferences.SORT_ANNOTATIONS,
236             SequenceAnnotationOrder.NONE.name()));
237     showAutocalculatedAbove = Cache.getDefault(
238             Preferences.SHOW_AUTOCALC_ABOVE, false);
239
240   }
241
242   void init()
243   {
244     this.startRes = 0;
245     this.endRes = alignment.getWidth() - 1;
246     this.startSeq = 0;
247     this.endSeq = alignment.getHeight() - 1;
248     applyViewProperties();
249
250     String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
251     String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "");
252     String fontSize = Cache.getDefault("FONT_SIZE", "10");
253
254     int style = 0;
255
256     if (fontStyle.equals("bold"))
257     {
258       style = 1;
259     }
260     else if (fontStyle.equals("italic"))
261     {
262       style = 2;
263     }
264
265     setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
266
267     alignment
268             .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
269
270     // We must set conservation and consensus before setting colour,
271     // as Blosum and Clustal require this to be done
272     if (hconsensus == null && !isDataset)
273     {
274       if (!alignment.isNucleotide())
275       {
276         showConservation = Cache.getDefault("SHOW_CONSERVATION", true);
277         showQuality = Cache.getDefault("SHOW_QUALITY", true);
278         showGroupConservation = Cache.getDefault("SHOW_GROUP_CONSERVATION",
279                 false);
280       }
281       showConsensusHistogram = Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM",
282               true);
283       showSequenceLogo = Cache.getDefault("SHOW_CONSENSUS_LOGO", false);
284       normaliseSequenceLogo = Cache.getDefault("NORMALISE_CONSENSUS_LOGO",
285               false);
286       showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false);
287       showConsensus = Cache.getDefault("SHOW_IDENTITY", true);
288     }
289     initAutoAnnotation();
290     if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
291     {
292       globalColourScheme = ColourSchemeProperty.getColour(alignment,
293               jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
294
295       if (globalColourScheme instanceof UserColourScheme)
296       {
297         globalColourScheme = UserDefinedColours.loadDefaultColours();
298         ((UserColourScheme) globalColourScheme).setThreshold(0,
299                 isIgnoreGapsConsensus());
300       }
301
302       if (globalColourScheme != null)
303       {
304         globalColourScheme.setConsensus(hconsensus);
305       }
306     }
307   }
308
309   /**
310    * centre columnar annotation labels in displayed alignment annotation TODO:
311    * add to jalviewXML and annotation display settings
312    */
313   boolean centreColumnLabels = false;
314
315   private boolean showdbrefs;
316
317   private boolean shownpfeats;
318
319   // --------END Structure Conservation
320
321   /**
322    * get the consensus sequence as displayed under the PID consensus annotation
323    * row.
324    * 
325    * @return consensus sequence as a new sequence object
326    */
327   public SequenceI getConsensusSeq()
328   {
329     if (consensus == null)
330     {
331       updateConsensus(null);
332     }
333     if (consensus == null)
334     {
335       return null;
336     }
337     StringBuffer seqs = new StringBuffer();
338     for (int i = 0; i < consensus.annotations.length; i++)
339     {
340       if (consensus.annotations[i] != null)
341       {
342         if (consensus.annotations[i].description.charAt(0) == '[')
343         {
344           seqs.append(consensus.annotations[i].description.charAt(1));
345         }
346         else
347         {
348           seqs.append(consensus.annotations[i].displayCharacter);
349         }
350       }
351     }
352
353     SequenceI sq = new Sequence("Consensus", seqs.toString());
354     sq.setDescription("Percentage Identity Consensus "
355             + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
356     return sq;
357   }
358
359   /**
360    * DOCUMENT ME!
361    * 
362    * @return DOCUMENT ME!
363    */
364   public int getStartRes()
365   {
366     return startRes;
367   }
368
369   /**
370    * DOCUMENT ME!
371    * 
372    * @return DOCUMENT ME!
373    */
374   public int getEndRes()
375   {
376     return endRes;
377   }
378
379   /**
380    * DOCUMENT ME!
381    * 
382    * @return DOCUMENT ME!
383    */
384   public int getStartSeq()
385   {
386     return startSeq;
387   }
388
389   /**
390    * DOCUMENT ME!
391    * 
392    * @param res
393    *          DOCUMENT ME!
394    */
395   public void setStartRes(int res)
396   {
397     this.startRes = res;
398   }
399
400   /**
401    * DOCUMENT ME!
402    * 
403    * @param seq
404    *          DOCUMENT ME!
405    */
406   public void setStartSeq(int seq)
407   {
408     this.startSeq = seq;
409   }
410
411   /**
412    * DOCUMENT ME!
413    * 
414    * @param res
415    *          DOCUMENT ME!
416    */
417   public void setEndRes(int res)
418   {
419     if (res > (alignment.getWidth() - 1))
420     {
421       // log.System.out.println(" Corrected res from " + res + " to maximum " +
422       // (alignment.getWidth()-1));
423       res = alignment.getWidth() - 1;
424     }
425
426     if (res < 0)
427     {
428       res = 0;
429     }
430
431     this.endRes = res;
432   }
433
434   /**
435    * DOCUMENT ME!
436    * 
437    * @param seq
438    *          DOCUMENT ME!
439    */
440   public void setEndSeq(int seq)
441   {
442     if (seq > alignment.getHeight())
443     {
444       seq = alignment.getHeight();
445     }
446
447     if (seq < 0)
448     {
449       seq = 0;
450     }
451
452     this.endSeq = seq;
453   }
454
455   /**
456    * DOCUMENT ME!
457    * 
458    * @return DOCUMENT ME!
459    */
460   public int getEndSeq()
461   {
462     return endSeq;
463   }
464
465   boolean validCharWidth;
466
467   /**
468    * DOCUMENT ME!
469    * 
470    * @param f
471    *          DOCUMENT ME!
472    */
473   public void setFont(Font f)
474   {
475     font = f;
476
477     Container c = new Container();
478
479     java.awt.FontMetrics fm = c.getFontMetrics(font);
480     setCharHeight(fm.getHeight());
481     setCharWidth(fm.charWidth('M'));
482     validCharWidth = true;
483   }
484
485   /**
486    * DOCUMENT ME!
487    * 
488    * @return DOCUMENT ME!
489    */
490   public Font getFont()
491   {
492     return font;
493   }
494
495   /**
496    * DOCUMENT ME!
497    * 
498    * @param align
499    *          DOCUMENT ME!
500    */
501   public void setAlignment(AlignmentI align)
502   {
503     if (alignment != null && alignment.getCodonFrames() != null)
504     {
505       StructureSelectionManager.getStructureSelectionManager(
506               Desktop.instance).removeMappings(alignment.getCodonFrames());
507     }
508     this.alignment = align;
509     if (alignment != null && alignment.getCodonFrames() != null)
510     {
511       StructureSelectionManager.getStructureSelectionManager(
512               Desktop.instance).addMappings(alignment.getCodonFrames());
513     }
514   }
515
516   /**
517    * DOCUMENT ME!
518    * 
519    * @return DOCUMENT ME!
520    */
521   public char getGapCharacter()
522   {
523     return getAlignment().getGapCharacter();
524   }
525
526   /**
527    * DOCUMENT ME!
528    * 
529    * @param gap
530    *          DOCUMENT ME!
531    */
532   public void setGapCharacter(char gap)
533   {
534     if (getAlignment() != null)
535     {
536       getAlignment().setGapCharacter(gap);
537     }
538   }
539
540   /**
541    * DOCUMENT ME!
542    * 
543    * @return DOCUMENT ME!
544    */
545   public ColumnSelection getColumnSelection()
546   {
547     return colSel;
548   }
549
550   /**
551    * DOCUMENT ME!
552    * 
553    * @param tree
554    *          DOCUMENT ME!
555    */
556   public void setCurrentTree(NJTree tree)
557   {
558     currentTree = tree;
559   }
560
561   /**
562    * DOCUMENT ME!
563    * 
564    * @return DOCUMENT ME!
565    */
566   public NJTree getCurrentTree()
567   {
568     return currentTree;
569   }
570
571   /**
572    * returns the visible column regions of the alignment
573    * 
574    * @param selectedRegionOnly
575    *          true to just return the contigs intersecting with the selected
576    *          area
577    * @return
578    */
579   public int[] getViewAsVisibleContigs(boolean selectedRegionOnly)
580   {
581     int[] viscontigs = null;
582     int start = 0, end = 0;
583     if (selectedRegionOnly && selectionGroup != null)
584     {
585       start = selectionGroup.getStartRes();
586       end = selectionGroup.getEndRes() + 1;
587     }
588     else
589     {
590       end = alignment.getWidth();
591     }
592     viscontigs = colSel.getVisibleContigs(start, end);
593     return viscontigs;
594   }
595
596   /**
597    * get hash of undo and redo list for the alignment
598    * 
599    * @return long[] { historyList.hashCode, redoList.hashCode };
600    */
601   public long[] getUndoRedoHash()
602   {
603     // TODO: JAL-1126
604     if (historyList == null || redoList == null)
605     {
606       return new long[]
607       { -1, -1 };
608     }
609     return new long[]
610     { historyList.hashCode(), this.redoList.hashCode() };
611   }
612
613   /**
614    * test if a particular set of hashcodes are different to the hashcodes for
615    * the undo and redo list.
616    * 
617    * @param undoredo
618    *          the stored set of hashcodes as returned by getUndoRedoHash
619    * @return true if the hashcodes differ (ie the alignment has been edited) or
620    *         the stored hashcode array differs in size
621    */
622   public boolean isUndoRedoHashModified(long[] undoredo)
623   {
624     if (undoredo == null)
625     {
626       return true;
627     }
628     long[] cstate = getUndoRedoHash();
629     if (cstate.length != undoredo.length)
630     {
631       return true;
632     }
633
634     for (int i = 0; i < cstate.length; i++)
635     {
636       if (cstate[i] != undoredo[i])
637       {
638         return true;
639       }
640     }
641     return false;
642   }
643
644   public boolean getCentreColumnLabels()
645   {
646     return centreColumnLabels;
647   }
648
649   public void setCentreColumnLabels(boolean centrecolumnlabels)
650   {
651     centreColumnLabels = centrecolumnlabels;
652   }
653
654   /**
655    * enable or disable the display of Database Cross References in the sequence
656    * ID tooltip
657    */
658   public void setShowDbRefs(boolean show)
659   {
660     showdbrefs = show;
661   }
662
663   /**
664    * 
665    * @return true if Database References are to be displayed on tooltips.
666    */
667   public boolean isShowDbRefs()
668   {
669     return showdbrefs;
670   }
671
672   /**
673    * 
674    * @return true if Non-positional features are to be displayed on tooltips.
675    */
676   public boolean isShowNpFeats()
677   {
678     return shownpfeats;
679   }
680
681   /**
682    * enable or disable the display of Non-Positional sequence features in the
683    * sequence ID tooltip
684    * 
685    * @param show
686    */
687   public void setShowNpFeats(boolean show)
688   {
689     shownpfeats = show;
690   }
691
692
693   /**
694    * when set, view will scroll to show the highlighted position
695    */
696   public boolean followHighlight = true;
697
698   /**
699    * @return true if view should scroll to show the highlighted region of a
700    *         sequence
701    * @return
702    */
703   public boolean getFollowHighlight()
704   {
705     return followHighlight;
706   }
707
708   public boolean followSelection = true;
709
710   /**
711    * @return true if view selection should always follow the selections
712    *         broadcast by other selection sources
713    */
714   public boolean getFollowSelection()
715   {
716     return followSelection;
717   }
718
719   public void sendSelection()
720   {
721     jalview.structure.StructureSelectionManager
722             .getStructureSelectionManager(Desktop.instance).sendSelection(
723                     new SequenceGroup(getSelectionGroup()),
724                     new ColumnSelection(getColumnSelection()), this);
725   }
726
727   /**
728    * return the alignPanel containing the given viewport. Use this to get the
729    * components currently handling the given viewport.
730    * 
731    * @param av
732    * @return null or an alignPanel guaranteed to have non-null alignFrame
733    *         reference
734    */
735   public AlignmentPanel getAlignPanel()
736   {
737     AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this
738             .getSequenceSetId());
739     AlignmentPanel ap = null;
740     for (int p = 0; aps != null && p < aps.length; p++)
741     {
742       if (aps[p].av == this)
743       {
744         return aps[p];
745       }
746     }
747     return null;
748   }
749
750   public boolean getSortByTree()
751   {
752     return sortByTree;
753   }
754
755   public void setSortByTree(boolean sort)
756   {
757     sortByTree = sort;
758   }
759
760   /**
761    * synthesize a column selection if none exists so it covers the given
762    * selection group. if wholewidth is false, no column selection is made if the
763    * selection group covers the whole alignment width.
764    * 
765    * @param sg
766    * @param wholewidth
767    */
768   public void expandColSelection(SequenceGroup sg, boolean wholewidth)
769   {
770     int sgs, sge;
771     if (sg != null
772             && (sgs = sg.getStartRes()) >= 0
773             && sg.getStartRes() <= (sge = sg.getEndRes())
774             && (colSel == null || colSel.getSelected() == null || colSel
775                     .getSelected().size() == 0))
776     {
777       if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
778       {
779         // do nothing
780         return;
781       }
782       if (colSel == null)
783       {
784         colSel = new ColumnSelection();
785       }
786       for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
787       {
788         colSel.addElement(cspos);
789       }
790     }
791   }
792
793   public StructureSelectionManager getStructureSelectionManager()
794   {
795     return StructureSelectionManager
796             .getStructureSelectionManager(Desktop.instance);
797   }
798
799   /**
800    * 
801    * @param pdbEntries
802    * @return a series of SequenceI arrays, one for each PDBEntry, listing which
803    *         sequence in the alignment holds a reference to it
804    */
805   public SequenceI[][] collateForPDB(PDBEntry[] pdbEntries)
806   {
807     ArrayList<SequenceI[]> seqvectors = new ArrayList<SequenceI[]>();
808     for (PDBEntry pdb : pdbEntries)
809     {
810       ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
811       for (int i = 0; i < alignment.getHeight(); i++)
812       {
813         Vector pdbs = alignment.getSequenceAt(i).getDatasetSequence()
814                 .getPDBId();
815         if (pdbs == null)
816         {
817           continue;
818         }
819         SequenceI sq;
820         for (int p = 0; p < pdbs.size(); p++)
821         {
822           PDBEntry p1 = (PDBEntry) pdbs.elementAt(p);
823           if (p1.getId().equals(pdb.getId()))
824           {
825             if (!seqs.contains(sq = alignment.getSequenceAt(i)))
826             {
827               seqs.add(sq);
828             }
829
830             continue;
831           }
832         }
833       }
834       seqvectors.add(seqs.toArray(new SequenceI[seqs.size()]));
835     }
836     return seqvectors.toArray(new SequenceI[seqvectors.size()][]);
837   }
838
839   public boolean isNormaliseSequenceLogo()
840   {
841     return normaliseSequenceLogo;
842   }
843
844   public void setNormaliseSequenceLogo(boolean state)
845   {
846     normaliseSequenceLogo = state;
847   }
848
849   /**
850    * 
851    * @return true if alignment characters should be displayed
852    */
853   public boolean isValidCharWidth()
854   {
855     return validCharWidth;
856   }
857
858   private Hashtable<String, AutoCalcSetting> calcIdParams = new Hashtable<String, AutoCalcSetting>();
859
860   private boolean showAutocalculatedAbove;
861
862   public AutoCalcSetting getCalcIdSettingsFor(String calcId)
863   {
864     return calcIdParams.get(calcId);
865   }
866
867   public void setCalcIdSettingsFor(String calcId, AutoCalcSetting settings,
868           boolean needsUpdate)
869   {
870     calcIdParams.put(calcId, settings);
871     // TODO: create a restart list to trigger any calculations that need to be
872     // restarted after load
873     // calculator.getRegisteredWorkersOfClass(settings.getWorkerClass())
874     if (needsUpdate)
875     {
876       Cache.log.debug("trigger update for " + calcId);
877     }
878   }
879
880   protected SequenceAnnotationOrder getSortAnnotationsBy()
881   {
882     return sortAnnotationsBy;
883   }
884
885   protected void setSortAnnotationsBy(SequenceAnnotationOrder sortAnnotationsBy)
886   {
887     this.sortAnnotationsBy = sortAnnotationsBy;
888   }
889
890   protected boolean isShowAutocalculatedAbove()
891   {
892     return showAutocalculatedAbove;
893   }
894
895   protected void setShowAutocalculatedAbove(boolean showAutocalculatedAbove)
896   {
897     this.showAutocalculatedAbove = showAutocalculatedAbove;
898   }
899
900   public AnnotationColumnChooser getAnnotationColumnSelectionState()
901   {
902     return annotationColumnSelectionState;
903   }
904
905   public void setAnnotationColumnSelectionState(
906           AnnotationColumnChooser currentAnnotationColumnSelectionState)
907   {
908     this.annotationColumnSelectionState = currentAnnotationColumnSelectionState;
909   }
910 }