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