From cb678533f3bbdce41510b5f2bc0c5291f920e664 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Tue, 24 Feb 2015 16:10:16 +0000 Subject: [PATCH] JAL-1677 save/restore SplitFrame to Jalview project --- schemas/jalview.xsd | 15 +- src/jalview/api/AlignViewportI.java | 7 + src/jalview/gui/Desktop.java | 9 +- src/jalview/gui/Jalview2XML.java | 241 +++++++++++++++++++------- src/jalview/viewmodel/AlignmentViewport.java | 1 + 5 files changed, 200 insertions(+), 73 deletions(-) diff --git a/schemas/jalview.xsd b/schemas/jalview.xsd index 27f952d..047353c 100755 --- a/schemas/jalview.xsd +++ b/schemas/jalview.xsd @@ -359,12 +359,11 @@ type="xs:boolean" use="optional" default="true" /> - + - - + @@ -388,6 +387,14 @@ + + + + The viewport id of this viewport's (cdna/protein) coding complement, if any + + + splitFrameCandidates = new HashMap(); + /** * create/return unique hash string for sq * @@ -298,12 +304,12 @@ public class Jalview2XML } /** - * This maintains a list of viewports, the key being the seqSetId. Important - * to set historyItem and redoList for multiple views + * This maintains a map of viewports, the key being the seqSetId. Important to + * set historyItem and redoList for multiple views */ - Hashtable viewportsAdded; + Map viewportsAdded = new HashMap(); - Hashtable annotationIds = new Hashtable(); + Map annotationIds = new HashMap(); String uniqueSetSuffix = ""; @@ -1042,6 +1048,10 @@ public class Jalview2XML view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), av.getSequenceSetId())); view.setId(av.getViewId()); + if (av.getCodingComplement() != null) + { + view.setComplementId(av.getCodingComplement().getViewId()); + } view.setViewName(av.viewName); view.setGatheredViews(av.isGatherViewsHere()); @@ -1654,7 +1664,7 @@ public class Jalview2XML } } throw new Error(MessageManager.formatMessage( - "error.unsupported_version_calcIdparam", new String[] + "error.unsupported_version_calcIdparam", new Object[] { calcIdParam.toString() })); } @@ -1987,7 +1997,7 @@ public class Jalview2XML errorMessage = null; uniqueSetSuffix = null; seqRefIds = null; - viewportsAdded = null; + viewportsAdded.clear(); frefedSequence = null; if (file.startsWith("http://")) @@ -2039,17 +2049,13 @@ public class Jalview2XML { seqRefIds = new HashMap(); } - if (viewportsAdded == null) - { - viewportsAdded = new Hashtable(); - } if (frefedSequence == null) { frefedSequence = new Vector(); } - jalview.gui.AlignFrame af = null, _af = null; - Hashtable gatherToThisFrame = new Hashtable(); + AlignFrame af = null, _af = null; + Map gatherToThisFrame = new HashMap(); final String file = jprovider.getFilename(); try { @@ -2149,11 +2155,13 @@ public class Jalview2XML Desktop.instance.stopLoading(); } - Enumeration en = gatherToThisFrame.elements(); - while (en.hasMoreElements()) + for (AlignFrame fr : gatherToThisFrame.values()) { - Desktop.instance.gatherViews((AlignFrame) en.nextElement()); + Desktop.instance.gatherViews(fr); } + + restoreSplitFrames(); + if (errorMessage != null) { reportErrors(); @@ -2162,6 +2170,107 @@ public class Jalview2XML } /** + * Try to reconstruct and display SplitFrame windows, where each contains + * complementary dna and protein alignments. Done by pairing up AlignFrame + * objects (created earlier) which have complementary viewport ids associated. + */ + protected void restoreSplitFrames() + { + List gatherTo = new ArrayList(); + List addedToSplitFrames = new ArrayList(); + Map dna = new HashMap(); + + /* + * Identify the DNA alignments + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (af.getViewport().getAlignment().isNucleotide()) + { + dna.put(candidate.getKey().getId(), af); + } + } + + /* + * Try to match up the protein complements + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (!af.getViewport().getAlignment().isNucleotide()) + { + String complementId = candidate.getKey().getComplementId(); + // only non-null complements should be in the Map + if (complementId != null && dna.containsKey(complementId)) + { + final AlignFrame dnaFrame = dna.get(complementId); + SplitFrame sf = createSplitFrame(dnaFrame, af); + addedToSplitFrames.add(dnaFrame); + addedToSplitFrames.add(af); + if (af.viewport.isGatherViewsHere()) + { + gatherTo.add(sf); + } + } + } + } + + /* + * Open any that we failed to pair up (which shouldn't happen!) as + * standalone AlignFrame's. + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (!addedToSplitFrames.contains(af)) { + Viewport view = candidate.getKey(); + Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), + view.getHeight()); + System.err.println("Failed to restore view " + view.getTitle() + + " to split frame"); + } + } + + /* + * Gather back into tabbed views as flagged. + */ + for (SplitFrame sf : gatherTo) + { + Desktop.instance.gatherViews(sf); + } + + splitFrameCandidates.clear(); + } + + /** + * Construct and display one SplitFrame holding DNA and protein alignments. + * + * @param dnaFrame + * @param proteinFrame + * @return + */ + protected SplitFrame createSplitFrame(AlignFrame dnaFrame, + AlignFrame proteinFrame) + { + dnaFrame.setVisible(true); + proteinFrame.setVisible(true); + proteinFrame.getViewport().setCodingComplement(dnaFrame.getViewport()); + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + ssm.addCommandListener(proteinFrame.getViewport()); + ssm.addCommandListener(dnaFrame.getViewport()); + + SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame); + String title = MessageManager.getString("label.linked_view_title"); + Desktop.addInternalFrame(splitFrame, title, -1, -1); + return splitFrame; + } + + /** * check errorMessage for a valid error message and raise an error box in the * GUI or write the current errorMessage to stderr and then clear the error * state. @@ -2198,7 +2307,7 @@ public class Jalview2XML errorMessage = null; } - Hashtable alreadyLoadedPDB; + Map alreadyLoadedPDB = new HashMap(); /** * when set, local views will be updated from view stored in JalviewXML @@ -2209,11 +2318,6 @@ public class Jalview2XML String loadPDBFile(jarInputStreamProvider jprovider, String pdbId) { - if (alreadyLoadedPDB == null) - { - alreadyLoadedPDB = new Hashtable(); - } - if (alreadyLoadedPDB.containsKey(pdbId)) { return alreadyLoadedPDB.get(pdbId).toString(); @@ -2315,10 +2419,10 @@ public class Jalview2XML // //////////////////////////////// // LOAD SEQUENCES - Vector hiddenSeqs = null; + List hiddenSeqs = null; jalview.datamodel.Sequence jseq; - ArrayList tmpseqs = new ArrayList(); + List tmpseqs = new ArrayList(); boolean multipleView = false; @@ -2350,10 +2454,10 @@ public class Jalview2XML { if (hiddenSeqs == null) { - hiddenSeqs = new Vector(); + hiddenSeqs = new ArrayList(); } - hiddenSeqs.addElement(seqRefIds.get(seqId)); + hiddenSeqs.add(seqRefIds.get(seqId)); } } @@ -2361,13 +2465,10 @@ public class Jalview2XML // / // Create the alignment object from the sequence set // /////////////////////////////// - jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs - .size()]; + SequenceI[] orderedSeqs = tmpseqs + .toArray(new SequenceI[tmpseqs.size()]); - tmpseqs.toArray(orderedSeqs); - - jalview.datamodel.Alignment al = new jalview.datamodel.Alignment( - orderedSeqs); + Alignment al = new Alignment(orderedSeqs); // / Add the alignment properties for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++) @@ -2394,7 +2495,7 @@ public class Jalview2XML } // /////////////////////////////// - Hashtable pdbloaded = new Hashtable(); + Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this?? if (!multipleView) { // load sequence features, database references and any associated PDB @@ -2502,7 +2603,7 @@ public class Jalview2XML // //////////////////////////////// // LOAD ANNOTATIONS - ArrayList autoAlan = new ArrayList(); + List autoAlan = new ArrayList(); /** * store any annotations which forward reference a group's ID */ @@ -2541,8 +2642,7 @@ public class Jalview2XML if (an[i].getId() != null && annotationIds.containsKey(an[i].getId())) { - jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds - .get(an[i].getId()); + AlignmentAnnotation jda = annotationIds.get(an[i].getId()); // in principle Visible should always be true for annotation displayed // in multiple views if (an[i].hasVisible()) @@ -3583,10 +3683,10 @@ public class Jalview2XML } } - AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs, - Alignment al, JalviewModelSequence jms, Viewport view, - String uniqueSeqSetId, String viewId, - ArrayList autoAlan) + AlignFrame loadViewport(String file, JSeq[] JSEQ, + List hiddenSeqs, Alignment al, + JalviewModelSequence jms, Viewport view, String uniqueSeqSetId, + String viewId, List autoAlan) { AlignFrame af = null; af = new AlignFrame(al, view.getWidth(), view.getHeight(), @@ -3604,8 +3704,7 @@ public class Jalview2XML if (view.getSequenceSetId() != null) { - AlignmentViewport av = (AlignmentViewport) viewportsAdded - .get(uniqueSeqSetId); + AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId); af.viewport.setSequenceSetId(uniqueSeqSetId); if (av != null) @@ -3637,14 +3736,17 @@ public class Jalview2XML af.viewport.hideRepSequences(al.getSequenceAt(s), hidden); } - jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs - .size()]; - - for (int s = 0; s < hiddenSeqs.size(); s++) - { - hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s); - } + // jalview.datamodel.SequenceI[] hseqs = new + // jalview.datamodel.SequenceI[hiddenSeqs + // .size()]; + // + // for (int s = 0; s < hiddenSeqs.size(); s++) + // { + // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s); + // } + SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs + .size()]); af.viewport.hideSequence(hseqs); } @@ -3893,12 +3995,27 @@ public class Jalview2XML } } af.setMenusFromViewport(af.viewport); + // TODO: we don't need to do this if the viewport is aready visible. - Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), - view.getHeight()); - af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation - reorderAutoannotation(af, al, autoAlan); - af.alignPanel.alignmentChanged(); + /* + * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it + * has a 'cdna/protein complement' view, in which case save it in order to + * populate a SplitFrame once all views have been read in. + */ + String complementaryViewId = view.getComplementId(); + if (complementaryViewId == null) + { + Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), + view.getHeight()); + // recompute any autoannotation + af.alignPanel.updateAnnotation(false, true); + reorderAutoannotation(af, al, autoAlan); + af.alignPanel.alignmentChanged(); + } + else + { + splitFrameCandidates.put(view, af); + } return af; } @@ -4028,7 +4145,7 @@ public class Jalview2XML } private void reorderAutoannotation(AlignFrame af, Alignment al, - ArrayList autoAlan) + List autoAlan) { // copy over visualization settings for autocalculated annotation in the // view @@ -4052,11 +4169,11 @@ public class Jalview2XML + auan.template.getCalcId()), auan); } int hSize = al.getAlignmentAnnotation().length; - ArrayList reorder = new ArrayList(); + List reorder = new ArrayList(); // work through any autoCalculated annotation already on the view // removing it if it should be placed in a different location on the // annotation panel. - List remains = new ArrayList(visan.keySet()); + List remains = new ArrayList(visan.keySet()); for (int h = 0; h < hSize; h++) { jalview.datamodel.AlignmentAnnotation jalan = al @@ -4304,7 +4421,7 @@ public class Jalview2XML // if (pre || post) if (sq != dsq) { - StringBuffer sb = new StringBuffer(); + // StringBuffer sb = new StringBuffer(); String newres = jalview.analysis.AlignSeq.extractGaps( jalview.util.Comparison.GapChars, sq.getSequenceAsString()); if (!newres.equalsIgnoreCase(dsq.getSequenceAsString()) @@ -4520,7 +4637,7 @@ public class Jalview2XML frefedSequence = new Vector(); } - viewportsAdded = new Hashtable(); + viewportsAdded.clear(); AlignFrame af = loadFromObject(jm, null, false, null); af.alignPanels.clear(); @@ -4667,13 +4784,9 @@ public class Jalview2XML } else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation) { - if (annotationIds == null) - { - annotationIds = new Hashtable(); - } String anid; - annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj); - jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj; + AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj; + annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann); if (jvann.annotationId == null) { jvann.annotationId = anid; diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 4fc587e..9a88a3f 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -1054,6 +1054,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ protected String viewId = null; + @Override public String getViewId() { if (viewId == null) -- 1.7.10.2