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