3 import jalview.api.AlignmentViewPanel;
4 import jalview.api.FeatureRenderer;
5 import jalview.bin.Cache;
6 import jalview.datamodel.PDBEntry;
7 import jalview.datamodel.SequenceI;
8 import jalview.gui.StructureViewer.ViewerType;
9 import jalview.io.DataSourceType;
10 import jalview.io.StructureFile;
11 import jalview.structures.models.AAStructureBindingModel;
12 import jalview.util.MessageManager;
15 import java.util.ArrayList;
16 import java.util.List;
18 import javax.swing.JInternalFrame;
19 import javax.swing.event.InternalFrameAdapter;
20 import javax.swing.event.InternalFrameEvent;
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);
60 private void openNewPymol(AlignmentPanel ap, PDBEntry[] pe,
64 binding = new PymolBindingModel(this, ap.getStructureSelectionManager(),
66 addAlignmentPanel(ap);
67 useAlignmentPanelForColourbyseq(ap);
71 useAlignmentPanelForSuperposition(ap);
73 binding.setColourBySequence(true);
74 setSize(myWidth, myHeight);
77 addingStructures = false;
78 worker = new Thread(this);
81 this.addInternalFrameListener(new InternalFrameAdapter()
84 public void internalFrameClosing(
85 InternalFrameEvent internalFrameEvent)
94 * Create a helper to manage progress bar display
96 protected void createProgressBar()
98 if (getProgressIndicator() == null)
100 setProgressIndicator(new ProgressBar(statusPanel, statusBar));
107 // todo pull up much of this
109 StringBuilder errormsgs = new StringBuilder(128);
110 List<PDBEntry> filePDB = new ArrayList<>();
111 List<Integer> filePDBpos = new ArrayList<>();
112 String[] curfiles = binding.getStructureFiles(); // files currently in viewer
113 for (int pi = 0; pi < binding.getPdbCount(); pi++)
116 PDBEntry thePdbEntry = binding.getPdbEntry(pi);
117 if (thePdbEntry.getFile() == null)
120 * Retrieve PDB data, save to file, attach to PDBEntry
122 file = fetchPdbFile(thePdbEntry);
125 errormsgs.append("'" + thePdbEntry.getId() + "' ");
133 file = new File(thePdbEntry.getFile()).getAbsoluteFile()
135 // todo - skip if already loaded in PyMOL
139 filePDB.add(thePdbEntry);
140 filePDBpos.add(Integer.valueOf(pi));
144 if (!filePDB.isEmpty())
147 * at least one structure to add to viewer
149 binding.setFinishedInit(false);
150 if (!addingStructures)
155 } catch (Exception ex)
157 Cache.log.error("Couldn't open PyMOL viewer!", ex);
161 for (PDBEntry pe : filePDB)
164 if (pe.getFile() != null)
168 int pos = filePDBpos.get(num).intValue();
169 long startTime = startProgressBar(getViewerName() + " "
170 + MessageManager.getString("status.opening_file_for")
172 binding.openFile(pe);
173 binding.addSequence(pos, binding.getSequence()[pos]);
174 File fl = new File(pe.getFile());
175 DataSourceType protocol = DataSourceType.URL;
180 protocol = DataSourceType.FILE;
182 } catch (Throwable e)
186 stopProgressBar("", startTime);
189 StructureFile pdb = binding.getSsm().setMapping(
190 binding.getSequence()[pos], binding.getChains()[pos],
191 pe.getFile(), protocol,
192 getProgressIndicator());
193 binding.stashFoundChains(pdb, pe.getFile());
194 } catch (Exception ex)
197 "Couldn't open " + pe.getFile() + " in Chimera viewer!",
201 // Cache.log.debug("File locations are " + files);
206 binding.refreshGUI();
207 binding.setFinishedInit(true);
208 binding.setLoadingFromArchive(false);
211 * ensure that any newly discovered features (e.g. RESNUM)
212 * are added to any open feature settings dialog
214 FeatureRenderer fr = getBinding().getFeatureRenderer(null);
220 // refresh the sequence colours for the new structure(s)
221 for (AlignmentViewPanel ap : _colourwith)
223 binding.updateColours(ap);
225 // do superposition if asked to
226 if (alignAddedStructures)
228 new Thread(new Runnable()
233 alignStructsWithAllAlignPanels();
237 addingStructures = false;
245 * Launch PyMOL. If we have a session file name, send PyMOL the command to
246 * open its saved session file.
250 Desktop.addInternalFrame(this,
251 binding.getViewerTitle(getViewerName(), true),
252 getBounds().width, getBounds().height);
254 if (!binding.launchPymol())
256 JvOptionPane.showMessageDialog(Desktop.desktop,
257 MessageManager.getString("label.pymol_failed"),
258 MessageManager.getString("label.error_loading_file"),
259 JvOptionPane.ERROR_MESSAGE);
264 if (this.pymolSessionFile != null)
266 boolean opened = binding.openSession(pymolSessionFile);
269 System.err.println("An error occurred opening PyMOL session file "
273 // binding.startPymolListener();
277 public AAStructureBindingModel getBinding()
283 public void closeViewer(boolean closePymol)
285 if (binding != null && binding.isPymolRunning())
289 // TODO i18n (and pull up)
290 String prompt = MessageManager
291 .formatMessage("label.confirm_close_pymol", new Object[]
292 { binding.getViewerTitle(getViewerName(), false) });
293 prompt = JvSwingUtils.wrapTooltip(true, prompt);
294 int confirm = JvOptionPane.showConfirmDialog(this, prompt,
295 MessageManager.getString("label.close_viewer"),
296 JvOptionPane.YES_NO_CANCEL_OPTION);
298 * abort closure if user hits escape or Cancel
300 if (confirm == JvOptionPane.CANCEL_OPTION
301 || confirm == JvOptionPane.CLOSED_OPTION)
305 closePymol = confirm == JvOptionPane.YES_OPTION;
307 binding.closeViewer(closePymol);
309 setAlignmentPanel(null);
313 // TODO: check for memory leaks where instance isn't finalised because
315 // holds a reference to the window
321 public String getStateInfo()
327 public ViewerType getViewerType()
329 return ViewerType.PYMOL;
333 protected String getViewerName()