3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
6 import java.util.ArrayList;
10 import javax.swing.JInternalFrame;
11 import javax.swing.JMenuItem;
12 import javax.swing.event.InternalFrameAdapter;
13 import javax.swing.event.InternalFrameEvent;
15 import jalview.api.AlignmentViewPanel;
16 import jalview.api.FeatureRenderer;
17 import jalview.bin.Cache;
18 import jalview.datamodel.PDBEntry;
19 import jalview.datamodel.SequenceI;
20 import jalview.datamodel.StructureViewerModel;
21 import jalview.datamodel.StructureViewerModel.StructureData;
22 import jalview.gui.StructureViewer.ViewerType;
23 import jalview.io.DataSourceType;
24 import jalview.io.StructureFile;
25 import jalview.structures.models.AAStructureBindingModel;
26 import jalview.util.MessageManager;
28 public class PymolViewer extends StructureViewerBase
30 private static final int myWidth = 500;
32 private static final int myHeight = 150;
34 private PymolBindingModel binding;
36 private String pymolSessionFile;
43 * closeViewer will decide whether or not to close this frame
44 * depending on whether user chooses to Cancel or not
46 setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
49 public PymolViewer(PDBEntry pdb, SequenceI[] seqs, Object object,
53 openNewPymol(ap, new PDBEntry[] { pdb },
58 public PymolViewer(PDBEntry[] pe, boolean alignAdded, SequenceI[][] seqs,
62 setAlignAddedStructures(alignAdded);
63 openNewPymol(ap, pe, seqs);
67 * Constructor given a session file to be restored
73 * @param colourByPymol
74 * @param colourBySequence
77 public PymolViewer(StructureViewerModel viewerModel,
78 AlignmentPanel alignPanel, String sessionFile, String vid)
80 // TODO convert to base/factory class method
83 this.pymolSessionFile = sessionFile;
84 Map<File, StructureData> pdbData = viewerModel.getFileData();
85 PDBEntry[] pdbArray = new PDBEntry[pdbData.size()];
86 SequenceI[][] seqsArray = new SequenceI[pdbData.size()][];
88 for (StructureData data : pdbData.values())
90 PDBEntry pdbentry = new PDBEntry(data.getPdbId(), null,
91 PDBEntry.Type.PDB, data.getFilePath());
92 pdbArray[i] = pdbentry;
93 List<SequenceI> sequencesForPdb = data.getSeqList();
94 seqsArray[i] = sequencesForPdb
95 .toArray(new SequenceI[sequencesForPdb.size()]);
99 openNewPymol(alignPanel, pdbArray, seqsArray);
100 if (viewerModel.isColourByViewer())
102 binding.setColourBySequence(false);
103 seqColour.setSelected(false);
104 viewerColour.setSelected(true);
106 else if (viewerModel.isColourWithAlignPanel())
108 binding.setColourBySequence(true);
109 seqColour.setSelected(true);
110 viewerColour.setSelected(false);
114 private void openNewPymol(AlignmentPanel ap, PDBEntry[] pe,
118 binding = new PymolBindingModel(this, ap.getStructureSelectionManager(),
120 addAlignmentPanel(ap);
121 useAlignmentPanelForColourbyseq(ap);
125 useAlignmentPanelForSuperposition(ap);
127 binding.setColourBySequence(true);
128 setSize(myWidth, myHeight);
130 viewerActionMenu.setText("PyMOL");
131 updateTitleAndMenus();
133 addingStructures = false;
134 worker = new Thread(this);
137 this.addInternalFrameListener(new InternalFrameAdapter()
140 public void internalFrameClosing(
141 InternalFrameEvent internalFrameEvent)
150 * Create a helper to manage progress bar display
152 protected void createProgressBar()
154 if (getProgressIndicator() == null)
156 setProgressIndicator(new ProgressBar(statusPanel, statusBar));
163 // todo pull up much of this
165 StringBuilder errormsgs = new StringBuilder(128);
166 List<PDBEntry> filePDB = new ArrayList<>();
167 List<Integer> filePDBpos = new ArrayList<>();
168 String[] curfiles = binding.getStructureFiles(); // files currently in viewer
169 for (int pi = 0; pi < binding.getPdbCount(); pi++)
172 PDBEntry thePdbEntry = binding.getPdbEntry(pi);
173 if (thePdbEntry.getFile() == null)
176 * Retrieve PDB data, save to file, attach to PDBEntry
178 file = fetchPdbFile(thePdbEntry);
181 errormsgs.append("'" + thePdbEntry.getId() + "' ");
189 file = new File(thePdbEntry.getFile()).getAbsoluteFile()
191 // todo - skip if already loaded in PyMOL
195 filePDB.add(thePdbEntry);
196 filePDBpos.add(Integer.valueOf(pi));
200 if (!filePDB.isEmpty())
203 * at least one structure to add to viewer
205 binding.setFinishedInit(false);
206 if (!addingStructures)
211 } catch (Exception ex)
213 Cache.log.error("Couldn't open PyMOL viewer!", ex);
217 for (PDBEntry pe : filePDB)
220 if (pe.getFile() != null)
224 int pos = filePDBpos.get(num).intValue();
225 long startTime = startProgressBar(getViewerName() + " "
226 + MessageManager.getString("status.opening_file_for")
228 binding.openFile(pe);
229 binding.addSequence(pos, binding.getSequence()[pos]);
230 File fl = new File(pe.getFile());
231 DataSourceType protocol = DataSourceType.URL;
236 protocol = DataSourceType.FILE;
238 } catch (Throwable e)
242 stopProgressBar("", startTime);
245 StructureFile pdb = binding.getSsm().setMapping(
246 binding.getSequence()[pos], binding.getChains()[pos],
247 pe.getFile(), protocol,
248 getProgressIndicator());
249 binding.stashFoundChains(pdb, pe.getFile());
250 } catch (Exception ex)
253 "Couldn't open " + pe.getFile() + " in Chimera viewer!",
257 // Cache.log.debug("File locations are " + files);
262 binding.refreshGUI();
263 binding.setFinishedInit(true);
264 binding.setLoadingFromArchive(false);
267 * ensure that any newly discovered features (e.g. RESNUM)
268 * are added to any open feature settings dialog
270 FeatureRenderer fr = getBinding().getFeatureRenderer(null);
276 // refresh the sequence colours for the new structure(s)
277 for (AlignmentViewPanel ap : _colourwith)
279 binding.updateColours(ap);
281 // do superposition if asked to
282 if (alignAddedStructures)
284 new Thread(new Runnable()
289 alignStructsWithAllAlignPanels();
293 addingStructures = false;
301 * Launch PyMOL. If we have a session file name, send PyMOL the command to
302 * open its saved session file.
306 Desktop.addInternalFrame(this,
307 binding.getViewerTitle(getViewerName(), true),
308 getBounds().width, getBounds().height);
310 if (!binding.launchPymol())
312 JvOptionPane.showMessageDialog(Desktop.desktop,
313 MessageManager.formatMessage("label.open_viewer_failed",
315 MessageManager.getString("label.error_loading_file"),
316 JvOptionPane.ERROR_MESSAGE);
321 if (this.pymolSessionFile != null)
323 boolean opened = binding.openSession(pymolSessionFile);
327 "An error occurred opening PyMOL session file "
331 // binding.startPymolListener();
335 public AAStructureBindingModel getBinding()
341 public ViewerType getViewerType()
343 return ViewerType.PYMOL;
347 protected String getViewerName()
353 protected void initMenus()
357 savemenu.setVisible(false); // not yet implemented
358 viewMenu.add(fitToWindow);
360 JMenuItem writeFeatures = new JMenuItem(
361 MessageManager.getString("label.create_viewer_attributes"));
362 writeFeatures.setToolTipText(MessageManager
363 .getString("label.create_viewer_attributes_tip"));
364 writeFeatures.addActionListener(new ActionListener()
367 public void actionPerformed(ActionEvent e)
369 sendFeaturesToPymol();
372 viewerActionMenu.add(writeFeatures);
375 protected void sendFeaturesToPymol()
377 int count = binding.sendFeaturesToViewer(getAlignmentPanel());
379 MessageManager.formatMessage("label.attributes_set", count));