2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
22 * Jalview - A Sequence Alignment Editor and Viewer
23 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version 2
28 * of the License, or (at your option) any later version.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
41 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
42 import jalview.analysis.NJTree;
43 import jalview.api.AlignViewportI;
44 import jalview.bin.Cache;
45 import jalview.commands.CommandI;
46 import jalview.datamodel.AlignmentI;
47 import jalview.datamodel.ColumnSelection;
48 import jalview.datamodel.PDBEntry;
49 import jalview.datamodel.Sequence;
50 import jalview.datamodel.SequenceGroup;
51 import jalview.datamodel.SequenceI;
52 import jalview.schemes.ColourSchemeProperty;
53 import jalview.schemes.UserColourScheme;
54 import jalview.structure.SelectionSource;
55 import jalview.structure.StructureSelectionManager;
56 import jalview.structure.VamsasSource;
57 import jalview.viewmodel.AlignmentViewport;
58 import jalview.ws.params.AutoCalcSetting;
60 import java.awt.Color;
61 import java.awt.Container;
63 import java.awt.Rectangle;
64 import java.util.ArrayList;
65 import java.util.Hashtable;
66 import java.util.Stack;
67 import java.util.Vector;
73 * @version $Revision: 1.141 $
75 public class AlignViewport extends AlignmentViewport implements
76 SelectionSource, VamsasSource, AlignViewportI
86 boolean showJVSuffix = true;
88 boolean showText = true;
90 boolean showColourText = false;
92 boolean showBoxes = true;
94 boolean wrapAlignment = false;
96 boolean renderGaps = true;
98 boolean showSequenceFeatures = false;
100 private boolean showAnnotation = true;
102 SequenceAnnotationOrder sortAnnotationsBy = null;
108 boolean validCharWidth;
114 boolean seqNameItalics;
116 NJTree currentTree = null;
118 boolean scaleAboveWrapped = false;
120 boolean scaleLeftWrapped = true;
122 boolean scaleRightWrapped = true;
124 boolean showHiddenMarkers = true;
126 boolean cursorMode = false;
129 * Keys are the feature types which are currently visible. Note: Values are
132 private Hashtable featuresDisplayed = null;
134 boolean antiAlias = false;
136 Rectangle explodedPosition;
140 boolean gatherViewsHere = false;
142 Stack<CommandI> historyList = new Stack<CommandI>();
144 Stack<CommandI> redoList = new Stack<CommandI>();
146 int thresholdTextColour = 0;
148 Color textColour = Color.black;
150 Color textColour2 = Color.white;
152 private boolean rightAlignIds = false;
154 private AnnotationColumnChooser currentAnnotationColumnSelectionState;
156 * Creates a new AlignViewport object.
161 public AlignViewport(AlignmentI al)
168 * Create a new AlignViewport object with a specific sequence set ID
172 * (may be null - but potential for ambiguous constructor exception)
174 public AlignViewport(AlignmentI al, String seqsetid)
176 this(al, seqsetid, null);
179 public AlignViewport(AlignmentI al, String seqsetid, String viewid)
181 sequenceSetID = seqsetid;
183 // TODO remove these once 2.4.VAMSAS release finished
184 if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null)
186 Cache.log.debug("Setting viewport's sequence set id : "
189 if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null)
191 Cache.log.debug("Setting viewport's view id : " + viewId);
198 * Create a new AlignViewport with hidden regions
202 * @param hiddenColumns
205 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns)
208 if (hiddenColumns != null)
210 this.colSel = hiddenColumns;
211 if (hiddenColumns.getHiddenColumns() != null
212 && hiddenColumns.getHiddenColumns().size() > 0)
214 hasHiddenColumns = true;
218 hasHiddenColumns = false;
225 * New viewport with hidden columns and an existing sequence set id
228 * @param hiddenColumns
232 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns,
235 this(al, hiddenColumns, seqsetid, null);
239 * New viewport with hidden columns and an existing sequence set id and viewid
242 * @param hiddenColumns
248 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns,
249 String seqsetid, String viewid)
251 sequenceSetID = seqsetid;
253 // TODO remove these once 2.4.VAMSAS release finished
254 if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null)
256 Cache.log.debug("Setting viewport's sequence set id : "
259 if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null)
261 Cache.log.debug("Setting viewport's view id : " + viewId);
264 if (hiddenColumns != null)
266 this.colSel = hiddenColumns;
267 if (hiddenColumns.getHiddenColumns() != null
268 && hiddenColumns.getHiddenColumns().size() > 0)
270 hasHiddenColumns = true;
274 hasHiddenColumns = false;
283 this.endRes = alignment.getWidth() - 1;
285 this.endSeq = alignment.getHeight() - 1;
287 antiAlias = Cache.getDefault("ANTI_ALIAS", false);
289 showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);
290 setShowAnnotation(Cache.getDefault("SHOW_ANNOTATIONS", true));
292 setRightAlignIds(Cache.getDefault("RIGHT_ALIGN_IDS", false));
293 centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false);
294 autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
296 setPadGaps(Cache.getDefault("PAD_GAPS", true));
297 shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true);
298 showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP", true);
300 String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
301 String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "");
302 String fontSize = Cache.getDefault("FONT_SIZE", "10");
304 seqNameItalics = Cache.getDefault("ID_ITALICS", true);
308 if (fontStyle.equals("bold"))
312 else if (fontStyle.equals("italic"))
317 setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
320 .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
322 // We must set conservation and consensus before setting colour,
323 // as Blosum and Clustal require this to be done
324 if (hconsensus == null && !isDataset)
326 if (!alignment.isNucleotide())
328 showConservation = Cache.getDefault("SHOW_CONSERVATION", true);
329 showQuality = Cache.getDefault("SHOW_QUALITY", true);
330 showGroupConservation = Cache.getDefault("SHOW_GROUP_CONSERVATION",
333 showConsensusHistogram = Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM",
335 showSequenceLogo = Cache.getDefault("SHOW_CONSENSUS_LOGO", false);
336 normaliseSequenceLogo = Cache.getDefault("NORMALISE_CONSENSUS_LOGO",
338 showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false);
339 showConsensus = Cache.getDefault("SHOW_IDENTITY", true);
341 initAutoAnnotation();
342 if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
344 globalColourScheme = ColourSchemeProperty.getColour(alignment,
345 jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
347 if (globalColourScheme instanceof UserColourScheme)
349 globalColourScheme = UserDefinedColours.loadDefaultColours();
350 ((UserColourScheme) globalColourScheme).setThreshold(0,
351 getIgnoreGapsConsensus());
354 if (globalColourScheme != null)
356 globalColourScheme.setConsensus(hconsensus);
360 wrapAlignment = Cache.getDefault("WRAP_ALIGNMENT", false);
361 showUnconserved = Cache.getDefault("SHOW_UNCONSERVED", false);
362 sortByTree = Cache.getDefault("SORT_BY_TREE", false);
363 followSelection = Cache.getDefault("FOLLOW_SELECTIONS", true);
364 sortAnnotationsBy = SequenceAnnotationOrder.valueOf(Cache.getDefault(
365 Preferences.SORT_ANNOTATIONS,
366 SequenceAnnotationOrder.NONE.name()));
367 showAutocalculatedAbove = Cache.getDefault(
368 Preferences.SHOW_AUTOCALC_ABOVE, false);
375 * features are displayed if true
377 public void setShowSequenceFeatures(boolean b)
379 showSequenceFeatures = b;
382 public boolean getShowSequenceFeatures()
384 return showSequenceFeatures;
388 * centre columnar annotation labels in displayed alignment annotation TODO:
389 * add to jalviewXML and annotation display settings
391 boolean centreColumnLabels = false;
393 private boolean showdbrefs;
395 private boolean shownpfeats;
397 // --------END Structure Conservation
400 * get the consensus sequence as displayed under the PID consensus annotation
403 * @return consensus sequence as a new sequence object
405 public SequenceI getConsensusSeq()
407 if (consensus == null)
409 updateConsensus(null);
411 if (consensus == null)
415 StringBuffer seqs = new StringBuffer();
416 for (int i = 0; i < consensus.annotations.length; i++)
418 if (consensus.annotations[i] != null)
420 if (consensus.annotations[i].description.charAt(0) == '[')
422 seqs.append(consensus.annotations[i].description.charAt(1));
426 seqs.append(consensus.annotations[i].displayCharacter);
431 SequenceI sq = new Sequence("Consensus", seqs.toString());
432 sq.setDescription("Percentage Identity Consensus "
433 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
440 * @return DOCUMENT ME!
442 public int getStartRes()
450 * @return DOCUMENT ME!
452 public int getEndRes()
460 * @return DOCUMENT ME!
462 public int getStartSeq()
473 public void setStartRes(int res)
484 public void setStartSeq(int seq)
495 public void setEndRes(int res)
497 if (res > (alignment.getWidth() - 1))
499 // log.System.out.println(" Corrected res from " + res + " to maximum " +
500 // (alignment.getWidth()-1));
501 res = alignment.getWidth() - 1;
518 public void setEndSeq(int seq)
520 if (seq > alignment.getHeight())
522 seq = alignment.getHeight();
536 * @return DOCUMENT ME!
538 public int getEndSeq()
549 public void setFont(Font f)
553 Container c = new Container();
555 java.awt.FontMetrics fm = c.getFontMetrics(font);
556 setCharHeight(fm.getHeight());
557 setCharWidth(fm.charWidth('M'));
558 validCharWidth = true;
564 * @return DOCUMENT ME!
566 public Font getFont()
577 public void setCharWidth(int w)
585 * @return DOCUMENT ME!
587 public int getCharWidth()
598 public void setCharHeight(int h)
606 * @return DOCUMENT ME!
608 public int getCharHeight()
619 public void setWrappedWidth(int w)
621 this.wrappedWidth = w;
627 * @return DOCUMENT ME!
629 public int getWrappedWidth()
637 * @return DOCUMENT ME!
639 public AlignmentI getAlignment()
650 public void setAlignment(AlignmentI align)
652 if (alignment != null && alignment.getCodonFrames() != null)
654 StructureSelectionManager.getStructureSelectionManager(
655 Desktop.instance).removeMappings(alignment.getCodonFrames());
657 this.alignment = align;
658 if (alignment != null && alignment.getCodonFrames() != null)
660 StructureSelectionManager.getStructureSelectionManager(
661 Desktop.instance).addMappings(alignment.getCodonFrames());
671 public void setWrapAlignment(boolean state)
673 wrapAlignment = state;
682 public void setShowText(boolean state)
693 public void setRenderGaps(boolean state)
701 * @return DOCUMENT ME!
703 public boolean getColourText()
705 return showColourText;
714 public void setColourText(boolean state)
716 showColourText = state;
725 public void setShowBoxes(boolean state)
733 * @return DOCUMENT ME!
735 public boolean getWrapAlignment()
737 return wrapAlignment;
743 * @return DOCUMENT ME!
745 public boolean getShowText()
753 * @return DOCUMENT ME!
755 public boolean getShowBoxes()
763 * @return DOCUMENT ME!
765 public char getGapCharacter()
767 return getAlignment().getGapCharacter();
776 public void setGapCharacter(char gap)
778 if (getAlignment() != null)
780 getAlignment().setGapCharacter(gap);
787 * @return DOCUMENT ME!
789 public ColumnSelection getColumnSelection()
800 public void setCurrentTree(NJTree tree)
808 * @return DOCUMENT ME!
810 public NJTree getCurrentTree()
818 * @return DOCUMENT ME!
820 public boolean getShowJVSuffix()
831 public void setShowJVSuffix(boolean b)
839 * @return DOCUMENT ME!
841 public boolean getShowAnnotation()
843 return isShowAnnotation();
852 public void setShowAnnotation(boolean b)
860 * @return DOCUMENT ME!
862 public boolean getScaleAboveWrapped()
864 return scaleAboveWrapped;
870 * @return DOCUMENT ME!
872 public boolean getScaleLeftWrapped()
874 return scaleLeftWrapped;
880 * @return DOCUMENT ME!
882 public boolean getScaleRightWrapped()
884 return scaleRightWrapped;
893 public void setScaleAboveWrapped(boolean b)
895 scaleAboveWrapped = b;
904 public void setScaleLeftWrapped(boolean b)
906 scaleLeftWrapped = b;
915 public void setScaleRightWrapped(boolean b)
917 scaleRightWrapped = b;
920 public void setDataset(boolean b)
925 public boolean isDataset()
930 public boolean getShowHiddenMarkers()
932 return showHiddenMarkers;
935 public void setShowHiddenMarkers(boolean show)
937 showHiddenMarkers = show;
941 * returns the visible column regions of the alignment
943 * @param selectedRegionOnly
944 * true to just return the contigs intersecting with the selected
948 public int[] getViewAsVisibleContigs(boolean selectedRegionOnly)
950 int[] viscontigs = null;
951 int start = 0, end = 0;
952 if (selectedRegionOnly && selectionGroup != null)
954 start = selectionGroup.getStartRes();
955 end = selectionGroup.getEndRes() + 1;
959 end = alignment.getWidth();
961 viscontigs = colSel.getVisibleContigs(start, end);
966 * get hash of undo and redo list for the alignment
968 * @return long[] { historyList.hashCode, redoList.hashCode };
970 public long[] getUndoRedoHash()
973 if (historyList == null || redoList == null)
979 { historyList.hashCode(), this.redoList.hashCode() };
983 * test if a particular set of hashcodes are different to the hashcodes for
984 * the undo and redo list.
987 * the stored set of hashcodes as returned by getUndoRedoHash
988 * @return true if the hashcodes differ (ie the alignment has been edited) or
989 * the stored hashcode array differs in size
991 public boolean isUndoRedoHashModified(long[] undoredo)
993 if (undoredo == null)
997 long[] cstate = getUndoRedoHash();
998 if (cstate.length != undoredo.length)
1003 for (int i = 0; i < cstate.length; i++)
1005 if (cstate[i] != undoredo[i])
1013 public boolean getCentreColumnLabels()
1015 return centreColumnLabels;
1018 public void setCentreColumnLabels(boolean centrecolumnlabels)
1020 centreColumnLabels = centrecolumnlabels;
1024 * enable or disable the display of Database Cross References in the sequence
1027 public void setShowDbRefs(boolean show)
1034 * @return true if Database References are to be displayed on tooltips.
1036 public boolean isShowDbRefs()
1043 * @return true if Non-positional features are to be displayed on tooltips.
1045 public boolean isShowNpFeats()
1051 * enable or disable the display of Non-Positional sequence features in the
1052 * sequence ID tooltip
1056 public void setShowNpFeats(boolean show)
1063 * @return true if view has hidden rows
1065 public boolean hasHiddenRows()
1067 return hasHiddenRows;
1072 * @return true if view has hidden columns
1074 public boolean hasHiddenColumns()
1076 return hasHiddenColumns;
1080 * when set, view will scroll to show the highlighted position
1082 public boolean followHighlight = true;
1085 * @return true if view should scroll to show the highlighted region of a
1089 public boolean getFollowHighlight()
1091 return followHighlight;
1094 public boolean followSelection = true;
1097 * @return true if view selection should always follow the selections
1098 * broadcast by other selection sources
1100 public boolean getFollowSelection()
1102 return followSelection;
1105 boolean showSeqFeaturesHeight;
1107 public void sendSelection()
1109 jalview.structure.StructureSelectionManager
1110 .getStructureSelectionManager(Desktop.instance).sendSelection(
1111 new SequenceGroup(getSelectionGroup()),
1112 new ColumnSelection(getColumnSelection()), this);
1115 public void setShowSequenceFeaturesHeight(boolean selected)
1117 showSeqFeaturesHeight = selected;
1120 public boolean getShowSequenceFeaturesHeight()
1122 return showSeqFeaturesHeight;
1126 * return the alignPanel containing the given viewport. Use this to get the
1127 * components currently handling the given viewport.
1130 * @return null or an alignPanel guaranteed to have non-null alignFrame
1133 public AlignmentPanel getAlignPanel()
1135 AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this
1136 .getSequenceSetId());
1137 AlignmentPanel ap = null;
1138 for (int p = 0; aps != null && p < aps.length; p++)
1140 if (aps[p].av == this)
1148 public boolean getSortByTree()
1153 public void setSortByTree(boolean sort)
1159 * synthesize a column selection if none exists so it covers the given
1160 * selection group. if wholewidth is false, no column selection is made if the
1161 * selection group covers the whole alignment width.
1166 public void expandColSelection(SequenceGroup sg, boolean wholewidth)
1170 && (sgs = sg.getStartRes()) >= 0
1171 && sg.getStartRes() <= (sge = sg.getEndRes())
1172 && (colSel == null || colSel.getSelected() == null || colSel
1173 .getSelected().size() == 0))
1175 if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
1182 colSel = new ColumnSelection();
1184 for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
1186 colSel.addElement(cspos);
1191 public StructureSelectionManager getStructureSelectionManager()
1193 return StructureSelectionManager
1194 .getStructureSelectionManager(Desktop.instance);
1200 * @return a series of SequenceI arrays, one for each PDBEntry, listing which
1201 * sequence in the alignment holds a reference to it
1203 public SequenceI[][] collateForPDB(PDBEntry[] pdbEntries)
1205 ArrayList<SequenceI[]> seqvectors = new ArrayList<SequenceI[]>();
1206 for (PDBEntry pdb : pdbEntries)
1208 ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
1209 for (int i = 0; i < alignment.getHeight(); i++)
1211 Vector pdbs = alignment.getSequenceAt(i).getDatasetSequence()
1218 for (int p = 0; p < pdbs.size(); p++)
1220 PDBEntry p1 = (PDBEntry) pdbs.elementAt(p);
1221 if (p1.getId().equals(pdb.getId()))
1223 if (!seqs.contains(sq = alignment.getSequenceAt(i)))
1232 seqvectors.add(seqs.toArray(new SequenceI[seqs.size()]));
1234 return seqvectors.toArray(new SequenceI[seqvectors.size()][]);
1237 public boolean isNormaliseSequenceLogo()
1239 return normaliseSequenceLogo;
1242 public void setNormaliseSequenceLogo(boolean state)
1244 normaliseSequenceLogo = state;
1249 * @return true if alignment characters should be displayed
1251 public boolean isValidCharWidth()
1253 return validCharWidth;
1256 private Hashtable<String, AutoCalcSetting> calcIdParams = new Hashtable<String, AutoCalcSetting>();
1258 private boolean showAutocalculatedAbove;
1260 public AutoCalcSetting getCalcIdSettingsFor(String calcId)
1262 return calcIdParams.get(calcId);
1265 public void setCalcIdSettingsFor(String calcId, AutoCalcSetting settings,
1266 boolean needsUpdate)
1268 calcIdParams.put(calcId, settings);
1269 // TODO: create a restart list to trigger any calculations that need to be
1270 // restarted after load
1271 // calculator.getRegisteredWorkersOfClass(settings.getWorkerClass())
1274 Cache.log.debug("trigger update for " + calcId);
1279 public Hashtable getFeaturesDisplayed()
1281 return featuresDisplayed;
1284 public void setFeaturesDisplayed(Hashtable featuresDisplayed)
1286 this.featuresDisplayed = featuresDisplayed;
1288 protected SequenceAnnotationOrder getSortAnnotationsBy()
1290 return sortAnnotationsBy;
1293 protected void setSortAnnotationsBy(SequenceAnnotationOrder sortAnnotationsBy)
1295 this.sortAnnotationsBy = sortAnnotationsBy;
1298 protected boolean isShowAutocalculatedAbove()
1300 return showAutocalculatedAbove;
1303 protected void setShowAutocalculatedAbove(boolean showAutocalculatedAbove)
1305 this.showAutocalculatedAbove = showAutocalculatedAbove;
1308 public boolean isShowAnnotation()
1310 return showAnnotation;
1313 public boolean isRightAlignIds()
1315 return rightAlignIds;
1318 public void setRightAlignIds(boolean rightAlignIds)
1320 this.rightAlignIds = rightAlignIds;
1323 public AnnotationColumnChooser getCurrentAnnotationColumnSelectionState()
1325 return currentAnnotationColumnSelectionState;
1328 public void setCurrentAnnotationColumnSelectionState(
1329 AnnotationColumnChooser currentAnnotationColumnSelectionState)
1331 this.currentAnnotationColumnSelectionState = currentAnnotationColumnSelectionState;