8bfd7b51eb3147c355d1fd42e5a5b0844eae9166
[jalview.git] / src / MCview / PDBViewer.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package MCview;
19
20 import java.io.*;
21
22 import java.awt.event.*;
23 import javax.swing.*;
24
25 import jalview.datamodel.*;
26 import jalview.gui.*;
27 import jalview.io.*;
28 import jalview.schemes.*;
29 import jalview.ws.ebi.EBIFetchClient;
30
31 public class PDBViewer extends JInternalFrame implements Runnable
32 {
33
34   /**
35    * The associated sequence in an alignment
36    */
37   PDBCanvas pdbcanvas;
38
39   PDBEntry pdbentry;
40
41   SequenceI[] seq;
42
43   String[] chains;
44
45   AlignmentPanel ap;
46
47   String protocol;
48
49   String tmpPDBFile;
50
51   public PDBViewer(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
52           AlignmentPanel ap, String protocol)
53
54   {
55     this.pdbentry = pdbentry;
56     this.seq = seq;
57     this.chains = chains;
58     this.ap = ap;
59     this.protocol = protocol;
60
61     try
62     {
63       jbInit();
64     } catch (Exception ex)
65     {
66       ex.printStackTrace();
67     }
68
69     StringBuffer title = new StringBuffer(seq[0].getName() + ":"
70             + pdbentry.getFile());
71
72     pdbcanvas = new PDBCanvas();
73
74     setContentPane(pdbcanvas);
75
76     if (pdbentry.getFile() != null)
77     {
78       try
79       {
80         tmpPDBFile = pdbentry.getFile();
81         PDBfile pdbfile = new PDBfile(tmpPDBFile,
82                 jalview.io.AppletFormatAdapter.FILE);
83
84         pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
85
86       } catch (java.io.IOException ex)
87       {
88         ex.printStackTrace();
89       }
90     }
91     else
92     {
93       Thread worker = new Thread(this);
94       worker.start();
95     }
96
97     if (pdbentry.getProperty() != null)
98     {
99       if (pdbentry.getProperty().get("method") != null)
100       {
101         title.append(" Method: ");
102         title.append(pdbentry.getProperty().get("method"));
103       }
104       if (pdbentry.getProperty().get("chains") != null)
105       {
106         title.append(" Chain:");
107         title.append(pdbentry.getProperty().get("chains"));
108       }
109     }
110     Desktop.addInternalFrame(this, title.toString(), 400, 400);
111   }
112
113   public void run()
114   {
115     try
116     {
117       EBIFetchClient ebi = new EBIFetchClient();
118       String query = "pdb:" + pdbentry.getId();
119       pdbentry.setFile(ebi.fetchDataAsFile(query, "default", "raw")
120               .getAbsolutePath());
121
122       if (pdbentry.getFile() != null)
123         pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
124     } catch (Exception ex)
125     {
126       pdbcanvas.errorMessage = "Error retrieving file: " + pdbentry.getId();
127       ex.printStackTrace();
128     }
129   }
130
131   private void jbInit() throws Exception
132   {
133     this.addKeyListener(new KeyAdapter()
134     {
135       public void keyPressed(KeyEvent evt)
136       {
137         pdbcanvas.keyPressed(evt);
138       }
139     });
140
141     this.setJMenuBar(jMenuBar1);
142     fileMenu.setText("File");
143     coloursMenu.setText("Colours");
144     saveMenu.setActionCommand("Save Image");
145     saveMenu.setText("Save As");
146     png.setText("PNG");
147     png.addActionListener(new ActionListener()
148     {
149       public void actionPerformed(ActionEvent e)
150       {
151         png_actionPerformed(e);
152       }
153     });
154     eps.setText("EPS");
155     eps.addActionListener(new ActionListener()
156     {
157       public void actionPerformed(ActionEvent e)
158       {
159         eps_actionPerformed(e);
160       }
161     });
162     mapping.setText("View Mapping");
163     mapping.addActionListener(new ActionListener()
164     {
165       public void actionPerformed(ActionEvent e)
166       {
167         mapping_actionPerformed(e);
168       }
169     });
170     wire.setText("Wireframe");
171     wire.addActionListener(new ActionListener()
172     {
173       public void actionPerformed(ActionEvent e)
174       {
175         wire_actionPerformed(e);
176       }
177     });
178     depth.setSelected(true);
179     depth.setText("Depthcue");
180     depth.addActionListener(new ActionListener()
181     {
182       public void actionPerformed(ActionEvent e)
183       {
184         depth_actionPerformed(e);
185       }
186     });
187     zbuffer.setSelected(true);
188     zbuffer.setText("Z Buffering");
189     zbuffer.addActionListener(new ActionListener()
190     {
191       public void actionPerformed(ActionEvent e)
192       {
193         zbuffer_actionPerformed(e);
194       }
195     });
196     charge.setText("Charge & Cysteine");
197     charge.addActionListener(new ActionListener()
198     {
199       public void actionPerformed(ActionEvent e)
200       {
201         charge_actionPerformed(e);
202       }
203     });
204     chain.setText("By Chain");
205     chain.addActionListener(new ActionListener()
206     {
207       public void actionPerformed(ActionEvent e)
208       {
209         chain_actionPerformed(e);
210       }
211     });
212     seqButton.setSelected(true);
213     seqButton.setText("By Sequence");
214     seqButton.addActionListener(new ActionListener()
215     {
216       public void actionPerformed(ActionEvent e)
217       {
218         seqButton_actionPerformed(e);
219       }
220     });
221     allchains.setSelected(true);
222     allchains.setText("Show All Chains");
223     allchains.addItemListener(new ItemListener()
224     {
225       public void itemStateChanged(ItemEvent e)
226       {
227         allchains_itemStateChanged(e);
228       }
229     });
230     zappo.setText("Zappo");
231     zappo.addActionListener(new ActionListener()
232     {
233       public void actionPerformed(ActionEvent e)
234       {
235         zappo_actionPerformed(e);
236       }
237     });
238     taylor.setText("Taylor");
239     taylor.addActionListener(new ActionListener()
240     {
241       public void actionPerformed(ActionEvent e)
242       {
243         taylor_actionPerformed(e);
244       }
245     });
246     hydro.setText("Hydro");
247     hydro.addActionListener(new ActionListener()
248     {
249       public void actionPerformed(ActionEvent e)
250       {
251         hydro_actionPerformed(e);
252       }
253     });
254     helix.setText("Helix");
255     helix.addActionListener(new ActionListener()
256     {
257       public void actionPerformed(ActionEvent e)
258       {
259         helix_actionPerformed(e);
260       }
261     });
262     strand.setText("Strand");
263     strand.addActionListener(new ActionListener()
264     {
265       public void actionPerformed(ActionEvent e)
266       {
267         strand_actionPerformed(e);
268       }
269     });
270     turn.setText("Turn");
271     turn.addActionListener(new ActionListener()
272     {
273       public void actionPerformed(ActionEvent e)
274       {
275         turn_actionPerformed(e);
276       }
277     });
278     buried.setText("Buried");
279     buried.addActionListener(new ActionListener()
280     {
281       public void actionPerformed(ActionEvent e)
282       {
283         buried_actionPerformed(e);
284       }
285     });
286     user.setText("User Defined...");
287     user.addActionListener(new ActionListener()
288     {
289       public void actionPerformed(ActionEvent e)
290       {
291         user_actionPerformed(e);
292       }
293     });
294     viewMenu.setText("View");
295     background.setText("Background Colour...");
296     background.addActionListener(new ActionListener()
297     {
298       public void actionPerformed(ActionEvent e)
299       {
300         background_actionPerformed(e);
301       }
302     });
303     savePDB.setText("PDB File");
304     savePDB.addActionListener(new ActionListener()
305     {
306       public void actionPerformed(ActionEvent e)
307       {
308         savePDB_actionPerformed(e);
309       }
310     });
311     jMenuBar1.add(fileMenu);
312     jMenuBar1.add(coloursMenu);
313     jMenuBar1.add(viewMenu);
314     fileMenu.add(saveMenu);
315     fileMenu.add(mapping);
316     saveMenu.add(savePDB);
317     saveMenu.add(png);
318     saveMenu.add(eps);
319     coloursMenu.add(seqButton);
320     coloursMenu.add(chain);
321     coloursMenu.add(charge);
322     coloursMenu.add(zappo);
323     coloursMenu.add(taylor);
324     coloursMenu.add(hydro);
325     coloursMenu.add(helix);
326     coloursMenu.add(strand);
327     coloursMenu.add(turn);
328     coloursMenu.add(buried);
329     coloursMenu.add(user);
330     coloursMenu.add(background);
331     ButtonGroup bg = new ButtonGroup();
332     bg.add(seqButton);
333     bg.add(chain);
334     bg.add(charge);
335     bg.add(zappo);
336     bg.add(taylor);
337     bg.add(hydro);
338     bg.add(helix);
339     bg.add(strand);
340     bg.add(turn);
341     bg.add(buried);
342     bg.add(user);
343
344     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
345     {
346       java.util.Enumeration userColours = jalview.gui.UserDefinedColours
347               .getUserColourSchemes().keys();
348
349       while (userColours.hasMoreElements())
350       {
351         final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(
352                 userColours.nextElement().toString());
353         radioItem.setName("USER_DEFINED");
354         radioItem.addMouseListener(new MouseAdapter()
355         {
356           public void mousePressed(MouseEvent evt)
357           {
358             if (evt.isControlDown()
359                     || SwingUtilities.isRightMouseButton(evt))
360             {
361               radioItem.removeActionListener(radioItem.getActionListeners()[0]);
362
363               int option = JOptionPane.showInternalConfirmDialog(
364                       jalview.gui.Desktop.desktop,
365                       "Remove from default list?",
366                       "Remove user defined colour",
367                       JOptionPane.YES_NO_OPTION);
368               if (option == JOptionPane.YES_OPTION)
369               {
370                 jalview.gui.UserDefinedColours
371                         .removeColourFromDefaults(radioItem.getText());
372                 coloursMenu.remove(radioItem);
373               }
374               else
375               {
376                 radioItem.addActionListener(new ActionListener()
377                 {
378                   public void actionPerformed(ActionEvent evt)
379                   {
380                     user_actionPerformed(evt);
381                   }
382                 });
383               }
384             }
385           }
386         });
387         radioItem.addActionListener(new ActionListener()
388         {
389           public void actionPerformed(ActionEvent evt)
390           {
391             user_actionPerformed(evt);
392           }
393         });
394         coloursMenu.add(radioItem);
395         bg.add(radioItem);
396       }
397     }
398
399     viewMenu.add(wire);
400     viewMenu.add(depth);
401     viewMenu.add(zbuffer);
402     viewMenu.add(allchains);
403   }
404
405   JMenuBar jMenuBar1 = new JMenuBar();
406
407   JMenu fileMenu = new JMenu();
408
409   JMenu coloursMenu = new JMenu();
410
411   JMenu saveMenu = new JMenu();
412
413   JMenuItem png = new JMenuItem();
414
415   JMenuItem eps = new JMenuItem();
416
417   JMenuItem mapping = new JMenuItem();
418
419   JCheckBoxMenuItem wire = new JCheckBoxMenuItem();
420
421   JCheckBoxMenuItem depth = new JCheckBoxMenuItem();
422
423   JCheckBoxMenuItem zbuffer = new JCheckBoxMenuItem();
424
425   JCheckBoxMenuItem allchains = new JCheckBoxMenuItem();
426
427   JRadioButtonMenuItem charge = new JRadioButtonMenuItem();
428
429   JRadioButtonMenuItem chain = new JRadioButtonMenuItem();
430
431   JRadioButtonMenuItem seqButton = new JRadioButtonMenuItem();
432
433   JRadioButtonMenuItem hydro = new JRadioButtonMenuItem();
434
435   JRadioButtonMenuItem taylor = new JRadioButtonMenuItem();
436
437   JRadioButtonMenuItem zappo = new JRadioButtonMenuItem();
438
439   JRadioButtonMenuItem user = new JRadioButtonMenuItem();
440
441   JRadioButtonMenuItem buried = new JRadioButtonMenuItem();
442
443   JRadioButtonMenuItem turn = new JRadioButtonMenuItem();
444
445   JRadioButtonMenuItem strand = new JRadioButtonMenuItem();
446
447   JRadioButtonMenuItem helix = new JRadioButtonMenuItem();
448
449   JMenu viewMenu = new JMenu();
450
451   JMenuItem background = new JMenuItem();
452
453   JMenuItem savePDB = new JMenuItem();
454
455   /**
456    * DOCUMENT ME!
457    * 
458    * @param e
459    *          DOCUMENT ME!
460    */
461   public void eps_actionPerformed(ActionEvent e)
462   {
463     makePDBImage(jalview.util.ImageMaker.EPS);
464   }
465
466   /**
467    * DOCUMENT ME!
468    * 
469    * @param e
470    *          DOCUMENT ME!
471    */
472   public void png_actionPerformed(ActionEvent e)
473   {
474     makePDBImage(jalview.util.ImageMaker.PNG);
475   }
476
477   void makePDBImage(int type)
478   {
479     int width = pdbcanvas.getWidth();
480     int height = pdbcanvas.getHeight();
481
482     jalview.util.ImageMaker im;
483
484     if (type == jalview.util.ImageMaker.PNG)
485     {
486       im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.PNG,
487               "Make PNG image from view", width, height, null, null);
488     }
489     else
490     {
491       im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.EPS,
492               "Make EPS file from view", width, height, null,
493               this.getTitle());
494     }
495
496     if (im.getGraphics() != null)
497     {
498       pdbcanvas.drawAll(im.getGraphics(), width, height);
499       im.writeImage();
500     }
501   }
502
503   public void charge_actionPerformed(ActionEvent e)
504   {
505     pdbcanvas.bysequence = false;
506     pdbcanvas.pdb.setChargeColours();
507     pdbcanvas.redrawneeded = true;
508     pdbcanvas.repaint();
509   }
510
511   public void hydro_actionPerformed(ActionEvent e)
512   {
513     pdbcanvas.bysequence = false;
514     pdbcanvas.pdb.setColours(new HydrophobicColourScheme());
515     pdbcanvas.redrawneeded = true;
516     pdbcanvas.repaint();
517   }
518
519   public void chain_actionPerformed(ActionEvent e)
520   {
521     pdbcanvas.bysequence = false;
522     pdbcanvas.pdb.setChainColours();
523     pdbcanvas.redrawneeded = true;
524     pdbcanvas.repaint();
525   }
526
527   public void zbuffer_actionPerformed(ActionEvent e)
528   {
529     pdbcanvas.zbuffer = !pdbcanvas.zbuffer;
530     pdbcanvas.redrawneeded = true;
531     pdbcanvas.repaint();
532   }
533
534   public void molecule_actionPerformed(ActionEvent e)
535   {
536     pdbcanvas.bymolecule = !pdbcanvas.bymolecule;
537     pdbcanvas.redrawneeded = true;
538     pdbcanvas.repaint();
539   }
540
541   public void depth_actionPerformed(ActionEvent e)
542   {
543     pdbcanvas.depthcue = !pdbcanvas.depthcue;
544     pdbcanvas.redrawneeded = true;
545     pdbcanvas.repaint();
546   }
547
548   public void wire_actionPerformed(ActionEvent e)
549   {
550     pdbcanvas.wire = !pdbcanvas.wire;
551     pdbcanvas.redrawneeded = true;
552     pdbcanvas.repaint();
553   }
554
555   public void seqButton_actionPerformed(ActionEvent e)
556   {
557     pdbcanvas.bysequence = true;
558     pdbcanvas.updateSeqColours();
559   }
560
561   public void mapping_actionPerformed(ActionEvent e)
562   {
563     jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();
564     try
565     {
566       cap.setText(pdbcanvas.mappingDetails.toString());
567       Desktop.addInternalFrame(cap, "PDB - Sequence Mapping", 550, 600);
568     } catch (OutOfMemoryError oom)
569     {
570       new OOMWarning("Opening sequence to structure mapping report", oom);
571       cap.dispose();
572     }
573   }
574
575   public void allchains_itemStateChanged(ItemEvent e)
576   {
577     pdbcanvas.setAllchainsVisible(allchains.getState());
578   }
579
580   public void zappo_actionPerformed(ActionEvent e)
581   {
582     pdbcanvas.bysequence = false;
583     pdbcanvas.pdb.setColours(new ZappoColourScheme());
584     pdbcanvas.redrawneeded = true;
585     pdbcanvas.repaint();
586   }
587
588   public void taylor_actionPerformed(ActionEvent e)
589   {
590     pdbcanvas.bysequence = false;
591     pdbcanvas.pdb.setColours(new TaylorColourScheme());
592     pdbcanvas.redrawneeded = true;
593     pdbcanvas.repaint();
594   }
595
596   public void helix_actionPerformed(ActionEvent e)
597   {
598     pdbcanvas.bysequence = false;
599     pdbcanvas.pdb.setColours(new HelixColourScheme());
600     pdbcanvas.redrawneeded = true;
601     pdbcanvas.repaint();
602   }
603
604   public void strand_actionPerformed(ActionEvent e)
605   {
606     pdbcanvas.bysequence = false;
607     pdbcanvas.pdb.setColours(new StrandColourScheme());
608     pdbcanvas.redrawneeded = true;
609     pdbcanvas.repaint();
610   }
611
612   public void turn_actionPerformed(ActionEvent e)
613   {
614     pdbcanvas.bysequence = false;
615     pdbcanvas.pdb.setColours(new TurnColourScheme());
616     pdbcanvas.redrawneeded = true;
617     pdbcanvas.repaint();
618   }
619
620   public void buried_actionPerformed(ActionEvent e)
621   {
622     pdbcanvas.bysequence = false;
623     pdbcanvas.pdb.setColours(new BuriedColourScheme());
624     pdbcanvas.redrawneeded = true;
625     pdbcanvas.repaint();
626   }
627
628   public void user_actionPerformed(ActionEvent e)
629   {
630     if (e.getActionCommand().equals("User Defined..."))
631     {
632       // new UserDefinedColours(pdbcanvas, null);
633     }
634     else
635     {
636       UserColourScheme udc = (UserColourScheme) UserDefinedColours
637               .getUserColourSchemes().get(e.getActionCommand());
638
639       pdbcanvas.pdb.setColours(udc);
640       pdbcanvas.redrawneeded = true;
641       pdbcanvas.repaint();
642     }
643   }
644
645   public void background_actionPerformed(ActionEvent e)
646   {
647     java.awt.Color col = JColorChooser.showDialog(this,
648             "Select Background Colour", pdbcanvas.backgroundColour);
649
650     if (col != null)
651     {
652       pdbcanvas.backgroundColour = col;
653       pdbcanvas.redrawneeded = true;
654       pdbcanvas.repaint();
655     }
656   }
657
658   public void savePDB_actionPerformed(ActionEvent e)
659   {
660     JalviewFileChooser chooser = new JalviewFileChooser(
661             jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
662
663     chooser.setFileView(new JalviewFileView());
664     chooser.setDialogTitle("Save PDB File");
665     chooser.setToolTipText("Save");
666
667     int value = chooser.showSaveDialog(this);
668
669     if (value == JalviewFileChooser.APPROVE_OPTION)
670     {
671       try
672       {
673         BufferedReader in = new BufferedReader(new FileReader(tmpPDBFile));
674         File outFile = chooser.getSelectedFile();
675
676         PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
677         String data;
678         while ((data = in.readLine()) != null)
679         {
680           if (!(data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1))
681           {
682             out.println(data);
683           }
684         }
685         out.close();
686         in.close();
687       } catch (Exception ex)
688       {
689         ex.printStackTrace();
690       }
691     }
692   }
693 }