X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FChimeraViewFrame.java;h=6edacd7fd7530b0893b2aa400d05cf965b7aa9a4;hb=c19d2a91ca05e052e3408bf5852d88eb5d0608f1;hp=f644e95ce4e6aeca189bd17f29b4a92f55ff91e2;hpb=f674538af980cae04d8d27033f493bda97a2d17e;p=jalview.git diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java index f644e95..6edacd7 100644 --- a/src/jalview/gui/ChimeraViewFrame.java +++ b/src/jalview/gui/ChimeraViewFrame.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.0b2) + * Copyright (C) 2015 The Jalview Authors * * This file is part of Jalview. * @@ -20,6 +20,31 @@ */ package jalview.gui; +import jalview.bin.Cache; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceI; +import jalview.ext.rbvi.chimera.JalviewChimeraBinding; +import jalview.gui.StructureViewer.ViewerType; +import jalview.io.AppletFormatAdapter; +import jalview.io.JalviewFileChooser; +import jalview.io.JalviewFileView; +import jalview.schemes.BuriedColourScheme; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.HelixColourScheme; +import jalview.schemes.HydrophobicColourScheme; +import jalview.schemes.PurinePyrimidineColourScheme; +import jalview.schemes.StrandColourScheme; +import jalview.schemes.TaylorColourScheme; +import jalview.schemes.TurnColourScheme; +import jalview.schemes.ZappoColourScheme; +import jalview.structures.models.AAStructureBindingModel; +import jalview.util.MessageManager; +import jalview.util.Platform; +import jalview.ws.dbsources.Pdb; + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; @@ -50,31 +75,6 @@ import javax.swing.event.InternalFrameEvent; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; -import jalview.bin.Cache; -import jalview.datamodel.Alignment; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.ColumnSelection; -import jalview.datamodel.PDBEntry; -import jalview.datamodel.SequenceI; -import jalview.ext.rbvi.chimera.JalviewChimeraBinding; -import jalview.gui.StructureViewer.ViewerType; -import jalview.io.AppletFormatAdapter; -import jalview.io.JalviewFileChooser; -import jalview.io.JalviewFileView; -import jalview.schemes.BuriedColourScheme; -import jalview.schemes.ColourSchemeI; -import jalview.schemes.HelixColourScheme; -import jalview.schemes.HydrophobicColourScheme; -import jalview.schemes.PurinePyrimidineColourScheme; -import jalview.schemes.StrandColourScheme; -import jalview.schemes.TaylorColourScheme; -import jalview.schemes.TurnColourScheme; -import jalview.schemes.ZappoColourScheme; -import jalview.structures.models.AAStructureBindingModel; -import jalview.util.MessageManager; -import jalview.util.Platform; -import jalview.ws.dbsources.Pdb; - /** * GUI elements for handling an external chimera display * @@ -87,23 +87,9 @@ public class ChimeraViewFrame extends StructureViewerBase private boolean allChainsSelected = false; - private boolean alignAddedStructures = false; - - /* - * state flag for PDB retrieval thread - */ - private boolean _started = false; - - private boolean addingStructures = false; - private IProgressIndicator progressBar = null; /* - * pdb retrieval thread. - */ - private Thread worker = null; - - /* * Path to Chimera session file. This is set when an open Jalview/Chimera * session is saved, or on restore from a Jalview project (if it holds the * filename of any saved Chimera sessions). @@ -170,8 +156,8 @@ public class ChimeraViewFrame extends StructureViewerBase alignStructs.setToolTipText(MessageManager .formatMessage( "label.align_structures_using_linked_alignment_views", - new Object[] - { new Integer(_alignwith.size()).toString() })); + new Object[] { new Integer(_alignwith + .size()).toString() })); } }); handler.itemStateChanged(null); @@ -211,158 +197,32 @@ public class ChimeraViewFrame extends StructureViewerBase String[] chains, final AlignmentPanel ap) { super(); - - /* - * is the pdb file already loaded? - */ String pdbId = pdbentry.getId(); - String alreadyMapped = ap.getStructureSelectionManager() - .alreadyMappedToFile(pdbId); - - if (alreadyMapped != null) - { - int option = chooseAddSequencesToViewer(pdbId); - if (option == JOptionPane.CANCEL_OPTION) - { - return; - } - if (option == JOptionPane.YES_OPTION) - { - addSequenceMappingsToStructure(seq, chains, ap, alreadyMapped); - return; - } - } /* - * Check if there are other Chimera views involving this alignment and give - * user the option to add and align this molecule to one of them + * If the PDB file is already loaded, the user may just choose to add to an + * existing viewer (or cancel) */ - List existingViews = getChimeraWindowsFor(ap); - for (ChimeraViewFrame view : existingViews) + if (addAlreadyLoadedFile(seq, chains, ap, pdbId)) { - // TODO: highlight view somehow - /* - * JAL-1742 exclude view with this structure already mapped (don't offer - * to align chain B to chain A of the same structure) - */ - if (view.hasPdbId(pdbId)) - { - continue; - } - int option = chooseAlignStructureToViewer(pdbId, view); - if (option == JOptionPane.CANCEL_OPTION) - { - return; - } - if (option == JOptionPane.YES_OPTION) - { - view.useAlignmentPanelForSuperposition(ap); - view.addStructure(pdbentry, seq, chains, true, ap.alignFrame); - return; - } + return; } /* - * If the options above are declined or do not apply, open a new viewer - */ - openNewChimera(ap, new PDBEntry[] - { pdbentry }, new SequenceI[][] - { seq }); - } - - /** - * Presents a dialog with the option to add an align a structure to an - * existing Chimera view - * - * @param pdbId - * @param view - * @return YES, NO or CANCEL JOptionPane code - */ - protected int chooseAlignStructureToViewer(String pdbId, - ChimeraViewFrame view) - { - int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop, - MessageManager.formatMessage("label.add_pdbentry_to_view", - new Object[] - { pdbId, view.getTitle() }), MessageManager - .getString("label.align_to_existing_structure_view"), - JOptionPane.YES_NO_CANCEL_OPTION); - return option; - } - - /** - * Presents a dialog with the option to add sequences to a viewer which - * already has their structure open - * - * @param pdbId - * @return YES, NO or CANCEL JOptionPane code - */ - protected int chooseAddSequencesToViewer(String pdbId) - { - int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop, - MessageManager.formatMessage( - "label.pdb_entry_is_already_displayed", new Object[] - { pdbId }), MessageManager.formatMessage( - "label.map_sequences_to_visible_window", new Object[] - { pdbId }), JOptionPane.YES_NO_CANCEL_OPTION); - return option; - } - - /** - * Adds mappings for the given sequences to an already opened PDB structure, - * and updates any viewers that have the PDB file - * - * @param seq - * @param chains - * @param ap - * @param pdbFilename - */ - protected void addSequenceMappingsToStructure(SequenceI[] seq, - String[] chains, final AlignmentPanel ap, String pdbFilename) - { - // TODO : Fix multiple seq to one chain issue here. - /* - * create the mappings - */ - ap.getStructureSelectionManager().setMapping(seq, chains, pdbFilename, - AppletFormatAdapter.FILE); - - /* - * alert the FeatureRenderer to show new (PDB RESNUM) features + * Check if there are other Chimera views involving this alignment and give + * user the option to add and align this molecule to one of them (or cancel) */ - if (ap.getSeqPanel().seqCanvas.fr != null) + if (addToExistingViewer(pdbentry, seq, chains, ap, pdbId)) { - ap.getSeqPanel().seqCanvas.fr.featuresAdded(); - ap.paintAlignment(true); + return; } /* - * add the sequences to any other Chimera viewers for this pdb file + * If the options above are declined or do not apply, show the structure in + * a new viewer */ - // JBPNOTE: this looks like a binding routine, rather than a gui routine - for (JInternalFrame frame : Desktop.instance.getAllFrames()) - { - if (frame instanceof ChimeraViewFrame) - { - ChimeraViewFrame chimeraView = ((ChimeraViewFrame) frame); - for (int pe = 0; pe < chimeraView.jmb.getPdbCount(); pe++) - { - if (chimeraView.jmb.getPdbEntry(pe).getFile().equals(pdbFilename)) - { - chimeraView.jmb.addSequence(pe, seq); - chimeraView.addAlignmentPanel(ap); - /* - * add it to the set of alignments used for colouring structure by - * sequence - */ - chimeraView.useAlignmentPanelForColourbyseq(ap); - chimeraView.buildActionMenu(); - ap.getStructureSelectionManager().sequenceColoursChanged(ap); - break; - } - } - } - } + openNewChimera(ap, new PDBEntry[] { pdbentry }, + new SequenceI[][] { seq }); } /** @@ -376,6 +236,10 @@ public class ChimeraViewFrame extends StructureViewerBase } } + /** + * Answers true if this viewer already involves the given PDB ID + */ + @Override protected boolean hasPdbId(String pdbId) { return jmb.hasPdbId(pdbId); @@ -434,7 +298,8 @@ public class ChimeraViewFrame extends StructureViewerBase String chain = null; if (seq.getDatasetSequence() != null) { - Vector pdbrefs = seq.getDatasetSequence().getPDBId(); + Vector pdbrefs = seq.getDatasetSequence() + .getAllPDBEntries(); if (pdbrefs != null && pdbrefs.size() > 0) { chain = pdbrefs.get(0).getChainCode(); @@ -459,8 +324,7 @@ public class ChimeraViewFrame extends StructureViewerBase * @param newViewId */ public ChimeraViewFrame(String chimeraSessionFile, - AlignmentPanel alignPanel, - PDBEntry[] pdbArray, + AlignmentPanel alignPanel, PDBEntry[] pdbArray, SequenceI[][] seqsArray, boolean colourByChimera, boolean colourBySequence, String newViewId) { @@ -521,73 +385,22 @@ public class ChimeraViewFrame extends StructureViewerBase } /** - * add a new structure (with associated sequences and chains) to this viewer, - * retrieving it if necessary first. - * - * @param pdbentry - * @param seq - * @param chains - * @param alignFrame - * @param align - * if true, new structure(s) will be align using associated alignment + * Returns a list of any Chimera viewers in the desktop. The list is + * restricted to those linked to the given alignment panel if it is not null. */ - private void addStructure(final PDBEntry pdbentry, final SequenceI[] seq, - final String[] chains, final boolean b, - final IProgressIndicator alignFrame) - { - if (pdbentry.getFile() == null) - { - if (worker != null && worker.isAlive()) - { - // a retrieval is in progress, wait around and add ourselves to the - // queue. - new Thread(new Runnable() - { - public void run() - { - while (worker != null && worker.isAlive() && _started) - { - try - { - Thread.sleep(100 + ((int) Math.random() * 100)); - - } catch (Exception e) - { - } - - } - // and call ourselves again. - addStructure(pdbentry, seq, chains, b, alignFrame); - } - }).start(); - return; - } - } - // otherwise, start adding the structure. - jmb.addSequenceAndChain(new PDBEntry[] - { pdbentry }, new SequenceI[][] - { seq }, new String[][] - { chains }); - addingStructures = true; - _started = false; - alignAddedStructures = b; - // progressBar = alignFrame; // visual indication happens on caller frame. - (worker = new Thread(this)).start(); - return; - } - - private List getChimeraWindowsFor(AlignmentPanel apanel) + @Override + protected List getViewersFor(AlignmentPanel ap) { - List result = new ArrayList(); + List result = new ArrayList(); JInternalFrame[] frames = Desktop.instance.getAllFrames(); for (JInternalFrame frame : frames) { if (frame instanceof ChimeraViewFrame) { - if (((StructureViewerBase) frame).isLinkedWith(apanel)) + if (ap == null || ((StructureViewerBase) frame).isLinkedWith(ap)) { - result.add((ChimeraViewFrame) frame); + result.add((StructureViewerBase) frame); } } } @@ -601,14 +414,13 @@ public class ChimeraViewFrame extends StructureViewerBase void initChimera() { jmb.setFinishedInit(false); - jalview.gui.Desktop.addInternalFrame(this, jmb.getViewerTitle("Chimera", true), - getBounds().width, getBounds().height); + jalview.gui.Desktop.addInternalFrame(this, + jmb.getViewerTitle("Chimera", true), getBounds().width, + getBounds().height); if (!jmb.launchChimera()) { - JOptionPane - .showMessageDialog( - Desktop.desktop, + JOptionPane.showMessageDialog(Desktop.desktop, MessageManager.getString("label.chimera_failed"), MessageManager.getString("label.error_loading_file"), JOptionPane.ERROR_MESSAGE); @@ -713,13 +525,13 @@ public class ChimeraViewFrame extends StructureViewerBase */ public void closeViewer(boolean closeChimera) { - if (jmb.isChimeraRunning()) + if (jmb != null && jmb.isChimeraRunning()) { if (!closeChimera) { String prompt = MessageManager.formatMessage( - "label.confirm_close_chimera", new Object[] - { jmb.getViewerTitle("Chimera", false) }); + "label.confirm_close_chimera", + new Object[] { jmb.getViewerTitle("Chimera", false) }); prompt = JvSwingUtils.wrapTooltip(true, prompt); int confirm = JOptionPane.showConfirmDialog(this, prompt, MessageManager.getString("label.close_viewer"), @@ -812,9 +624,8 @@ public class ChimeraViewFrame extends StructureViewerBase JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager .formatMessage("label.pdb_entries_couldnt_be_retrieved", - new Object[] - { errormsgs.toString() }), MessageManager - .getString("label.couldnt_load_file"), + new Object[] { errormsgs.toString() }), + MessageManager.getString("label.couldnt_load_file"), JOptionPane.ERROR_MESSAGE); } @@ -859,9 +670,7 @@ public class ChimeraViewFrame extends StructureViewerBase } // Explicitly map to the filename used by Chimera ; jmb.getSsm().setMapping(jmb.getSequence()[pos], - jmb.getChains()[pos], - pe.getFile(), - protocol); + jmb.getChains()[pos], pe.getFile(), protocol); } catch (OutOfMemoryError oomerror) { new OOMWarning( @@ -886,7 +695,7 @@ public class ChimeraViewFrame extends StructureViewerBase jmb.updateColours(ap); } // do superposition if asked to - if (alignAddedStructures) + if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures) { new Thread(new Runnable() { @@ -924,8 +733,7 @@ public class ChimeraViewFrame extends StructureViewerBase * Write 'fetching PDB' progress on AlignFrame as we are not yet visible */ String msg = MessageManager.formatMessage("status.fetching_pdb", - new Object[] - { pdbid }); + new Object[] { pdbid }); getAlignmentPanel().alignFrame.setProgressBar(msg, handle); // long hdl = startProgressBar(MessageManager.formatMessage( // "status.fetching_pdb", new Object[] @@ -938,8 +746,7 @@ public class ChimeraViewFrame extends StructureViewerBase new OOMWarning("Retrieving PDB id " + pdbid, oomerror); } finally { - msg = pdbid + " " - + MessageManager.getString("label.state_completed"); + msg = pdbid + " " + MessageManager.getString("label.state_completed"); getAlignmentPanel().alignFrame.setProgressBar(msg, handle); // stopProgressBar(msg, hdl); } @@ -950,7 +757,7 @@ public class ChimeraViewFrame extends StructureViewerBase if (pdbseq != null && pdbseq.getHeight() > 0) { // just use the file name from the first sequence's first PDBEntry - filePath = new File(pdbseq.getSequenceAt(0).getPDBId() + filePath = new File(pdbseq.getSequenceAt(0).getAllPDBEntries() .elementAt(0).getFile()).getAbsolutePath(); processingEntry.setFile(filePath); } @@ -1395,4 +1202,10 @@ public class ChimeraViewFrame extends StructureViewerBase { return ViewerType.CHIMERA; } + + @Override + protected AAStructureBindingModel getBindingModel() + { + return jmb; + } }