JAL-2791 refactored Export Features to apply all visibility tests
[jalview.git] / src / jalview / gui / AnnotationExporter.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.api.FeatureRenderer;
24 import jalview.bin.Cache;
25 import jalview.datamodel.AlignmentAnnotation;
26 import jalview.datamodel.SequenceI;
27 import jalview.io.AnnotationFile;
28 import jalview.io.FeaturesFile;
29 import jalview.io.JalviewFileChooser;
30 import jalview.io.JalviewFileView;
31 import jalview.util.MessageManager;
32
33 import java.awt.BorderLayout;
34 import java.awt.Color;
35 import java.awt.FlowLayout;
36 import java.awt.event.ActionEvent;
37 import java.awt.event.ActionListener;
38 import java.io.FileWriter;
39 import java.io.PrintWriter;
40
41 import javax.swing.BorderFactory;
42 import javax.swing.ButtonGroup;
43 import javax.swing.JButton;
44 import javax.swing.JInternalFrame;
45 import javax.swing.JLabel;
46 import javax.swing.JLayeredPane;
47 import javax.swing.JPanel;
48 import javax.swing.JRadioButton;
49 import javax.swing.SwingConstants;
50
51 /**
52  * 
53  * GUI dialog for exporting features or alignment annotations depending upon
54  * which method is called.
55  * 
56  * @author AMW
57  * 
58  */
59 public class AnnotationExporter extends JPanel
60 {
61   private JInternalFrame frame;
62
63   private AlignmentPanel ap;
64
65   /*
66    * true if exporting features, false if exporting annotations
67    */
68   private boolean exportFeatures = true;
69
70   private AlignmentAnnotation[] annotations;
71
72   private boolean wholeView;
73
74   public AnnotationExporter(AlignmentPanel panel)
75   {
76     this.ap = panel;
77     try
78     {
79       jbInit();
80     } catch (Exception ex)
81     {
82       ex.printStackTrace();
83     }
84
85     frame = new JInternalFrame();
86     frame.setContentPane(this);
87     frame.setLayer(JLayeredPane.PALETTE_LAYER);
88     Desktop.addInternalFrame(frame, "", frame.getPreferredSize().width,
89             frame.getPreferredSize().height);
90   }
91
92   /**
93    * Configures the diglog for options to export visible features
94    */
95   public void exportFeatures()
96   {
97     exportFeatures = true;
98     CSVFormat.setVisible(false);
99     frame.setTitle(MessageManager.getString("label.export_features"));
100   }
101
102   /**
103    * Configures the dialog for options to export all visible annotations
104    */
105   public void exportAnnotations()
106   {
107     boolean showAnnotation = ap.av.isShowAnnotation();
108     exportAnnotation(showAnnotation ? null
109             : ap.av.getAlignment().getAlignmentAnnotation(), true);
110   }
111
112   /**
113    * Configures the dialog for options to export the given annotation row
114    * 
115    * @param toExport
116    */
117   public void exportAnnotation(AlignmentAnnotation toExport)
118   {
119     exportAnnotation(new AlignmentAnnotation[] { toExport }, false);
120   }
121
122   private void exportAnnotation(AlignmentAnnotation[] toExport,
123           boolean forWholeView)
124   {
125     wholeView = forWholeView;
126     annotations = toExport;
127     exportFeatures = false;
128     GFFFormat.setVisible(false);
129     CSVFormat.setVisible(true);
130     frame.setTitle(MessageManager.getString("label.export_annotations"));
131   }
132
133   private void toFile_actionPerformed()
134   {
135     JalviewFileChooser chooser = new JalviewFileChooser(
136             Cache.getProperty("LAST_DIRECTORY"));
137
138     chooser.setFileView(new JalviewFileView());
139     chooser.setDialogTitle(exportFeatures
140             ? MessageManager.getString("label.save_features_to_file")
141             : MessageManager.getString("label.save_annotation_to_file"));
142     chooser.setToolTipText(MessageManager.getString("action.save"));
143
144     int value = chooser.showSaveDialog(this);
145
146     if (value == JalviewFileChooser.APPROVE_OPTION)
147     {
148       String text = getText();
149
150       try
151       {
152         PrintWriter out = new PrintWriter(
153                 new FileWriter(chooser.getSelectedFile()));
154         out.print(text);
155         out.close();
156       } catch (Exception ex)
157       {
158         ex.printStackTrace();
159       }
160     }
161
162     close_actionPerformed();
163   }
164
165   /**
166    * Answers the text to output for either Features (in GFF or Jalview format) or
167    * Annotations (in CSV or Jalview format)
168    * 
169    * @return
170    */
171   private String getText()
172   {
173     return exportFeatures ? getFeaturesText() : getAnnotationsText();
174   }
175
176   /**
177    * Returns the text contents for output of annotations in either CSV or Jalview
178    * format
179    * 
180    * @return
181    */
182   private String getAnnotationsText()
183   {
184     String text;
185     if (CSVFormat.isSelected())
186     {
187       text = new AnnotationFile().printCSVAnnotations(annotations);
188     }
189     else
190     {
191       if (wholeView)
192       {
193         text = new AnnotationFile().printAnnotationsForView(ap.av);
194       }
195       else
196       {
197         text = new AnnotationFile().printAnnotations(annotations, null,
198                 null);
199       }
200     }
201     return text;
202   }
203
204   /**
205    * Returns the text contents for output of features in either GFF or Jalview
206    * format
207    * 
208    * @return
209    */
210   private String getFeaturesText()
211   {
212     String text;
213     SequenceI[] sequences = ap.av.getAlignment().getSequencesArray();
214     boolean includeNonPositional = ap.av.isShowNPFeats();
215
216     FeaturesFile formatter = new FeaturesFile();
217     final FeatureRenderer fr = ap.getFeatureRenderer();
218     if (GFFFormat.isSelected())
219     {
220       text = formatter.printGffFormat(sequences, fr, includeNonPositional);
221     }
222     else
223     {
224       text = formatter.printJalviewFormat(sequences, fr,
225               includeNonPositional);
226     }
227     return text;
228   }
229
230   private void toTextbox_actionPerformed()
231   {
232     CutAndPasteTransfer cap = new CutAndPasteTransfer();
233
234     try
235     {
236       String text = getText();
237       cap.setText(text);
238       Desktop.addInternalFrame(cap, (exportFeatures ? MessageManager
239               .formatMessage("label.features_for_params", new String[]
240               { ap.alignFrame.getTitle() })
241               : MessageManager.formatMessage("label.annotations_for_params",
242                       new String[]
243                       { ap.alignFrame.getTitle() })),
244               600, 500);
245     } catch (OutOfMemoryError oom)
246     {
247       new OOMWarning((exportFeatures ? MessageManager.formatMessage(
248               "label.generating_features_for_params", new String[]
249               { ap.alignFrame.getTitle() })
250               : MessageManager.formatMessage(
251                       "label.generating_annotations_for_params",
252                       new String[]
253                       { ap.alignFrame.getTitle() })),
254               oom);
255       cap.dispose();
256     }
257
258     close_actionPerformed();
259   }
260
261   private void close_actionPerformed()
262   {
263     try
264     {
265       frame.setClosed(true);
266     } catch (java.beans.PropertyVetoException ex)
267     {
268     }
269   }
270
271   private void jbInit() throws Exception
272   {
273     this.setLayout(new BorderLayout());
274
275     toFile.setText(MessageManager.getString("label.to_file"));
276     toFile.addActionListener(new ActionListener()
277     {
278       @Override
279       public void actionPerformed(ActionEvent e)
280       {
281         toFile_actionPerformed();
282       }
283     });
284     toTextbox.setText(MessageManager.getString("label.to_textbox"));
285     toTextbox.addActionListener(new ActionListener()
286     {
287       @Override
288       public void actionPerformed(ActionEvent e)
289       {
290         toTextbox_actionPerformed();
291       }
292     });
293     close.setText(MessageManager.getString("action.close"));
294     close.addActionListener(new ActionListener()
295     {
296       @Override
297       public void actionPerformed(ActionEvent e)
298       {
299         close_actionPerformed();
300       }
301     });
302     jalviewFormat.setOpaque(false);
303     jalviewFormat.setSelected(true);
304     jalviewFormat.setText("Jalview");
305     GFFFormat.setOpaque(false);
306     GFFFormat.setText("GFF");
307     CSVFormat.setOpaque(false);
308     CSVFormat.setText(MessageManager.getString("label.csv_spreadsheet"));
309     jLabel1.setHorizontalAlignment(SwingConstants.TRAILING);
310     jLabel1.setText(MessageManager.getString("action.format") + " ");
311     this.setBackground(Color.white);
312     jPanel3.setBorder(BorderFactory.createEtchedBorder());
313     jPanel3.setOpaque(false);
314     jPanel1.setOpaque(false);
315     jPanel1.add(toFile);
316     jPanel1.add(toTextbox);
317     jPanel1.add(close);
318     jPanel3.add(jLabel1);
319     jPanel3.add(jalviewFormat);
320     jPanel3.add(GFFFormat);
321     jPanel3.add(CSVFormat);
322     buttonGroup.add(jalviewFormat);
323     buttonGroup.add(GFFFormat);
324     buttonGroup.add(CSVFormat);
325     this.add(jPanel3, BorderLayout.CENTER);
326     this.add(jPanel1, BorderLayout.SOUTH);
327   }
328
329   JPanel jPanel1 = new JPanel();
330
331   JButton toFile = new JButton();
332
333   JButton toTextbox = new JButton();
334
335   JButton close = new JButton();
336
337   ButtonGroup buttonGroup = new ButtonGroup();
338
339   JRadioButton jalviewFormat = new JRadioButton();
340
341   JRadioButton GFFFormat = new JRadioButton();
342
343   JRadioButton CSVFormat = new JRadioButton();
344
345   JLabel jLabel1 = new JLabel();
346
347   JPanel jPanel3 = new JPanel();
348
349   FlowLayout flowLayout1 = new FlowLayout();
350 }