loadingFromArchive flag added
[jalview.git] / src / jalview / gui / AppJMol.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import java.util.regex.*;\r
22 import java.util.*;\r
23 import java.awt.*;\r
24 import javax.swing.*;\r
25 import javax.swing.event.*;\r
26 import java.awt.event.*;\r
27 import java.io.*;\r
28 \r
29 import jalview.jbgui.GStructureViewer;\r
30 import jalview.datamodel.*;\r
31 import jalview.gui.*;\r
32 import jalview.structure.*;\r
33 import jalview.datamodel.PDBEntry;\r
34 import jalview.io.*;\r
35 import jalview.schemes.*;\r
36 \r
37 import org.jmol.api.*;\r
38 import org.jmol.adapter.smarter.SmarterJmolAdapter;\r
39 import org.jmol.popup.*;\r
40 \r
41 \r
42 public class AppJMol\r
43     extends GStructureViewer\r
44     implements StructureListener, JmolStatusListener, Runnable\r
45 \r
46 {\r
47   JmolViewer viewer;\r
48   JmolPopup jmolpopup;\r
49   ScriptWindow scriptWindow;\r
50   PDBEntry pdbentry;\r
51   SequenceI[] sequence;\r
52   StructureSelectionManager ssm;\r
53   JSplitPane splitPane;\r
54   RenderPanel renderPanel;\r
55   AlignmentPanel ap;\r
56   String fileLoadingError;\r
57   boolean colourBySequence = true;\r
58   boolean loadingFromArchive = false;\r
59 \r
60   public AppJMol(String file, String id,\r
61                  SequenceI[] seq,\r
62                  AlignmentPanel ap,\r
63                  String loadStatus,\r
64                  Rectangle bounds)\r
65   {\r
66     loadingFromArchive = true;\r
67     pdbentry = new PDBEntry();\r
68     pdbentry.setFile(file);\r
69     pdbentry.setId(id);\r
70     this.sequence = seq;\r
71     this.ap = ap;\r
72     this.setBounds(bounds);\r
73 \r
74     colourBySequence = false;\r
75     seqColour.setSelected(false);\r
76 \r
77     jalview.gui.Desktop.addInternalFrame(this, "Loading File",\r
78                                          bounds.width,bounds.height);\r
79 \r
80     initJmol(loadStatus);\r
81 \r
82     this.addInternalFrameListener(new InternalFrameAdapter()\r
83     {\r
84       public void internalFrameClosing(InternalFrameEvent internalFrameEvent)\r
85       {\r
86         closeViewer();\r
87       }\r
88     });\r
89   }\r
90 \r
91   public AppJMol(PDBEntry pdbentry, SequenceI[] seq, AlignmentPanel ap)\r
92   {\r
93     //////////////////////////////////\r
94     //Is the pdb file already loaded?\r
95     String alreadyMapped = StructureSelectionManager\r
96         .getStructureSelectionManager()\r
97         .alreadyMappedToFile(pdbentry.getId());\r
98 \r
99     if (alreadyMapped != null)\r
100     {\r
101       int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
102           pdbentry.getId() + " is already displayed."\r
103           + "\nDo you want to map sequences to the visible structure?",\r
104           "Map Sequences to Visible Window: " + pdbentry.getId(),\r
105           JOptionPane.YES_NO_OPTION);\r
106 \r
107       if (option == JOptionPane.YES_OPTION)\r
108       {\r
109         StructureSelectionManager.getStructureSelectionManager()\r
110             .setMapping(seq, alreadyMapped, AppletFormatAdapter.FILE);\r
111         return;\r
112       }\r
113     }\r
114     ///////////////////////////////////\r
115 \r
116     this.ap = ap;\r
117     this.pdbentry = pdbentry;\r
118     this.sequence = seq;\r
119 \r
120     jalview.gui.Desktop.addInternalFrame(this, "Loading File", 400, 400);\r
121 \r
122     if (pdbentry.getFile() != null)\r
123     {\r
124       initJmol("load \""+pdbentry.getFile()+"\"");\r
125     }\r
126     else\r
127     {\r
128       Thread worker = new Thread(this);\r
129       worker.start();\r
130     }\r
131 \r
132     this.addInternalFrameListener(new InternalFrameAdapter()\r
133     {\r
134       public void internalFrameClosing(InternalFrameEvent internalFrameEvent)\r
135       {\r
136         closeViewer();\r
137       }\r
138     });\r
139   }\r
140 \r
141   void initJmol(String command)\r
142   {\r
143     renderPanel = new RenderPanel();\r
144 \r
145     this.getContentPane().add(renderPanel, java.awt.BorderLayout.CENTER);\r
146 \r
147     StringBuffer title = new StringBuffer(sequence[0].getName() + ":" +\r
148                                           pdbentry.getId());\r
149 \r
150     if (pdbentry.getProperty() != null)\r
151     {\r
152       if (pdbentry.getProperty().get("method") != null)\r
153       {\r
154         title.append(" Method: ");\r
155         title.append(pdbentry.getProperty().get("method"));\r
156       }\r
157       if (pdbentry.getProperty().get("chains") != null)\r
158       {\r
159         title.append(" Chain:");\r
160         title.append(pdbentry.getProperty().get("chains"));\r
161       }\r
162     }\r
163 \r
164     this.setTitle(title.toString());\r
165 \r
166     viewer = org.jmol.api.JmolViewer.allocateViewer(renderPanel,\r
167         new SmarterJmolAdapter());\r
168 \r
169 \r
170     viewer.setAppletContext("", null, null, "");\r
171 \r
172     viewer.setJmolStatusListener(this);\r
173 \r
174     jmolpopup = JmolPopup.newJmolPopup(viewer);\r
175 \r
176     viewer.evalStringQuiet(command);\r
177   }\r
178 \r
179 \r
180   void setChainMenuItems(Vector chains)\r
181   {\r
182     chainMenu.removeAll();\r
183 \r
184     JMenuItem menuItem = new JMenuItem("All");\r
185     menuItem.addActionListener(new ActionListener()\r
186         {\r
187           public void actionPerformed(ActionEvent evt)\r
188           {\r
189             allChainsSelected = true;\r
190             for(int i=0; i<chainMenu.getItemCount(); i++)\r
191             {\r
192               if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)\r
193                 ( (JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);\r
194             }\r
195             centerViewer();\r
196             allChainsSelected = false;\r
197           }\r
198         });\r
199 \r
200     chainMenu.add(menuItem);\r
201 \r
202     for (int c = 0; c < chains.size(); c++)\r
203     {\r
204       menuItem = new JCheckBoxMenuItem(chains.elementAt(c).toString(), true);\r
205       menuItem.addItemListener(new ItemListener()\r
206       {\r
207         public void itemStateChanged(ItemEvent evt)\r
208         {\r
209           if (!allChainsSelected)\r
210             centerViewer();\r
211         }\r
212       });\r
213 \r
214       chainMenu.add(menuItem);\r
215     }\r
216   }\r
217 \r
218   boolean allChainsSelected = false;\r
219   void centerViewer()\r
220   {\r
221     StringBuffer cmd = new StringBuffer();\r
222     for(int i=0; i<chainMenu.getItemCount(); i++)\r
223     {\r
224       if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)\r
225       {\r
226        JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i);\r
227        if(item.isSelected())\r
228          cmd.append(":"+item.getText()+" or ");\r
229       }\r
230     }\r
231 \r
232     if (cmd.length() > 0)\r
233       cmd.setLength(cmd.length() - 4);\r
234 \r
235     viewer.evalStringQuiet("select *;restrict "\r
236                       +cmd+";cartoon;center "+cmd);\r
237   }\r
238 \r
239   void closeViewer()\r
240   {\r
241     viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);\r
242     viewer.evalStringQuiet("zap");\r
243     viewer.setJmolStatusListener(null);\r
244     viewer = null;\r
245 \r
246     //We'll need to find out what other\r
247     // listeners need to be shut down in Jmol\r
248     StructureSelectionManager\r
249         .getStructureSelectionManager()\r
250         .removeStructureViewerListener(this, pdbentry.getFile());\r
251   }\r
252 \r
253   public void run()\r
254   {\r
255     try\r
256     {\r
257       EBIFetchClient ebi = new EBIFetchClient();\r
258       String query = "pdb:" + pdbentry.getId();\r
259       pdbentry.setFile(ebi.fetchDataAsFile(query, "default", "raw")\r
260                        .getAbsolutePath());\r
261       initJmol("load "+pdbentry.getFile());\r
262     }\r
263     catch (Exception ex)\r
264     {\r
265       ex.printStackTrace();\r
266     }\r
267   }\r
268 \r
269   public void pdbFile_actionPerformed(ActionEvent actionEvent)\r
270   {\r
271     JalviewFileChooser chooser = new JalviewFileChooser(\r
272         jalview.bin.Cache.getProperty(\r
273             "LAST_DIRECTORY"));\r
274 \r
275     chooser.setFileView(new JalviewFileView());\r
276     chooser.setDialogTitle("Save PDB File");\r
277     chooser.setToolTipText("Save");\r
278 \r
279     int value = chooser.showSaveDialog(this);\r
280 \r
281     if (value == JalviewFileChooser.APPROVE_OPTION)\r
282     {\r
283       try\r
284       {\r
285         BufferedReader in = new BufferedReader(new FileReader(pdbentry.getFile()));\r
286         File outFile = chooser.getSelectedFile();\r
287 \r
288         PrintWriter out = new PrintWriter(new FileOutputStream(outFile));\r
289         String data;\r
290         while ( (data = in.readLine()) != null)\r
291         {\r
292           if (\r
293               ! (data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1)\r
294               )\r
295           {\r
296             out.println(data);\r
297           }\r
298         }\r
299         out.close();\r
300       }\r
301       catch (Exception ex)\r
302       {\r
303         ex.printStackTrace();\r
304       }\r
305     }\r
306   }\r
307 \r
308   public void viewMapping_actionPerformed(ActionEvent actionEvent)\r
309   {\r
310     jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();\r
311     jalview.gui.Desktop.addInternalFrame(cap, "PDB - Sequence Mapping", 550,\r
312                                          600);\r
313     cap.setText(\r
314         StructureSelectionManager.getStructureSelectionManager().printMapping(\r
315             pdbentry.getFile())\r
316         );\r
317   }\r
318 \r
319   /**\r
320    * DOCUMENT ME!\r
321    *\r
322    * @param e DOCUMENT ME!\r
323    */\r
324   public void eps_actionPerformed(ActionEvent e)\r
325   {\r
326     makePDBImage(jalview.util.ImageMaker.EPS);\r
327   }\r
328 \r
329   /**\r
330    * DOCUMENT ME!\r
331    *\r
332    * @param e DOCUMENT ME!\r
333    */\r
334   public void png_actionPerformed(ActionEvent e)\r
335   {\r
336     makePDBImage(jalview.util.ImageMaker.PNG);\r
337   }\r
338 \r
339   void makePDBImage(int type)\r
340   {\r
341     int width = getWidth();\r
342     int height = getHeight();\r
343 \r
344     jalview.util.ImageMaker im;\r
345 \r
346     if (type == jalview.util.ImageMaker.PNG)\r
347     {\r
348       im = new jalview.util.ImageMaker(this,\r
349                                        jalview.util.ImageMaker.PNG,\r
350                                        "Make PNG image from view",\r
351                                        width, height,\r
352                                        null, null);\r
353     }\r
354     else\r
355     {\r
356       im = new jalview.util.ImageMaker(this,\r
357                                        jalview.util.ImageMaker.EPS,\r
358                                        "Make EPS file from view",\r
359                                        width, height,\r
360                                        null, this.getTitle());\r
361     }\r
362 \r
363     if (im.getGraphics() != null)\r
364     {\r
365       Rectangle rect = new Rectangle(width, height);\r
366       viewer.renderScreenImage(im.getGraphics(),\r
367                                rect.getSize(), rect);\r
368       im.writeImage();\r
369     }\r
370   }\r
371 \r
372 \r
373   public void seqColour_actionPerformed(ActionEvent actionEvent)\r
374   {\r
375     colourBySequence = seqColour.isSelected();\r
376     colourBySequence(ap);\r
377   }\r
378 \r
379   public void chainColour_actionPerformed(ActionEvent actionEvent)\r
380   {\r
381     colourBySequence = false;\r
382     seqColour.setSelected(false);\r
383     viewer.evalStringQuiet("select *;color chain");\r
384   }\r
385 \r
386   public void chargeColour_actionPerformed(ActionEvent actionEvent)\r
387   {\r
388     colourBySequence = false;\r
389     seqColour.setSelected(false);\r
390     viewer.evalStringQuiet("select *;color white;select ASP,GLU;color red;"\r
391                       +"select LYS,ARG;color blue;select CYS;color yellow");\r
392   }\r
393 \r
394   public void zappoColour_actionPerformed(ActionEvent actionEvent)\r
395   {\r
396     setJalviewColourScheme(new ZappoColourScheme());\r
397   }\r
398 \r
399   public void taylorColour_actionPerformed(ActionEvent actionEvent)\r
400   {\r
401     setJalviewColourScheme(new TaylorColourScheme());\r
402   }\r
403 \r
404   public void hydroColour_actionPerformed(ActionEvent actionEvent)\r
405   {\r
406     setJalviewColourScheme(new HydrophobicColourScheme());\r
407   }\r
408 \r
409   public void helixColour_actionPerformed(ActionEvent actionEvent)\r
410   {\r
411     setJalviewColourScheme(new HelixColourScheme());\r
412   }\r
413 \r
414   public void strandColour_actionPerformed(ActionEvent actionEvent)\r
415   {\r
416     setJalviewColourScheme(new StrandColourScheme());\r
417   }\r
418 \r
419   public void turnColour_actionPerformed(ActionEvent actionEvent)\r
420   {\r
421     setJalviewColourScheme(new TurnColourScheme());\r
422   }\r
423 \r
424   public void buriedColour_actionPerformed(ActionEvent actionEvent)\r
425   {\r
426     setJalviewColourScheme(new BuriedColourScheme());\r
427   }\r
428 \r
429   public void setJalviewColourScheme(ColourSchemeI cs)\r
430   {\r
431     colourBySequence = false;\r
432     seqColour.setSelected(false);\r
433 \r
434     if(cs==null)\r
435       return;\r
436 \r
437     String res;\r
438     int index;\r
439     Color col;\r
440 \r
441     Enumeration en = ResidueProperties.aa3Hash.keys();\r
442     StringBuffer command = new StringBuffer("select *;color white;");\r
443     while(en.hasMoreElements())\r
444     {\r
445       res = en.nextElement().toString();\r
446       index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();\r
447       if(index>20)\r
448         continue;\r
449 \r
450       col = cs.findColour(ResidueProperties.aa[index].charAt(0));\r
451 \r
452       command.append("select "+res+";color["\r
453                         + col.getRed() + ","\r
454                         + col.getGreen() + ","\r
455                         + col.getBlue() + "];");\r
456     }\r
457 \r
458     viewer.evalStringQuiet(command.toString());\r
459   }\r
460 \r
461   public void userColour_actionPerformed(ActionEvent actionEvent)\r
462   {\r
463     new UserDefinedColours(this, null);\r
464   }\r
465 \r
466   public void backGround_actionPerformed(ActionEvent actionEvent)\r
467   {\r
468     java.awt.Color col = JColorChooser.showDialog(this,\r
469                                                   "Select Background Colour",\r
470                                                   null);\r
471 \r
472     if (col != null)\r
473     {\r
474       viewer.evalStringQuiet("background ["\r
475                         + col.getRed() + ","\r
476                         + col.getGreen() + ","\r
477                         + col.getBlue() + "];");\r
478     }\r
479   }\r
480 \r
481 \r
482   public void jmolHelp_actionPerformed(ActionEvent actionEvent)\r
483   {\r
484        try{\r
485          jalview.util.BrowserLauncher.openURL(\r
486              "http://jmol.sourceforge.net/docs/JmolUserGuide/");\r
487        }catch(Exception ex){}\r
488    }\r
489 \r
490 \r
491   //////////////////////////////////\r
492   ///StructureListener\r
493   public String getPdbFile()\r
494   {\r
495     return pdbentry.getFile();\r
496   }\r
497 \r
498   Pattern pattern = Pattern.compile(\r
499       "\\[(.*)\\]([0-9]+)(:[a-zA-Z]*)?\\.([a-zA-Z]+)(/[0-9]*)?"\r
500       );\r
501 \r
502   String lastMessage;\r
503   public void mouseOverStructure(int atomIndex, String strInfo)\r
504   {\r
505     Matcher matcher = pattern.matcher(strInfo);\r
506     matcher.find();\r
507     matcher.group(1);\r
508     int pdbResNum = Integer.parseInt(matcher.group(2));\r
509     String chainId = matcher.group(3);\r
510 \r
511     if (chainId != null)\r
512       chainId = chainId.substring(1, chainId.length());\r
513     else\r
514     {\r
515       chainId = " ";\r
516     }\r
517 \r
518     if (lastMessage == null || !lastMessage.equals(strInfo))\r
519       ssm.mouseOverStructure(pdbResNum, chainId, pdbentry.getFile());\r
520 \r
521     lastMessage = strInfo;\r
522   }\r
523 \r
524   StringBuffer resetLastRes = new StringBuffer();\r
525   StringBuffer eval = new StringBuffer();\r
526 \r
527   public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)\r
528   {\r
529     if (!pdbfile.equals(pdbentry.getFile()))\r
530       return;\r
531 \r
532     if (resetLastRes.length() > 0)\r
533     {\r
534       viewer.evalStringQuiet(resetLastRes.toString());\r
535     }\r
536 \r
537     eval.setLength(0);\r
538     eval.append("select " + pdbResNum);\r
539 \r
540     resetLastRes.setLength(0);\r
541     resetLastRes.append("select " + pdbResNum);\r
542 \r
543     if (!chain.equals(" "))\r
544     {\r
545       eval.append(":" + chain);\r
546       resetLastRes.append(":" + chain);\r
547     }\r
548 \r
549     eval.append(";color gold;wireframe 100");\r
550 \r
551     Color col = new Color(viewer.getAtomArgb(atomIndex));\r
552 \r
553     resetLastRes.append(";color["\r
554                         + col.getRed() + ","\r
555                         + col.getGreen() + ","\r
556                         + col.getBlue() + "];wireframe 0");\r
557 \r
558     viewer.evalStringQuiet(eval.toString());\r
559 \r
560   }\r
561 \r
562   public void updateColours(Object source)\r
563   {\r
564     colourBySequence( (AlignmentPanel) source);\r
565   }\r
566 \r
567 \r
568 //End StructureListener\r
569 ////////////////////////////\r
570 \r
571   FeatureRenderer fr;\r
572   public void colourBySequence(AlignmentPanel ap)\r
573   {\r
574     if(!colourBySequence)\r
575       return;\r
576 \r
577 \r
578     StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());\r
579 \r
580     if (mapping.length < 1)\r
581       return;\r
582 \r
583     SequenceRenderer sr = ap.seqPanel.seqCanvas.getSequenceRenderer();\r
584 \r
585     boolean showFeatures = false;\r
586     if (ap.av.showSequenceFeatures)\r
587     {\r
588       showFeatures = true;\r
589       if (fr == null)\r
590       {\r
591         fr = new jalview.gui.FeatureRenderer(ap.av);\r
592       }\r
593 \r
594       fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());\r
595     }\r
596 \r
597     StringBuffer command = new StringBuffer();\r
598 \r
599     int lastPos = -1;\r
600     for (int s = 0; s < sequence.length; s++)\r
601     {\r
602       for (int m = 0; m < mapping.length; m++)\r
603       {\r
604         if (mapping[m].getSequence() == sequence[s])\r
605         {\r
606           for (int r = 0; r < sequence[s].getLength(); r++)\r
607           {\r
608             int pos = mapping[m].getPDBResNum(\r
609                 sequence[s].findPosition(r));\r
610 \r
611             if (pos < 1 || pos==lastPos)\r
612               continue;\r
613 \r
614             lastPos = pos;\r
615 \r
616             Color col = sr.getResidueBoxColour(sequence[s], r);\r
617 \r
618             if (showFeatures)\r
619               col = fr.findFeatureColour(col, sequence[s], r);\r
620 \r
621             if (command.toString().endsWith(":" + mapping[m].getChain()+\r
622                                             ";color["\r
623                                             + col.getRed() + ","\r
624                                             + col.getGreen() + ","\r
625                                             + col.getBlue() + "]"))\r
626             {\r
627               command = condenseCommand(command, pos);\r
628               continue;\r
629             }\r
630 \r
631             command.append(";select " + pos);\r
632 \r
633             if (!mapping[m].getChain().equals(" "))\r
634             {\r
635               command.append(":" + mapping[m].getChain());\r
636             }\r
637 \r
638             command.append(";color["\r
639                              + col.getRed() + ","\r
640                              + col.getGreen() + ","\r
641                              + col.getBlue() + "]");\r
642 \r
643           }\r
644           break;\r
645         }\r
646       }\r
647     }\r
648 \r
649     viewer.evalStringQuiet(command.toString());\r
650   }\r
651 \r
652   StringBuffer condenseCommand(StringBuffer command, int pos)\r
653   {\r
654     StringBuffer sb = new StringBuffer(command.substring(0, command.lastIndexOf("select")+7));\r
655 \r
656     command.delete(0, sb.length());\r
657 \r
658     String start;\r
659 \r
660     if (command.indexOf("-") > -1)\r
661     {\r
662       start = command.substring(0,command.indexOf("-"));\r
663     }\r
664     else\r
665     {\r
666       start = command.substring(0, command.indexOf(":"));\r
667     }\r
668 \r
669     sb.append(start+"-"+pos+command.substring(command.indexOf(":")));\r
670 \r
671     return sb;\r
672   }\r
673 \r
674   /////////////////////////////////\r
675   //JmolStatusListener\r
676 \r
677   public String eval(String strEval)\r
678   {\r
679    // System.out.println(strEval);\r
680    //"# 'eval' is implemented only for the applet.";\r
681     return null;\r
682   }\r
683 \r
684   public void createImage(String file, String type, int quality)\r
685   {\r
686     System.out.println("JMOL CREATE IMAGE");\r
687   }\r
688 \r
689   public void setCallbackFunction(String callbackType,\r
690                                   String callbackFunction)\r
691   {}\r
692 \r
693   public void notifyFileLoaded(String fullPathName, String fileName,\r
694                                String modelName, Object clientFile,\r
695                                String errorMsg)\r
696   {\r
697     if(errorMsg!=null)\r
698     {\r
699       fileLoadingError = errorMsg;\r
700       repaint();\r
701       return;\r
702     }\r
703 \r
704     fileLoadingError = null;\r
705 \r
706     if (fileName != null)\r
707     {\r
708 \r
709       //FILE LOADED OK\r
710       ssm = StructureSelectionManager.getStructureSelectionManager();\r
711       MCview.PDBfile pdbFile = ssm.setMapping(sequence, pdbentry.getFile(), AppletFormatAdapter.FILE);\r
712       ssm.addStructureViewerListener(this);\r
713 \r
714       Vector chains = new Vector();\r
715       for(int i=0; i<pdbFile.chains.size(); i++)\r
716       {\r
717         chains.addElement(((MCview.PDBChain)pdbFile.chains.elementAt(i)).id);\r
718       }\r
719       setChainMenuItems(chains);\r
720 \r
721       jmolpopup.updateComputedMenus();\r
722 \r
723       if(!loadingFromArchive)\r
724       {\r
725         viewer.evalStringQuiet(\r
726              "select backbone;restrict;cartoon;wireframe off;spacefill off");\r
727 \r
728         colourBySequence(ap);\r
729       }\r
730 \r
731       loadingFromArchive = false;\r
732     }\r
733     else\r
734       return;\r
735   }\r
736 \r
737   public void notifyFrameChanged(int frameNo)\r
738   {\r
739     boolean isAnimationRunning = (frameNo <= -2);\r
740   }\r
741 \r
742   public void notifyScriptStart(String statusMessage, String additionalInfo)\r
743   {}\r
744 \r
745   public void sendConsoleEcho(String strEcho)\r
746   {\r
747     if (scriptWindow != null)\r
748       scriptWindow.sendConsoleEcho(strEcho);\r
749   }\r
750 \r
751   public void sendConsoleMessage(String strStatus)\r
752   {\r
753     if (scriptWindow != null)\r
754       scriptWindow.sendConsoleMessage(strStatus);\r
755   }\r
756 \r
757   public void notifyScriptTermination(String strStatus, int msWalltime)\r
758   {\r
759     if (scriptWindow != null)\r
760       scriptWindow.notifyScriptTermination(strStatus, msWalltime);\r
761   }\r
762 \r
763   public void handlePopupMenu(int x, int y)\r
764   {\r
765     jmolpopup.show(x, y);\r
766   }\r
767 \r
768   public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)\r
769   {\r
770     notifyAtomPicked(iatom, strMeasure);\r
771   }\r
772 \r
773   public void notifyNewDefaultModeMeasurement(int count, String strInfo)\r
774   {}\r
775 \r
776   public void notifyAtomPicked(int atomIndex, String strInfo)\r
777   {\r
778     if (scriptWindow != null)\r
779     {\r
780       scriptWindow.sendConsoleMessage(strInfo);\r
781       scriptWindow.sendConsoleMessage("\n");\r
782     }\r
783   }\r
784 \r
785   public void notifyAtomHovered(int atomIndex, String strInfo)\r
786   {\r
787     mouseOverStructure(atomIndex, strInfo);\r
788   }\r
789 \r
790   public void sendSyncScript(String script, String appletName)\r
791   {}\r
792 \r
793   public void showUrl(String url)\r
794   {}\r
795 \r
796   public void showConsole(boolean showConsole)\r
797   {\r
798     if (scriptWindow == null)\r
799       scriptWindow = new ScriptWindow(this);\r
800 \r
801     if(showConsole)\r
802     {\r
803       if(splitPane==null)\r
804       {\r
805         splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);\r
806         splitPane.setTopComponent(renderPanel);\r
807         splitPane.setBottomComponent(scriptWindow);\r
808         this.getContentPane().add(splitPane, BorderLayout.CENTER);\r
809       }\r
810 \r
811       splitPane.setDividerLocation(getHeight()-200);\r
812       splitPane.validate();\r
813     }\r
814     else\r
815     {\r
816       if (splitPane != null)\r
817         splitPane.setVisible(false);\r
818 \r
819       splitPane = null;\r
820 \r
821       this.getContentPane().add(renderPanel, BorderLayout.CENTER);\r
822     }\r
823 \r
824     validate();\r
825   }\r
826 \r
827   public float functionXY(String functionName, int x, int y)\r
828   {\r
829     return 0;\r
830   }\r
831 \r
832   ///End JmolStatusListener\r
833   ///////////////////////////////\r
834 \r
835 \r
836   class RenderPanel\r
837       extends JPanel\r
838   {\r
839     final Dimension currentSize = new Dimension();\r
840     final Rectangle rectClip = new Rectangle();\r
841 \r
842     public void paintComponent(Graphics g)\r
843     {\r
844       getSize(currentSize);\r
845       g.getClipBounds(rectClip);\r
846 \r
847       if (viewer == null)\r
848       {\r
849         g.setColor(Color.black);\r
850         g.fillRect(0, 0, currentSize.width, currentSize.height);\r
851         g.setColor(Color.white);\r
852         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
853         g.drawString("Retrieving PDB data....", 20, currentSize.height / 2);\r
854       }\r
855       else if(fileLoadingError!=null)\r
856       {\r
857         g.setColor(Color.black);\r
858         g.fillRect(0, 0, currentSize.width, currentSize.height);\r
859         g.setColor(Color.white);\r
860         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
861         g.drawString("Error loading file..." + pdbentry.getId(), 20,\r
862                      currentSize.height / 2);\r
863       }\r
864       else\r
865       {\r
866         viewer.renderScreenImage(g, currentSize, rectClip);\r
867       }\r
868     }\r
869   }\r
870 \r
871 }\r