X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FAlignmentViewport.java;h=a15e9a67b0300ebf547796632e7d68df93fb93bc;hb=17e77c3f2949a0729322b4a8d907f3f34b6a9914;hp=7054ed3d068efc7bb2640fff3724fffdbf1dce09;hpb=be32c14cd8e48fe0a207cd7030cb9cd46f894678;p=jalview.git diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 7054ed3..a15e9a6 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -1,6 +1,6 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) - * Copyright (C) $$Year-Rel$$ The Jalview Authors + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9) + * Copyright (C) 2015 The Jalview Authors * * This file is part of Jalview. * @@ -20,17 +20,6 @@ */ package jalview.viewmodel; -import java.awt.Color; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Deque; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Set; - import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.analysis.Conservation; import jalview.api.AlignCalcManagerI; @@ -46,6 +35,8 @@ import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenSequences; +import jalview.datamodel.SearchResults; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; @@ -57,12 +48,25 @@ import jalview.schemes.ResidueProperties; import jalview.structure.CommandListener; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; +import jalview.util.Comparison; +import jalview.util.MappingUtils; import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; import jalview.workers.ComplementConsensusThread; import jalview.workers.ConsensusThread; import jalview.workers.StrucConsensusThread; +import java.awt.Color; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Deque; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * base class holding visualization and analysis attributes and common logic for * an active alignment view displayed in the GUI @@ -71,7 +75,7 @@ import jalview.workers.StrucConsensusThread; * */ public abstract class AlignmentViewport implements AlignViewportI, - ViewStyleI, CommandListener, VamsasSource + CommandListener, VamsasSource { protected ViewStyleI viewStyle = new ViewStyle(); @@ -502,15 +506,6 @@ public abstract class AlignmentViewport implements AlignViewportI, } /** - * @param selected - * @see jalview.api.ViewStyleI#setShowSeqFeaturesHeight(boolean) - */ - public void setShowSeqFeaturesHeight(boolean selected) - { - viewStyle.setShowSeqFeaturesHeight(selected); - } - - /** * alignment displayed in the viewport. Please use get/setter */ protected AlignmentI alignment; @@ -545,7 +540,6 @@ public abstract class AlignmentViewport implements AlignViewportI, return isDataset; } - private Map hiddenRepSequences; protected ColumnSelection colSel = new ColumnSelection(); @@ -558,12 +552,11 @@ public abstract class AlignmentViewport implements AlignViewportI, protected ColourSchemeI globalColourScheme = null; - @Override public void setGlobalColourScheme(ColourSchemeI cs) { // TODO: logic refactored from AlignFrame changeColour - - // autorecalc stuff should be changed to rely on the worker system + // 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 // - means that caller decides if they want to just modify state and defer @@ -635,7 +628,6 @@ public abstract class AlignmentViewport implements AlignViewportI, } } } - } @Override @@ -984,7 +976,6 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public boolean sortByTree = false; - /** * * @@ -1060,12 +1051,10 @@ public abstract class AlignmentViewport implements AlignViewportI, // hasHiddenColumns = colSel.hasHiddenColumns(); } - protected boolean hasHiddenRows = false; - @Override public boolean hasHiddenRows() { - return hasHiddenRows; + return alignment.getHiddenSequences().getSize() > 0; } protected SequenceGroup selectionGroup; @@ -1196,6 +1185,20 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean showAutocalculatedAbove; /** + * when set, view will scroll to show the highlighted position + */ + 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 * * @param listener @@ -1290,7 +1293,6 @@ public abstract class AlignmentViewport implements AlignViewportI, setSequenceAnnotationsVisible(seq, true); } - hasHiddenRows = false; hiddenRepSequences = null; firePropertyChange("alignment", null, alignment.getSequences()); @@ -1303,8 +1305,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public void showSequence(int index) { List tmp = alignment.getHiddenSequences().showSequence( - index, - hiddenRepSequences); + index, hiddenRepSequences); if (tmp.size() > 0) { if (selectionGroup == null) @@ -1318,12 +1319,6 @@ public abstract class AlignmentViewport implements AlignViewportI, selectionGroup.addSequence(seq, false); setSequenceAnnotationsVisible(seq, true); } - // JBPNote: refactor: only update flag if we modified visiblity (used to - // do this regardless) - if (alignment.getHiddenSequences().getSize() < 1) - { - hasHiddenRows = false; - } firePropertyChange("alignment", null, alignment.getSequences()); sendSelection(); } @@ -1352,7 +1347,6 @@ public abstract class AlignmentViewport implements AlignViewportI, alignment.getHiddenSequences().hideSequence(seq[i]); setSequenceAnnotationsVisible(seq[i], false); } - hasHiddenRows = true; firePropertyChange("alignment", null, alignment.getSequences()); } } @@ -1412,8 +1406,9 @@ public abstract class AlignmentViewport implements AlignViewportI, public boolean isHiddenRepSequence(SequenceI seq) { - return alignment.getSeqrep()==seq || (hiddenRepSequences != null - && hiddenRepSequences.containsKey(seq)); + return alignment.getSeqrep() == seq + || (hiddenRepSequences != null && hiddenRepSequences + .containsKey(seq)); } public SequenceGroup getRepresentedSequences(SequenceI seq) @@ -1435,7 +1430,6 @@ public abstract class AlignmentViewport implements AlignViewportI, colSel.invertColumnSelection(0, alignment.getWidth()); } - @Override public SequenceI[] getSelectionAsNewSequence() { @@ -1463,7 +1457,6 @@ public abstract class AlignmentViewport implements AlignViewportI, return sequences; } - @Override public SequenceI[] getSequenceSelection() { @@ -1479,16 +1472,13 @@ public abstract class AlignmentViewport implements AlignViewportI, return sequences; } - @Override - public CigarArray getViewAsCigars( - boolean selectedRegionOnly) + public CigarArray getViewAsCigars(boolean selectedRegionOnly) { return new CigarArray(alignment, colSel, (selectedRegionOnly ? selectionGroup : null)); } - @Override public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly) @@ -1496,7 +1486,6 @@ public abstract class AlignmentViewport implements AlignViewportI, return getAlignmentView(selectedOnly, false); } - @Override public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly, boolean markGroups) @@ -1506,7 +1495,6 @@ public abstract class AlignmentViewport implements AlignViewportI, markGroups); } - @Override public String[] getViewAsString(boolean selectedRegionOnly) { @@ -1544,7 +1532,6 @@ public abstract class AlignmentViewport implements AlignViewportI, return selection; } - @Override public List getVisibleRegionBoundaries(int min, int max) { @@ -1572,8 +1559,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } } - regions.add(new int[] - { start, end }); + regions.add(new int[] { start, end }); if (colSel != null && colSel.hasHiddenColumns()) { @@ -1588,19 +1574,23 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public List getVisibleAlignmentAnnotation(boolean selectedOnly) + public List getVisibleAlignmentAnnotation( + boolean selectedOnly) { ArrayList ala = new ArrayList(); AlignmentAnnotation[] aa; - if ((aa=alignment.getAlignmentAnnotation())!=null) + if ((aa = alignment.getAlignmentAnnotation()) != null) { - for (AlignmentAnnotation annot:aa) + for (AlignmentAnnotation annot : aa) { AlignmentAnnotation clone = new AlignmentAnnotation(annot); - if (selectedOnly && selectionGroup!=null) + if (selectedOnly && selectionGroup != null) + { + colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), + selectionGroup.getEndRes(), clone); + } + else { - colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), selectionGroup.getEndRes(),clone); - } else { colSel.makeVisibleAnnotation(clone); } ala.add(clone); @@ -1609,14 +1599,12 @@ public abstract class AlignmentViewport implements AlignViewportI, return ala; } - @Override public boolean isPadGaps() { return padGaps; } - @Override public void setPadGaps(boolean padGaps) { @@ -1731,7 +1719,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * If this is a protein alignment and there are mappings to cDNA, add the cDNA * consensus annotation. */ - protected void initComplementConsensus() + public void initComplementConsensus() { if (!alignment.isNucleotide()) { @@ -1944,6 +1932,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } oldrfs.clear(); } + @Override public boolean isDisplayReferenceSeq() { @@ -2052,7 +2041,8 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public boolean areFeaturesDisplayed() { - return featuresDisplayed != null && featuresDisplayed.getRegisterdFeaturesCount()>0; + return featuresDisplayed != null + && featuresDisplayed.getRegisterdFeaturesCount() > 0; } /** @@ -2066,6 +2056,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { viewStyle.setShowSequenceFeatures(b); } + @Override public boolean isShowSequenceFeatures() { @@ -2075,7 +2066,7 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public void setShowSequenceFeaturesHeight(boolean selected) { - viewStyle.setShowSeqFeaturesHeight(selected); + viewStyle.setShowSequenceFeaturesHeight(selected); } @Override @@ -2084,8 +2075,6 @@ public abstract class AlignmentViewport implements AlignViewportI, return viewStyle.isShowSequenceFeaturesHeight(); } - - @Override public void setShowAnnotation(boolean b) { @@ -2175,14 +2164,6 @@ public abstract class AlignmentViewport implements AlignViewportI, { return viewStyle.isShowColourText(); } - /** - * @return - * @see jalview.api.ViewStyleI#isShowSeqFeaturesHeight() - */ - public boolean isShowSeqFeaturesHeight() - { - return viewStyle.isShowSeqFeaturesHeight(); - } /** * @param conservationColourSelected @@ -2338,7 +2319,8 @@ public abstract class AlignmentViewport implements AlignViewportI, protected void broadcastCommand(CommandI command, boolean undo) { - getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource()); + getStructureSelectionManager().commandPerformed(command, undo, + getVamsasSource()); } /** @@ -2411,4 +2393,168 @@ public abstract class AlignmentViewport implements AlignViewportI, { this.showAutocalculatedAbove = showAutocalculatedAbove; } + + @Override + public boolean isScaleProteinAsCdna() + { + return viewStyle.isScaleProteinAsCdna(); + } + + @Override + public void setScaleProteinAsCdna(boolean b) + { + viewStyle.setScaleProteinAsCdna(b); + } + + /** + * @return true if view should scroll to show the highlighted region of a + * sequence + * @return + */ + @Override + public final boolean isFollowHighlight() + { + return followHighlight; + } + + @Override + public final void setFollowHighlight(boolean b) + { + this.followHighlight = b; + } + + public int getStartRes() + { + return startRes; + } + + 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) + { + 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; + } + + /** + * Helper method to populate the SearchResults with the location in the + * complementary alignment to scroll to, in order to match this one. + * + * @param sr + * the SearchResults to add to + * @return the offset (below top of visible region) of the matched sequence + */ + protected int findComplementScrollTarget(SearchResults sr) + { + final AlignViewportI complement = getCodingComplement(); + if (complement == null || !complement.isFollowHighlight()) + { + return 0; + } + boolean iAmProtein = !getAlignment().isNucleotide(); + AlignmentI proteinAlignment = iAmProtein ? getAlignment() : complement + .getAlignment(); + if (proteinAlignment == null) + { + return 0; + } + final Set mappings = proteinAlignment + .getCodonFrames(); + + /* + * Heuristic: find the first mapped sequence (if any) with a non-gapped + * residue in the middle column of the visible region. Scroll the + * complementary alignment to line up the corresponding residue. + */ + int seqOffset = 0; + SequenceI sequence = null; + + /* + * locate 'middle' column (true middle if an odd number visible, left of + * middle if an even number visible) + */ + int middleColumn = getStartRes() + (getEndRes() - getStartRes()) / 2; + final HiddenSequences hiddenSequences = getAlignment() + .getHiddenSequences(); + + /* + * searching to the bottom of the alignment gives smoother scrolling across + * all gapped visible regions + */ + int lastSeq = alignment.getHeight() - 1; + for (int seqNo = getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++) + { + sequence = getAlignment().getSequenceAt(seqNo); + if (hiddenSequences != null && hiddenSequences.isHidden(sequence)) + { + continue; + } + if (Comparison.isGap(sequence.getCharAt(middleColumn))) + { + continue; + } + List seqMappings = MappingUtils + .findMappingsForSequence(sequence, mappings); + if (!seqMappings.isEmpty()) + { + break; + } + } + + if (sequence == null) + { + /* + * No ungapped mapped sequence in middle column - do nothing + */ + return 0; + } + MappingUtils.addSearchResults(sr, sequence, + sequence.findPosition(middleColumn), mappings); + return seqOffset; + } }