X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FAlignmentViewport.java;h=7e0b6b434e9387c88923f621913f106483cbe258;hb=refs%2Fheads%2Fspike%2FJAL-4047%2FJAL-4048_columns_in_sequenceID;hp=b62c61c9cffe688064c0fce22f56256aafadf286;hpb=79631ef84a124bfefa84c24b85dc77883366ad4a;p=jalview.git diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index b62c61c..7e0b6b4 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -20,21 +20,39 @@ */ package jalview.viewmodel; +import java.awt.Color; +import java.beans.PropertyChangeSupport; +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.Iterator; +import java.util.List; +import java.util.Map; + import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.analysis.Conservation; +import jalview.analysis.TreeModel; import jalview.api.AlignCalcManagerI; +import jalview.api.AlignExportSettingsI; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.FeaturesDisplayedI; import jalview.api.ViewStyleI; +import jalview.bin.Console; import jalview.commands.CommandI; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentExportData; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; -import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.ContactListI; +import jalview.datamodel.ContactMatrixI; +import jalview.datamodel.HiddenColumns; import jalview.datamodel.HiddenSequences; import jalview.datamodel.ProfilesI; import jalview.datamodel.SearchResultsI; @@ -42,6 +60,8 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.gui.QuitHandler; +import jalview.project.Jalview2XML; import jalview.renderer.ResidueShader; import jalview.renderer.ResidueShaderI; import jalview.schemes.ColourSchemeI; @@ -51,23 +71,14 @@ import jalview.structure.VamsasSource; import jalview.util.Comparison; import jalview.util.MapList; import jalview.util.MappingUtils; +import jalview.util.MessageManager; +import jalview.viewmodel.seqfeatures.IdColumns; 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.beans.PropertyChangeSupport; -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; - /** * base class holding visualization and analysis attributes and common logic for * an active alignment view displayed in the GUI @@ -75,10 +86,10 @@ import java.util.Map; * @author jimp * */ -public abstract class AlignmentViewport implements AlignViewportI, - CommandListener, VamsasSource +public abstract class AlignmentViewport + implements AlignViewportI, CommandListener, VamsasSource { - protected ViewportPositionProps posProps; + protected ViewportRanges ranges; protected ViewStyleI viewStyle = new ViewStyle(); @@ -90,9 +101,25 @@ public abstract class AlignmentViewport implements AlignViewportI, FeaturesDisplayedI featuresDisplayed = null; - protected Deque historyList = new ArrayDeque(); + protected Deque historyList = new ArrayDeque<>(); + + protected Deque redoList = new ArrayDeque<>(); + + /** + * used to determine if quit should be confirmed + */ + private boolean savedUpToDate = false; + + /** + * 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 @@ -392,6 +419,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public void setWrapAlignment(boolean state) { viewStyle.setWrapAlignment(state); + ranges.setWrappedMode(state); } /** @@ -554,11 +582,6 @@ 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() { @@ -589,9 +612,9 @@ public abstract class AlignmentViewport implements AlignViewportI, return isDataset; } + private Map hiddenRepSequences; - - // protected ColumnSelection colSel = new ColumnSelection(); + protected ColumnSelection colSel = new ColumnSelection(); public boolean autoCalculateConsensus = true; @@ -599,7 +622,7 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean ignoreGapsInConsensusCalculation = false; - protected ResidueShaderI residueShading; + protected ResidueShaderI residueShading = new ResidueShader(); @Override public void setGlobalColourScheme(ColourSchemeI cs) @@ -632,7 +655,12 @@ public abstract class AlignmentViewport implements AlignViewportI, { residueShading.setConservation(hconservation); } - residueShading.alignmentChanged(alignment, getHiddenRepSequences()); + /* + * reset conservation flag in case just set to false if + * Conservation was null (calculation still in progress) + */ + residueShading.setConservationApplied(getConservationSelected()); + residueShading.alignmentChanged(alignment, hiddenRepSequences); } /* @@ -647,12 +675,11 @@ public abstract class AlignmentViewport implements AlignViewportI, * retain any colour thresholds per group while * changing choice of colour scheme (JAL-2386) */ - sg.setColourScheme(cs); + sg.setColourScheme(cs == null ? null : cs.getInstance(this, sg)); if (cs != null) { - sg.getGroupColourScheme() -.alignmentChanged(sg, - getHiddenRepSequences()); + sg.getGroupColourScheme().alignmentChanged(sg, + hiddenRepSequences); } } } @@ -661,8 +688,7 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public ColourSchemeI getGlobalColourScheme() { - return residueShading == null ? null : residueShading - .getColourScheme(); + return residueShading == null ? null : residueShading.getColourScheme(); } @Override @@ -675,6 +701,8 @@ public abstract class AlignmentViewport implements AlignViewportI, protected AlignmentAnnotation complementConsensus; + protected AlignmentAnnotation gapcounts; + protected AlignmentAnnotation strucConsensus; protected AlignmentAnnotation conservation; @@ -693,13 +721,13 @@ public abstract class AlignmentViewport implements AlignViewportI, /** * results of cDNA complement consensus visible portion of view */ - protected Hashtable[] hcomplementConsensus = null; + protected Hashtable[] hcomplementConsensus = null; /** * results of secondary structure base pair consensus for visible portion of * view */ - protected Hashtable[] hStrucConsensus = null; + protected Hashtable[] hStrucConsensus = null; protected Conservation hconservation = null; @@ -728,7 +756,8 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public void setComplementConsensusHash(Hashtable[] hconsensus) + public void setComplementConsensusHash( + Hashtable[] hconsensus) { this.hcomplementConsensus = hconsensus; } @@ -740,19 +769,20 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public Hashtable[] getComplementConsensusHash() + public Hashtable[] getComplementConsensusHash() { return hcomplementConsensus; } @Override - public Hashtable[] getRnaStructureConsensusHash() + public Hashtable[] getRnaStructureConsensusHash() { return hStrucConsensus; } @Override - public void setRnaStructureConsensusHash(Hashtable[] hStrucConsensus) + public void setRnaStructureConsensusHash( + Hashtable[] hStrucConsensus) { this.hStrucConsensus = hStrucConsensus; @@ -777,6 +807,12 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override + public AlignmentAnnotation getAlignmentGapAnnotation() + { + return gapcounts; + } + + @Override public AlignmentAnnotation getComplementConsensusAnnotation() { return complementConsensus; @@ -802,11 +838,11 @@ public abstract class AlignmentViewport implements AlignViewportI, { return; } - if (calculator - .getRegisteredWorkersOfClass(jalview.workers.ConservationThread.class) == null) + if (calculator.getRegisteredWorkersOfClass( + jalview.workers.ConservationThread.class) == null) { - calculator.registerWorker(new jalview.workers.ConservationThread( - this, ap)); + calculator.registerWorker( + new jalview.workers.ConservationThread(this, ap)); } } @@ -820,7 +856,8 @@ public abstract class AlignmentViewport implements AlignViewportI, { return; } - if (calculator.getRegisteredWorkersOfClass(ConsensusThread.class) == null) + if (calculator + .getRegisteredWorkersOfClass(ConsensusThread.class) == null) { calculator.registerWorker(new ConsensusThread(this, ap)); } @@ -851,8 +888,8 @@ public abstract class AlignmentViewport implements AlignViewportI, } if (doConsensus) { - if (calculator - .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null) + if (calculator.getRegisteredWorkersOfClass( + ComplementConsensusThread.class) == null) { calculator .registerWorker(new ComplementConsensusThread(this, ap)); @@ -876,7 +913,8 @@ public abstract class AlignmentViewport implements AlignViewportI, { return; } - if (calculator.getRegisteredWorkersOfClass(StrucConsensusThread.class) == null) + if (calculator.getRegisteredWorkersOfClass( + StrucConsensusThread.class) == null) { calculator.registerWorker(new StrucConsensusThread(this, ap)); } @@ -897,7 +935,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } if (calculator.workingInvolvedWith(alignmentAnnotation)) { - // System.err.println("grey out ("+alignmentAnnotation.label+")"); + // jalview.bin.Console.errPrintln("grey out ("+alignmentAnnotation.label+")"); return true; } return false; @@ -926,11 +964,16 @@ public abstract class AlignmentViewport implements AlignViewportI, groupConsensus = null; groupConservation = null; hconsensus = null; + hconservation = null; hcomplementConsensus = null; - // colour scheme may hold reference to consensus - residueShading = null; - // TODO remove listeners from changeSupport? + gapcounts = null; + calculator = null; + residueShading = null; // may hold a reference to Consensus changeSupport = null; + ranges = null; + currentTree = null; + selectionGroup = null; + colSel = null; setAlignment(null); } @@ -1093,29 +1136,26 @@ public abstract class AlignmentViewport implements AlignViewportI, } } - public void setHiddenColumns(ColumnSelection colsel) + public void setHiddenColumns(HiddenColumns hidden) { - posProps.setHiddenColumns(colsel); - // this.colSel = colsel; + this.alignment.setHiddenColumns(hidden); } @Override public ColumnSelection getColumnSelection() { - return posProps.getColumnSelection(); - // return colSel; + return colSel; } @Override public void setColumnSelection(ColumnSelection colSel) { - posProps.setColumnSelection(colSel); - /*this.colSel = colSel; + this.colSel = colSel; if (colSel != null) { updateHiddenColumns(); } - isColSelChanged(true);*/ + isColSelChanged(true); } /** @@ -1125,14 +1165,14 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public Map getHiddenRepSequences() { - return posProps.getHiddenRepSequences(); + return hiddenRepSequences; } @Override public void setHiddenRepSequences( Map hiddenRepSequences) { - posProps.getHiddenRepSequences(); + this.hiddenRepSequences = hiddenRepSequences; } @Override @@ -1145,8 +1185,8 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public boolean hasHiddenColumns() { - return posProps.hasHiddenColumns(); - // return colSel != null && colSel.hasHiddenColumns(); + return alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns(); } public void updateHiddenColumns() @@ -1168,8 +1208,8 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (sequenceSetID != null) { - System.err - .println("Warning - overwriting a sequenceSetId for a viewport!"); + jalview.bin.Console.errPrintln( + "Warning - overwriting a sequenceSetId for a viewport!"); } sequenceSetID = new String(newid); } @@ -1216,7 +1256,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } - private long sgrouphash = -1; + private long sgrouphash = -1, colselhash = -1; /** * checks current SelectionGroup against record of last hash value, and @@ -1252,8 +1292,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public boolean isColSelChanged(boolean b) { - return posProps.isColSelChanged(b); - /*int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode(); + int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode(); if (hc != -1 && hc != colselhash) { if (b) @@ -1262,7 +1301,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } return true; } - return false;*/ + return false; } @Override @@ -1282,7 +1321,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; @@ -1293,14 +1334,6 @@ public abstract class AlignmentViewport implements AlignViewportI, */ private boolean followHighlight = true; - /*private int startRes; - - private int endRes; - - private int startSeq; - - private int endSeq;*/ - /** * Property change listener for changes in alignment * @@ -1322,7 +1355,10 @@ public abstract class AlignmentViewport implements AlignViewportI, public void removePropertyChangeListener( java.beans.PropertyChangeListener listener) { - changeSupport.removePropertyChangeListener(listener); + if (changeSupport != null) + { + changeSupport.removePropertyChangeListener(listener); + } } /** @@ -1343,21 +1379,6 @@ public abstract class AlignmentViewport implements AlignViewportI, // common hide/show column stuff - public void hideColumns(int start, int end) - { - posProps.hideColumns(start, end); - } - - public void showColumn(int col) - { - posProps.showColumn(col); - } - - public void showAllHiddenColumns() - { - posProps.showAllHiddenColumns(); - } - public void hideSelectedColumns() { if (colSel.isEmpty()) @@ -1365,47 +1386,75 @@ public abstract class AlignmentViewport implements AlignViewportI, return; } - colSel.hideSelectedColumns(); + colSel.hideSelectedColumns(alignment); setSelectionGroup(null); isColSelChanged(true); } + public void hideColumns(int start, int end) + { + if (start == end) + { + colSel.hideSelectedColumns(start, alignment.getHiddenColumns()); + } + else + { + alignment.getHiddenColumns().hideColumns(start, end); + } + isColSelChanged(true); + } + public void showColumn(int col) + { + alignment.getHiddenColumns().revealHiddenColumns(col, colSel); + isColSelChanged(true); + } + + public void showAllHiddenColumns() + { + alignment.getHiddenColumns().revealAllHiddenColumns(colSel); + isColSelChanged(true); + } // common hide/show seq stuff public void showAllHiddenSeqs() { - selectionGroup = posProps.showAllHiddenSeqs(selectionGroup); + int startSeq = ranges.getStartSeq(); + int endSeq = ranges.getEndSeq(); - /* if (alignment.getHiddenSequences().getSize() > 0) - { - if (selectionGroup == null) - { - selectionGroup = new SequenceGroup(); - selectionGroup.setEndRes(alignment.getWidth() - 1); - } - List tmp = alignment.getHiddenSequences().showAll( - hiddenRepSequences); - for (SequenceI seq : tmp) - { - selectionGroup.addSequence(seq, false); - setSequenceAnnotationsVisible(seq, true); - } + if (alignment.getHiddenSequences().getSize() > 0) + { + if (selectionGroup == null) + { + selectionGroup = new SequenceGroup(); + selectionGroup.setEndRes(alignment.getWidth() - 1); + } + List tmp = alignment.getHiddenSequences() + .showAll(hiddenRepSequences); + for (SequenceI seq : tmp) + { + selectionGroup.addSequence(seq, false); + setSequenceAnnotationsVisible(seq, true); + } + + hiddenRepSequences = null; - hiddenRepSequences = null; + ranges.setStartEndSeq(startSeq, endSeq + tmp.size()); - firePropertyChange("alignment", null, alignment.getSequences()); - // used to set hasHiddenRows/hiddenRepSequences here, after the property - // changed event - sendSelection(); - }*/ + firePropertyChange("alignment", null, alignment.getSequences()); + // used to set hasHiddenRows/hiddenRepSequences here, after the property + // changed event + sendSelection(); + } } public void showSequence(int index) { - posProps.showSequence(index, selectionGroup); - /*List tmp = alignment.getHiddenSequences().showSequence( - index, hiddenRepSequences); + int startSeq = ranges.getStartSeq(); + int endSeq = ranges.getEndSeq(); + + List tmp = alignment.getHiddenSequences().showSequence(index, + hiddenRepSequences); if (tmp.size() > 0) { if (selectionGroup == null) @@ -1419,15 +1468,17 @@ public abstract class AlignmentViewport implements AlignViewportI, selectionGroup.addSequence(seq, false); setSequenceAnnotationsVisible(seq, true); } + + ranges.setStartEndSeq(startSeq, endSeq + tmp.size()); + firePropertyChange("alignment", null, alignment.getSequences()); sendSelection(); - }*/ + } } public void hideAllSelectedSeqs() { - posProps.hideAllSelectedSeqs(selectionGroup); - /*if (selectionGroup == null || selectionGroup.getSize() < 1) + if (selectionGroup == null || selectionGroup.getSize() < 1) { return; } @@ -1436,21 +1487,26 @@ public abstract class AlignmentViewport implements AlignViewportI, hideSequence(seqs); - setSelectionGroup(null);*/ + setSelectionGroup(null); } public void hideSequence(SequenceI[] seq) { - posProps.hideSequence(seq); - /*if (seq != null) + /* + * cache offset to first visible sequence + */ + int startSeq = ranges.getStartSeq(); + + if (seq != null) { for (int i = 0; i < seq.length; i++) { alignment.getHiddenSequences().hideSequence(seq[i]); setSequenceAnnotationsVisible(seq[i], false); } + ranges.setStartSeq(startSeq); firePropertyChange("alignment", null, alignment.getSequences()); - }*/ + } } /** @@ -1464,8 +1520,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public void hideSequences(SequenceI sequence, boolean representGroup) { - posProps.hideSequences(sequence, representGroup, selectionGroup); - /*if (selectionGroup == null || selectionGroup.getSize() < 1) + if (selectionGroup == null || selectionGroup.getSize() < 1) { hideSequence(new SequenceI[] { sequence }); return; @@ -1479,19 +1534,38 @@ public abstract class AlignmentViewport implements AlignViewportI, } int gsize = selectionGroup.getSize(); - SequenceI[] hseqs = selectionGroup.getSequences().toArray( - new SequenceI[gsize]); + SequenceI[] hseqs = selectionGroup.getSequences() + .toArray(new SequenceI[gsize]); hideSequence(hseqs); setSelectionGroup(null); - sendSelection();*/ + sendSelection(); } + /** + * Set visibility for any annotations for the given sequence. + * + * @param sequenceI + */ + protected void setSequenceAnnotationsVisible(SequenceI sequenceI, + boolean visible) + { + AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation(); + if (anns != null) + { + for (AlignmentAnnotation ann : anns) + { + if (ann.sequenceRef == sequenceI) + { + ann.visible = visible; + } + } + } + } public void hideRepSequences(SequenceI repSequence, SequenceGroup sg) { - posProps.hideRepSequences(repSequence, sg); - /*int sSize = sg.getSize(); + int sSize = sg.getSize(); if (sSize < 2) { return; @@ -1499,7 +1573,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (hiddenRepSequences == null) { - hiddenRepSequences = new Hashtable(); + hiddenRepSequences = new Hashtable<>(); } hiddenRepSequences.put(repSequence, sg); @@ -1521,7 +1595,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } sg.setSeqrep(repSequence); // note: not done in 2.7applet sg.setHidereps(true); // note: not done in 2.7applet - hideSequence(seqs);*/ + hideSequence(seqs); } @@ -1551,9 +1625,8 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public boolean isHiddenRepSequence(SequenceI seq) { - return posProps.isHiddenRepSequence(seq); - // return (hiddenRepSequences != null && hiddenRepSequences - // .containsKey(seq)); + return (hiddenRepSequences != null + && hiddenRepSequences.containsKey(seq)); } /** @@ -1564,24 +1637,22 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public SequenceGroup getRepresentedSequences(SequenceI seq) { - return posProps.getRepresentedSequences(seq); - // return (SequenceGroup) (hiddenRepSequences == null ? null - // : hiddenRepSequences.get(seq)); + return (SequenceGroup) (hiddenRepSequences == null ? null + : hiddenRepSequences.get(seq)); } @Override public int adjustForHiddenSeqs(int alignmentIndex) { - return posProps.adjustForHiddenSeqs(alignmentIndex); - // return alignment.getHiddenSequences().adjustForHiddenSeqs( - // alignmentIndex); + return alignment.getHiddenSequences() + .adjustForHiddenSeqs(alignmentIndex); } @Override public void invertColumnSelection() { - posProps.invertColumnSelection(); - // colSel.invertColumnSelection(0, alignment.getWidth()); + colSel.invertColumnSelection(0, alignment.getWidth(), alignment); + isColSelChanged(true); } @Override @@ -1627,13 +1698,6 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public CigarArray getViewAsCigars(boolean selectedRegionOnly) - { - return new CigarArray(alignment, posProps.getColumnSelection(), - (selectedRegionOnly ? selectionGroup : null)); - } - - @Override public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly) { @@ -1644,9 +1708,11 @@ public abstract class AlignmentViewport implements AlignViewportI, public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly, boolean markGroups) { - return new AlignmentView(alignment, posProps.getColumnSelection(), - selectionGroup, posProps.hasHiddenColumns(), selectedOnly, - markGroups); + return new AlignmentView(alignment, alignment.getHiddenColumns(), + selectionGroup, + alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns(), + selectedOnly, markGroups); } @Override @@ -1689,9 +1755,15 @@ public abstract class AlignmentViewport implements AlignViewportI, } selection = new String[iSize]; - if (posProps.hasHiddenColumns()) + if (alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns()) { - selection = posProps.getVisibleSequenceStrings(start, end, seqs); + for (i = 0; i < iSize; i++) + { + Iterator blocks = alignment.getHiddenColumns() + .getVisContigsIterator(start, end + 1, false); + selection[i] = seqs[i].getSequenceStringFromIterator(blocks); + } } else { @@ -1707,52 +1779,50 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public List getVisibleRegionBoundaries(int min, int max) { - return posProps.getVisibleRegionBoundaries(min, max); - /* ArrayList regions = new ArrayList(); - int start = min; - int end = max; + ArrayList regions = new ArrayList<>(); + int start = min; + int end = max; + + do + { + HiddenColumns hidden = alignment.getHiddenColumns(); + if (hidden != null && hidden.hasHiddenColumns()) + { + if (start == 0) + { + start = hidden.visibleToAbsoluteColumn(start); + } - do + end = hidden.getNextHiddenBoundary(false, start); + if (start == end) { - if (colSel != null && colSel.hasHiddenColumns()) - { - if (start == 0) - { - start = colSel.adjustForHiddenColumns(start); - } - - end = colSel.getHiddenBoundaryRight(start); - if (start == end) - { - end = max; - } - if (end > max) - { - end = max; - } - } + end = max; + } + if (end > max) + { + end = max; + } + } - regions.add(new int[] { start, end }); + regions.add(new int[] { start, end }); - if (posProps.hasHiddenColumns()) - { - start = colSel.adjustForHiddenColumns(end); - start = colSel.getHiddenBoundaryLeft(start) + 1; - } - } while (end < max); + if (hidden != null && hidden.hasHiddenColumns()) + { + start = hidden.visibleToAbsoluteColumn(end); + start = hidden.getNextHiddenBoundary(true, start) + 1; + } + } while (end < max); - int[][] startEnd = new int[regions.size()][2]; + // int[][] startEnd = new int[regions.size()][2]; - return regions;*/ + return regions; } @Override public List getVisibleAlignmentAnnotation( boolean selectedOnly) { - return posProps.getVisibleAlignmentAnnotation(selectedOnly, - selectionGroup); - /*ArrayList ala = new ArrayList(); + ArrayList ala = new ArrayList<>(); AlignmentAnnotation[] aa; if ((aa = alignment.getAlignmentAnnotation()) != null) { @@ -1761,17 +1831,17 @@ public abstract class AlignmentViewport implements AlignViewportI, AlignmentAnnotation clone = new AlignmentAnnotation(annot); if (selectedOnly && selectionGroup != null) { - colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), - selectionGroup.getEndRes(), clone); + clone.makeVisibleAnnotation(selectionGroup.getStartRes(), + selectionGroup.getEndRes(), alignment.getHiddenColumns()); } else { - colSel.makeVisibleAnnotation(clone); + clone.makeVisibleAnnotation(alignment.getHiddenColumns()); } ala.add(clone); } } - return ala;*/ + return ala; } @Override @@ -1844,7 +1914,7 @@ public abstract class AlignmentViewport implements AlignViewportI, ResidueShaderI rs = residueShading; if (rs != null) { - rs.alignmentChanged(alignment, posProps.getHiddenRepSequences()); + rs.alignmentChanged(alignment, hiddenRepSequences); rs.setConsensus(hconsensus); if (rs.conservationApplied()) @@ -1859,7 +1929,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (sg.cs != null) { - sg.cs.alignmentChanged(sg, posProps.getHiddenRepSequences()); + sg.cs.alignmentChanged(sg, hiddenRepSequences); } sg.recalcConservation(); } @@ -1882,19 +1952,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()) { @@ -1918,12 +1990,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) @@ -1937,6 +2013,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) @@ -1944,9 +2039,9 @@ public abstract class AlignmentViewport implements AlignViewportI, if (conservation == null) { conservation = new AlignmentAnnotation("Conservation", - "Conservation of total alignment less than " - + getConsPercGaps() + "% gaps", new Annotation[1], - 0f, 11f, AlignmentAnnotation.BAR_GRAPH); + MessageManager.formatMessage("label.conservation_descr", + getConsPercGaps()), + new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); conservation.hasText = true; conservation.autoCalculated = true; alignment.addAnnotation(conservation); @@ -1961,7 +2056,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; @@ -1974,7 +2069,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; @@ -2005,7 +2101,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (aa == null) { - System.err.println("Null annotation row: ignoring."); + jalview.bin.Console.errPrintln("Null annotation row: ignoring."); continue; } if (!aa.visible) @@ -2037,7 +2133,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (aa.graph > 0) { - aa.height += aa.graphHeight; + aa.height += aa.graphHeight+20; } if (aa.height == 0) @@ -2071,7 +2167,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * TODO reorder the annotation rows according to group/sequence ordering on * alignment */ - boolean sortg = true; + // boolean sortg = true; // remove old automatic annotation // add any new annotation @@ -2079,7 +2175,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++) @@ -2181,7 +2277,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public void clearSequenceColours() { sequenceColours.clear(); - }; + } @Override public AlignViewportI getCodingComplement() @@ -2198,7 +2294,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (this == av) { - System.err.println("Ignoring recursive setCodingComplement request"); + jalview.bin.Console.errPrintln("Ignoring recursive setCodingComplement request"); } else { @@ -2425,8 +2521,8 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle = new ViewStyle(settingsForView); if (residueShading != null) { - residueShading.setConservationApplied(settingsForView - .isConservationColourSelected()); + residueShading.setConservationApplied( + settingsForView.isConservationColourSelected()); } } @@ -2529,6 +2625,8 @@ public abstract class AlignmentViewport implements AlignViewportI, { this.historyList.push(command); broadcastCommand(command, false); + setSavedUpToDate(false); + Jalview2XML.setStateSavedUpToDate(false); } } @@ -2594,7 +2692,8 @@ public abstract class AlignmentViewport implements AlignViewportI, return sortAnnotationsBy; } - public void setSortAnnotationsBy(SequenceAnnotationOrder sortAnnotationsBy) + public void setSortAnnotationsBy( + SequenceAnnotationOrder sortAnnotationsBy) { this.sortAnnotationsBy = sortAnnotationsBy; } @@ -2621,94 +2720,63 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle.setScaleProteinAsCdna(b); } - /** - * @return true if view should scroll to show the highlighted region of a - * sequence - * @return - */ @Override - public final boolean isFollowHighlight() + public boolean isProteinFontAsCdna() { - return followHighlight; + return viewStyle.isProteinFontAsCdna(); } @Override - public final void setFollowHighlight(boolean b) + public void setProteinFontAsCdna(boolean b) { - this.followHighlight = b; + viewStyle.setProteinFontAsCdna(b); } @Override - public ViewportPositionProps getPosProps() + public void setShowComplementFeatures(boolean b) { - return posProps; + viewStyle.setShowComplementFeatures(b); } @Override - public int getStartRes() + public boolean isShowComplementFeatures() { - return posProps.getStartRes(); + return viewStyle.isShowComplementFeatures(); } @Override - public int getEndRes() + public void setShowComplementFeaturesOnTop(boolean b) { - return posProps.getEndRes(); + viewStyle.setShowComplementFeaturesOnTop(b); } @Override - public int getStartSeq() + public boolean isShowComplementFeaturesOnTop() { - return posProps.getStartSeq(); + return viewStyle.isShowComplementFeaturesOnTop(); } - public void setStartRes(int res) - { - posProps.setStartRes(res); - // this.startRes = res; - } - - public void setStartSeq(int seq) - { - posProps.setStartSeq(seq); - // this.startSeq = seq; - } - - public void setEndRes(int res) + /** + * @return true if view should scroll to show the highlighted region of a + * sequence + * @return + */ + @Override + public final boolean isFollowHighlight() { - posProps.setEndRes(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;*/ + return followHighlight; } - public void setEndSeq(int seq) + @Override + public final void setFollowHighlight(boolean b) { - posProps.setEndSeq(seq); - /*if (seq > alignment.getHeight()) - { - seq = alignment.getHeight(); - } - if (seq < 0) - { - seq = 0; - } - this.endSeq = seq;*/ + this.followHighlight = b; } @Override - public int getEndSeq() + public ViewportRanges getRanges() { - return posProps.getEndSeq(); - // return endSeq; + return ranges; } /** @@ -2727,8 +2795,8 @@ public abstract class AlignmentViewport implements AlignViewportI, return 0; } boolean iAmProtein = !getAlignment().isNucleotide(); - AlignmentI proteinAlignment = iAmProtein ? getAlignment() : complement - .getAlignment(); + AlignmentI proteinAlignment = iAmProtein ? getAlignment() + : complement.getAlignment(); if (proteinAlignment == null) { return 0; @@ -2748,7 +2816,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(); @@ -2758,7 +2827,8 @@ 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)) @@ -2769,9 +2839,9 @@ public abstract class AlignmentViewport implements AlignViewportI, { continue; } - seqMappings = MappingUtils - .findMappingsForSequenceAndOthers(sequence, mappings, - getCodingComplement().getAlignment().getSequences()); + seqMappings = MappingUtils.findMappingsForSequenceAndOthers(sequence, + mappings, + getCodingComplement().getAlignment().getSequences()); if (!seqMappings.isEmpty()) { break; @@ -2800,11 +2870,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public void expandColSelection(SequenceGroup sg, boolean wholewidth) { - if (!this.hasSelectedColumns()) - { - posProps.expandColSelection(sg, wholewidth); - } - /*int sgs, sge; + int sgs, sge; if (sg != null && (sgs = sg.getStartRes()) >= 0 && sg.getStartRes() <= (sge = sg.getEndRes()) && !this.hasSelectedColumns()) @@ -2822,7 +2888,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { colSel.addElement(cspos); } - }*/ + } } /** @@ -2830,7 +2896,6 @@ public abstract class AlignmentViewport implements AlignViewportI, */ private boolean selectionIsDefinedGroup = false; - @Override public boolean isSelectionDefinedGroup() { @@ -2851,8 +2916,7 @@ public abstract class AlignmentViewport implements AlignViewportI, selectionIsDefinedGroup = gps.contains(selectionGroup); } } - return selectionGroup.getContext() == alignment - || selectionIsDefinedGroup; + return selectionGroup.isDefined() || selectionIsDefinedGroup; } /** @@ -2860,6 +2924,8 @@ public abstract class AlignmentViewport implements AlignViewportI, */ private SearchResultsI searchResults = null; + protected TreeModel currentTree = null; + @Override public boolean hasSearchResults() { @@ -2877,4 +2943,225 @@ public abstract class AlignmentViewport implements AlignViewportI, { return searchResults; } + + @Override + public ContactListI getContactList(AlignmentAnnotation _aa, int column) + { + return alignment.getContactListFor(_aa, column); + } + + @Override + public ContactMatrixI getContactMatrix( + AlignmentAnnotation alignmentAnnotation) + { + return alignment.getContactMatrixFor(alignmentAnnotation); + } + + /** + * 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; + } + + @Override + public void setCurrentTree(TreeModel tree) + { + currentTree = tree; + } + + @Override + public TreeModel getCurrentTree() + { + return currentTree; + } + + @Override + public AlignmentExportData getAlignExportData( + AlignExportSettingsI options) + { + AlignmentI alignmentToExport = null; + String[] omitHidden = null; + alignmentToExport = null; + + if (hasHiddenColumns() && !options.isExportHiddenColumns()) + { + omitHidden = getViewAsString(false, + options.isExportHiddenSequences()); + } + + int[] alignmentStartEnd = new int[2]; + if (hasHiddenRows() && options.isExportHiddenSequences()) + { + alignmentToExport = getAlignment().getHiddenSequences() + .getFullAlignment(); + } + else + { + alignmentToExport = getAlignment(); + } + alignmentStartEnd = getAlignment().getHiddenColumns() + .getVisibleStartAndEndIndex(alignmentToExport.getWidth()); + AlignmentExportData ed = new AlignmentExportData(alignmentToExport, + omitHidden, alignmentStartEnd); + return ed; + } + + /** + * flag set to indicate if structure views might be out of sync with sequences + * in the alignment + */ + + private boolean needToUpdateStructureViews = false; + + @Override + public boolean isUpdateStructures() + { + return needToUpdateStructureViews; + } + + @Override + public void setUpdateStructures(boolean update) + { + needToUpdateStructureViews = update; + } + + @Override + public boolean needToUpdateStructureViews() + { + boolean update = needToUpdateStructureViews; + needToUpdateStructureViews = false; + return update; + } + + @Override + public void addSequenceGroup(SequenceGroup sequenceGroup) + { + alignment.addGroup(sequenceGroup); + + Color col = sequenceGroup.idColour; + if (col != null) + { + col = col.brighter(); + + for (SequenceI sq : sequenceGroup.getSequences()) + { + setSequenceColour(sq, col); + } + } + + if (codingComplement != null) + { + SequenceGroup mappedGroup = MappingUtils + .mapSequenceGroup(sequenceGroup, this, codingComplement); + if (mappedGroup.getSequences().size() > 0) + { + codingComplement.getAlignment().addGroup(mappedGroup); + + if (col != null) + { + for (SequenceI seq : mappedGroup.getSequences()) + { + codingComplement.setSequenceColour(seq, col); + } + } + } + // propagate the structure view update flag according to our own setting + codingComplement.setUpdateStructures(needToUpdateStructureViews); + } + } + + @Override + public Iterator getViewAsVisibleContigs(boolean selectedRegionOnly) + { + int start = 0; + int end = 0; + if (selectedRegionOnly && selectionGroup != null) + { + start = selectionGroup.getStartRes(); + end = selectionGroup.getEndRes() + 1; + } + else + { + end = alignment.getWidth(); + } + return (alignment.getHiddenColumns().getVisContigsIterator(start, end, + false)); + } + + /** + * ordered list of annotation values displayed per sequence in ID panel + */ + private IdColumns id_columns = null; + + /** + * available and currently visible columns for this view + */ + @Override + public IdColumns getIdColumns() + { + if (alignment == null) + { + return null; + } + if (id_columns == null) + { + id_columns = new IdColumns(alignment); + } + return id_columns; + } + + public void setSavedUpToDate(boolean s) + { + setSavedUpToDate(s, QuitHandler.Message.UNSAVED_CHANGES); + } + + public void setSavedUpToDate(boolean s, QuitHandler.Message m) + { + Console.debug( + "Setting " + this.getViewId() + " setSavedUpToDate to " + s); + savedUpToDate = s; + QuitHandler.setMessage(m); + } + + public boolean savedUpToDate() + { + Console.debug("Returning " + this.getViewId() + " savedUpToDate value: " + + savedUpToDate); + return savedUpToDate; + } }