Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
AnnotationExporter | 60 | 124 | 36 |
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.Color; | |
24 | import java.awt.Dimension; | |
25 | import java.awt.event.ActionEvent; | |
26 | import java.awt.event.ActionListener; | |
27 | import java.io.FileWriter; | |
28 | import java.io.PrintWriter; | |
29 | import java.util.Locale; | |
30 | ||
31 | import javax.swing.BoxLayout; | |
32 | import javax.swing.ButtonGroup; | |
33 | import javax.swing.JButton; | |
34 | import javax.swing.JCheckBox; | |
35 | import javax.swing.JInternalFrame; | |
36 | import javax.swing.JLabel; | |
37 | import javax.swing.JLayeredPane; | |
38 | import javax.swing.JPanel; | |
39 | import javax.swing.JRadioButton; | |
40 | import javax.swing.SwingConstants; | |
41 | ||
42 | import jalview.api.FeatureRenderer; | |
43 | import jalview.bin.Cache; | |
44 | import jalview.datamodel.AlignmentAnnotation; | |
45 | import jalview.datamodel.SequenceI; | |
46 | import jalview.io.AnnotationFile; | |
47 | import jalview.io.FeaturesFile; | |
48 | import jalview.io.JalviewFileChooser; | |
49 | import jalview.io.JalviewFileView; | |
50 | import jalview.util.MessageManager; | |
51 | ||
52 | /** | |
53 | * | |
54 | * GUI dialog for exporting features or alignment annotations depending upon | |
55 | * which method is called. | |
56 | * | |
57 | * @author AMW | |
58 | * | |
59 | */ | |
60 | public class AnnotationExporter extends JPanel | |
61 | { | |
62 | private JInternalFrame frame; | |
63 | ||
64 | private AlignmentPanel ap; | |
65 | ||
66 | /* | |
67 | * true if exporting features, false if exporting annotations | |
68 | */ | |
69 | private boolean exportFeatures = true; | |
70 | ||
71 | private AlignmentAnnotation[] annotations; | |
72 | ||
73 | private boolean wholeView; | |
74 | ||
75 | /* | |
76 | * option to export linked (CDS/peptide) features when shown | |
77 | * on the alignment, converted to this alignment's coordinates | |
78 | */ | |
79 | private JCheckBox includeLinkedFeatures; | |
80 | ||
81 | /* | |
82 | * output format option shown for feature export | |
83 | */ | |
84 | JRadioButton GFFFormat = new JRadioButton(); | |
85 | ||
86 | /* | |
87 | * output format option shown for annotation export | |
88 | */ | |
89 | JRadioButton CSVFormat = new JRadioButton(); | |
90 | ||
91 | private JPanel linkedFeaturesPanel; | |
92 | ||
93 | /** | |
94 | * Constructor | |
95 | * | |
96 | * @param panel | |
97 | */ | |
98 | 1 | public AnnotationExporter(AlignmentPanel panel) |
99 | { | |
100 | 1 | this.ap = panel; |
101 | 1 | try |
102 | { | |
103 | 1 | jbInit(); |
104 | } catch (Exception ex) | |
105 | { | |
106 | 0 | ex.printStackTrace(); |
107 | } | |
108 | ||
109 | 1 | frame = new JInternalFrame(); |
110 | 1 | frame.setFrameIcon(null); |
111 | 1 | frame.setContentPane(this); |
112 | 1 | frame.setLayer(JLayeredPane.PALETTE_LAYER); |
113 | 1 | Dimension preferredSize = frame.getPreferredSize(); |
114 | 1 | Desktop.addInternalFrame(frame, "", true, preferredSize.width, |
115 | preferredSize.height, true, true); | |
116 | } | |
117 | ||
118 | /** | |
119 | * Configures the dialog for options to export visible features. If from a | |
120 | * split frame panel showing linked features, make the option to include these | |
121 | * in the export visible. | |
122 | */ | |
123 | 0 | public void exportFeatures() |
124 | { | |
125 | 0 | exportFeatures = true; |
126 | 0 | CSVFormat.setVisible(false); |
127 | 0 | if (ap.av.isShowComplementFeatures()) |
128 | { | |
129 | 0 | linkedFeaturesPanel.setVisible(true); |
130 | 0 | frame.pack(); |
131 | } | |
132 | 0 | frame.setTitle(MessageManager.getString("label.export_features")); |
133 | } | |
134 | ||
135 | /** | |
136 | * Configures the dialog for options to export all visible annotations | |
137 | */ | |
138 | 1 | public void exportAnnotations() |
139 | { | |
140 | 1 | boolean showAnnotation = ap.av.isShowAnnotation(); |
141 | 1 | exportAnnotation(showAnnotation ? null |
142 | : ap.av.getAlignment().getAlignmentAnnotation(), true); | |
143 | } | |
144 | ||
145 | /** | |
146 | * Configures the dialog for options to export the given annotation row | |
147 | * | |
148 | * @param toExport | |
149 | */ | |
150 | 1 | public void exportAnnotation(AlignmentAnnotation toExport) |
151 | { | |
152 | 1 | exportAnnotation(new AlignmentAnnotation[] { toExport }, false); |
153 | } | |
154 | ||
155 | 2 | private void exportAnnotation(AlignmentAnnotation[] toExport, |
156 | boolean forWholeView) | |
157 | { | |
158 | 2 | wholeView = forWholeView; |
159 | 2 | annotations = toExport; |
160 | 2 | exportFeatures = false; |
161 | 2 | GFFFormat.setVisible(false); |
162 | 2 | CSVFormat.setVisible(true); |
163 | 2 | frame.setTitle(MessageManager.getString("label.export_annotations")); |
164 | } | |
165 | ||
166 | 1 | public void setExportAsCSV() |
167 | { | |
168 | 1 | if (CSVFormat != null) |
169 | { | |
170 | 1 | CSVFormat.setSelected(true); |
171 | } | |
172 | } | |
173 | ||
174 | 0 | private void toFile_actionPerformed() |
175 | { | |
176 | // TODO: JAL-3048 JalviewFileChooser - Save option | |
177 | 0 | JalviewFileChooser chooser = new JalviewFileChooser( |
178 | Cache.getProperty("LAST_DIRECTORY")); | |
179 | ||
180 | 0 | chooser.setFileView(new JalviewFileView()); |
181 | 0 | chooser.setDialogTitle(exportFeatures |
182 | ? MessageManager.getString("label.save_features_to_file") | |
183 | : MessageManager.getString("label.save_annotation_to_file")); | |
184 | 0 | chooser.setToolTipText(MessageManager.getString("action.save")); |
185 | ||
186 | 0 | int value = chooser.showSaveDialog(this); |
187 | ||
188 | 0 | if (value == JalviewFileChooser.APPROVE_OPTION) |
189 | { | |
190 | 0 | String text = getText(); |
191 | ||
192 | 0 | try |
193 | { | |
194 | 0 | PrintWriter out = new PrintWriter( |
195 | new FileWriter(chooser.getSelectedFile())); | |
196 | 0 | out.print(text); |
197 | 0 | out.close(); |
198 | } catch (Exception ex) | |
199 | { | |
200 | 0 | ex.printStackTrace(); |
201 | } | |
202 | } | |
203 | ||
204 | 0 | close_actionPerformed(); |
205 | } | |
206 | ||
207 | /** | |
208 | * Answers the text to output for either Features (in GFF or Jalview format) | |
209 | * or Annotations (in CSV or Jalview format) | |
210 | * | |
211 | * @return | |
212 | */ | |
213 | 0 | public String getText() |
214 | { | |
215 | 0 | return exportFeatures ? getFeaturesText() : getAnnotationsText(); |
216 | } | |
217 | ||
218 | /** | |
219 | * Returns the text contents for output of annotations in either CSV or | |
220 | * Jalview format | |
221 | * | |
222 | * @return | |
223 | */ | |
224 | 2 | public String getAnnotationsText() |
225 | { | |
226 | 2 | String text; |
227 | 2 | if (CSVFormat.isSelected()) |
228 | { | |
229 | 2 | text = new AnnotationFile().printCSVAnnotations( |
230 | 2 | wholeView ? ap.av.getAlignment().getAlignmentAnnotation() |
231 | : annotations); | |
232 | } | |
233 | else | |
234 | { | |
235 | 0 | if (wholeView) |
236 | { | |
237 | 0 | text = new AnnotationFile().printAnnotationsForView(ap.av); |
238 | } | |
239 | else | |
240 | { | |
241 | 0 | text = new AnnotationFile().printAnnotations(annotations, null, |
242 | null); | |
243 | } | |
244 | } | |
245 | 2 | return text; |
246 | } | |
247 | ||
248 | /** | |
249 | * Returns the text contents for output of features in either GFF or Jalview | |
250 | * format | |
251 | * | |
252 | * @return | |
253 | */ | |
254 | 0 | public String getFeaturesText() |
255 | { | |
256 | 0 | String text; |
257 | 0 | SequenceI[] sequences = ap.av.getAlignment().getSequencesArray(); |
258 | 0 | boolean includeNonPositional = ap.av.isShowNPFeats(); |
259 | ||
260 | 0 | FeaturesFile formatter = new FeaturesFile(); |
261 | 0 | final FeatureRenderer fr = ap.getFeatureRenderer(); |
262 | 0 | boolean includeComplement = includeLinkedFeatures.isSelected(); |
263 | ||
264 | 0 | if (GFFFormat.isSelected()) |
265 | { | |
266 | 0 | text = formatter.printGffFormat(sequences, fr, includeNonPositional, |
267 | includeComplement); | |
268 | } | |
269 | else | |
270 | { | |
271 | 0 | text = formatter.printJalviewFormat(sequences, fr, |
272 | includeNonPositional, includeComplement); | |
273 | } | |
274 | 0 | return text; |
275 | } | |
276 | ||
277 | 0 | private void toTextbox_actionPerformed() |
278 | { | |
279 | 0 | CutAndPasteTransfer cap = new CutAndPasteTransfer(); |
280 | ||
281 | 0 | try |
282 | { | |
283 | 0 | String text = getText(); |
284 | 0 | cap.setText(text); |
285 | 0 | Desktop.addInternalFrame(cap, (exportFeatures ? MessageManager |
286 | .formatMessage("label.features_for_params", new String[] | |
287 | { ap.alignFrame.getTitle() }) | |
288 | : MessageManager.formatMessage("label.annotations_for_params", | |
289 | new String[] | |
290 | { ap.alignFrame.getTitle() })), | |
291 | 600, 500); | |
292 | } catch (OutOfMemoryError oom) | |
293 | { | |
294 | 0 | new OOMWarning((exportFeatures ? MessageManager.formatMessage( |
295 | "label.generating_features_for_params", new String[] | |
296 | { ap.alignFrame.getTitle() }) | |
297 | : MessageManager.formatMessage( | |
298 | "label.generating_annotations_for_params", | |
299 | new String[] | |
300 | { ap.alignFrame.getTitle() })), | |
301 | oom); | |
302 | 0 | cap.dispose(); |
303 | } | |
304 | ||
305 | 0 | close_actionPerformed(); |
306 | } | |
307 | ||
308 | 0 | private void close_actionPerformed() |
309 | { | |
310 | 0 | try |
311 | { | |
312 | 0 | frame.setClosed(true); |
313 | } catch (java.beans.PropertyVetoException ex) | |
314 | { | |
315 | } | |
316 | } | |
317 | ||
318 | /** | |
319 | * Adds widgets to the panel | |
320 | * | |
321 | * @throws Exception | |
322 | */ | |
323 | 1 | private void jbInit() throws Exception |
324 | { | |
325 | 1 | this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
326 | 1 | this.setBackground(Color.white); |
327 | ||
328 | 1 | JPanel formatPanel = buildFormatOptionsPanel(); |
329 | 1 | JPanel linkedFeatures = buildLinkedFeaturesPanel(); |
330 | 1 | JPanel actionsPanel = buildActionsPanel(); |
331 | ||
332 | 1 | this.add(formatPanel); |
333 | 1 | this.add(linkedFeatures); |
334 | 1 | this.add(actionsPanel); |
335 | } | |
336 | ||
337 | /** | |
338 | * Builds a panel with a checkbox for the option to export linked | |
339 | * (CDS/peptide) features. This is hidden by default, and only made visible if | |
340 | * exporting features from a split frame panel which is configured to show | |
341 | * linked features. | |
342 | * | |
343 | * @return | |
344 | */ | |
345 | 1 | private JPanel buildLinkedFeaturesPanel() |
346 | { | |
347 | 1 | linkedFeaturesPanel = new JPanel(); |
348 | 1 | linkedFeaturesPanel.setOpaque(false); |
349 | ||
350 | 1 | boolean nucleotide = ap.av.isNucleotide(); |
351 | 1 | String complement = nucleotide ? MessageManager |
352 | .getString("label.protein").toLowerCase(Locale.ROOT) : "CDS"; | |
353 | 1 | JLabel label = new JLabel(MessageManager |
354 | .formatMessage("label.include_linked_features", complement)); | |
355 | 1 | label.setHorizontalAlignment(SwingConstants.TRAILING); |
356 | 1 | String tooltip = MessageManager |
357 | .formatMessage("label.include_linked_tooltip", complement); | |
358 | 1 | label.setToolTipText(JvSwingUtils.wrapTooltip(true, tooltip)); |
359 | ||
360 | 1 | includeLinkedFeatures = new JCheckBox(); |
361 | 1 | linkedFeaturesPanel.add(label); |
362 | 1 | linkedFeaturesPanel.add(includeLinkedFeatures); |
363 | 1 | linkedFeaturesPanel.setVisible(false); |
364 | ||
365 | 1 | return linkedFeaturesPanel; |
366 | } | |
367 | ||
368 | /** | |
369 | * Builds the panel with to File or Textbox or Close actions | |
370 | * | |
371 | * @return | |
372 | */ | |
373 | 1 | JPanel buildActionsPanel() |
374 | { | |
375 | 1 | JPanel actionsPanel = new JPanel(); |
376 | 1 | actionsPanel.setOpaque(false); |
377 | ||
378 | 1 | JButton toFile = new JButton(MessageManager.getString("label.to_file")); |
379 | 1 | toFile.addActionListener(new ActionListener() |
380 | { | |
381 | 0 | @Override |
382 | public void actionPerformed(ActionEvent e) | |
383 | { | |
384 | 0 | toFile_actionPerformed(); |
385 | } | |
386 | }); | |
387 | 1 | JButton toTextbox = new JButton( |
388 | MessageManager.getString("label.to_textbox")); | |
389 | 1 | toTextbox.addActionListener(new ActionListener() |
390 | { | |
391 | 0 | @Override |
392 | public void actionPerformed(ActionEvent e) | |
393 | { | |
394 | 0 | toTextbox_actionPerformed(); |
395 | } | |
396 | }); | |
397 | 1 | JButton close = new JButton(MessageManager.getString("action.close")); |
398 | 1 | close.addActionListener(new ActionListener() |
399 | { | |
400 | 0 | @Override |
401 | public void actionPerformed(ActionEvent e) | |
402 | { | |
403 | 0 | close_actionPerformed(); |
404 | } | |
405 | }); | |
406 | ||
407 | 1 | actionsPanel.add(toFile); |
408 | 1 | actionsPanel.add(toTextbox); |
409 | 1 | actionsPanel.add(close); |
410 | ||
411 | 1 | return actionsPanel; |
412 | } | |
413 | ||
414 | /** | |
415 | * Builds the panel with options to output in Jalview, GFF or CSV format. GFF | |
416 | * is only made visible when exporting features, CSV only when exporting | |
417 | * annotation. | |
418 | * | |
419 | * @return | |
420 | */ | |
421 | 1 | JPanel buildFormatOptionsPanel() |
422 | { | |
423 | 1 | JPanel formatPanel = new JPanel(); |
424 | // formatPanel.setBorder(BorderFactory.createEtchedBorder()); | |
425 | 1 | formatPanel.setOpaque(false); |
426 | ||
427 | 1 | JRadioButton jalviewFormat = new JRadioButton("Jalview"); |
428 | 1 | jalviewFormat.setOpaque(false); |
429 | 1 | jalviewFormat.setSelected(true); |
430 | 1 | GFFFormat.setOpaque(false); |
431 | 1 | GFFFormat.setText("GFF"); |
432 | 1 | CSVFormat.setOpaque(false); |
433 | 1 | CSVFormat.setText(MessageManager.getString("label.csv_spreadsheet")); |
434 | ||
435 | 1 | ButtonGroup buttonGroup = new ButtonGroup(); |
436 | 1 | buttonGroup.add(jalviewFormat); |
437 | 1 | buttonGroup.add(GFFFormat); |
438 | 1 | buttonGroup.add(CSVFormat); |
439 | ||
440 | 1 | JLabel format = new JLabel( |
441 | MessageManager.getString("action.format") + " "); | |
442 | 1 | format.setHorizontalAlignment(SwingConstants.TRAILING); |
443 | ||
444 | 1 | formatPanel.add(format); |
445 | 1 | formatPanel.add(jalviewFormat); |
446 | 1 | formatPanel.add(GFFFormat); |
447 | 1 | formatPanel.add(CSVFormat); |
448 | ||
449 | 1 | return formatPanel; |
450 | } | |
451 | } |