X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FChimeraViewFrame.java;fp=src%2Fjalview%2Fgui%2FChimeraViewFrame.java;h=ba360af3117fc953555dc98f06d739adc08e63ad;hb=f063821ed0be9c1581af74643a1aa5798731af65;hp=b82eef3bd7eae14845ae38a589ed338967afc972;hpb=fd18e2c73cd015d4e38ad91da0e5d7532ff0ef42;p=jalview.git diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java index b82eef3..ba360af 100644 --- a/src/jalview/gui/ChimeraViewFrame.java +++ b/src/jalview/gui/ChimeraViewFrame.java @@ -20,57 +20,41 @@ */ package jalview.gui; +import jalview.api.FeatureRenderer; 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.ChimeraCommands; import jalview.ext.rbvi.chimera.JalviewChimeraBinding; import jalview.gui.StructureViewer.ViewerType; import jalview.io.DataSourceType; -import jalview.io.JalviewFileChooser; -import jalview.io.JalviewFileView; import jalview.io.StructureFile; -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.BrowserLauncher; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.ws.dbsources.Pdb; import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.io.BufferedReader; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; 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.Random; -import java.util.Vector; import javax.swing.JCheckBoxMenuItem; -import javax.swing.JColorChooser; import javax.swing.JInternalFrame; import javax.swing.JMenu; -import javax.swing.JOptionPane; +import javax.swing.JMenuItem; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; -import javax.swing.event.MenuEvent; -import javax.swing.event.MenuListener; /** * GUI elements for handling an external chimera display @@ -82,8 +66,6 @@ public class ChimeraViewFrame extends StructureViewerBase { private JalviewChimeraBinding jmb; - private boolean allChainsSelected = false; - private IProgressIndicator progressBar = null; /* @@ -95,91 +77,128 @@ public class ChimeraViewFrame extends StructureViewerBase private Random random = new Random(); + private int myWidth = 500; + + private int myHeight = 150; + /** * Initialise menu options. */ - private void initMenus() + @Override + protected void initMenus() { + super.initMenus(); + 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")); + helpItem.setText(MessageManager.getString("label.chimera_help")); - seqColour.setSelected(jmb.isColourBySequence()); - viewerColour.setSelected(!jmb.isColourBySequence()); - if (_colourwith == null) + 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()) { - _colourwith = new Vector(); + 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( + 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); } - if (_alignwith == null) + } + + /** + * 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) { - _alignwith = new Vector(); + return; } - - // save As not yet implemented - savemenu.setVisible(false); - - ViewSelectionMenu seqColourBy = new ViewSelectionMenu( - MessageManager.getString("label.colour_by"), this, _colourwith, - new ItemListener() - { - @Override - public void itemStateChanged(ItemEvent e) - { - if (!seqColour.isSelected()) - { - seqColour.doClick(); - } - else - { - // update the Chimera display now. - seqColour_actionPerformed(null); - } - } - }); - viewMenu.add(seqColourBy); - viewMenu.add(fitToWindow); - - final ItemListener handler; - JMenu alpanels = new ViewSelectionMenu( - MessageManager.getString("label.superpose_with"), this, - _alignwith, handler = new ItemListener() - { - @Override - public void itemStateChanged(ItemEvent e) - { - alignStructs.setEnabled(_alignwith.size() > 0); - alignStructs.setToolTipText(MessageManager - .formatMessage( - "label.align_structures_using_linked_alignment_views", - new Object[] { new Integer(_alignwith - .size()).toString() })); - } - }); - handler.itemStateChanged(null); - viewerActionMenu.add(alpanels); - viewerActionMenu.addMenuListener(new MenuListener() + attributesMenu.removeAll(); + Collections.sort(atts); + for (String att : atts) { + final String attName = att.split(" ")[1]; - @Override - public void menuSelected(MenuEvent e) + /* + * ignore 'jv_*' attributes, as these are Jalview features that have + * been transferred to residue attributes in Chimera! + */ + if (!attName.startsWith(ChimeraCommands.NAMESPACE_PREFIX)) { - handler.itemStateChanged(null); + JMenuItem menuItem = new JMenuItem(attName); + menuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + getChimeraAttributes(attName); + } + }); + attributesMenu.add(menuItem); } + } + } - @Override - public void menuDeselected(MenuEvent e) - { - // TODO Auto-generated method stub - } + /** + * 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()); + } - @Override - public void menuCanceled(MenuEvent e) - { - // TODO Auto-generated method stub - } - }); + /** + * 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() + { + int count = jmb.sendFeaturesToViewer(getAlignmentPanel()); + statusBar.setText( + MessageManager.formatMessage("label.attributes_set", count)); } /** @@ -219,7 +238,8 @@ public class ChimeraViewFrame extends StructureViewerBase * a new viewer */ openNewChimera(ap, new PDBEntry[] { pdbentry }, - new SequenceI[][] { seq }); + new SequenceI[][] + { seq }); } /** @@ -233,31 +253,22 @@ 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); - } - private void openNewChimera(AlignmentPanel ap, PDBEntry[] pdbentrys, SequenceI[][] seqs) { createProgressBar(); - // FIXME extractChains needs pdbentries to match IDs to PDBEntry(s) on seqs jmb = new JalviewChimeraBindingModel(this, ap.getStructureSelectionManager(), pdbentrys, seqs, null); addAlignmentPanel(ap); useAlignmentPanelForColourbyseq(ap); + if (pdbentrys.length > 1) { alignAddedStructures = true; useAlignmentPanelForSuperposition(ap); } jmb.setColourBySequence(true); - setSize(400, 400); // probably should be a configurable/dynamic default here + setSize(myWidth, myHeight); initMenus(); addingStructures = false; @@ -267,7 +278,8 @@ public class ChimeraViewFrame extends StructureViewerBase this.addInternalFrameListener(new InternalFrameAdapter() { @Override - public void internalFrameClosing(InternalFrameEvent internalFrameEvent) + public void internalFrameClosing( + InternalFrameEvent internalFrameEvent) { closeViewer(false); } @@ -275,8 +287,6 @@ public class ChimeraViewFrame extends StructureViewerBase } - - /** * Create a new viewer from saved session state data including Chimera session * file @@ -371,8 +381,8 @@ public class ChimeraViewFrame extends StructureViewerBase void initChimera() { jmb.setFinishedInit(false); - jalview.gui.Desktop.addInternalFrame(this, - jmb.getViewerTitle("Chimera", true), getBounds().width, + Desktop.addInternalFrame(this, + jmb.getViewerTitle(getViewerName(), true), getBounds().width, getBounds().height); if (!jmb.launchChimera()) @@ -390,17 +400,14 @@ 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); } } - jmb.setFinishedInit(true); jmb.startChimeraListener(); } - /** * Show only the selected chain(s) in the viewer */ @@ -437,9 +444,9 @@ public class ChimeraViewFrame extends StructureViewerBase { if (!closeChimera) { - String prompt = MessageManager.formatMessage( - "label.confirm_close_chimera", - new Object[] { jmb.getViewerTitle("Chimera", 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"), @@ -483,7 +490,7 @@ public class ChimeraViewFrame extends StructureViewerBase 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++) @@ -535,21 +542,23 @@ 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); } if (files.length() > 0) { + jmb.setFinishedInit(false); if (!addingStructures) { try @@ -569,7 +578,7 @@ public class ChimeraViewFrame extends StructureViewerBase try { int pos = filePDBpos.get(num).intValue(); - long startTime = startProgressBar("Chimera " + long startTime = startProgressBar(getViewerName() + " " + MessageManager.getString("status.opening_file_for") + " " + pe.getId()); jmb.openFile(pe); @@ -599,18 +608,30 @@ 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); } } } + jmb.refreshGUI(); jmb.setFinishedInit(true); jmb.setLoadingFromArchive(false); + /* + * ensure that any newly discovered features (e.g. RESNUM) + * are added to any open feature settings dialog + */ + FeatureRenderer fr = getBinding().getFeatureRenderer(null); + if (fr != null) + { + fr.featuresAdded(); + } + // refresh the sequence colours for the new structure(s) for (AlignmentPanel ap : _colourwith) { @@ -648,12 +669,13 @@ public class ChimeraViewFrame extends StructureViewerBase { for (int i = 0; i < pdb.getChains().size(); i++) { - String chid = new String(pdb.getId() + ":" - + pdb.getChains().elementAt(i).id); + 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 ? @@ -668,7 +690,8 @@ 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[] @@ -734,213 +757,17 @@ public class ChimeraViewFrame extends StructureViewerBase } @Override - public void pdbFile_actionPerformed(ActionEvent actionEvent) - { - JalviewFileChooser chooser = new JalviewFileChooser( - jalview.bin.Cache.getProperty("LAST_DIRECTORY")); - - chooser.setFileView(new JalviewFileView()); - chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file")); - chooser.setToolTipText(MessageManager.getString("action.save")); - - int value = chooser.showSaveDialog(this); - - if (value == JalviewFileChooser.APPROVE_OPTION) - { - BufferedReader in = null; - try - { - // TODO: cope with multiple PDB files in view - in = new BufferedReader(new FileReader(jmb.getPdbFile()[0])); - File outFile = chooser.getSelectedFile(); - - PrintWriter out = new PrintWriter(new FileOutputStream(outFile)); - String data; - while ((data = in.readLine()) != null) - { - if (!(data.indexOf("

") > -1 || data.indexOf("
") > -1)) - { - out.println(data); - } - } - out.close(); - } catch (Exception ex) - { - ex.printStackTrace(); - } finally - { - if (in != null) - { - try - { - in.close(); - } catch (IOException e) - { - e.printStackTrace(); - } - } - } - } - } - - @Override - public void viewMapping_actionPerformed(ActionEvent actionEvent) - { - jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer(); - try - { - cap.appendText(jmb.printMappings()); - } catch (OutOfMemoryError e) - { - new OOMWarning( - "composing sequence-structure alignments for display in text box.", - e); - cap.dispose(); - return; - } - jalview.gui.Desktop.addInternalFrame(cap, - MessageManager.getString("label.pdb_sequence_mapping"), 550, - 600); - } - - @Override public void eps_actionPerformed(ActionEvent e) { - 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) { - throw new Error( - MessageManager - .getString("error.png_generation_not_implemented")); - } - - @Override - public void viewerColour_actionPerformed(ActionEvent actionEvent) - { - if (viewerColour.isSelected()) - { - // disable automatic sequence colouring. - jmb.setColourBySequence(false); - } - } - - @Override - public void seqColour_actionPerformed(ActionEvent actionEvent) - { - jmb.setColourBySequence(seqColour.isSelected()); - if (_colourwith == null) - { - _colourwith = new Vector(); - } - if (jmb.isColourBySequence()) - { - if (!jmb.isLoadingFromArchive()) - { - if (_colourwith.size() == 0 && getAlignmentPanel() != null) - { - // Make the currently displayed alignment panel the associated view - _colourwith.add(getAlignmentPanel().alignFrame.alignPanel); - } - } - // Set the colour using the current view for the associated alignframe - for (AlignmentPanel ap : _colourwith) - { - jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap); - } - } - } - - @Override - public void chainColour_actionPerformed(ActionEvent actionEvent) - { - chainColour.setSelected(true); - jmb.colourByChain(); - } - - @Override - public void chargeColour_actionPerformed(ActionEvent actionEvent) - { - chargeColour.setSelected(true); - jmb.colourByCharge(); - } - - @Override - public void zappoColour_actionPerformed(ActionEvent actionEvent) - { - zappoColour.setSelected(true); - jmb.setJalviewColourScheme(new ZappoColourScheme()); - } - - @Override - public void taylorColour_actionPerformed(ActionEvent actionEvent) - { - taylorColour.setSelected(true); - jmb.setJalviewColourScheme(new TaylorColourScheme()); - } - - @Override - public void hydroColour_actionPerformed(ActionEvent actionEvent) - { - hydroColour.setSelected(true); - jmb.setJalviewColourScheme(new HydrophobicColourScheme()); - } - - @Override - public void helixColour_actionPerformed(ActionEvent actionEvent) - { - helixColour.setSelected(true); - jmb.setJalviewColourScheme(new HelixColourScheme()); - } - - @Override - public void strandColour_actionPerformed(ActionEvent actionEvent) - { - strandColour.setSelected(true); - jmb.setJalviewColourScheme(new StrandColourScheme()); - } - - @Override - public void turnColour_actionPerformed(ActionEvent actionEvent) - { - turnColour.setSelected(true); - jmb.setJalviewColourScheme(new TurnColourScheme()); - } - - @Override - public void buriedColour_actionPerformed(ActionEvent actionEvent) - { - buriedColour.setSelected(true); - jmb.setJalviewColourScheme(new BuriedColourScheme()); - } - - @Override - public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent) - { - setJalviewColourScheme(new PurinePyrimidineColourScheme()); - } - - @Override - public void userColour_actionPerformed(ActionEvent actionEvent) - { - userColour.setSelected(true); - new UserDefinedColours(this, null); - } - - @Override - public void backGround_actionPerformed(ActionEvent actionEvent) - { - java.awt.Color col = JColorChooser - .showDialog(this, MessageManager - .getString("label.select_backgroud_colour"), null); - if (col != null) - { - jmb.setBackgroundColour(col); - } + throw new Error(MessageManager + .getString("error.png_generation_not_implemented")); } @Override @@ -948,107 +775,11 @@ public class ChimeraViewFrame extends StructureViewerBase { try { - jalview.util.BrowserLauncher + BrowserLauncher .openURL("https://www.cgl.ucsf.edu/chimera/docs/UsersGuide"); - } catch (Exception ex) - { - } - } - - public void updateTitleAndMenus() - { - if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0) - { - repaint(); - return; - } - setChainMenuItems(jmb.getChainNames()); - - this.setTitle(jmb.getViewerTitle("Chimera", true)); - if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1) - { - viewerActionMenu.setVisible(true); - } - if (!jmb.isLoadingFromArchive()) - { - seqColour_actionPerformed(null); - } - } - - /* - * (non-Javadoc) - * - * @see - * jalview.jbgui.GStructureViewer#alignStructs_actionPerformed(java.awt.event - * .ActionEvent) - */ - @Override - protected void alignStructs_actionPerformed(ActionEvent actionEvent) - { - alignStructs_withAllAlignPanels(); - } - - private void alignStructs_withAllAlignPanels() - { - if (getAlignmentPanel() == null) - { - return; - } - - if (_alignwith.size() == 0) - { - _alignwith.add(getAlignmentPanel()); - } - - try - { - AlignmentI[] als = new Alignment[_alignwith.size()]; - ColumnSelection[] alc = new ColumnSelection[_alignwith.size()]; - int[] alm = new int[_alignwith.size()]; - int a = 0; - - for (AlignmentPanel ap : _alignwith) - { - als[a] = ap.av.getAlignment(); - alm[a] = -1; - alc[a++] = ap.av.getColumnSelection(); - } - jmb.superposeStructures(als, alm, alc); - } catch (Exception e) - { - StringBuffer sp = new StringBuffer(); - for (AlignmentPanel ap : _alignwith) - { - sp.append("'" + ap.alignFrame.getTitle() + "' "); - } - Cache.log.info("Couldn't align structures with the " + sp.toString() - + "associated alignment panels.", e); - } - } - - @Override - public void setJalviewColourScheme(ColourSchemeI ucs) - { - jmb.setJalviewColourScheme(ucs); - - } - - /** - * - * @param alignment - * @return first alignment panel displaying given alignment, or the default - * alignment panel - */ - public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment) - { - for (AlignmentPanel ap : getAllAlignmentPanels()) + } catch (IOException ex) { - if (ap.av.getAlignment() == alignment) - { - return ap; - } } - return getAlignmentPanel(); } @Override @@ -1140,8 +871,24 @@ public class ChimeraViewFrame extends StructureViewerBase } @Override - protected AAStructureBindingModel getBindingModel() + protected String getViewerName() { - return jmb; + 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; } }