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.formatMessage("label.open_viewer_failed",
295 MessageManager.getString("label.error_loading_file"),
296 JvOptionPane.ERROR_MESSAGE);
301 if (this.pymolSessionFile != null)
303 boolean opened = binding.openSession(pymolSessionFile);
306 System.err.println("An error occurred opening PyMOL session file "
310 // binding.startPymolListener();
314 public AAStructureBindingModel getBinding()
320 public ViewerType getViewerType()
322 return ViewerType.PYMOL;
326 protected String getViewerName()