2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 import jalview.analysis.*;
25 import jalview.datamodel.*;
27 import jalview.schemes.*;
40 public class AlignViewport
46 boolean showJVSuffix = true;
47 boolean showText = true;
48 boolean showColourText = false;
49 boolean showBoxes = true;
50 boolean wrapAlignment = false;
51 boolean renderGaps = true;
52 boolean showSequenceFeatures = false;
53 boolean showAnnotation = true;
54 boolean showConservation = true;
55 boolean showQuality = true;
56 boolean showIdentity = true;
57 boolean colourAppliesToAllGroups = true;
58 ColourSchemeI globalColourScheme = null;
59 boolean conservationColourSelected = false;
60 boolean abovePIDThreshold = false;
61 SequenceGroup selectionGroup;
64 boolean validCharWidth;
68 ColumnSelection colSel = new ColumnSelection();
71 NJTree currentTree = null;
72 boolean scaleAboveWrapped = false;
73 boolean scaleLeftWrapped = true;
74 boolean scaleRightWrapped = true;
75 boolean hasHiddenColumns = false;
76 boolean hasHiddenRows = false;
77 boolean showHiddenMarkers = true;
79 boolean cursorMode = false;
81 // The following vector holds the features which are
82 // currently visible, in the correct order or rendering
83 Hashtable featuresDisplayed = null;
87 public Vector vconsensus;
88 AlignmentAnnotation consensus;
89 AlignmentAnnotation conservation;
90 AlignmentAnnotation quality;
91 boolean autoCalculateConsensus = true;
94 public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
96 // JBPNote Prolly only need this in the applet version.
97 private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);
99 boolean ignoreGapsInConsensusCalculation = false;
101 boolean isDataset = false;
103 boolean antiAlias = false;
105 boolean padGaps = false;
108 public AlignViewport(AlignmentI al, boolean dataset)
115 * Creates a new AlignViewport object.
117 * @param al DOCUMENT ME!
119 public AlignViewport(AlignmentI al)
125 * Create a new AlignViewport with hidden regions
126 * @param al AlignmentI
127 * @param hiddenColumns ColumnSelection
129 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns) {
131 if (hiddenColumns!=null) {
132 this.colSel = hiddenColumns;
133 if (hiddenColumns.getHiddenColumns() != null)
134 hasHiddenColumns = true;
142 this.endRes = alignment.getWidth() - 1;
144 this.endSeq = alignment.getHeight() - 1;
146 antiAlias = Cache.getDefault("ANTI_ALIAS", false);
148 showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);
149 showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);
150 showConservation = Cache.getDefault("SHOW_CONSERVATION", true);
152 showQuality = Cache.getDefault("SHOW_QUALITY", true);
153 showIdentity = Cache.getDefault("SHOW_IDENTITY", true);
155 autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
157 padGaps = Cache.getDefault("PAD_GAPS", false);
159 String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
160 String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "") ;
161 String fontSize = Cache.getDefault("FONT_SIZE", "10");
165 if (fontStyle.equals("bold"))
169 else if (fontStyle.equals("italic"))
174 setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
177 alignment.setGapCharacter( Cache.getDefault("GAP_SYMBOL", "-").charAt(0) );
180 // We must set conservation and consensus before setting colour,
181 // as Blosum and Clustal require this to be done
182 if(vconsensus==null && !isDataset)
184 updateConservation();
188 if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
190 globalColourScheme = ColourSchemeProperty.getColour(alignment,
191 jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
193 if (globalColourScheme instanceof UserColourScheme)
195 globalColourScheme = UserDefinedColours.loadDefaultColours();
196 ((UserColourScheme)globalColourScheme).setThreshold(0, getIgnoreGapsConsensus());
199 if (globalColourScheme != null)
201 globalColourScheme.setConsensus(vconsensus);
211 * @param b DOCUMENT ME!
213 public void setShowSequenceFeatures(boolean b)
215 showSequenceFeatures = b;
218 public boolean getShowSequenceFeatures()
220 return showSequenceFeatures;
226 public void updateConservation()
228 if(alignment.isNucleotide())
232 Conservation cons = new jalview.analysis.Conservation("All",
233 jalview.schemes.ResidueProperties.propHash, 3,
234 alignment.getSequences(), 0, alignment.getWidth() - 1);
236 cons.verdict(false, ConsPercGaps);
239 int alWidth = alignment.getWidth();
240 Annotation[] annotations = new Annotation[alWidth];
241 Annotation[] qannotations = new Annotation[alWidth];
242 String sequence = cons.getConsSequence().getSequence();
254 maxB = 0f - minB; // scalable range for colouring both Conservation and Quality
258 float qmin = cons.qualityRange[0].floatValue();
259 float qmax = cons.qualityRange[1].floatValue();
261 for (int i = 0; i < alWidth; i++)
267 value = Integer.parseInt(sequence.charAt(i) + "");
271 if (sequence.charAt(i) == '*')
276 if (sequence.charAt(i) == '+')
282 float vprop = value - min;
284 annotations[i] = new Annotation(sequence.charAt(i) + "",
285 String.valueOf(value), ' ', value,
286 new Color(minR + (maxR * vprop),
287 minG + (maxG * vprop),
288 minB + (maxB * vprop)));
291 value = ( (Double) cons.quality.get(i)).floatValue();
292 vprop = value - qmin;
294 qannotations[i] = new Annotation(" ", String.valueOf(value), ' ',
296 new Color(minR + (maxR * vprop),
297 minG + (maxG * vprop),
298 minB + (maxB * vprop)));
301 if (conservation == null)
303 conservation = new AlignmentAnnotation("Conservation",
304 "Conservation of total alignment less than " +
305 ConsPercGaps + "% gaps",
306 annotations, 0f, // cons.qualityRange[0].floatValue(),
307 11f, // cons.qualityRange[1].floatValue()
308 AlignmentAnnotation.BAR_GRAPH);
310 if (showConservation)
312 alignment.addAnnotation(conservation);
315 quality = new AlignmentAnnotation("Quality",
316 "Alignment Quality based on Blosum62 scores",
318 cons.qualityRange[0].floatValue(),
319 cons.qualityRange[1].floatValue(),
320 AlignmentAnnotation.BAR_GRAPH);
324 alignment.addAnnotation(quality);
329 conservation.annotations = annotations;
330 quality.annotations = qannotations;
331 quality.graphMax = cons.qualityRange[1].floatValue();
334 catch (OutOfMemoryError error)
336 javax.swing.SwingUtilities.invokeLater(new Runnable()
340 javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
341 "Out of memory calculating conservation!!"
343 "\nSee help files for increasing Java Virtual Machine memory."
345 javax.swing.JOptionPane.WARNING_MESSAGE);
349 System.out.println("Conservation calculation: " + error);
358 public void updateConsensus()
361 Annotation[] annotations = new Annotation[alignment.getWidth()];
363 // this routine prevents vconsensus becoming a new object each time
364 // consenus is calculated. Important for speed of Blosum62
365 // and PID colouring of alignment
366 if (vconsensus == null)
368 vconsensus = alignment.getAAFrequency();
372 Vector temp = alignment.getAAFrequency();
375 Enumeration e = temp.elements();
377 while (e.hasMoreElements())
379 vconsensus.add(e.nextElement());
383 Hashtable hash = null;
385 for (int i = 0; i < alignment.getWidth(); i++)
387 hash = (Hashtable) vconsensus.elementAt(i);
390 if (ignoreGapsInConsensusCalculation)
391 value = ( (Float) hash.get("pid_nogaps")).floatValue();
393 value = ( (Float) hash.get("pid_gaps")).floatValue();
395 String maxRes = hash.get("maxResidue").toString();
396 String mouseOver = hash.get("maxResidue") + " ";
398 if (maxRes.length() > 1)
400 mouseOver = "[" + maxRes + "] ";
404 mouseOver += ( (int) value + "%");
405 annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);
408 if (consensus == null)
410 consensus = new AlignmentAnnotation("Consensus", "PID",
411 annotations, 0f, 100f,AlignmentAnnotation.BAR_GRAPH);
415 alignment.addAnnotation(consensus);
420 consensus.annotations = annotations;
423 if (globalColourScheme != null)
424 globalColourScheme.setConsensus(vconsensus);
426 }catch(OutOfMemoryError error)
428 javax.swing.SwingUtilities.invokeLater(new Runnable()
432 javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
433 "Out of memory calculating consensus!!"
435 "\nSee help files for increasing Java Virtual Machine memory."
437 javax.swing.JOptionPane.WARNING_MESSAGE);
442 System.out.println("Consensus calculation: " + error);
448 * get the consensus sequence as displayed under the PID consensus annotation row.
449 * @return consensus sequence as a new sequence object
451 public SequenceI getConsensusSeq() {
456 StringBuffer seqs=new StringBuffer();
457 for (int i=0; i<consensus.annotations.length; i++) {
458 if (consensus.annotations[i]!=null) {
459 if (consensus.annotations[i].description.charAt(0) == '[')
460 seqs.append(consensus.annotations[i].description.charAt(1));
462 seqs.append(consensus.annotations[i].displayCharacter);
465 SequenceI sq = new Sequence("Consensus", seqs.toString());
466 sq.setDescription("Percentage Identity Consensus "+((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
472 * @return DOCUMENT ME!
474 public SequenceGroup getSelectionGroup()
476 return selectionGroup;
482 * @param sg DOCUMENT ME!
484 public void setSelectionGroup(SequenceGroup sg)
492 * @return DOCUMENT ME!
494 public boolean getConservationSelected()
496 return conservationColourSelected;
502 * @param b DOCUMENT ME!
504 public void setConservationSelected(boolean b)
506 conservationColourSelected = b;
512 * @return DOCUMENT ME!
514 public boolean getAbovePIDThreshold()
516 return abovePIDThreshold;
522 * @param b DOCUMENT ME!
524 public void setAbovePIDThreshold(boolean b)
526 abovePIDThreshold = b;
532 * @return DOCUMENT ME!
534 public int getStartRes()
542 * @return DOCUMENT ME!
544 public int getEndRes()
552 * @return DOCUMENT ME!
554 public int getStartSeq()
562 * @param cs DOCUMENT ME!
564 public void setGlobalColourScheme(ColourSchemeI cs)
566 globalColourScheme = cs;
572 * @return DOCUMENT ME!
574 public ColourSchemeI getGlobalColourScheme()
576 return globalColourScheme;
582 * @param res DOCUMENT ME!
584 public void setStartRes(int res)
592 * @param seq DOCUMENT ME!
594 public void setStartSeq(int seq)
602 * @param res DOCUMENT ME!
604 public void setEndRes(int res)
606 if (res > (alignment.getWidth() - 1))
608 // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));
609 res = alignment.getWidth() - 1;
623 * @param seq DOCUMENT ME!
625 public void setEndSeq(int seq)
627 if (seq > alignment.getHeight())
629 seq = alignment.getHeight();
643 * @return DOCUMENT ME!
645 public int getEndSeq()
653 * @param f DOCUMENT ME!
655 public void setFont(Font f)
659 Container c = new Container();
661 java.awt.FontMetrics fm = c.getFontMetrics(font);
662 setCharHeight(fm.getHeight());
663 setCharWidth(fm.charWidth('M'));
664 validCharWidth = true;
670 * @return DOCUMENT ME!
672 public Font getFont()
680 * @param w DOCUMENT ME!
682 public void setCharWidth(int w)
690 * @return DOCUMENT ME!
692 public int getCharWidth()
700 * @param h DOCUMENT ME!
702 public void setCharHeight(int h)
710 * @return DOCUMENT ME!
712 public int getCharHeight()
720 * @param w DOCUMENT ME!
722 public void setWrappedWidth(int w)
724 this.wrappedWidth = w;
730 * @return DOCUMENT ME!
732 public int getWrappedWidth()
741 * @return DOCUMENT ME!
743 public AlignmentI getAlignment()
751 * @param align DOCUMENT ME!
753 public void setAlignment(AlignmentI align)
755 this.alignment = align;
761 * @param state DOCUMENT ME!
763 public void setWrapAlignment(boolean state)
765 wrapAlignment = state;
771 * @param state DOCUMENT ME!
773 public void setShowText(boolean state)
781 * @param state DOCUMENT ME!
783 public void setRenderGaps(boolean state)
791 * @return DOCUMENT ME!
793 public boolean getColourText()
795 return showColourText;
801 * @param state DOCUMENT ME!
803 public void setColourText(boolean state)
805 showColourText = state;
811 * @param state DOCUMENT ME!
813 public void setShowBoxes(boolean state)
821 * @return DOCUMENT ME!
823 public boolean getWrapAlignment()
825 return wrapAlignment;
831 * @return DOCUMENT ME!
833 public boolean getShowText()
841 * @return DOCUMENT ME!
843 public boolean getShowBoxes()
851 * @return DOCUMENT ME!
853 public char getGapCharacter()
855 return getAlignment().getGapCharacter();
861 * @param gap DOCUMENT ME!
863 public void setGapCharacter(char gap)
865 if (getAlignment() != null)
867 getAlignment().setGapCharacter(gap);
874 * @param thresh DOCUMENT ME!
876 public void setThreshold(int thresh)
884 * @return DOCUMENT ME!
886 public int getThreshold()
894 * @param inc DOCUMENT ME!
896 public void setIncrement(int inc)
904 * @return DOCUMENT ME!
906 public int getIncrement()
915 * @return DOCUMENT ME!
917 public ColumnSelection getColumnSelection()
926 * @param tree DOCUMENT ME!
928 public void setCurrentTree(NJTree tree)
936 * @return DOCUMENT ME!
938 public NJTree getCurrentTree()
946 * @param b DOCUMENT ME!
948 public void setColourAppliesToAllGroups(boolean b)
950 colourAppliesToAllGroups = b;
956 * @return DOCUMENT ME!
958 public boolean getColourAppliesToAllGroups()
960 return colourAppliesToAllGroups;
966 * @return DOCUMENT ME!
968 public boolean getShowJVSuffix()
976 * @param b DOCUMENT ME!
978 public void setShowJVSuffix(boolean b)
987 * @return DOCUMENT ME!
989 public boolean getShowAnnotation()
991 return showAnnotation;
997 * @param b DOCUMENT ME!
999 public void setShowAnnotation(boolean b)
1007 * @return DOCUMENT ME!
1009 public boolean getScaleAboveWrapped()
1011 return scaleAboveWrapped;
1017 * @return DOCUMENT ME!
1019 public boolean getScaleLeftWrapped()
1021 return scaleLeftWrapped;
1027 * @return DOCUMENT ME!
1029 public boolean getScaleRightWrapped()
1031 return scaleRightWrapped;
1037 * @param b DOCUMENT ME!
1039 public void setScaleAboveWrapped(boolean b)
1041 scaleAboveWrapped = b;
1047 * @param b DOCUMENT ME!
1049 public void setScaleLeftWrapped(boolean b)
1051 scaleLeftWrapped = b;
1057 * @param b DOCUMENT ME!
1059 public void setScaleRightWrapped(boolean b)
1061 scaleRightWrapped = b;
1065 * Property change listener for changes in alignment
1067 * @param listener DOCUMENT ME!
1069 public void addPropertyChangeListener(
1070 java.beans.PropertyChangeListener listener)
1072 changeSupport.addPropertyChangeListener(listener);
1078 * @param listener DOCUMENT ME!
1080 public void removePropertyChangeListener(
1081 java.beans.PropertyChangeListener listener)
1083 changeSupport.removePropertyChangeListener(listener);
1087 * Property change listener for changes in alignment
1089 * @param prop DOCUMENT ME!
1090 * @param oldvalue DOCUMENT ME!
1091 * @param newvalue DOCUMENT ME!
1093 public void firePropertyChange(String prop, Object oldvalue, Object newvalue)
1095 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1098 public void setIgnoreGapsConsensus(boolean b)
1100 ignoreGapsInConsensusCalculation = b;
1102 if(globalColourScheme!=null)
1104 globalColourScheme.setThreshold(globalColourScheme.getThreshold(), ignoreGapsInConsensusCalculation);
1108 public boolean getIgnoreGapsConsensus()
1110 return ignoreGapsInConsensusCalculation;
1113 public void setDataset(boolean b)
1118 public boolean isDataset()
1124 public void hideSelectedColumns()
1126 if (colSel.size() < 1)
1129 colSel.hideSelectedColumns();
1130 setSelectionGroup(null);
1132 hasHiddenColumns = true;
1136 public void hideColumns(int start, int end)
1139 colSel.hideColumns(start);
1141 colSel.hideColumns(start, end);
1143 hasHiddenColumns = true;
1146 public void hideAllSelectedSeqs()
1148 if (selectionGroup == null)
1151 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1155 setSelectionGroup(null);
1158 public void hideSequence(SequenceI [] seq)
1162 for (int i = 0; i < seq.length; i++)
1163 alignment.getHiddenSequences().hideSequence(seq[i]);
1165 hasHiddenRows = true;
1166 firePropertyChange("alignment", null, alignment.getSequences());
1170 public void showSequence(int index)
1172 Vector tmp = alignment.getHiddenSequences().showSequence(index);
1175 if(selectionGroup==null)
1177 selectionGroup = new SequenceGroup();
1178 selectionGroup.setEndRes(alignment.getWidth()-1);
1181 for (int t = 0; t < tmp.size(); t++)
1183 selectionGroup.addSequence(
1184 (SequenceI) tmp.elementAt(t), false
1187 firePropertyChange("alignment", null, alignment.getSequences());
1190 if(alignment.getHiddenSequences().getSize()<1)
1191 hasHiddenRows = false;
1194 public void showColumn(int col)
1196 colSel.revealHiddenColumns(col);
1197 if(colSel.getHiddenColumns()==null)
1198 hasHiddenColumns = false;
1201 public void showAllHiddenColumns()
1203 colSel.revealAllHiddenColumns();
1204 hasHiddenColumns = false;
1207 public void showAllHiddenSeqs()
1209 if(alignment.getHiddenSequences().getSize()>0)
1211 if(selectionGroup==null)
1213 selectionGroup = new SequenceGroup();
1214 selectionGroup.setEndRes(alignment.getWidth()-1);
1216 Vector tmp = alignment.getHiddenSequences().showAll();
1217 for(int t=0; t<tmp.size(); t++)
1219 selectionGroup.addSequence(
1220 (SequenceI)tmp.elementAt(t), false
1223 firePropertyChange("alignment", null, alignment.getSequences());
1224 hasHiddenRows = false;
1228 public void invertColumnSelection()
1231 for(int i=0; i<alignment.getWidth(); i++)
1235 if(colSel.contains(column))
1236 colSel.removeElement(column);
1238 colSel.addElement(column);
1244 public int adjustForHiddenSeqs(int alignmentIndex)
1246 return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);
1250 * This method returns the a new SequenceI [] with
1251 * the selection sequence and start and end points adjusted
1254 public SequenceI[] getSelectionAsNewSequence()
1256 SequenceI[] sequences;
1258 if (selectionGroup == null)
1259 sequences = alignment.getSequencesArray();
1261 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1267 * This method returns the visible alignment as text, as
1268 * seen on the GUI, ie if columns are hidden they will not
1269 * be returned in the result.
1270 * Use this for calculating trees, PCA, redundancy etc on views
1271 * which contain hidden columns.
1274 public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)
1276 CigarArray selection=null;
1277 SequenceI [] seqs= null;
1279 int start = 0, end = 0;
1280 if(selectedRegionOnly && selectionGroup!=null)
1282 iSize = selectionGroup.getSize(false);
1283 seqs = selectionGroup.getSequencesInOrder(alignment);
1284 start = selectionGroup.getStartRes();
1285 end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor
1289 iSize = alignment.getHeight();
1290 seqs = alignment.getSequencesArray();
1291 end = alignment.getWidth()-1;
1293 SeqCigar[] selseqs = new SeqCigar[iSize];
1294 for(i=0; i<iSize; i++)
1296 selseqs[i] = new SeqCigar(seqs[i], start, end);
1298 selection=new CigarArray(selseqs);
1299 // now construct the CigarArray operations
1300 if (hasHiddenColumns) {
1301 Vector regions = colSel.getHiddenColumns();
1303 int hideStart, hideEnd;
1305 for (int j = 0; last<end & j < regions.size(); j++)
1307 region = (int[]) regions.elementAt(j);
1308 hideStart = region[0];
1309 hideEnd = region[1];
1310 // edit hidden regions to selection range
1311 if(hideStart<last) {
1325 if (hideStart>hideEnd)
1328 * form operations...
1331 selection.addOperation(CigarArray.M, hideStart-last);
1332 selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);
1335 // Final match if necessary.
1337 selection.addOperation(CigarArray.M, end-last+1);
1339 selection.addOperation(CigarArray.M, end-start+1);
1344 * return a compact representation of the current alignment selection to
1345 * pass to an analysis function
1346 * @param selectedOnly boolean true to just return the selected view
1347 * @return AlignmentView
1349 jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {
1351 // this is here because the AlignmentView constructor modifies the CigarArray
1352 // object. Refactoring of Cigar and alignment view representation should
1353 // be done to remove redundancy.
1354 CigarArray aligview = getViewAsCigars(selectedOnly);
1356 return new AlignmentView(aligview);
1360 * This method returns the visible alignment as text, as
1361 * seen on the GUI, ie if columns are hidden they will not
1362 * be returned in the result.
1363 * Use this for calculating trees, PCA, redundancy etc on views
1364 * which contain hidden columns.
1367 public String [] getViewAsString(boolean selectedRegionOnly)
1369 String [] selection = null;
1370 SequenceI [] seqs= null;
1372 int start = 0, end = 0;
1373 if(selectedRegionOnly && selectionGroup!=null)
1375 iSize = selectionGroup.getSize(false);
1376 seqs = selectionGroup.getSequencesInOrder(alignment);
1377 start = selectionGroup.getStartRes();
1378 end = selectionGroup.getEndRes()+1;
1382 iSize = alignment.getHeight();
1383 seqs = alignment.getSequencesArray();
1384 end = alignment.getWidth();
1387 selection = new String[iSize];
1388 if (hasHiddenColumns) {
1389 selection = colSel.getVisibleSequenceStrings(start, end, seqs);
1391 for(i=0; i<iSize; i++)
1393 selection[i] = seqs[i].getSequence(start, end);
1400 public boolean getShowHiddenMarkers()
1402 return showHiddenMarkers;
1405 public void setShowHiddenMarkers(boolean show)
1407 showHiddenMarkers = show;