X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FAlignmentViewport.java;h=5e88c87ee752a059bb4c9e906c1650cd8a166124;hb=0a1844850e4663d353cc52b5a97b1fbdb0e825da;hp=a954a83be4cf8c4f15df2ceda6140a2b11997044;hpb=ef72c714cc7edbc26c4518e0c84a15b110bc6e3d;p=jalview.git diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index a954a83..5e88c87 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -35,22 +35,24 @@ import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenColumns; import jalview.datamodel.HiddenSequences; -import jalview.datamodel.SearchResults; +import jalview.datamodel.ProfilesI; +import jalview.datamodel.SearchResultsI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; -import jalview.schemes.Blosum62ColourScheme; +import jalview.renderer.ResidueShader; +import jalview.renderer.ResidueShaderI; import jalview.schemes.ColourSchemeI; -import jalview.schemes.PIDColourScheme; -import jalview.schemes.ResidueProperties; import jalview.structure.CommandListener; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; import jalview.util.Comparison; import jalview.util.MapList; import jalview.util.MappingUtils; +import jalview.util.MessageManager; import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; import jalview.workers.ComplementConsensusThread; @@ -58,6 +60,7 @@ import jalview.workers.ConsensusThread; import jalview.workers.StrucConsensusThread; import java.awt.Color; +import java.beans.PropertyChangeSupport; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.BitSet; @@ -77,6 +80,8 @@ import java.util.Map; public abstract class AlignmentViewport implements AlignViewportI, CommandListener, VamsasSource { + final protected ViewportRanges ranges; + protected ViewStyleI viewStyle = new ViewStyle(); /** @@ -87,9 +92,20 @@ public abstract class AlignmentViewport implements AlignViewportI, FeaturesDisplayedI featuresDisplayed = null; - protected Deque historyList = new ArrayDeque(); + protected Deque historyList = new ArrayDeque<>(); + + protected Deque redoList = new ArrayDeque<>(); + + /** + * alignment displayed in the viewport. Please use get/setter + */ + protected AlignmentI alignment; - protected Deque redoList = new ArrayDeque(); + public AlignmentViewport(AlignmentI al) + { + setAlignment(al); + ranges = new ViewportRanges(al); + } /** * @param name @@ -389,6 +405,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public void setWrapAlignment(boolean state) { viewStyle.setWrapAlignment(state); + ranges.setWrappedMode(state); } /** @@ -551,10 +568,7 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle.setSeqNameItalics(default1); } - /** - * alignment displayed in the viewport. Please use get/setter - */ - protected AlignmentI alignment; + @Override public AlignmentI getAlignment() @@ -596,7 +610,7 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean ignoreGapsInConsensusCalculation = false; - protected ColourSchemeI globalColourScheme = null; + protected ResidueShaderI residueShading = new ResidueShader(); @Override public void setGlobalColourScheme(ColourSchemeI cs) @@ -604,73 +618,51 @@ public abstract class AlignmentViewport implements AlignViewportI, // TODO: logic refactored from AlignFrame changeColour - // TODO: autorecalc stuff should be changed to rely on the worker system // check to see if we should implement a changeColour(cs) method rather than - // put th logic in here + // put the logic in here // - means that caller decides if they want to just modify state and defer // calculation till later or to do all calculations in thread. // via changecolour - globalColourScheme = cs; - boolean recalc = false; + + /* + * only instantiate alignment colouring once, thereafter update it; + * this means that any conservation or PID threshold settings + * persist when the alignment colour scheme is changed + */ + if (residueShading == null) + { + residueShading = new ResidueShader(viewStyle); + } + residueShading.setColourScheme(cs); + + // TODO: do threshold and increment belong in ViewStyle or ResidueShader? + // ...problem: groups need these, but do not currently have a ViewStyle + if (cs != null) { - cs.setConservationApplied(recalc = getConservationSelected()); - if (getAbovePIDThreshold() || cs instanceof PIDColourScheme - || cs instanceof Blosum62ColourScheme) - { - recalc = true; - cs.setThreshold(viewStyle.getThreshold(), - ignoreGapsInConsensusCalculation); - } - else - { - cs.setThreshold(0, ignoreGapsInConsensusCalculation); - } - if (recalc) + if (getConservationSelected()) { - cs.setConsensus(hconsensus); - cs.setConservation(hconservation); + residueShading.setConservation(hconservation); } - cs.alignmentChanged(alignment, hiddenRepSequences); + residueShading.alignmentChanged(alignment, hiddenRepSequences); } + + /* + * if 'apply colour to all groups' is selected... do so + * (but don't transfer any colour threshold settings to groups) + */ if (getColourAppliesToAllGroups()) { for (SequenceGroup sg : getAlignment().getGroups()) { - if (cs == null) - { - sg.cs = null; - continue; - } - sg.cs = cs.applyTo(sg, getHiddenRepSequences()); - sg.setConsPercGaps(ConsPercGaps); - if (getAbovePIDThreshold() || cs instanceof PIDColourScheme - || cs instanceof Blosum62ColourScheme) + /* + * retain any colour thresholds per group while + * changing choice of colour scheme (JAL-2386) + */ + sg.setColourScheme(cs); + if (cs != null) { - sg.cs.setThreshold(viewStyle.getThreshold(), - isIgnoreGapsConsensus()); - recalc = true; - } - else - { - sg.cs.setThreshold(0, isIgnoreGapsConsensus()); - } - - if (getConservationSelected()) - { - sg.cs.setConservationApplied(true); - recalc = true; - } - else - { - sg.cs.setConservation(null); - // sg.cs.setThreshold(0, getIgnoreGapsConsensus()); - } - if (recalc) - { - sg.recalcConservation(); - } - else - { - sg.cs.alignmentChanged(sg, hiddenRepSequences); + sg.getGroupColourScheme() + .alignmentChanged(sg, hiddenRepSequences); } } } @@ -679,13 +671,22 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public ColourSchemeI getGlobalColourScheme() { - return globalColourScheme; + return residueShading == null ? null : residueShading + .getColourScheme(); + } + + @Override + public ResidueShaderI getResidueShading() + { + return residueShading; } protected AlignmentAnnotation consensus; protected AlignmentAnnotation complementConsensus; + protected AlignmentAnnotation gapcounts; + protected AlignmentAnnotation strucConsensus; protected AlignmentAnnotation conservation; @@ -699,7 +700,7 @@ public abstract class AlignmentViewport implements AlignViewportI, /** * results of alignment consensus analysis for visible portion of view */ - protected Hashtable[] hconsensus = null; + protected ProfilesI hconsensus = null; /** * results of cDNA complement consensus visible portion of view @@ -733,7 +734,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public void setSequenceConsensusHash(Hashtable[] hconsensus) + public void setSequenceConsensusHash(ProfilesI hconsensus) { this.hconsensus = hconsensus; } @@ -745,7 +746,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public Hashtable[] getSequenceConsensusHash() + public ProfilesI getSequenceConsensusHash() { return hconsensus; } @@ -788,6 +789,12 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override + public AlignmentAnnotation getAlignmentGapAnnotation() + { + return gapcounts; + } + + @Override public AlignmentAnnotation getComplementConsensusAnnotation() { return complementConsensus; @@ -807,7 +814,8 @@ public abstract class AlignmentViewport implements AlignViewportI, public void updateConservation(final AlignmentViewPanel ap) { // see note in mantis : issue number 8585 - if (alignment.isNucleotide() || conservation == null + if (alignment.isNucleotide() + || (conservation == null && quality == null) || !autoCalculateConsensus) { return; @@ -913,6 +921,37 @@ public abstract class AlignmentViewport implements AlignViewportI, return false; } + public void setAlignment(AlignmentI align) + { + this.alignment = align; + } + + /** + * Clean up references when this viewport is closed + */ + @Override + public void dispose() + { + /* + * defensively null out references to large objects in case + * this object is not garbage collected (as if!) + */ + consensus = null; + complementConsensus = null; + strucConsensus = null; + conservation = null; + quality = null; + groupConsensus = null; + groupConservation = null; + hconsensus = null; + hcomplementConsensus = null; + // colour scheme may hold reference to consensus + residueShading = null; + // TODO remove listeners from changeSupport? + changeSupport = null; + setAlignment(null); + } + @Override public boolean isClosed() { @@ -1055,7 +1094,8 @@ public abstract class AlignmentViewport implements AlignViewportI, } /** - * Set the selection group for this window. + * Set the selection group for this window. Also sets the current alignment as + * the context for the group, if it does not already have one. * * @param sg * - group holding references to sequences in this alignment view @@ -1065,11 +1105,15 @@ public abstract class AlignmentViewport implements AlignViewportI, public void setSelectionGroup(SequenceGroup sg) { selectionGroup = sg; + if (sg != null && sg.getContext() == null) + { + sg.setContext(alignment); + } } - public void setHiddenColumns(ColumnSelection colsel) + public void setHiddenColumns(HiddenColumns hidden) { - this.colSel = colsel; + this.alignment.setHiddenColumns(hidden); } @Override @@ -1107,9 +1151,17 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override + public boolean hasSelectedColumns() + { + ColumnSelection columnSelection = getColumnSelection(); + return columnSelection != null && columnSelection.hasSelectedColumns(); + } + + @Override public boolean hasHiddenColumns() { - return colSel != null && colSel.hasHiddenColumns(); + return alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns(); } public void updateHiddenColumns() @@ -1170,9 +1222,9 @@ public abstract class AlignmentViewport implements AlignViewportI, if (ap != null) { updateConsensus(ap); - if (globalColourScheme != null) + if (residueShading != null) { - globalColourScheme.setThreshold(globalColourScheme.getThreshold(), + residueShading.setThreshold(residueShading.getThreshold(), ignoreGapsInConsensusCalculation); } } @@ -1233,10 +1285,9 @@ public abstract class AlignmentViewport implements AlignViewportI, return ignoreGapsInConsensusCalculation; } - // / property change stuff - + // property change stuff // JBPNote Prolly only need this in the applet version. - private final java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport( + private PropertyChangeSupport changeSupport = new PropertyChangeSupport( this); protected boolean showConservation = true; @@ -1245,7 +1296,9 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean showConsensus = true; - private Map sequenceColours = new HashMap(); + protected boolean showOccupancy = true; + + private Map sequenceColours = new HashMap<>(); protected SequenceAnnotationOrder sortAnnotationsBy = null; @@ -1256,15 +1309,6 @@ public abstract class AlignmentViewport implements AlignViewportI, */ private boolean followHighlight = true; - // TODO private with getters and setters? - public int startRes; - - public int endRes; - - public int startSeq; - - public int endSeq; - /** * Property change listener for changes in alignment * @@ -1314,7 +1358,7 @@ public abstract class AlignmentViewport implements AlignViewportI, return; } - colSel.hideSelectedColumns(); + colSel.hideSelectedColumns(alignment); setSelectionGroup(null); isColSelChanged(true); } @@ -1323,30 +1367,32 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (start == end) { - colSel.hideColumns(start); + colSel.hideSelectedColumns(start, alignment.getHiddenColumns()); } else { - colSel.hideColumns(start, end); + alignment.getHiddenColumns().hideColumns(start, end); } isColSelChanged(true); } public void showColumn(int col) { - colSel.revealHiddenColumns(col); + alignment.getHiddenColumns().revealHiddenColumns(col, colSel); isColSelChanged(true); } public void showAllHiddenColumns() { - colSel.revealAllHiddenColumns(); + alignment.getHiddenColumns().revealAllHiddenColumns(colSel); isColSelChanged(true); } // common hide/show seq stuff public void showAllHiddenSeqs() { + int startSeq = ranges.getStartSeq(); + if (alignment.getHiddenSequences().getSize() > 0) { if (selectionGroup == null) @@ -1364,6 +1410,8 @@ public abstract class AlignmentViewport implements AlignViewportI, hiddenRepSequences = null; + ranges.setStartSeq(startSeq); + firePropertyChange("alignment", null, alignment.getSequences()); // used to set hasHiddenRows/hiddenRepSequences here, after the property // changed event @@ -1373,6 +1421,8 @@ public abstract class AlignmentViewport implements AlignViewportI, public void showSequence(int index) { + int startSeq = ranges.getStartSeq(); + List tmp = alignment.getHiddenSequences().showSequence( index, hiddenRepSequences); if (tmp.size() > 0) @@ -1388,6 +1438,7 @@ public abstract class AlignmentViewport implements AlignViewportI, selectionGroup.addSequence(seq, false); setSequenceAnnotationsVisible(seq, true); } + ranges.setStartSeq(startSeq); firePropertyChange("alignment", null, alignment.getSequences()); sendSelection(); } @@ -1409,6 +1460,11 @@ public abstract class AlignmentViewport implements AlignViewportI, public void hideSequence(SequenceI[] seq) { + /* + * cache offset to first visible sequence + */ + int startSeq = ranges.getStartSeq(); + if (seq != null) { for (int i = 0; i < seq.length; i++) @@ -1416,6 +1472,7 @@ public abstract class AlignmentViewport implements AlignViewportI, alignment.getHiddenSequences().hideSequence(seq[i]); setSequenceAnnotationsVisible(seq[i], false); } + ranges.setStartSeq(startSeq); firePropertyChange("alignment", null, alignment.getSequences()); } } @@ -1484,7 +1541,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (hiddenRepSequences == null) { - hiddenRepSequences = new Hashtable(); + hiddenRepSequences = new Hashtable<>(); } hiddenRepSequences.put(repSequence, sg); @@ -1537,7 +1594,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public boolean isHiddenRepSequence(SequenceI seq) { return (hiddenRepSequences != null && hiddenRepSequences - .containsKey(seq)); + .containsKey(seq)); } /** @@ -1562,7 +1619,7 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public void invertColumnSelection() { - colSel.invertColumnSelection(0, alignment.getWidth()); + colSel.invertColumnSelection(0, alignment.getWidth(), alignment); } @Override @@ -1610,7 +1667,7 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public CigarArray getViewAsCigars(boolean selectedRegionOnly) { - return new CigarArray(alignment, colSel, + return new CigarArray(alignment, alignment.getHiddenColumns(), (selectedRegionOnly ? selectionGroup : null)); } @@ -1625,8 +1682,10 @@ public abstract class AlignmentViewport implements AlignViewportI, public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly, boolean markGroups) { - return new AlignmentView(alignment, colSel, selectionGroup, - colSel != null && colSel.hasHiddenColumns(), selectedOnly, + return new AlignmentView(alignment, alignment.getHiddenColumns(), + selectionGroup, alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns(), + selectedOnly, markGroups); } @@ -1670,9 +1729,11 @@ public abstract class AlignmentViewport implements AlignViewportI, } selection = new String[iSize]; - if (colSel != null && colSel.hasHiddenColumns()) + if (alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns()) { - selection = colSel.getVisibleSequenceStrings(start, end, seqs); + selection = alignment.getHiddenColumns().getVisibleSequenceStrings( + start, end, seqs); } else { @@ -1688,20 +1749,21 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public List getVisibleRegionBoundaries(int min, int max) { - ArrayList regions = new ArrayList(); + ArrayList regions = new ArrayList<>(); int start = min; int end = max; do { - if (colSel != null && colSel.hasHiddenColumns()) + HiddenColumns hidden = alignment.getHiddenColumns(); + if (hidden != null && hidden.hasHiddenColumns()) { if (start == 0) { - start = colSel.adjustForHiddenColumns(start); + start = hidden.adjustForHiddenColumns(start); } - end = colSel.getHiddenBoundaryRight(start); + end = hidden.getHiddenBoundaryRight(start); if (start == end) { end = max; @@ -1714,10 +1776,10 @@ public abstract class AlignmentViewport implements AlignViewportI, regions.add(new int[] { start, end }); - if (colSel != null && colSel.hasHiddenColumns()) + if (hidden != null && hidden.hasHiddenColumns()) { - start = colSel.adjustForHiddenColumns(end); - start = colSel.getHiddenBoundaryLeft(start) + 1; + start = hidden.adjustForHiddenColumns(end); + start = hidden.getHiddenBoundaryLeft(start) + 1; } } while (end < max); @@ -1730,7 +1792,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public List getVisibleAlignmentAnnotation( boolean selectedOnly) { - ArrayList ala = new ArrayList(); + ArrayList ala = new ArrayList<>(); AlignmentAnnotation[] aa; if ((aa = alignment.getAlignmentAnnotation()) != null) { @@ -1739,12 +1801,13 @@ public abstract class AlignmentViewport implements AlignViewportI, AlignmentAnnotation clone = new AlignmentAnnotation(annot); if (selectedOnly && selectionGroup != null) { - colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), + alignment.getHiddenColumns().makeVisibleAnnotation( + selectionGroup.getStartRes(), selectionGroup.getEndRes(), clone); } else { - colSel.makeVisibleAnnotation(clone); + alignment.getHiddenColumns().makeVisibleAnnotation(clone); } ala.add(clone); } @@ -1809,7 +1872,7 @@ public abstract class AlignmentViewport implements AlignViewportI, selectionGroup.setEndRes(alWidth - 1); } - resetAllColourSchemes(); + updateAllColourSchemes(); calculator.restartWorkers(); // alignment.adjustSequenceAnnotations(); } @@ -1817,19 +1880,19 @@ public abstract class AlignmentViewport implements AlignViewportI, /** * reset scope and do calculations for all applied colourschemes on alignment */ - void resetAllColourSchemes() + void updateAllColourSchemes() { - ColourSchemeI cs = globalColourScheme; - if (cs != null) + ResidueShaderI rs = residueShading; + if (rs != null) { - cs.alignmentChanged(alignment, hiddenRepSequences); + rs.alignmentChanged(alignment, hiddenRepSequences); - cs.setConsensus(hconsensus); - if (cs.conservationApplied()) + rs.setConsensus(hconsensus); + if (rs.conservationApplied()) { - cs.setConservation(Conservation.calculateConservation("All", - ResidueProperties.propHash, 3, alignment.getSequences(), 0, - alignment.getWidth(), false, getConsPercGaps(), false)); + rs.setConservation(Conservation.calculateConservation("All", + alignment.getSequences(), 0, alignment.getWidth(), false, + getConsPercGaps(), false)); } } @@ -1860,19 +1923,21 @@ public abstract class AlignmentViewport implements AlignViewportI, { initRNAStructure(); } - consensus = new AlignmentAnnotation("Consensus", "PID", + consensus = new AlignmentAnnotation("Consensus", + MessageManager.getString("label.consensus_descr"), new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); initConsensus(consensus); + initGapCounts(); initComplementConsensus(); } } /** - * If this is a protein alignment and there are mappings to cDNA, add the cDNA - * consensus annotation. + * If this is a protein alignment and there are mappings to cDNA, adds the + * cDNA consensus annotation and returns true, else returns false. */ - public void initComplementConsensus() + public boolean initComplementConsensus() { if (!alignment.isNucleotide()) { @@ -1896,12 +1961,16 @@ public abstract class AlignmentViewport implements AlignViewportI, if (doConsensus) { complementConsensus = new AlignmentAnnotation("cDNA Consensus", - "PID for cDNA", new Annotation[1], 0f, 100f, + MessageManager + .getString("label.complement_consensus_descr"), + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); initConsensus(complementConsensus); + return true; } } } + return false; } private void initConsensus(AlignmentAnnotation aa) @@ -1915,6 +1984,25 @@ public abstract class AlignmentViewport implements AlignViewportI, } } + // these should be extracted from the view model - style and settings for + // derived annotation + private void initGapCounts() + { + if (showOccupancy) + { + gapcounts = new AlignmentAnnotation("Occupancy", + MessageManager.getString("label.occupancy_descr"), + new Annotation[1], 0f, + alignment.getHeight(), AlignmentAnnotation.BAR_GRAPH); + gapcounts.hasText = true; + gapcounts.autoCalculated = true; + gapcounts.scaleColLabel = true; + gapcounts.graph = AlignmentAnnotation.BAR_GRAPH; + + alignment.addAnnotation(gapcounts); + } + } + private void initConservation() { if (showConservation) @@ -1922,8 +2010,8 @@ public abstract class AlignmentViewport implements AlignViewportI, if (conservation == null) { conservation = new AlignmentAnnotation("Conservation", - "Conservation of total alignment less than " - + getConsPercGaps() + "% gaps", new Annotation[1], + MessageManager.formatMessage("label.conservation_descr", + getConsPercGaps()), new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); conservation.hasText = true; conservation.autoCalculated = true; @@ -1939,7 +2027,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (quality == null) { quality = new AlignmentAnnotation("Quality", - "Alignment Quality based on Blosum62 scores", + MessageManager.getString("label.quality_descr"), new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); quality.hasText = true; quality.autoCalculated = true; @@ -1952,7 +2040,8 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (alignment.hasRNAStructure() && strucConsensus == null) { - strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID", + strucConsensus = new AlignmentAnnotation("StrucConsensus", + MessageManager.getString("label.strucconsensus_descr"), new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); strucConsensus.hasText = true; strucConsensus.autoCalculated = true; @@ -2057,7 +2146,7 @@ public abstract class AlignmentViewport implements AlignViewportI, // intersect alignment annotation with alignment groups AlignmentAnnotation[] aan = alignment.getAlignmentAnnotation(); - List oldrfs = new ArrayList(); + List oldrfs = new ArrayList<>(); if (aan != null) { for (int an = 0; an < aan.length; an++) @@ -2401,6 +2490,11 @@ public abstract class AlignmentViewport implements AlignViewportI, public void setViewStyle(ViewStyleI settingsForView) { viewStyle = new ViewStyle(settingsForView); + if (residueShading != null) + { + residueShading.setConservationApplied(settingsForView + .isConservationColourSelected()); + } } @Override @@ -2594,6 +2688,18 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle.setScaleProteinAsCdna(b); } + @Override + public boolean isProteinFontAsCdna() + { + return viewStyle.isProteinFontAsCdna(); + } + + @Override + public void setProteinFontAsCdna(boolean b) + { + viewStyle.setProteinFontAsCdna(b); + } + /** * @return true if view should scroll to show the highlighted region of a * sequence @@ -2611,63 +2717,10 @@ public abstract class AlignmentViewport implements AlignViewportI, this.followHighlight = b; } - public int getStartRes() - { - return startRes; - } - @Override - public int getEndRes() - { - return endRes; - } - - public int getStartSeq() - { - return startSeq; - } - - public void setStartRes(int res) - { - this.startRes = res; - } - - public void setStartSeq(int seq) - { - this.startSeq = seq; - } - - public void setEndRes(int res) + public ViewportRanges getRanges() { - if (res > alignment.getWidth() - 1) - { - // log.System.out.println(" Corrected res from " + res + " to maximum " + - // (alignment.getWidth()-1)); - res = alignment.getWidth() - 1; - } - if (res < 0) - { - res = 0; - } - this.endRes = res; - } - - public void setEndSeq(int seq) - { - if (seq > alignment.getHeight()) - { - seq = alignment.getHeight(); - } - if (seq < 0) - { - seq = 0; - } - this.endSeq = seq; - } - - public int getEndSeq() - { - return endSeq; + return ranges; } /** @@ -2678,7 +2731,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * the SearchResults to add to * @return the offset (below top of visible region) of the matched sequence */ - protected int findComplementScrollTarget(SearchResults sr) + protected int findComplementScrollTarget(SearchResultsI sr) { final AlignViewportI complement = getCodingComplement(); if (complement == null || !complement.isFollowHighlight()) @@ -2707,7 +2760,8 @@ public abstract class AlignmentViewport implements AlignViewportI, * locate 'middle' column (true middle if an odd number visible, left of * middle if an even number visible) */ - int middleColumn = getStartRes() + (getEndRes() - getStartRes()) / 2; + int middleColumn = ranges.getStartRes() + + (ranges.getEndRes() - ranges.getStartRes()) / 2; final HiddenSequences hiddenSequences = getAlignment() .getHiddenSequences(); @@ -2717,7 +2771,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ int lastSeq = alignment.getHeight() - 1; List seqMappings = null; - for (int seqNo = getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++) + for (int seqNo = ranges.getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++) { sequence = getAlignment().getSequenceAt(seqNo); if (hiddenSequences != null && hiddenSequences.isHidden(sequence)) @@ -2760,11 +2814,9 @@ public abstract class AlignmentViewport implements AlignViewportI, public void expandColSelection(SequenceGroup sg, boolean wholewidth) { int sgs, sge; - if (sg != null - && (sgs = sg.getStartRes()) >= 0 + if (sg != null && (sgs = sg.getStartRes()) >= 0 && sg.getStartRes() <= (sge = sg.getEndRes()) - && (colSel == null || colSel.getSelected() == null || colSel - .getSelected().size() == 0)) + && !this.hasSelectedColumns()) { if (!wholewidth && alignment.getWidth() == (1 + sge - sgs)) { @@ -2782,5 +2834,95 @@ public abstract class AlignmentViewport implements AlignViewportI, } } + /** + * hold status of current selection group - defined on alignment or not. + */ + private boolean selectionIsDefinedGroup = false; + @Override + public boolean isSelectionDefinedGroup() + { + if (selectionGroup == null) + { + return false; + } + if (isSelectionGroupChanged(true)) + { + selectionIsDefinedGroup = false; + List gps = alignment.getGroups(); + if (gps == null || gps.size() == 0) + { + selectionIsDefinedGroup = false; + } + else + { + selectionIsDefinedGroup = gps.contains(selectionGroup); + } + } + return selectionGroup.isDefined() || selectionIsDefinedGroup; + } + + /** + * null, or currently highlighted results on this view + */ + private SearchResultsI searchResults = null; + + @Override + public boolean hasSearchResults() + { + return searchResults != null; + } + + @Override + public void setSearchResults(SearchResultsI results) + { + searchResults = results; + } + + @Override + public SearchResultsI getSearchResults() + { + return searchResults; + } + + /** + * get the consensus sequence as displayed under the PID consensus annotation + * row. + * + * @return consensus sequence as a new sequence object + */ + public SequenceI getConsensusSeq() + { + if (consensus == null) + { + updateConsensus(null); + } + if (consensus == null) + { + return null; + } + StringBuffer seqs = new StringBuffer(); + for (int i = 0; i < consensus.annotations.length; i++) + { + Annotation annotation = consensus.annotations[i]; + if (annotation != null) + { + String description = annotation.description; + if (description != null && description.startsWith("[")) + { + // consensus is a tie - just pick the first one + seqs.append(description.charAt(1)); + } + else + { + seqs.append(annotation.displayCharacter); + } + } + } + + SequenceI sq = new Sequence("Consensus", seqs.toString()); + sq.setDescription("Percentage Identity Consensus " + + ((ignoreGapsInConsensusCalculation) ? " without gaps" : "")); + return sq; + } }