JAL-1078 - extend applet cut'n'paste features/annotation to support t-coffee file
[jalview.git] / src / jalview / appletgui / CutAndPasteTransfer.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, 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 jalview.appletgui;
19
20 import java.awt.*;
21 import java.awt.event.*;
22
23 import jalview.datamodel.*;
24 import jalview.io.*;
25 import jalview.schemes.TCoffeeColourScheme;
26
27 public class CutAndPasteTransfer extends Panel implements ActionListener,
28         MouseListener
29 {
30   boolean pdbImport = false;
31
32   boolean treeImport = false;
33
34   boolean annotationImport = false;
35
36   Sequence seq;
37
38   AlignFrame alignFrame;
39
40   public CutAndPasteTransfer(boolean forImport, AlignFrame alignFrame)
41   {
42     try
43     {
44       jbInit();
45     } catch (Exception e)
46     {
47       e.printStackTrace();
48     }
49
50     this.alignFrame = alignFrame;
51
52     if (!forImport)
53     {
54       buttonPanel.setVisible(false);
55     }
56   }
57
58   public String getText()
59   {
60     return textarea.getText();
61   }
62
63   public void setText(String text)
64   {
65     textarea.setText(text);
66   }
67
68   public void setPDBImport(Sequence seq)
69   {
70     this.seq = seq;
71     accept.setLabel("Accept");
72     addSequences.setVisible(false);
73     pdbImport = true;
74   }
75
76   public void setTreeImport()
77   {
78     treeImport = true;
79     accept.setLabel("Accept");
80     addSequences.setVisible(false);
81   }
82
83   public void setAnnotationImport()
84   {
85     annotationImport = true;
86     accept.setLabel("Accept");
87     addSequences.setVisible(false);
88   }
89
90   public void actionPerformed(ActionEvent evt)
91   {
92     if (evt.getSource() == accept)
93     {
94       ok(true);
95     }
96     else if (evt.getSource() == addSequences)
97     {
98       ok(false);
99     }
100     else if (evt.getSource() == cancel)
101     {
102       cancel();
103     }
104   }
105
106   protected void ok(boolean newWindow)
107   {
108     String text = getText();
109     int length = text.length();
110     textarea.append("\n");
111     if (textarea.getText().length() == length)
112     {
113       String warning = "\n\n#################################################\n"
114               + "WARNING!! THIS IS THE MAXIMUM SIZE OF TEXTAREA!!\n"
115               + "\nCAN'T INPUT FULL ALIGNMENT"
116               + "\n\nYOU MUST DELETE THIS WARNING TO CONTINUE"
117               + "\n\nMAKE SURE LAST SEQUENCE PASTED IS COMPLETE"
118               + "\n#################################################\n";
119       textarea.setText(text.substring(0, text.length() - warning.length())
120               + warning);
121
122       textarea.setCaretPosition(text.length());
123     }
124
125     if (pdbImport)
126     {
127       PDBEntry pdb = new PDBEntry();
128       pdb.setFile(text);
129
130       if (alignFrame.alignPanel.av.applet.jmolAvailable)
131         new jalview.appletgui.AppletJmol(pdb, new Sequence[]
132         { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE);
133       else
134
135         new MCview.AppletPDBViewer(pdb, new Sequence[]
136         { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE);
137
138     }
139     else if (treeImport)
140     {
141       try
142       {
143         jalview.io.NewickFile fin = new jalview.io.NewickFile(
144                 textarea.getText(), "Paste");
145
146         fin.parse();
147         if (fin.getTree() != null)
148         {
149           alignFrame.loadTree(fin, "Pasted tree file");
150         }
151
152       } catch (Exception ex)
153       {
154         // TODO: JAL-1102 - should have a warning message in dialog, not simply overwrite the broken input data with the exception
155         textarea.setText("Could not parse Newick file!\n" + ex);
156         return;
157       }
158     }
159     else if (annotationImport)
160     {
161       TCoffeeScoreFile tcf = null;
162       try
163       {
164         tcf = new TCoffeeScoreFile(textarea.getText(),
165                 jalview.io.AppletFormatAdapter.PASTE);
166         if (tcf.isValid())
167         {
168           if (tcf.annotateAlignment(alignFrame.viewport.getAlignment(),
169                   true))
170           {
171             alignFrame.tcoffeeColour.setEnabled(true);
172             alignFrame.alignPanel.fontChanged();
173             alignFrame.changeColour(new TCoffeeColourScheme(
174                     alignFrame.viewport.getAlignment()));
175             alignFrame.statusBar
176                     .setText("Successfully pasted T-Coffee scores to alignment.");
177           }
178           else
179           {
180             // file valid but didn't get added to alignment for some reason
181             alignFrame.statusBar.setText("Failed to add T-Coffee scores: "+(tcf.getWarningMessage()!=null ? tcf.getWarningMessage():""));
182           }
183         }
184         else
185         {
186           tcf = null;
187         }
188       } catch (Exception x)
189       {
190         tcf = null;
191       }
192       if (tcf == null)
193       {
194         if (new AnnotationFile().readAnnotationFile(
195                 alignFrame.viewport.getAlignment(), textarea.getText(),
196                 jalview.io.AppletFormatAdapter.PASTE))
197         {
198           alignFrame.alignPanel.fontChanged();
199           alignFrame.alignPanel.setScrollValues(0, 0);
200           alignFrame.statusBar
201                   .setText("Successfully pasted annotation to alignment.");
202
203         }
204         else
205         {
206           if (!alignFrame.parseFeaturesFile(textarea.getText(),
207                   jalview.io.AppletFormatAdapter.PASTE))
208           {
209             alignFrame.statusBar.setText("Couldn't parse pasted text as a valid annotation, feature, GFF, or T-Coffee score file.");
210           }
211         }
212       }
213     }
214     else if (alignFrame != null)
215     {
216       Alignment al = null;
217
218       String format = new IdentifyFile().Identify(text,
219               AppletFormatAdapter.PASTE);
220       try
221       {
222         al = new AppletFormatAdapter().readFile(text,
223                 AppletFormatAdapter.PASTE, format);
224       } catch (java.io.IOException ex)
225       {
226         ex.printStackTrace();
227       }
228
229       if (al != null)
230       {
231         if (newWindow)
232         {
233           AlignFrame af = new AlignFrame(al, alignFrame.viewport.applet,
234                   "Cut & Paste input - " + format, false);
235           af.statusBar.setText("Successfully pasted alignment file");
236         }
237         else
238         {
239           alignFrame.addSequences(al.getSequencesArray());
240           alignFrame.statusBar
241                   .setText("Successfully pasted alignment file");
242         }
243       }
244     }
245     // TODO: dialog should indicate if data was parsed correctly or not - see
246     // JAL-1102
247     if (this.getParent() instanceof Frame)
248     {
249       ((Frame) this.getParent()).setVisible(false);
250     }
251     else
252     {
253       ((Dialog) this.getParent()).setVisible(false);
254     }
255   }
256
257   protected void cancel()
258   {
259     textarea.setText("");
260     if (this.getParent() instanceof Frame)
261     {
262       ((Frame) this.getParent()).setVisible(false);
263     }
264     else
265     {
266       ((Dialog) this.getParent()).setVisible(false);
267     }
268   }
269
270   protected TextArea textarea = new TextArea();
271
272   Button accept = new Button("New Window");
273
274   Button addSequences = new Button("Add to Current Alignment");
275
276   Button cancel = new Button("Close");
277
278   protected Panel buttonPanel = new Panel();
279
280   BorderLayout borderLayout1 = new BorderLayout();
281
282   private void jbInit() throws Exception
283   {
284     textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 10));
285     textarea.setText("Paste your alignment file here");
286     textarea.addMouseListener(this);
287     this.setLayout(borderLayout1);
288     accept.addActionListener(this);
289     addSequences.addActionListener(this);
290     cancel.addActionListener(this);
291     this.add(buttonPanel, BorderLayout.SOUTH);
292     buttonPanel.add(accept, null);
293     buttonPanel.add(addSequences);
294     buttonPanel.add(cancel, null);
295     this.add(textarea, java.awt.BorderLayout.CENTER);
296   }
297
298   public void mousePressed(MouseEvent evt)
299   {
300     if (textarea.getText().startsWith("Paste your"))
301     {
302       textarea.setText("");
303     }
304   }
305
306   public void mouseReleased(MouseEvent evt)
307   {
308   }
309
310   public void mouseClicked(MouseEvent evt)
311   {
312   }
313
314   public void mouseEntered(MouseEvent evt)
315   {
316   }
317
318   public void mouseExited(MouseEvent evt)
319   {
320   }
321 }