updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
[jalview.git] / src / jalview / gui / TreePanel.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 jalview.gui;
20
21 import jalview.analysis.*;
22
23 import jalview.datamodel.*;
24
25 import jalview.io.*;
26
27 import jalview.jbgui.*;
28
29 import org.jibble.epsgraphics.*;
30
31 import java.awt.*;
32 import java.awt.event.*;
33 import java.awt.image.*;
34
35 import java.io.*;
36
37 import java.util.*;
38
39 import javax.imageio.*;
40
41 import java.beans.PropertyChangeEvent;
42
43
44 /**
45  * DOCUMENT ME!
46  *
47  * @author $author$
48  * @version $Revision$
49  */
50 public class TreePanel extends GTreePanel
51 {
52     String type;
53     String pwtype;
54     TreeCanvas treeCanvas;
55     NJTree tree;
56     AlignViewport av;
57
58     /**
59      * Creates a new TreePanel object.
60      *
61      * @param av DOCUMENT ME!
62      * @param seqVector DOCUMENT ME!
63      * @param type DOCUMENT ME!
64      * @param pwtype DOCUMENT ME!
65      * @param s DOCUMENT ME!
66      * @param e DOCUMENT ME!
67      */
68     public TreePanel(AlignViewport av, String type, String pwtype)
69     {
70       super();
71       initTreePanel(av, type, pwtype, null);
72
73       // We know this tree has distances. JBPNote TODO: prolly should add this as a userdefined default
74       // showDistances(true);
75     }
76
77     /**
78      * Creates a new TreePanel object.
79      *
80      * @param av DOCUMENT ME!
81      * @param seqVector DOCUMENT ME!
82      * @param newtree DOCUMENT ME!
83      * @param type DOCUMENT ME!
84      * @param pwtype DOCUMENT ME!
85      */
86     public TreePanel(AlignViewport av,
87                      String type,
88                      String pwtype,
89                      NewickFile newtree)
90     {
91       super();
92       initTreePanel(av, type, pwtype, newtree);
93     }
94
95     public AlignmentI getAlignment()
96     {
97       return treeCanvas.av.getAlignment();
98     }
99
100
101     void initTreePanel(AlignViewport av, String type,  String pwtype,
102                        NewickFile newTree)
103     {
104
105       this.type = type;
106       this.pwtype = pwtype;
107
108       treeCanvas = new TreeCanvas(av, scrollPane);
109       scrollPane.setViewportView(treeCanvas);
110
111       av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
112       {
113         public void propertyChange(PropertyChangeEvent evt)
114         {
115           if (evt.getPropertyName().equals("alignment"))
116           {
117             if(tree==null)
118               System.out.println("tree is null");
119             if(evt.getNewValue()==null)
120               System.out.println("new value is null");
121
122             tree.UpdatePlaceHolders( (Vector) evt.getNewValue());
123
124             repaint();
125           }
126         }
127       });
128
129       this.av = av;
130
131
132       TreeLoader tl = new TreeLoader(newTree);
133       tl.start();
134
135     }
136
137     class TreeLoader extends Thread
138     {
139       NewickFile newtree;
140       jalview.datamodel.AlignmentView odata=null;
141       public TreeLoader(NewickFile newtree)
142       {
143         this.newtree = newtree;
144         if (newtree != null)
145         {
146           // Must be outside run(), as Jalview2XML tries to
147           // update distance/bootstrap visibility at the same time
148           showBootstrap(newtree.HasBootstrap());
149           showDistances(newtree.HasDistances());
150         }
151       }
152
153       public void run()
154       {
155
156         if(newtree!=null)
157         {
158           if (odata==null) {
159             tree = new NJTree(av.alignment.getSequencesArray(),
160                               newtree);
161           } else {
162             tree = new NJTree(av.alignment.getSequencesArray(), odata, newtree);
163           }
164           if (!tree.hasOriginalSequenceData())
165             allowOriginalSeqData(false);
166         }
167         else
168         {
169           int start, end;
170           SequenceI [] seqs;
171           AlignmentView seqStrings = av.getAlignmentView(av.getSelectionGroup()!=null);
172           if(av.getSelectionGroup()==null)
173           {
174             start = 0;
175             end = av.alignment.getWidth();
176             seqs = av.alignment.getSequencesArray();
177           }
178           else
179           {
180             start = av.getSelectionGroup().getStartRes();
181             end = av.getSelectionGroup().getEndRes()+1;
182             seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
183           }
184
185           tree = new NJTree(seqs, seqStrings, type, pwtype, start, end);
186           showDistances(true);
187         }
188
189
190         tree.reCount(tree.getTopNode());
191         tree.findHeight(tree.getTopNode());
192         treeCanvas.setTree(tree);
193         treeCanvas.repaint();
194         av.setCurrentTree(tree);
195
196       }
197     }
198
199     public void showDistances(boolean b)
200     {
201       treeCanvas.setShowDistances(b);
202       distanceMenu.setSelected(b);
203     }
204
205     public void showBootstrap(boolean b)
206     {
207       treeCanvas.setShowBootstrap(b);
208       bootstrapMenu.setSelected(b);
209     }
210
211     public void showPlaceholders(boolean b)
212     {
213       placeholdersMenu.setState(b);
214       treeCanvas.setMarkPlaceholders(b);
215     }
216
217     private void allowOriginalSeqData(boolean b) {
218       originalSeqData.setVisible(b);
219     }
220
221
222
223     /**
224      * DOCUMENT ME!
225      *
226      * @return DOCUMENT ME!
227      */
228     public NJTree getTree()
229     {
230         return tree;
231     }
232
233
234     /**
235      * DOCUMENT ME!
236      *
237      * @param e DOCUMENT ME!
238      */
239     public void textbox_actionPerformed(ActionEvent e)
240     {
241         CutAndPasteTransfer cap = new CutAndPasteTransfer();
242
243         StringBuffer buffer = new StringBuffer();
244
245         if (type.equals("AV"))
246         {
247             buffer.append("Average distance tree using ");
248         }
249         else
250         {
251             buffer.append("Neighbour joining tree using ");
252         }
253
254         if (pwtype.equals("BL"))
255         {
256             buffer.append("BLOSUM62");
257         }
258         else
259         {
260             buffer.append("PID");
261         }
262
263         Desktop.addInternalFrame(cap, buffer.toString(), 500, 100);
264
265         jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());
266         cap.setText(fout.print(tree.isHasBootstrap(), tree.isHasDistances(), tree.isHasRootDistance()));
267     }
268
269     /**
270      * DOCUMENT ME!
271      *
272      * @param e DOCUMENT ME!
273      */
274     public void saveAsNewick_actionPerformed(ActionEvent e)
275     {
276         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
277                     "LAST_DIRECTORY"));
278         chooser.setFileView(new JalviewFileView());
279         chooser.setDialogTitle("Save tree as newick file");
280         chooser.setToolTipText("Save");
281
282         int value = chooser.showSaveDialog(null);
283
284         if (value == JalviewFileChooser.APPROVE_OPTION)
285         {
286             String choice = chooser.getSelectedFile().getPath();
287             jalview.bin.Cache.setProperty("LAST_DIRECTORY",
288                 chooser.getSelectedFile().getParent());
289
290             try
291             {
292                 jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());
293                 String output = fout.print(tree.isHasBootstrap(), tree.isHasDistances(), tree.isHasRootDistance());
294                 java.io.PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
295                             choice));
296                 out.println(output);
297                 out.close();
298             }
299             catch (Exception ex)
300             {
301                 ex.printStackTrace();
302             }
303         }
304     }
305
306     /**
307      * DOCUMENT ME!
308      *
309      * @param e DOCUMENT ME!
310      */
311     public void printMenu_actionPerformed(ActionEvent e)
312     {
313         //Putting in a thread avoids Swing painting problems
314         treeCanvas.startPrinting();
315     }
316
317
318     public void originalSeqData_actionPerformed(ActionEvent e)
319     {
320       if (!tree.hasOriginalSequenceData())
321       {
322         jalview.bin.Cache.log.info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
323         return;
324       }
325       // decide if av alignment is sufficiently different to original data to warrant a new window to be created
326       // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)
327       // or create a selection box around columns in alignment view
328       // test Alignment(SeqCigar[])
329       Object[] alAndColsel = tree.seqData.getAlignmentAndColumnSelection(av.
330           getGapCharacter());
331
332
333       if (alAndColsel != null && alAndColsel[0]!=null)
334        {
335          // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
336
337          Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);
338          Alignment dataset = av.getAlignment().getDataset();
339          if (dataset != null)
340          {
341            al.setDataset(dataset);
342          }
343
344          if (true)
345          {
346            // make a new frame!
347            AlignFrame af = new AlignFrame(al, (ColumnSelection) alAndColsel[1]);
348
349            //>>>This is a fix for the moment, until a better solution is found!!<<<
350            // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
351
352        //           af.addSortByOrderMenuItem(ServiceName + " Ordering",
353        //                                     msaorder);
354
355            Desktop.addInternalFrame(af, "Original Data for " + this.title,
356                                     AlignFrame.NEW_WINDOW_WIDTH,
357                                     AlignFrame.NEW_WINDOW_HEIGHT);
358          }
359        }
360     }
361
362
363     /**
364      * DOCUMENT ME!
365      *
366      * @param e DOCUMENT ME!
367      */
368     public void fitToWindow_actionPerformed(ActionEvent e)
369     {
370         treeCanvas.fitToWindow = fitToWindow.isSelected();
371         repaint();
372     }
373
374     /**
375      * DOCUMENT ME!
376      *
377      * @param e DOCUMENT ME!
378      */
379     public void font_actionPerformed(ActionEvent e)
380     {
381         if (treeCanvas == null)
382         {
383             return;
384         }
385
386         new FontChooser(this);
387     }
388
389     public Font getTreeFont()
390     {
391         return treeCanvas.font;
392     }
393
394     public void setTreeFont(Font font)
395     {
396       if(treeCanvas!=null)
397       treeCanvas.setFont(font);
398     }
399
400     /**
401      * DOCUMENT ME!
402      *
403      * @param e DOCUMENT ME!
404      */
405     public void distanceMenu_actionPerformed(ActionEvent e)
406     {
407         treeCanvas.setShowDistances(distanceMenu.isSelected());
408     }
409
410     /**
411      * DOCUMENT ME!
412      *
413      * @param e DOCUMENT ME!
414      */
415     public void bootstrapMenu_actionPerformed(ActionEvent e)
416     {
417         treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());
418     }
419
420     /**
421      * DOCUMENT ME!
422      *
423      * @param e DOCUMENT ME!
424      */
425     public void placeholdersMenu_actionPerformed(ActionEvent e)
426     {
427         treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected());
428     }
429
430     /**
431      * DOCUMENT ME!
432      *
433      * @param e DOCUMENT ME!
434      */
435     public void epsTree_actionPerformed(ActionEvent e)
436     {
437       boolean accurateText = true;
438
439       String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
440           "Prompt each time");
441
442     // If we need to prompt, and if the GUI is visible then
443     // Prompt for EPS rendering style
444       if (renderStyle.equalsIgnoreCase("Prompt each time")
445           && !
446           (System.getProperty("java.awt.headless") != null
447            && System.getProperty("java.awt.headless").equals("true")))
448       {
449         EPSOptions eps = new EPSOptions();
450         renderStyle = eps.getValue();
451
452         if (renderStyle==null || eps.cancelled)
453           return;
454
455
456       }
457
458       if (renderStyle.equalsIgnoreCase("text"))
459       {
460         accurateText = false;
461       }
462
463         int width = treeCanvas.getWidth();
464         int height = treeCanvas.getHeight();
465
466         try
467         {
468             jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(
469                         "LAST_DIRECTORY"), new String[] { "eps" },
470                     new String[] { "Encapsulated Postscript" },
471                     "Encapsulated Postscript");
472             chooser.setFileView(new jalview.io.JalviewFileView());
473             chooser.setDialogTitle("Create EPS file from tree");
474             chooser.setToolTipText("Save");
475
476             int value = chooser.showSaveDialog(this);
477
478             if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)
479             {
480                 return;
481             }
482
483             jalview.bin.Cache.setProperty("LAST_DIRECTORY",
484                                           chooser.getSelectedFile().getParent());
485
486             FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());
487             EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,
488                                                  height);
489
490             pg.setAccurateTextMode(accurateText);
491
492             treeCanvas.draw(pg, width, height);
493
494             pg.flush();
495             pg.close();
496         }
497         catch (Exception ex)
498         {
499             ex.printStackTrace();
500         }
501     }
502
503     /**
504      * DOCUMENT ME!
505      *
506      * @param e DOCUMENT ME!
507      */
508     public void pngTree_actionPerformed(ActionEvent e)
509     {
510         int width = treeCanvas.getWidth();
511         int height = treeCanvas.getHeight();
512
513         try
514         {
515             jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(
516                         "LAST_DIRECTORY"), new String[] { "png" },
517                     new String[] { "Portable network graphics" },
518                     "Portable network graphics");
519
520             chooser.setFileView(new jalview.io.JalviewFileView());
521             chooser.setDialogTitle("Create PNG image from tree");
522             chooser.setToolTipText("Save");
523
524             int value = chooser.showSaveDialog(this);
525
526             if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)
527             {
528                 return;
529             }
530
531             jalview.bin.Cache.setProperty("LAST_DIRECTORY",
532                 chooser.getSelectedFile().getParent());
533
534             FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());
535
536             BufferedImage bi = new BufferedImage(width, height,
537                     BufferedImage.TYPE_INT_RGB);
538             Graphics png = bi.getGraphics();
539
540             treeCanvas.draw(png, width, height);
541
542             ImageIO.write(bi, "png", out);
543             out.close();
544         }
545         catch (Exception ex)
546         {
547             ex.printStackTrace();
548         }
549     }
550 }