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