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