X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FChimeraViewFrame.java;h=a6e479d0a784136b236fa435644e4af357f7a95b;hb=42f4227ed213d422a87d3b22fc9e85d14ffaf53f;hp=ab6f6c855ab880b417290c6c58ec3cd439cc8ff3;hpb=124aa4823768a2c745a5e41f2ebfe13ab77bbea4;p=jalview.git diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java index ab6f6c8..a6e479d 100644 --- a/src/jalview/gui/ChimeraViewFrame.java +++ b/src/jalview/gui/ChimeraViewFrame.java @@ -20,12 +20,11 @@ */ package jalview.gui; +import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.bin.Cache; -import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; -import jalview.ext.rbvi.chimera.ChimeraCommands; import jalview.ext.rbvi.chimera.JalviewChimeraBinding; import jalview.gui.StructureViewer.ViewerType; import jalview.io.DataSourceType; @@ -34,7 +33,6 @@ import jalview.structures.models.AAStructureBindingModel; import jalview.util.BrowserLauncher; import jalview.util.MessageManager; import jalview.util.Platform; -import jalview.ws.dbsources.Pdb; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -47,9 +45,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Random; -import javax.swing.JCheckBoxMenuItem; import javax.swing.JInternalFrame; import javax.swing.JMenu; import javax.swing.JMenuItem; @@ -66,8 +62,6 @@ public class ChimeraViewFrame extends StructureViewerBase { private JalviewChimeraBinding jmb; - private IProgressIndicator progressBar = 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 @@ -75,8 +69,6 @@ public class ChimeraViewFrame extends StructureViewerBase */ private String chimeraSessionFile = null; - private Random random = new Random(); - private int myWidth = 500; private int myHeight = 150; @@ -91,8 +83,8 @@ public class ChimeraViewFrame extends StructureViewerBase viewerActionMenu.setText(MessageManager.getString("label.chimera")); - viewerColour.setText(MessageManager - .getString("label.colour_with_chimera")); + viewerColour + .setText(MessageManager.getString("label.colour_with_chimera")); viewerColour.setToolTipText(MessageManager .getString("label.let_chimera_manage_structure_colours")); @@ -100,41 +92,34 @@ public class ChimeraViewFrame extends StructureViewerBase savemenu.setVisible(false); // not yet implemented viewMenu.add(fitToWindow); - /* - * exchange of Jalview features and Chimera attributes is for now - * an optionally enabled experimental feature - */ - if (Desktop.instance.showExperimental()) + JMenuItem writeFeatures = new JMenuItem( + MessageManager.getString("label.create_chimera_attributes")); + writeFeatures.setToolTipText(MessageManager + .getString("label.create_chimera_attributes_tip")); + writeFeatures.addActionListener(new ActionListener() { - JMenuItem writeFeatures = new JMenuItem( - MessageManager.getString("label.create_chimera_attributes")); - writeFeatures.setToolTipText(MessageManager - .getString("label.create_chimera_attributes_tip")); - writeFeatures.addActionListener(new ActionListener() + @Override + public void actionPerformed(ActionEvent e) { - @Override - public void actionPerformed(ActionEvent e) - { - sendFeaturesToChimera(); - } - }); - viewerActionMenu.add(writeFeatures); + sendFeaturesToChimera(); + } + }); + viewerActionMenu.add(writeFeatures); - final JMenu fetchAttributes = new JMenu( - MessageManager.getString("label.fetch_chimera_attributes")); - fetchAttributes.setToolTipText(MessageManager - .getString("label.fetch_chimera_attributes_tip")); - fetchAttributes.addMouseListener(new MouseAdapter() - { + final JMenu fetchAttributes = new JMenu( + MessageManager.getString("label.fetch_chimera_attributes")); + fetchAttributes.setToolTipText( + MessageManager.getString("label.fetch_chimera_attributes_tip")); + fetchAttributes.addMouseListener(new MouseAdapter() + { - @Override - public void mouseEntered(MouseEvent e) - { - buildAttributesMenu(fetchAttributes); - } - }); - viewerActionMenu.add(fetchAttributes); - } + @Override + public void mouseEntered(MouseEvent e) + { + buildAttributesMenu(fetchAttributes); + } + }); + viewerActionMenu.add(fetchAttributes); } /** @@ -145,34 +130,21 @@ public class ChimeraViewFrame extends StructureViewerBase */ protected void buildAttributesMenu(JMenu attributesMenu) { - List atts = jmb.sendChimeraCommand("list resattr", true); - if (atts == null) - { - return; - } + List atts = jmb.getChimeraAttributes(); attributesMenu.removeAll(); Collections.sort(atts); - for (String att : atts) + for (String attName : atts) { - final String attName = att.split(" ")[1]; - - /* - * ignore 'jv_*' attributes, as these are Jalview features that have - * been transferred to residue attributes in Chimera! - */ - if (!attName.startsWith(ChimeraCommands.NAMESPACE_PREFIX)) + JMenuItem menuItem = new JMenuItem(attName); + menuItem.addActionListener(new ActionListener() { - JMenuItem menuItem = new JMenuItem(attName); - menuItem.addActionListener(new ActionListener() + @Override + public void actionPerformed(ActionEvent e) { - @Override - public void actionPerformed(ActionEvent e) - { - getChimeraAttributes(attName); - } - }); - attributesMenu.add(menuItem); - } + getChimeraAttributes(attName); + } + }); + attributesMenu.add(menuItem); } } @@ -190,19 +162,19 @@ public class ChimeraViewFrame extends StructureViewerBase /** * Send a command to Chimera to create residue attributes for Jalview features *

- * The syntax is: setattr r + * The syntax is: setattr r <attName> <attValue> <atomSpec> *

- * For example: setattr r jv:chain "Ferredoxin-1, Chloroplastic" #0:94.A + * For example: setattr r jv_chain "Ferredoxin-1, Chloroplastic" #0:94.A */ protected void sendFeaturesToChimera() { int count = jmb.sendFeaturesToViewer(getAlignmentPanel()); - statusBar.setText(MessageManager.formatMessage("label.attributes_set", - count)); + statusBar.setText( + MessageManager.formatMessage("label.attributes_set", count)); } /** - * add a single PDB structure to a new or existing Chimera view + * open a single PDB structure in a new Chimera view * * @param pdbentry * @param seq @@ -213,32 +185,10 @@ public class ChimeraViewFrame extends StructureViewerBase String[] chains, final AlignmentPanel ap) { this(); - String pdbId = pdbentry.getId(); - - /* - * If the PDB file is already loaded, the user may just choose to add to an - * existing viewer (or cancel) - */ - if (addAlreadyLoadedFile(seq, chains, ap, pdbId)) - { - 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 (or cancel) - */ - if (addToExistingViewer(pdbentry, seq, chains, ap, pdbId)) - { - return; - } - - /* - * If the options above are declined or do not apply, show the structure in - * a new viewer - */ openNewChimera(ap, new PDBEntry[] { pdbentry }, - new SequenceI[][] { seq }); + new SequenceI[][] + { seq }); } /** @@ -246,9 +196,9 @@ public class ChimeraViewFrame extends StructureViewerBase */ protected void createProgressBar() { - if (progressBar == null) + if (getProgressIndicator() == null) { - progressBar = new ProgressBar(statusPanel, statusBar); + setProgressIndicator(new ProgressBar(statusPanel, statusBar)); } } @@ -256,14 +206,12 @@ public class ChimeraViewFrame extends StructureViewerBase SequenceI[][] seqs) { createProgressBar(); - jmb = new JalviewChimeraBindingModel(this, - ap.getStructureSelectionManager(), pdbentrys, seqs, null); + jmb = newBindingModel(ap, pdbentrys, seqs); addAlignmentPanel(ap); useAlignmentPanelForColourbyseq(ap); if (pdbentrys.length > 1) { - alignAddedStructures = true; useAlignmentPanelForSuperposition(ap); } jmb.setColourBySequence(true); @@ -277,7 +225,8 @@ public class ChimeraViewFrame extends StructureViewerBase this.addInternalFrameListener(new InternalFrameAdapter() { @Override - public void internalFrameClosing(InternalFrameEvent internalFrameEvent) + public void internalFrameClosing( + InternalFrameEvent internalFrameEvent) { closeViewer(false); } @@ -285,6 +234,13 @@ public class ChimeraViewFrame extends StructureViewerBase } + protected JalviewChimeraBindingModel newBindingModel(AlignmentPanel ap, + PDBEntry[] pdbentrys, SequenceI[][] seqs) + { + return new JalviewChimeraBindingModel(this, + ap.getStructureSelectionManager(), pdbentrys, seqs, null); + } + /** * Create a new viewer from saved session state data including Chimera session * file @@ -321,17 +277,19 @@ public class ChimeraViewFrame extends StructureViewerBase } /** - * create a new viewer containing several structures superimposed using the - * given alignPanel. + * create a new viewer containing several structures, optionally superimposed + * using the given alignPanel. * * @param pe * @param seqs * @param ap */ - public ChimeraViewFrame(PDBEntry[] pe, SequenceI[][] seqs, + public ChimeraViewFrame(PDBEntry[] pe, boolean alignAdded, + SequenceI[][] seqs, AlignmentPanel ap) { this(); + setAlignAddedStructures(alignAdded); openNewChimera(ap, pe, seqs); } @@ -350,29 +308,6 @@ public class ChimeraViewFrame extends StructureViewerBase } /** - * 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. - */ - @Override - protected List getViewersFor(AlignmentPanel ap) - { - List result = new ArrayList(); - JInternalFrame[] frames = Desktop.instance.getAllFrames(); - - for (JInternalFrame frame : frames) - { - if (frame instanceof ChimeraViewFrame) - { - if (ap == null || ((StructureViewerBase) frame).isLinkedWith(ap)) - { - result.add((StructureViewerBase) frame); - } - } - } - return result; - } - - /** * Launch Chimera. If we have a chimera session file name, send Chimera the * command to open its saved session file. */ @@ -398,9 +333,8 @@ public class ChimeraViewFrame extends StructureViewerBase boolean opened = jmb.openSession(chimeraSessionFile); if (!opened) { - System.err - .println("An error occurred opening Chimera session file " - + chimeraSessionFile); + System.err.println("An error occurred opening Chimera session file " + + chimeraSessionFile); } } @@ -408,27 +342,6 @@ public class ChimeraViewFrame extends StructureViewerBase } /** - * Show only the selected chain(s) in the viewer - */ - @Override - void showSelectedChains() - { - List toshow = new ArrayList(); - for (int i = 0; i < chainMenu.getItemCount(); i++) - { - if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem) - { - JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i); - if (item.isSelected()) - { - toshow.add(item.getText()); - } - } - } - jmb.showChains(toshow); - } - - /** * Close down this instance of Jalview's Chimera viewer, giving the user the * option to close the associated Chimera window (process). They may wish to * keep it open until they have had an opportunity to save any work. @@ -443,10 +356,9 @@ public class ChimeraViewFrame extends StructureViewerBase { if (!closeChimera) { - String prompt = MessageManager.formatMessage( - "label.confirm_close_chimera", - new Object[] { jmb.getViewerTitle(getViewerName(), - false) }); + String prompt = MessageManager + .formatMessage("label.confirm_close_chimera", new Object[] + { jmb.getViewerTitle(getViewerName(), false) }); prompt = JvSwingUtils.wrapTooltip(true, prompt); int confirm = JvOptionPane.showConfirmDialog(this, prompt, MessageManager.getString("label.close_viewer"), @@ -484,13 +396,13 @@ public class ChimeraViewFrame extends StructureViewerBase // todo - record which pdbids were successfully imported. StringBuilder errormsgs = new StringBuilder(128); StringBuilder files = new StringBuilder(128); - List filePDB = new ArrayList(); - List filePDBpos = new ArrayList(); + List filePDB = new ArrayList<>(); + List filePDBpos = new ArrayList<>(); PDBEntry thePdbEntry = null; StructureFile pdb = null; try { - String[] curfiles = jmb.getPdbFile(); // files currently in viewer + String[] curfiles = jmb.getStructureFiles(); // files currently in viewer // TODO: replace with reference fetching/transfer code (validate PDBentry // as a DBRef?) for (int pi = 0; pi < jmb.getPdbCount(); pi++) @@ -532,7 +444,7 @@ public class ChimeraViewFrame extends StructureViewerBase { filePDB.add(thePdbEntry); filePDBpos.add(Integer.valueOf(pi)); - files.append(" \"" + Platform.escapeString(file) + "\""); + files.append(" \"" + Platform.escapeBackslashes(file) + "\""); } } } catch (OutOfMemoryError oomerror) @@ -542,15 +454,16 @@ public class ChimeraViewFrame extends StructureViewerBase } catch (Exception ex) { ex.printStackTrace(); - errormsgs.append("When retrieving pdbfiles for '" - + thePdbEntry.getId() + "'"); + errormsgs.append( + "When retrieving pdbfiles for '" + thePdbEntry.getId() + "'"); } if (errormsgs.length() > 0) { - JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager - .formatMessage("label.pdb_entries_couldnt_be_retrieved", - new Object[] { errormsgs.toString() }), + JvOptionPane.showInternalMessageDialog(Desktop.desktop, + MessageManager.formatMessage( + "label.pdb_entries_couldnt_be_retrieved", new Object[] + { errormsgs.toString() }), MessageManager.getString("label.couldnt_load_file"), JvOptionPane.ERROR_MESSAGE); } @@ -597,9 +510,12 @@ public class ChimeraViewFrame extends StructureViewerBase stopProgressBar("", startTime); } // Explicitly map to the filename used by Chimera ; + pdb = jmb.getSsm().setMapping(jmb.getSequence()[pos], - jmb.getChains()[pos], pe.getFile(), protocol); - stashFoundChains(pdb, pe.getFile()); + jmb.getChains()[pos], pe.getFile(), protocol, + getProgressIndicator()); + jmb.stashFoundChains(pdb, pe.getFile()); + } catch (OutOfMemoryError oomerror) { new OOMWarning( @@ -607,8 +523,9 @@ public class ChimeraViewFrame extends StructureViewerBase oomerror); } catch (Exception ex) { - Cache.log.error("Couldn't open " + pe.getFile() - + " in Chimera viewer!", ex); + Cache.log.error( + "Couldn't open " + pe.getFile() + " in Chimera viewer!", + ex); } finally { Cache.log.debug("File locations are " + files); @@ -631,22 +548,21 @@ public class ChimeraViewFrame extends StructureViewerBase } // refresh the sequence colours for the new structure(s) - for (AlignmentPanel ap : _colourwith) + for (AlignmentViewPanel ap : _colourwith) { jmb.updateColours(ap); } // do superposition if asked to - if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures) + if (alignAddedStructures) { new Thread(new Runnable() { @Override public void run() { - alignStructs_withAllAlignPanels(); + alignStructsWithAllAlignPanels(); } }).start(); - alignAddedStructures = false; } addingStructures = false; } @@ -654,129 +570,31 @@ public class ChimeraViewFrame extends StructureViewerBase worker = null; } - /** - * Fetch PDB data and save to a local file. Returns the full path to the file, - * or null if fetch fails. - * - * @param processingEntry - * @return - * @throws Exception - */ - - private void stashFoundChains(StructureFile pdb, String file) - { - for (int i = 0; i < pdb.getChains().size(); i++) - { - String chid = new String(pdb.getId() + ":" - + pdb.getChains().elementAt(i).id); - jmb.getChainNames().add(chid); - jmb.getChainFile().put(chid, file); - } - } - private String fetchPdbFile(PDBEntry processingEntry) throws Exception - { - // FIXME: this is duplicated code with Jmol frame ? - String filePath = null; - Pdb pdbclient = new Pdb(); - AlignmentI pdbseq = null; - String pdbid = processingEntry.getId(); - long handle = System.currentTimeMillis() - + Thread.currentThread().hashCode(); - - /* - * Write 'fetching PDB' progress on AlignFrame as we are not yet visible - */ - String msg = MessageManager.formatMessage("status.fetching_pdb", - new Object[] { pdbid }); - getAlignmentPanel().alignFrame.setProgressBar(msg, handle); - // long hdl = startProgressBar(MessageManager.formatMessage( - // "status.fetching_pdb", new Object[] - // { pdbid })); - try - { - pdbseq = pdbclient.getSequenceRecords(pdbid); - } catch (OutOfMemoryError oomerror) - { - new OOMWarning("Retrieving PDB id " + pdbid, oomerror); - } finally - { - msg = pdbid + " " + MessageManager.getString("label.state_completed"); - getAlignmentPanel().alignFrame.setProgressBar(msg, handle); - // stopProgressBar(msg, hdl); - } - /* - * If PDB data were saved and are not invalid (empty alignment), return the - * file path. - */ - if (pdbseq != null && pdbseq.getHeight() > 0) - { - // just use the file name from the first sequence's first PDBEntry - filePath = new File(pdbseq.getSequenceAt(0).getAllPDBEntries() - .elementAt(0).getFile()).getAbsolutePath(); - processingEntry.setFile(filePath); - } - return filePath; - } - - /** - * Convenience method to update the progress bar if there is one. Be sure to - * call stopProgressBar with the returned handle to remove the message. - * - * @param msg - * @param handle - */ - public long startProgressBar(String msg) - { - // TODO would rather have startProgress/stopProgress as the - // IProgressIndicator interface - long tm = random.nextLong(); - if (progressBar != null) - { - progressBar.setProgressBar(msg, tm); - } - return tm; - } - - /** - * End the progress bar with the specified handle, leaving a message (if not - * null) on the status bar - * - * @param msg - * @param handle - */ - public void stopProgressBar(String msg, long handle) - { - if (progressBar != null) - { - progressBar.setProgressBar(msg, handle); - } - } - @Override - public void eps_actionPerformed(ActionEvent e) + public void eps_actionPerformed() { - throw new Error( - MessageManager - .getString("error.eps_generation_not_implemented")); + throw new Error(MessageManager + .getString("error.eps_generation_not_implemented")); } @Override - public void png_actionPerformed(ActionEvent e) + public void png_actionPerformed() { - throw new Error( - MessageManager - .getString("error.png_generation_not_implemented")); + throw new Error(MessageManager + .getString("error.png_generation_not_implemented")); } @Override - public void showHelp_actionPerformed(ActionEvent actionEvent) + public void showHelp_actionPerformed() { try { - BrowserLauncher - .openURL("https://www.cgl.ucsf.edu/chimera/docs/UsersGuide"); + String url = jmb.getHelpURL(); + BrowserLauncher.openURL(url); } catch (IOException ex) { + System.err + .println("Show Chimera help failed with: " + ex.getMessage()); } } @@ -801,7 +619,8 @@ public class ChimeraViewFrame extends StructureViewerBase { if (pathUsed == null) { - File tempFile = File.createTempFile("chimera", ".py"); + String suffix = jmb.getSessionFileExtension(); + File tempFile = File.createTempFile("chimera", suffix); tempFile.deleteOnExit(); pathUsed = tempFile.getPath(); } @@ -873,20 +692,4 @@ public class ChimeraViewFrame extends StructureViewerBase { return "Chimera"; } - - /** - * Sends commands to align structures according to associated alignment(s). - * - * @return - */ - @Override - protected String alignStructs_withAllAlignPanels() - { - String reply = super.alignStructs_withAllAlignPanels(); - if (reply != null) - { - statusBar.setText("Superposition failed: " + reply); - } - return reply; - } }