JAL-1665 create dataset sequences in applet
[jalview.git] / src / jalview / appletgui / CutAndPasteTransfer.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 The Jalview Authors
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
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.appletgui;
22
23 import jalview.datamodel.Alignment;
24 import jalview.datamodel.PDBEntry;
25 import jalview.datamodel.Sequence;
26 import jalview.io.AnnotationFile;
27 import jalview.io.AppletFormatAdapter;
28 import jalview.io.IdentifyFile;
29 import jalview.io.NewickFile;
30 import jalview.io.TCoffeeScoreFile;
31 import jalview.schemes.TCoffeeColourScheme;
32 import jalview.util.MessageManager;
33
34 import java.awt.BorderLayout;
35 import java.awt.Button;
36 import java.awt.Dialog;
37 import java.awt.Font;
38 import java.awt.Frame;
39 import java.awt.Panel;
40 import java.awt.TextArea;
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.event.MouseEvent;
44 import java.awt.event.MouseListener;
45
46 public class CutAndPasteTransfer extends Panel implements ActionListener,
47         MouseListener
48 {
49   boolean pdbImport = false;
50
51   boolean treeImport = false;
52
53   boolean annotationImport = false;
54
55   Sequence seq;
56
57   AlignFrame alignFrame;
58
59   public CutAndPasteTransfer(boolean forImport, AlignFrame alignFrame)
60   {
61     try
62     {
63       jbInit();
64     } catch (Exception e)
65     {
66       e.printStackTrace();
67     }
68
69     this.alignFrame = alignFrame;
70
71     if (!forImport)
72     {
73       buttonPanel.setVisible(false);
74     }
75   }
76
77   public String getText()
78   {
79     return textarea.getText();
80   }
81
82   public void setText(String text)
83   {
84     textarea.setText(text);
85   }
86
87   public void setPDBImport(Sequence seq)
88   {
89     this.seq = seq;
90     accept.setLabel(MessageManager.getString("action.accept"));
91     addSequences.setVisible(false);
92     pdbImport = true;
93   }
94
95   public void setTreeImport()
96   {
97     treeImport = true;
98     accept.setLabel(MessageManager.getString("action.accept"));
99     addSequences.setVisible(false);
100   }
101
102   public void setAnnotationImport()
103   {
104     annotationImport = true;
105     accept.setLabel(MessageManager.getString("action.accept"));
106     addSequences.setVisible(false);
107   }
108
109   public void actionPerformed(ActionEvent evt)
110   {
111     if (evt.getSource() == accept)
112     {
113       ok(true);
114     }
115     else if (evt.getSource() == addSequences)
116     {
117       ok(false);
118     }
119     else if (evt.getSource() == cancel)
120     {
121       cancel();
122     }
123   }
124
125   protected void ok(boolean newWindow)
126   {
127     String text = getText();
128     int length = text.length();
129     textarea.append("\n");
130     if (textarea.getText().length() == length)
131     {
132       String warning = "\n\n#################################################\n"
133               + "WARNING!! THIS IS THE MAXIMUM SIZE OF TEXTAREA!!\n"
134               + "\nCAN'T INPUT FULL ALIGNMENT"
135               + "\n\nYOU MUST DELETE THIS WARNING TO CONTINUE"
136               + "\n\nMAKE SURE LAST SEQUENCE PASTED IS COMPLETE"
137               + "\n#################################################\n";
138       textarea.setText(text.substring(0, text.length() - warning.length())
139               + warning);
140
141       textarea.setCaretPosition(text.length());
142     }
143
144     if (pdbImport)
145     {
146       openPdbViewer(text);
147
148     }
149     else if (treeImport)
150     {
151       if (!loadTree())
152       {
153         return;
154       }
155     }
156     else if (annotationImport)
157     {
158       loadAnnotations();
159     }
160     else if (alignFrame != null)
161     {
162       loadAlignment(text, newWindow);
163     }
164
165     // TODO: dialog should indicate if data was parsed correctly or not - see
166     // JAL-1102
167     if (this.getParent() instanceof Frame)
168     {
169       ((Frame) this.getParent()).setVisible(false);
170     }
171     else
172     {
173       ((Dialog) this.getParent()).setVisible(false);
174     }
175   }
176
177   /**
178    * Parses text as Newick Tree format, and loads on to the alignment. Returns
179    * true if successful, else false.
180    */
181   protected boolean loadTree()
182   {
183     try
184     {
185       NewickFile fin = new NewickFile(textarea.getText(), "Paste");
186
187       fin.parse();
188       if (fin.getTree() != null)
189       {
190         alignFrame.loadTree(fin, "Pasted tree file");
191         return true;
192       }
193     } catch (Exception ex)
194     {
195       // TODO: JAL-1102 - should have a warning message in dialog, not simply
196       // overwrite the broken input data with the exception
197       textarea.setText(MessageManager.formatMessage(
198               "label.could_not_parse_newick_file", new Object[]
199               { ex.getMessage() }));
200       return false;
201     }
202     return false;
203   }
204
205   /**
206    * Parse text as an alignment file and add to the current or a new window.
207    * 
208    * @param text
209    * @param newWindow
210    */
211   protected void loadAlignment(String text, boolean newWindow)
212   {
213     Alignment al = null;
214
215     String format = new IdentifyFile().Identify(text,
216             AppletFormatAdapter.PASTE);
217     try
218     {
219       al = new AppletFormatAdapter().readFile(text,
220               AppletFormatAdapter.PASTE, format);
221     } catch (java.io.IOException ex)
222     {
223       ex.printStackTrace();
224     }
225
226     if (al != null)
227     {
228       al.setDataset(null);
229       if (newWindow)
230       {
231         AlignFrame af = new AlignFrame(al, alignFrame.viewport.applet,
232                 "Cut & Paste input - " + format, false);
233         af.statusBar
234                 .setText(MessageManager
235                         .getString("label.successfully_pasted_annotation_to_alignment"));
236       }
237       else
238       {
239         alignFrame.addSequences(al.getSequencesArray());
240         alignFrame.statusBar.setText(MessageManager
241                 .getString("label.successfully_pasted_alignment_file"));
242       }
243     }
244   }
245
246   /**
247    * Parse the text as a TCoffee score file, if successful add scores as
248    * alignment annotations.
249    */
250   protected void loadAnnotations()
251   {
252     TCoffeeScoreFile tcf = null;
253     try
254     {
255       tcf = new TCoffeeScoreFile(textarea.getText(),
256               jalview.io.AppletFormatAdapter.PASTE);
257       if (tcf.isValid())
258       {
259         if (tcf.annotateAlignment(alignFrame.viewport.getAlignment(),
260                 true))
261         {
262           alignFrame.tcoffeeColour.setEnabled(true);
263           alignFrame.alignPanel.fontChanged();
264           alignFrame.changeColour(new TCoffeeColourScheme(
265                   alignFrame.viewport.getAlignment()));
266           alignFrame.statusBar
267                   .setText(MessageManager
268                           .getString("label.successfully_pasted_tcoffee_scores_to_alignment"));
269         }
270         else
271         {
272           // file valid but didn't get added to alignment for some reason
273           alignFrame.statusBar.setText(MessageManager.formatMessage(
274                   "label.failed_add_tcoffee_scores",
275                   new Object[]
276                   { (tcf.getWarningMessage() != null ? tcf
277                           .getWarningMessage() : "") }));
278         }
279       }
280       else
281       {
282         tcf = null;
283       }
284     } catch (Exception x)
285     {
286       tcf = null;
287     }
288     if (tcf == null)
289     {
290       if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport,
291               textarea.getText(),
292               jalview.io.AppletFormatAdapter.PASTE))
293       {
294         alignFrame.alignPanel.fontChanged();
295         alignFrame.alignPanel.setScrollValues(0, 0);
296         alignFrame.statusBar
297                 .setText(MessageManager
298                         .getString("label.successfully_pasted_annotation_to_alignment"));
299
300       }
301       else
302       {
303         if (!alignFrame.parseFeaturesFile(textarea.getText(),
304                 jalview.io.AppletFormatAdapter.PASTE))
305         {
306           alignFrame.statusBar
307                   .setText(MessageManager
308                           .getString("label.couldnt_parse_pasted_text_as_valid_annotation_feature_GFF_tcoffee_file"));
309         }
310       }
311     }
312   }
313
314   /**
315    * Open a Jmol viewer (if available), failing that the built-in PDB viewer,
316    * passing the input text as the PDB file data.
317    * 
318    * @param text
319    */
320   protected void openPdbViewer(String text)
321   {
322     PDBEntry pdb = new PDBEntry();
323     pdb.setFile(text);
324
325     if (alignFrame.alignPanel.av.applet.jmolAvailable)
326     {
327       new jalview.appletgui.AppletJmol(pdb, new Sequence[]
328       { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE);
329     }
330     else
331     {
332       new MCview.AppletPDBViewer(pdb, new Sequence[]
333       { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE);
334     }
335   }
336
337   protected void cancel()
338   {
339     textarea.setText("");
340     if (this.getParent() instanceof Frame)
341     {
342       ((Frame) this.getParent()).setVisible(false);
343     }
344     else
345     {
346       ((Dialog) this.getParent()).setVisible(false);
347     }
348   }
349
350   protected TextArea textarea = new TextArea();
351
352   Button accept = new Button("New Window");
353
354   Button addSequences = new Button("Add to Current Alignment");
355
356   Button cancel = new Button("Close");
357
358   protected Panel buttonPanel = new Panel();
359
360   BorderLayout borderLayout1 = new BorderLayout();
361
362   private void jbInit() throws Exception
363   {
364     textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 10));
365     textarea.setText(MessageManager
366             .getString("label.paste_your_alignment_file"));
367     textarea.addMouseListener(this);
368     this.setLayout(borderLayout1);
369     accept.addActionListener(this);
370     addSequences.addActionListener(this);
371     cancel.addActionListener(this);
372     this.add(buttonPanel, BorderLayout.SOUTH);
373     buttonPanel.add(accept, null);
374     buttonPanel.add(addSequences);
375     buttonPanel.add(cancel, null);
376     this.add(textarea, java.awt.BorderLayout.CENTER);
377   }
378
379   public void mousePressed(MouseEvent evt)
380   {
381     if (textarea.getText().startsWith(
382             MessageManager.getString("label.paste_your")))
383     {
384       textarea.setText("");
385     }
386   }
387
388   public void mouseReleased(MouseEvent evt)
389   {
390   }
391
392   public void mouseClicked(MouseEvent evt)
393   {
394   }
395
396   public void mouseEntered(MouseEvent evt)
397   {
398   }
399
400   public void mouseExited(MouseEvent evt)
401   {
402   }
403 }