Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID
[jalview.git] / src / jalview / gui / AlignExportOptions.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.BorderLayout;
24 import java.awt.FlowLayout;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.ItemEvent;
28 import java.awt.event.ItemListener;
29
30 import javax.swing.JCheckBox;
31 import javax.swing.JPanel;
32
33 import jalview.api.AlignExportSettingsI;
34 import jalview.api.AlignViewportI;
35 import jalview.bin.Jalview;
36 import jalview.io.FileFormatI;
37 import jalview.util.MessageManager;
38
39 /**
40  * A dialog that allows the user to specify whether to include hidden columns or
41  * sequences in an alignment export, and possibly features, annotations and
42  * groups, if applicable to the output file format
43  */
44 @SuppressWarnings("serial")
45 public class AlignExportOptions extends JPanel
46 {
47   protected JCheckBox chkHiddenSeqs = new JCheckBox();
48
49   protected JCheckBox chkHiddenCols = new JCheckBox();
50
51   protected JCheckBox chkExportAnnots = new JCheckBox();
52
53   protected JCheckBox chkExportFeats = new JCheckBox();
54
55   protected JCheckBox chkExportGrps = new JCheckBox();
56
57   protected AlignExportSettingsI settings;
58
59   private boolean isComplexAlignFile;
60
61   JvOptionPane dialog;
62
63   /**
64    * A convenience method that answers true if this dialog should be shown -
65    * that is, if the alignment has any hidden rows or columns, or if the file
66    * format is one that can (optionally) represent annotations, features or
67    * groups data - else false
68    * 
69    * @param viewport
70    * @param format
71    * @return
72    */
73   public static boolean isNeeded(AlignViewportI viewport,
74           FileFormatI format)
75   {
76     return !Jalview.getInstance().isHeadlessMode()
77             && (viewport.hasHiddenColumns() || viewport.hasHiddenRows()
78                     || format.isComplexAlignFile());
79   }
80
81   /**
82    * Constructor that passes in an initial set of export options. User choices
83    * in the dialog should update this object, and the <em>same</em> object
84    * should be used in any action handler set by calling
85    * <code>setResponseAction</code>.
86    * 
87    * @param viewport
88    * @param format
89    * @param defaults
90    */
91   public AlignExportOptions(AlignViewportI viewport, FileFormatI format,
92           AlignExportSettingsI defaults)
93   {
94     this.settings = defaults;
95     this.isComplexAlignFile = format.isComplexAlignFile();
96     init(viewport.hasHiddenRows(), viewport.hasHiddenColumns());
97     dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
98   }
99
100   /**
101    * Shows the dialog, and runs any registered response actions that correspond
102    * to user choices
103    */
104   public void showDialog()
105   {
106     Object[] options = new Object[] { MessageManager.getString("action.ok"),
107         MessageManager.getString("action.cancel") };
108     dialog.showInternalDialog(this,
109             MessageManager.getString("label.export_settings"),
110             JvOptionPane.OK_CANCEL_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
111             options, MessageManager.getString("action.ok"));
112   }
113
114   /**
115    * Registers a Runnable action to be performed for a particular user response
116    * in the dialog
117    * 
118    * @param action
119    */
120   public void setResponseAction(Object response, Runnable action)
121   {
122     dialog.setResponseHandler(response, action);
123   }
124
125   /**
126    * Selects/deselects all enabled and shown options on 'Check all' selected or
127    * deselected
128    * 
129    * @param isSelected
130    */
131   void checkAllAction(boolean isSelected)
132   {
133     boolean set = chkHiddenSeqs.isEnabled() && isSelected;
134     chkHiddenSeqs.setSelected(set);
135     settings.setExportHiddenSequences(set);
136
137     set = chkHiddenCols.isEnabled() && isSelected;
138     chkHiddenCols.setSelected(set);
139     settings.setExportHiddenColumns(set);
140
141     set = isComplexAlignFile && chkExportAnnots.isEnabled() && isSelected;
142     chkExportAnnots.setSelected(set);
143     settings.setExportAnnotations(set);
144
145     set = isComplexAlignFile && chkExportFeats.isEnabled() && isSelected;
146     chkExportFeats.setSelected(set);
147     settings.setExportFeatures(set);
148
149     set = isComplexAlignFile && chkExportGrps.isEnabled() && isSelected;
150     chkExportGrps.setSelected(set);
151     settings.setExportGroups(set);
152   }
153
154   /**
155    * Initialises the components of the display
156    * 
157    * @param hasHiddenSeq
158    * @param hasHiddenCols
159    */
160   private void init(boolean hasHiddenSeq, boolean hasHiddenCols)
161   {
162     chkHiddenSeqs.setText(
163             MessageManager.getString("action.export_hidden_sequences"));
164     chkHiddenSeqs.addActionListener(new ActionListener()
165     {
166       @Override
167       public void actionPerformed(ActionEvent e)
168       {
169         settings.setExportHiddenSequences(chkHiddenSeqs.isSelected());
170       }
171     });
172
173     chkHiddenCols.setText(
174             MessageManager.getString("action.export_hidden_columns"));
175     chkHiddenCols.addActionListener(new ActionListener()
176     {
177       @Override
178       public void actionPerformed(ActionEvent e)
179       {
180         settings.setExportHiddenColumns(chkHiddenCols.isSelected());
181       }
182     });
183
184     chkExportAnnots
185             .setText(MessageManager.getString("action.export_annotations"));
186     chkExportAnnots.addActionListener(new ActionListener()
187     {
188       @Override
189       public void actionPerformed(ActionEvent e)
190       {
191         settings.setExportAnnotations(chkExportAnnots.isSelected());
192       }
193     });
194
195     chkExportFeats
196             .setText(MessageManager.getString("action.export_features"));
197     chkExportFeats.addActionListener(new ActionListener()
198     {
199       @Override
200       public void actionPerformed(ActionEvent e)
201       {
202         settings.setExportFeatures(chkExportFeats.isSelected());
203       }
204     });
205
206     chkExportGrps.setText(MessageManager.getString("action.export_groups"));
207     chkExportGrps.addActionListener(new ActionListener()
208     {
209       @Override
210       public void actionPerformed(ActionEvent e)
211       {
212         settings.setExportGroups(chkExportGrps.isSelected());
213       }
214     });
215
216     JCheckBox chkAll = new JCheckBox(
217             MessageManager.getString("action.select_all"));
218
219     JPanel hiddenRegionConfPanel = new JPanel(new BorderLayout());
220     JPanel complexExportPanel = new JPanel(new BorderLayout());
221     this.setLayout(new BorderLayout());
222
223     chkAll.addItemListener(new ItemListener()
224     {
225       @Override
226       public void itemStateChanged(ItemEvent e)
227       {
228         checkAllAction(chkAll.isSelected());
229       }
230     });
231
232     hiddenRegionConfPanel.add(chkHiddenSeqs, BorderLayout.CENTER);
233     hiddenRegionConfPanel.add(chkHiddenCols, BorderLayout.SOUTH);
234     chkHiddenSeqs.setEnabled(hasHiddenSeq);
235     chkHiddenCols.setEnabled(hasHiddenCols);
236
237     complexExportPanel.add(chkExportAnnots, BorderLayout.NORTH);
238     complexExportPanel.add(chkExportFeats, BorderLayout.CENTER);
239     complexExportPanel.add(chkExportGrps, BorderLayout.SOUTH);
240
241     JPanel actionPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
242     actionPanel.add(chkAll);
243
244     JPanel optionsPanel = new JPanel();
245     if (this.isComplexAlignFile)
246     {
247       optionsPanel.add(complexExportPanel);
248     }
249
250     if (hasHiddenSeq || hasHiddenCols)
251     {
252       optionsPanel.add(hiddenRegionConfPanel);
253     }
254
255     add(optionsPanel, BorderLayout.NORTH);
256     add(actionPanel, BorderLayout.SOUTH);
257   }
258 }