X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FChimeraViewFrame.java;h=e76f11e73c0e33bbac4ea0d2fd56ea01a6b9bd90;hb=7d8f40032746ee633dd980d5609c4d517a40421a;hp=c30a41835e4dd95b02d384f1ec06952a7f93e43c;hpb=37de9310bec3501cbc6381e0c3dcb282fcaad812;p=jalview.git diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java index c30a418..e76f11e 100644 --- a/src/jalview/gui/ChimeraViewFrame.java +++ b/src/jalview/gui/ChimeraViewFrame.java @@ -26,11 +26,13 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; 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.AppletFormatAdapter; import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; +import jalview.io.StructureFile; import jalview.schemes.BuriedColourScheme; import jalview.schemes.ColourSchemeI; import jalview.schemes.HelixColourScheme; @@ -49,6 +51,8 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -58,10 +62,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Random; -import java.util.Set; import java.util.Vector; import javax.swing.JCheckBoxMenuItem; @@ -183,6 +186,97 @@ public class ChimeraViewFrame extends StructureViewerBase // TODO Auto-generated method stub } }); + + 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) + { + sendFeaturesToChimera(); + } + }); + viewerActionMenu.add(writeFeatures); + + final JMenu fetchAttributes = new JMenu("Fetch Chimera attributes"); + fetchAttributes + .setToolTipText("Copy Chimera attribute to Jalview feature"); + fetchAttributes.addMouseListener(new MouseAdapter() + { + + @Override + public void mouseEntered(MouseEvent e) + { + buildAttributesMenu(fetchAttributes); + } + }); + viewerActionMenu.add(fetchAttributes); + + } + + /** + * Query Chimera for its residue attribute names and add them as items off the + * attributes menu + * + * @param attributesMenu + */ + protected void buildAttributesMenu(JMenu attributesMenu) + { + List atts = jmb.sendChimeraCommand("list resattr", true); + if (atts == null) + { + return; + } + attributesMenu.removeAll(); + Collections.sort(atts); + for (String att : 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() + { + @Override + public void actionPerformed(ActionEvent e) + { + getChimeraAttributes(attName); + } + }); + attributesMenu.add(menuItem); + } + } + } + + /** + * Read residues in Chimera with the given attribute name, and set as features + * on the corresponding sequence positions (if any) + * + * @param attName + */ + protected void getChimeraAttributes(String attName) + { + jmb.copyStructureAttributesToFeatures(attName, getAlignmentPanel()); + } + + /** + * Send a command to Chimera to create residue attributes for Jalview features + *

+ * The syntax is: setattr r + *

+ * For example: setattr r jv:chain "Ferredoxin-1, Chloroplastic" #0:94.A + */ + protected void sendFeaturesToChimera() + { + jmb.sendFeaturesToViewer(getAlignmentPanel()); } /** @@ -196,7 +290,7 @@ public class ChimeraViewFrame extends StructureViewerBase public ChimeraViewFrame(PDBEntry pdbentry, SequenceI[] seq, String[] chains, final AlignmentPanel ap) { - super(); + this(); String pdbId = pdbentry.getId(); /* @@ -249,11 +343,8 @@ public class ChimeraViewFrame extends StructureViewerBase SequenceI[][] seqs) { createProgressBar(); - // FIXME extractChains needs pdbentries to match IDs to PDBEntry(s) on seqs - String[][] chains = extractChains(seqs); jmb = new JalviewChimeraBindingModel(this, - ap.getStructureSelectionManager(), pdbentrys, seqs, chains, - null); + ap.getStructureSelectionManager(), pdbentrys, seqs, null); addAlignmentPanel(ap); useAlignmentPanelForColourbyseq(ap); if (pdbentrys.length > 1) @@ -281,42 +372,6 @@ public class ChimeraViewFrame extends StructureViewerBase } /** - * Retrieve chains for sequences by inspecting their PDB refs. The hope is - * that the first will be to the sequence's own chain. Really need a more - * managed way of doing this. - * - * @param seqs - * @return - */ - protected String[][] extractChains(SequenceI[][] seqs) - { - String[][] chains = new String[seqs.length][]; - for (int i = 0; i < seqs.length; i++) - { - chains[i] = new String[seqs[i].length]; - int seqno = 0; - for (SequenceI seq : seqs[i]) - { - String chain = null; - if (seq.getDatasetSequence() != null) - { - Vector pdbrefs = seq.getDatasetSequence() - .getAllPDBEntries(); - if (pdbrefs != null && pdbrefs.size() > 0) - { - // FIXME: SequenceI.PDBEntry[0] chain mapping used for - // ChimeraViewFrame. Is this even used ??? - - chain = pdbrefs.get(0).getChainCode(); - } - } - chains[i][seqno++] = chain; - } - } - return chains; - } - - /** * Create a new viewer from saved session state data including Chimera session * file * @@ -333,7 +388,7 @@ public class ChimeraViewFrame extends StructureViewerBase SequenceI[][] seqsArray, boolean colourByChimera, boolean colourBySequence, String newViewId) { - super(); + this(); setViewId(newViewId); this.chimeraSessionFile = chimeraSessionFile; openNewChimera(alignPanel, pdbArray, seqsArray); @@ -362,31 +417,22 @@ public class ChimeraViewFrame extends StructureViewerBase public ChimeraViewFrame(PDBEntry[] pe, SequenceI[][] seqs, AlignmentPanel ap) { - super(); + this(); openNewChimera(ap, pe, seqs); } - public ChimeraViewFrame(Map> toView, - AlignmentPanel alignPanel) + /** + * Default constructor + */ + public ChimeraViewFrame() { super(); /* - * Convert the map of sequences per pdb entry into the tied arrays expected - * by openNewChimera - * - * TODO pass the Map down to openNewChimera and its callees instead + * closeViewer will decide whether or not to close this frame + * depending on whether user chooses to Cancel or not */ - final Set pdbEntries = toView.keySet(); - PDBEntry[] pdbs = pdbEntries.toArray(new PDBEntry[pdbEntries.size()]); - SequenceI[][] seqsForPdbs = new SequenceI[pdbEntries.size()][]; - for (int i = 0; i < pdbs.length; i++) - { - final List seqsForPdb = toView.get(pdbs[i]); - seqsForPdbs[i] = seqsForPdb.toArray(new SequenceI[seqsForPdb.size()]); - } - - openNewChimera(alignPanel, pdbs, seqsForPdbs); + setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE); } /** @@ -418,10 +464,8 @@ public class ChimeraViewFrame extends StructureViewerBase */ void initChimera() { - jmb.setFinishedInit(false); - jalview.gui.Desktop.addInternalFrame(this, - jmb.getViewerTitle("Chimera", true), getBounds().width, - getBounds().height); + Desktop.addInternalFrame(this, jmb.getViewerTitle("Chimera", true), + getBounds().width, getBounds().height); if (!jmb.launchChimera()) { @@ -443,7 +487,6 @@ public class ChimeraViewFrame extends StructureViewerBase + chimeraSessionFile); } } - jmb.setFinishedInit(true); jmb.startChimeraListener(); } @@ -454,6 +497,7 @@ public class ChimeraViewFrame extends StructureViewerBase * * @param chainNames */ + @Override void setChainMenuItems(List chainNames) { chainMenu.removeAll(); @@ -505,6 +549,7 @@ public class ChimeraViewFrame extends StructureViewerBase /** * Show only the selected chain(s) in the viewer */ + @Override void showSelectedChains() { List toshow = new ArrayList(); @@ -543,7 +588,15 @@ public class ChimeraViewFrame extends StructureViewerBase prompt = JvSwingUtils.wrapTooltip(true, prompt); int confirm = JOptionPane.showConfirmDialog(this, prompt, MessageManager.getString("label.close_viewer"), - JOptionPane.YES_NO_OPTION); + JOptionPane.YES_NO_CANCEL_OPTION); + /* + * abort closure if user hits escape or Cancel + */ + if (confirm == JOptionPane.CANCEL_OPTION + || confirm == JOptionPane.CLOSED_OPTION) + { + return; + } closeChimera = confirm == JOptionPane.YES_OPTION; } jmb.closeViewer(closeChimera); @@ -555,6 +608,7 @@ public class ChimeraViewFrame extends StructureViewerBase // TODO: check for memory leaks where instance isn't finalised because jmb // holds a reference to the window jmb = null; + dispose(); } /** @@ -571,6 +625,7 @@ public class ChimeraViewFrame extends StructureViewerBase List filePDB = new ArrayList(); List filePDBpos = new ArrayList(); PDBEntry thePdbEntry = null; + StructureFile pdb = null; try { String[] curfiles = jmb.getPdbFile(); // files currently in viewer @@ -640,6 +695,7 @@ public class ChimeraViewFrame extends StructureViewerBase if (files.length() > 0) { + jmb.setFinishedInit(false); if (!addingStructures) { try @@ -679,8 +735,9 @@ public class ChimeraViewFrame extends StructureViewerBase stopProgressBar("", startTime); } // Explicitly map to the filename used by Chimera ; - jmb.getSsm().setMapping(jmb.getSequence()[pos], + pdb = jmb.getSsm().setMapping(jmb.getSequence()[pos], jmb.getChains()[pos], pe.getFile(), protocol); + stashFoundChains(pdb, pe.getFile()); } catch (OutOfMemoryError oomerror) { new OOMWarning( @@ -696,6 +753,8 @@ public class ChimeraViewFrame extends StructureViewerBase } } } + + jmb.refreshGUI(); jmb.setFinishedInit(true); jmb.setLoadingFromArchive(false); @@ -731,6 +790,17 @@ public class ChimeraViewFrame extends StructureViewerBase * @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 ? @@ -1042,10 +1112,10 @@ public class ChimeraViewFrame extends StructureViewerBase setChainMenuItems(jmb.getChainNames()); this.setTitle(jmb.getViewerTitle("Chimera", true)); - if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1) - { + // if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1) + // { viewerActionMenu.setVisible(true); - } + // } if (!jmb.isLoadingFromArchive()) { seqColour_actionPerformed(null);