Merge branch 'JAL-3878_ws-overhaul-3' into with_ws_overhaul-3
[jalview.git] / src / jalview / gui / CutAndPasteTransfer.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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.gui;
22
23 import jalview.bin.Cache;
24 import jalview.api.AlignViewportI;
25 import jalview.api.AlignmentViewPanel;
26 import jalview.api.ComplexAlignFile;
27 import jalview.api.FeatureSettingsModelI;
28 import jalview.api.FeaturesDisplayedI;
29 import jalview.api.FeaturesSourceI;
30 import jalview.bin.Jalview;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.HiddenColumns;
33 import jalview.datamodel.SequenceI;
34 import jalview.io.AlignmentFileReaderI;
35 import jalview.io.AppletFormatAdapter;
36 import jalview.io.DataSourceType;
37 import jalview.io.FileFormatException;
38 import jalview.io.FileFormatI;
39 import jalview.io.FormatAdapter;
40 import jalview.io.IdentifyFile;
41 import jalview.io.JalviewFileChooser;
42 import jalview.io.JalviewFileView;
43 import jalview.jbgui.GCutAndPasteTransfer;
44 import jalview.json.binding.biojson.v1.ColourSchemeMapper;
45 import jalview.schemes.ColourSchemeI;
46 import jalview.util.MessageManager;
47
48 import java.awt.Toolkit;
49 import java.awt.datatransfer.Clipboard;
50 import java.awt.datatransfer.DataFlavor;
51 import java.awt.datatransfer.StringSelection;
52 import java.awt.datatransfer.Transferable;
53 import java.awt.event.ActionEvent;
54 import java.awt.event.ActionListener;
55 import java.awt.event.MouseEvent;
56 import java.io.FileWriter;
57 import java.io.IOException;
58 import java.io.PrintWriter;
59
60 import javax.swing.JMenuItem;
61 import javax.swing.JPopupMenu;
62 import javax.swing.SwingUtilities;
63
64 /**
65  * Cut'n'paste files into the desktop See JAL-1105
66  * 
67  * @author $author$
68  * @version $Revision$
69  */
70 public class CutAndPasteTransfer extends GCutAndPasteTransfer
71 {
72
73   AlignmentViewPanel alignpanel;
74
75   AlignViewportI viewport;
76
77   AlignmentFileReaderI source = null;
78
79   public CutAndPasteTransfer()
80   {
81     SwingUtilities.invokeLater(new Runnable()
82     {
83       @Override
84       public void run()
85       {
86         textarea.requestFocus();
87       }
88     });
89
90   }
91
92   /**
93    * DOCUMENT ME!
94    */
95   public void setForInput(AlignmentViewPanel viewpanel)
96   {
97     this.alignpanel = viewpanel;
98     if (alignpanel != null)
99     {
100       this.viewport = alignpanel.getAlignViewport();
101     }
102     if (viewport != null)
103     {
104       ok.setText(MessageManager.getString("action.add"));
105     }
106
107     getContentPane().add(inputButtonPanel, java.awt.BorderLayout.SOUTH);
108   }
109
110   /**
111    * DOCUMENT ME!
112    * 
113    * @return DOCUMENT ME!
114    */
115   public String getText()
116   {
117     return textarea.getText();
118   }
119
120   /**
121    * DOCUMENT ME!
122    * 
123    * @param text
124    *          DOCUMENT ME!
125    */
126   public void setText(String text)
127   {
128     textarea.setText(text);
129   }
130
131   public void appendText(String text)
132   {
133     textarea.append(text);
134   }
135
136   @Override
137   public void save_actionPerformed(ActionEvent e)
138   {
139     // TODO: JAL-3048 JalviewFileChooser - Save option
140
141     JalviewFileChooser chooser = new JalviewFileChooser(
142             Cache.getProperty("LAST_DIRECTORY"));
143
144     chooser.setAcceptAllFileFilterUsed(false);
145     chooser.setFileView(new JalviewFileView());
146     chooser.setDialogTitle(
147             MessageManager.getString("label.save_text_to_file"));
148     chooser.setToolTipText(MessageManager.getString("action.save"));
149
150     int value = chooser.showSaveDialog(this);
151
152     if (value == JalviewFileChooser.APPROVE_OPTION)
153     {
154       try
155       {
156         PrintWriter out = new PrintWriter(
157                 new FileWriter(chooser.getSelectedFile()));
158
159         out.print(getText());
160         out.close();
161       } catch (Exception ex)
162       {
163         ex.printStackTrace();
164       }
165
166     }
167   }
168
169   /**
170    * DOCUMENT ME!
171    * 
172    * @param e
173    *          DOCUMENT ME!
174    */
175   @Override
176   public void copyItem_actionPerformed(ActionEvent e)
177   {
178     textarea.getSelectedText();
179     Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
180     c.setContents(new StringSelection(textarea.getSelectedText()), null);
181   }
182
183   /**
184    * DOCUMENT ME!
185    * 
186    * @param e
187    *          DOCUMENT ME!
188    */
189   @Override
190   public void pasteMenu_actionPerformed(ActionEvent e)
191   {
192     Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
193     Transferable contents = c.getContents(this);
194
195     if (contents == null)
196     {
197       return;
198     }
199
200     try
201     {
202       textarea.append(
203               (String) contents.getTransferData(DataFlavor.stringFlavor));
204     } catch (Exception ex)
205     {
206     }
207   }
208
209   /**
210    * DOCUMENT ME!
211    * 
212    * @param e
213    *          DOCUMENT ME!
214    */
215   @Override
216   public void ok_actionPerformed(ActionEvent e)
217   {
218     String text = getText();
219     if (text.trim().length() < 1)
220     {
221       return;
222     }
223
224     FileFormatI format = null;
225     try
226     {
227       format = new IdentifyFile().identify(text, DataSourceType.PASTE);
228     } catch (FileFormatException e1)
229     {
230       // leave as null
231     }
232     if (format == null)
233     {
234       System.err
235               .println(MessageManager.getString("label.couldnt_read_data"));
236       if (!Jalview.isHeadlessMode())
237       {
238         JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
239                 AppletFormatAdapter.getSupportedFormats(),
240                 MessageManager.getString("label.couldnt_read_data"),
241                 JvOptionPane.WARNING_MESSAGE);
242       }
243       return;
244     }
245
246     // TODO: identify feature, annotation or tree file and parse appropriately.
247     AlignmentI al = null;
248
249     try
250     {
251       FormatAdapter fa = new FormatAdapter(alignpanel);
252       al = fa.readFile(getText(), DataSourceType.PASTE, format);
253       source = fa.getAlignFile();
254
255     } catch (IOException ex)
256     {
257       JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), MessageManager
258               .formatMessage("label.couldnt_read_pasted_text", new String[]
259               { ex.toString() }),
260               MessageManager.getString("label.error_parsing_text"),
261               JvOptionPane.WARNING_MESSAGE);
262     }
263
264     if (al != null && al.hasValidSequence())
265     {
266       String title = MessageManager
267               .formatMessage("label.input_cut_paste_params", new String[]
268               { format.getName() });
269       FeatureSettingsModelI proxyColourScheme = source
270               .getFeatureColourScheme();
271
272       /*
273        * if the view panel was closed its alignment is nulled
274        * and this is an orphaned cut and paste window
275        */
276       if (viewport != null && viewport.getAlignment() != null)
277       {
278         ((AlignViewport) viewport).addAlignment(al, title);
279         viewport.applyFeaturesStyle(proxyColourScheme);
280       }
281       else
282       {
283
284         AlignFrame af;
285         if (source instanceof ComplexAlignFile)
286         {
287           HiddenColumns hidden = ((ComplexAlignFile) source)
288                   .getHiddenColumns();
289           SequenceI[] hiddenSeqs = ((ComplexAlignFile) source)
290                   .getHiddenSequences();
291           boolean showSeqFeatures = ((ComplexAlignFile) source)
292                   .isShowSeqFeatures();
293           String colourSchemeName = ((ComplexAlignFile) source)
294                   .getGlobalColourScheme();
295           FeaturesDisplayedI fd = ((ComplexAlignFile) source)
296                   .getDisplayedFeatures();
297           af = new AlignFrame(al, hiddenSeqs, hidden,
298                   AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
299           af.getViewport().setShowSequenceFeatures(showSeqFeatures);
300           af.getViewport().setFeaturesDisplayed(fd);
301           af.setMenusForViewport();
302           ColourSchemeI cs = ColourSchemeMapper
303                   .getJalviewColourScheme(colourSchemeName, al);
304           if (cs != null)
305           {
306             af.changeColour(cs);
307           }
308         }
309         else
310         {
311           af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
312                   AlignFrame.DEFAULT_HEIGHT);
313           if (source instanceof FeaturesSourceI)
314           {
315             af.getViewport().setShowSequenceFeatures(true);
316           }
317         }
318         if (proxyColourScheme != null)
319         {
320           af.getViewport().applyFeaturesStyle(proxyColourScheme);
321         }
322         af.currentFileFormat = format;
323         Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH,
324                 AlignFrame.DEFAULT_HEIGHT);
325         af.setStatus(MessageManager
326                 .getString("label.successfully_pasted_alignment_file"));
327
328         try
329         {
330           af.setMaximum(Cache.getDefault("SHOW_FULLSCREEN", false));
331         } catch (Exception ex)
332         {
333         }
334       }
335     }
336     else
337     {
338       System.err
339               .println(MessageManager.getString("label.couldnt_read_data"));
340       if (!Jalview.isHeadlessMode())
341       {
342         JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
343                 AppletFormatAdapter.getSupportedFormats(),
344                 MessageManager.getString("label.couldnt_read_data"),
345                 JvOptionPane.WARNING_MESSAGE);
346       }
347     }
348   }
349
350   /**
351    * DOCUMENT ME!
352    * 
353    * @param e
354    *          DOCUMENT ME!
355    */
356   @Override
357   public void cancel_actionPerformed(ActionEvent e)
358   {
359     try
360     {
361       this.setClosed(true);
362     } catch (Exception ex)
363     {
364     }
365   }
366
367   @Override
368   public void textarea_mousePressed(MouseEvent e)
369   {
370     /*
371      * isPopupTrigger is checked in mousePressed on Mac,
372      * in mouseReleased on Windows
373      */
374     if (e.isPopupTrigger())
375     {
376       JPopupMenu popup = new JPopupMenu(
377               MessageManager.getString("action.edit"));
378       JMenuItem item = new JMenuItem(
379               MessageManager.getString("action.copy"));
380       item.addActionListener(new ActionListener()
381       {
382         @Override
383         public void actionPerformed(ActionEvent e)
384         {
385           copyItem_actionPerformed(e);
386         }
387       });
388       popup.add(item);
389       item = new JMenuItem(MessageManager.getString("action.paste"));
390       item.addActionListener(new ActionListener()
391       {
392         @Override
393         public void actionPerformed(ActionEvent e)
394         {
395           pasteMenu_actionPerformed(e);
396         }
397       });
398       popup.add(item);
399       popup.show(this, e.getX() + 10, e.getY() + textarea.getY() + 40);
400
401     }
402   }
403
404 }