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.Console;
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 }, new SequenceI[][] { seqs });
56 public PymolViewer(PDBEntry[] pe, boolean alignAdded, SequenceI[][] seqs,
60 setAlignAddedStructures(alignAdded);
61 openNewPymol(ap, pe, seqs);
65 * Constructor given a session file to be restored
71 * @param colourByPymol
72 * @param colourBySequence
75 public PymolViewer(StructureViewerModel viewerModel,
76 AlignmentPanel alignPanel, String sessionFile, String vid)
78 // TODO convert to base/factory class method
81 this.pymolSessionFile = sessionFile;
82 Map<File, StructureData> pdbData = viewerModel.getFileData();
83 PDBEntry[] pdbArray = new PDBEntry[pdbData.size()];
84 SequenceI[][] seqsArray = new SequenceI[pdbData.size()][];
86 for (StructureData data : pdbData.values())
88 PDBEntry pdbentry = new PDBEntry(data.getPdbId(), null,
89 PDBEntry.Type.PDB, data.getFilePath());
90 pdbArray[i] = pdbentry;
91 List<SequenceI> sequencesForPdb = data.getSeqList();
92 seqsArray[i] = sequencesForPdb
93 .toArray(new SequenceI[sequencesForPdb.size()]);
97 openNewPymol(alignPanel, pdbArray, seqsArray);
98 if (viewerModel.isColourByViewer())
100 binding.setColourBySequence(false);
101 seqColour.setSelected(false);
102 viewerColour.setSelected(true);
104 else if (viewerModel.isColourWithAlignPanel())
106 binding.setColourBySequence(true);
107 seqColour.setSelected(true);
108 viewerColour.setSelected(false);
112 private void openNewPymol(AlignmentPanel ap, PDBEntry[] pe,
116 binding = new PymolBindingModel(this, ap.getStructureSelectionManager(),
118 addAlignmentPanel(ap);
119 useAlignmentPanelForColourbyseq(ap);
123 useAlignmentPanelForSuperposition(ap);
125 binding.setColourBySequence(true);
126 setSize(myWidth, myHeight);
128 viewerActionMenu.setText("PyMOL");
129 updateTitleAndMenus();
131 addingStructures = false;
132 worker = new Thread(this);
135 this.addInternalFrameListener(new InternalFrameAdapter()
138 public void internalFrameClosing(
139 InternalFrameEvent internalFrameEvent)
148 * Create a helper to manage progress bar display
150 protected void createProgressBar()
152 if (getProgressIndicator() == null)
154 setProgressIndicator(new ProgressBar(statusPanel, statusBar));
161 // todo pull up much of this
163 StringBuilder errormsgs = new StringBuilder(128);
164 List<PDBEntry> filePDB = new ArrayList<>();
165 List<Integer> filePDBpos = new ArrayList<>();
166 String[] curfiles = binding.getStructureFiles(); // files currently in
168 for (int pi = 0; pi < binding.getPdbCount(); pi++)
171 PDBEntry thePdbEntry = binding.getPdbEntry(pi);
172 if (thePdbEntry.getFile() == null)
175 * Retrieve PDB data, save to file, attach to PDBEntry
177 file = fetchPdbFile(thePdbEntry);
180 errormsgs.append("'" + thePdbEntry.getId() + "' ");
188 file = new File(thePdbEntry.getFile()).getAbsoluteFile().getPath();
189 // todo - skip if already loaded in PyMOL
193 filePDB.add(thePdbEntry);
194 filePDBpos.add(Integer.valueOf(pi));
198 if (!filePDB.isEmpty())
201 * at least one structure to add to viewer
203 binding.setFinishedInit(false);
204 if (!addingStructures)
209 } catch (Exception ex)
211 Console.error("Couldn't open PyMOL viewer!", ex);
212 // if we couldn't open Pymol, no point continuing
216 if (!binding.isViewerRunning())
219 // TODO: ensure we tidy up JAL-3619
225 for (PDBEntry pe : filePDB)
228 if (pe.getFile() != null)
232 int pos = filePDBpos.get(num).intValue();
233 long startTime = startProgressBar(getViewerName() + " "
234 + MessageManager.getString("status.opening_file_for")
236 binding.openFile(pe);
237 binding.addSequence(pos, binding.getSequence()[pos]);
238 File fl = new File(pe.getFile());
239 DataSourceType protocol = DataSourceType.URL;
244 protocol = DataSourceType.FILE;
246 } catch (Throwable e)
250 stopProgressBar("", startTime);
253 StructureFile pdb = binding.getSsm().setMapping(
254 binding.getSequence()[pos], binding.getChains()[pos],
255 pe.getFile(), protocol, getProgressIndicator());
256 binding.stashFoundChains(pdb, pe.getFile());
257 } catch (Exception ex)
259 Console.error("Couldn't open " + pe.getFile() + " in "
260 + getViewerName() + "!", ex);
263 // Cache.debug("File locations are " + files);
268 binding.refreshGUI();
269 binding.setFinishedInit(true);
270 binding.setLoadingFromArchive(false);
273 * ensure that any newly discovered features (e.g. RESNUM)
274 * are added to any open feature settings dialog
276 FeatureRenderer fr = getBinding().getFeatureRenderer(null);
282 // refresh the sequence colours for the new structure(s)
283 for (AlignmentViewPanel ap : _colourwith)
285 binding.updateColours(ap);
287 // do superposition if asked to
288 if (alignAddedStructures)
290 new Thread(new Runnable()
295 alignStructsWithAllAlignPanels();
299 addingStructures = false;
307 * Launch PyMOL. If we have a session file name, send PyMOL the command to
308 * open its saved session file.
312 Desktop.addInternalFrame(this,
313 binding.getViewerTitle(getViewerName(), true),
314 getBounds().width, getBounds().height);
316 if (!binding.launchPymol())
318 JvOptionPane.showMessageDialog(Desktop.desktop,
319 MessageManager.formatMessage("label.open_viewer_failed",
321 MessageManager.getString("label.error_loading_file"),
322 JvOptionPane.ERROR_MESSAGE);
323 binding.closeViewer(true);
328 if (this.pymolSessionFile != null)
330 boolean opened = binding.openSession(pymolSessionFile);
333 Console.error("An error occurred opening PyMOL session file "
337 // binding.startPymolListener();
341 public AAStructureBindingModel getBinding()
347 public ViewerType getViewerType()
349 return ViewerType.PYMOL;
353 protected String getViewerName()
358 JMenuItem writeFeatures = null;
361 protected void initMenus()
365 savemenu.setVisible(false); // not yet implemented
366 viewMenu.add(fitToWindow);
368 writeFeatures = new JMenuItem(
369 MessageManager.getString("label.create_viewer_attributes"));
370 writeFeatures.setToolTipText(
371 MessageManager.getString("label.create_viewer_attributes_tip"));
372 writeFeatures.addActionListener(new ActionListener()
375 public void actionPerformed(ActionEvent e)
377 sendFeaturesToPymol();
380 viewerActionMenu.add(writeFeatures);
384 protected void buildActionMenu()
386 super.buildActionMenu();
387 viewerActionMenu.add(writeFeatures);
390 protected void sendFeaturesToPymol()
392 int count = binding.sendFeaturesToViewer(getAlignmentPanel());
393 statusBar.setText(MessageManager.formatMessage("label.attributes_set",
394 count, getViewerName()));