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