4 import java.util.ArrayList;
7 import javax.swing.JInternalFrame;
8 import javax.swing.event.InternalFrameAdapter;
9 import javax.swing.event.InternalFrameEvent;
11 import jalview.api.AlignmentViewPanel;
12 import jalview.api.FeatureRenderer;
13 import jalview.bin.Cache;
14 import jalview.datamodel.PDBEntry;
15 import jalview.datamodel.SequenceI;
16 import jalview.gui.StructureViewer.ViewerType;
17 import jalview.io.DataSourceType;
18 import jalview.io.StructureFile;
19 import jalview.structures.models.AAStructureBindingModel;
20 import jalview.util.MessageManager;
22 public class PymolViewer extends StructureViewerBase
24 private static final int myWidth = 500;
26 private static final int myHeight = 150;
28 private PymolBindingModel binding;
30 private String pymolSessionFile;
37 * closeViewer will decide whether or not to close this frame
38 * depending on whether user chooses to Cancel or not
40 setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
43 public PymolViewer(PDBEntry pdb, SequenceI[] seqs, Object object,
47 openNewPymol(ap, new PDBEntry[] { pdb },
52 public PymolViewer(PDBEntry[] pe, boolean alignAdded, SequenceI[][] seqs,
56 setAlignAddedStructures(alignAdded);
57 openNewPymol(ap, pe, seqs);
61 * Constructor given a session file to be restored
67 * @param colourByPymol
68 * @param colourBySequence
71 public PymolViewer(String sessionFile, AlignmentPanel alignPanel,
72 PDBEntry[] pdbArray, SequenceI[][] seqsArray,
73 boolean colourByPymol, boolean colourBySequence, String newViewId)
75 // TODO convert to base/factory class method
78 this.pymolSessionFile = sessionFile;
79 openNewPymol(alignPanel, pdbArray, seqsArray);
82 binding.setColourBySequence(false);
83 seqColour.setSelected(false);
84 viewerColour.setSelected(true);
86 else if (colourBySequence)
88 binding.setColourBySequence(true);
89 seqColour.setSelected(true);
90 viewerColour.setSelected(false);
94 private void openNewPymol(AlignmentPanel ap, PDBEntry[] pe,
98 binding = new PymolBindingModel(this, ap.getStructureSelectionManager(),
100 addAlignmentPanel(ap);
101 useAlignmentPanelForColourbyseq(ap);
105 useAlignmentPanelForSuperposition(ap);
107 binding.setColourBySequence(true);
108 setSize(myWidth, myHeight);
110 viewerActionMenu.setText("PyMOL");
111 updateTitleAndMenus();
113 addingStructures = false;
114 worker = new Thread(this);
117 this.addInternalFrameListener(new InternalFrameAdapter()
120 public void internalFrameClosing(
121 InternalFrameEvent internalFrameEvent)
130 * Create a helper to manage progress bar display
132 protected void createProgressBar()
134 if (getProgressIndicator() == null)
136 setProgressIndicator(new ProgressBar(statusPanel, statusBar));
143 // todo pull up much of this
145 StringBuilder errormsgs = new StringBuilder(128);
146 List<PDBEntry> filePDB = new ArrayList<>();
147 List<Integer> filePDBpos = new ArrayList<>();
148 String[] curfiles = binding.getStructureFiles(); // files currently in viewer
149 for (int pi = 0; pi < binding.getPdbCount(); pi++)
152 PDBEntry thePdbEntry = binding.getPdbEntry(pi);
153 if (thePdbEntry.getFile() == null)
156 * Retrieve PDB data, save to file, attach to PDBEntry
158 file = fetchPdbFile(thePdbEntry);
161 errormsgs.append("'" + thePdbEntry.getId() + "' ");
169 file = new File(thePdbEntry.getFile()).getAbsoluteFile()
171 // todo - skip if already loaded in PyMOL
175 filePDB.add(thePdbEntry);
176 filePDBpos.add(Integer.valueOf(pi));
180 if (!filePDB.isEmpty())
183 * at least one structure to add to viewer
185 binding.setFinishedInit(false);
186 if (!addingStructures)
191 } catch (Exception ex)
193 Cache.log.error("Couldn't open PyMOL viewer!", ex);
197 for (PDBEntry pe : filePDB)
200 if (pe.getFile() != null)
204 int pos = filePDBpos.get(num).intValue();
205 long startTime = startProgressBar(getViewerName() + " "
206 + MessageManager.getString("status.opening_file_for")
208 binding.openFile(pe);
209 binding.addSequence(pos, binding.getSequence()[pos]);
210 File fl = new File(pe.getFile());
211 DataSourceType protocol = DataSourceType.URL;
216 protocol = DataSourceType.FILE;
218 } catch (Throwable e)
222 stopProgressBar("", startTime);
225 StructureFile pdb = binding.getSsm().setMapping(
226 binding.getSequence()[pos], binding.getChains()[pos],
227 pe.getFile(), protocol,
228 getProgressIndicator());
229 binding.stashFoundChains(pdb, pe.getFile());
230 } catch (Exception ex)
233 "Couldn't open " + pe.getFile() + " in Chimera viewer!",
237 // Cache.log.debug("File locations are " + files);
242 binding.refreshGUI();
243 binding.setFinishedInit(true);
244 binding.setLoadingFromArchive(false);
247 * ensure that any newly discovered features (e.g. RESNUM)
248 * are added to any open feature settings dialog
250 FeatureRenderer fr = getBinding().getFeatureRenderer(null);
256 // refresh the sequence colours for the new structure(s)
257 for (AlignmentViewPanel ap : _colourwith)
259 binding.updateColours(ap);
261 // do superposition if asked to
262 if (alignAddedStructures)
264 new Thread(new Runnable()
269 alignStructsWithAllAlignPanels();
273 addingStructures = false;
281 * Launch PyMOL. If we have a session file name, send PyMOL the command to
282 * open its saved session file.
286 Desktop.addInternalFrame(this,
287 binding.getViewerTitle(getViewerName(), true),
288 getBounds().width, getBounds().height);
290 if (!binding.launchPymol())
292 JvOptionPane.showMessageDialog(Desktop.desktop,
293 MessageManager.getString("label.pymol_failed"),
294 MessageManager.getString("label.error_loading_file"),
295 JvOptionPane.ERROR_MESSAGE);
300 if (this.pymolSessionFile != null)
302 boolean opened = binding.openSession(pymolSessionFile);
305 System.err.println("An error occurred opening PyMOL session file "
309 // binding.startPymolListener();
313 public AAStructureBindingModel getBinding()
319 public void closeViewer(boolean closePymol)
321 if (binding != null && binding.isPymolRunning())
325 // TODO i18n (and pull up)
326 String prompt = MessageManager
327 .formatMessage("label.confirm_close_pymol", new Object[]
328 { binding.getViewerTitle(getViewerName(), false) });
329 prompt = JvSwingUtils.wrapTooltip(true, prompt);
330 int confirm = JvOptionPane.showConfirmDialog(this, prompt,
331 MessageManager.getString("label.close_viewer"),
332 JvOptionPane.YES_NO_CANCEL_OPTION);
334 * abort closure if user hits escape or Cancel
336 if (confirm == JvOptionPane.CANCEL_OPTION
337 || confirm == JvOptionPane.CLOSED_OPTION)
341 closePymol = confirm == JvOptionPane.YES_OPTION;
343 binding.closeViewer(closePymol);
345 setAlignmentPanel(null);
349 // TODO: check for memory leaks where instance isn't finalised because
351 // holds a reference to the window
357 public ViewerType getViewerType()
359 return ViewerType.PYMOL;
363 protected String getViewerName()