JAL-1988 JAL-3772 Non-blocking modal dialogs for unsaved changes and saving files...
[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 import java.util.concurrent.Callable;
30
31 import javax.swing.JCheckBox;
32 import javax.swing.JPanel;
33
34 import jalview.api.AlignExportSettingsI;
35 import jalview.api.AlignViewportI;
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     if (viewport.hasHiddenColumns() || viewport.hasHiddenRows()
77             || format.isComplexAlignFile())
78     {
79       return true;
80     }
81     return false;
82   }
83
84   /**
85    * Constructor that passes in an initial set of export options. User choices
86    * in the dialog should update this object, and the <em>same</em> object
87    * should be used in any action handler set by calling
88    * <code>setResponseAction</code>.
89    * 
90    * @param viewport
91    * @param format
92    * @param defaults
93    */
94   public AlignExportOptions(AlignViewportI viewport, FileFormatI format,
95           AlignExportSettingsI defaults)
96   {
97     this.settings = defaults;
98     this.isComplexAlignFile = format.isComplexAlignFile();
99     init(viewport.hasHiddenRows(), viewport.hasHiddenColumns());
100     dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
101   }
102
103   /**
104    * Shows the dialog, and runs any registered response actions that correspond
105    * to user choices
106    */
107   public void showDialog()
108   {
109     Object[] options = new Object[] { MessageManager.getString("action.ok"),
110         MessageManager.getString("action.cancel") };
111     dialog.showInternalDialog(this,
112             MessageManager.getString("label.export_settings"),
113             JvOptionPane.OK_CANCEL_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
114             options, MessageManager.getString("action.ok"));
115   }
116
117   /**
118    * Registers a Runnable action to be performed for a particular user response
119    * in the dialog
120    * 
121    * @param action
122    */
123   public void setResponseAction(Object response, Callable action)
124   {
125     dialog.setResponseHandler(response, action);
126   }
127
128   /**
129    * Selects/deselects all enabled and shown options on 'Check all' selected or
130    * deselected
131    * 
132    * @param isSelected
133    */
134   void checkAllAction(boolean isSelected)
135   {
136     boolean set = chkHiddenSeqs.isEnabled() && isSelected;
137     chkHiddenSeqs.setSelected(set);
138     settings.setExportHiddenSequences(set);
139
140     set = chkHiddenCols.isEnabled() && isSelected;
141     chkHiddenCols.setSelected(set);
142     settings.setExportHiddenColumns(set);
143
144     set = isComplexAlignFile && chkExportAnnots.isEnabled() && isSelected;
145     chkExportAnnots.setSelected(set);
146     settings.setExportAnnotations(set);
147
148     set = isComplexAlignFile && chkExportFeats.isEnabled() && isSelected;
149     chkExportFeats.setSelected(set);
150     settings.setExportFeatures(set);
151
152     set = isComplexAlignFile && chkExportGrps.isEnabled() && isSelected;
153     chkExportGrps.setSelected(set);
154     settings.setExportGroups(set);
155   }
156
157   /**
158    * Initialises the components of the display
159    * 
160    * @param hasHiddenSeq
161    * @param hasHiddenCols
162    */
163   private void init(boolean hasHiddenSeq, boolean hasHiddenCols)
164   {
165     chkHiddenSeqs.setText(
166             MessageManager.getString("action.export_hidden_sequences"));
167     chkHiddenSeqs.addActionListener(new ActionListener()
168     {
169       @Override
170       public void actionPerformed(ActionEvent e)
171       {
172         settings.setExportHiddenSequences(chkHiddenSeqs.isSelected());
173       }
174     });
175
176     chkHiddenCols.setText(
177             MessageManager.getString("action.export_hidden_columns"));
178     chkHiddenCols.addActionListener(new ActionListener()
179     {
180       @Override
181       public void actionPerformed(ActionEvent e)
182       {
183         settings.setExportHiddenColumns(chkHiddenCols.isSelected());
184       }
185     });
186
187     chkExportAnnots
188             .setText(MessageManager.getString("action.export_annotations"));
189     chkExportAnnots.addActionListener(new ActionListener()
190     {
191       @Override
192       public void actionPerformed(ActionEvent e)
193       {
194         settings.setExportAnnotations(chkExportAnnots.isSelected());
195       }
196     });
197
198     chkExportFeats
199             .setText(MessageManager.getString("action.export_features"));
200     chkExportFeats.addActionListener(new ActionListener()
201     {
202       @Override
203       public void actionPerformed(ActionEvent e)
204       {
205         settings.setExportFeatures(chkExportFeats.isSelected());
206       }
207     });
208
209     chkExportGrps.setText(MessageManager.getString("action.export_groups"));
210     chkExportGrps.addActionListener(new ActionListener()
211     {
212       @Override
213       public void actionPerformed(ActionEvent e)
214       {
215         settings.setExportGroups(chkExportGrps.isSelected());
216       }
217     });
218
219     JCheckBox chkAll = new JCheckBox(
220             MessageManager.getString("action.select_all"));
221
222     JPanel hiddenRegionConfPanel = new JPanel(new BorderLayout());
223     JPanel complexExportPanel = new JPanel(new BorderLayout());
224     this.setLayout(new BorderLayout());
225
226     chkAll.addItemListener(new ItemListener()
227     {
228       @Override
229       public void itemStateChanged(ItemEvent e)
230       {
231         checkAllAction(chkAll.isSelected());
232       }
233     });
234
235     hiddenRegionConfPanel.add(chkHiddenSeqs, BorderLayout.CENTER);
236     hiddenRegionConfPanel.add(chkHiddenCols, BorderLayout.SOUTH);
237     chkHiddenSeqs.setEnabled(hasHiddenSeq);
238     chkHiddenCols.setEnabled(hasHiddenCols);
239
240     complexExportPanel.add(chkExportAnnots, BorderLayout.NORTH);
241     complexExportPanel.add(chkExportFeats, BorderLayout.CENTER);
242     complexExportPanel.add(chkExportGrps, BorderLayout.SOUTH);
243
244     JPanel actionPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
245     actionPanel.add(chkAll);
246
247     JPanel optionsPanel = new JPanel();
248     if (this.isComplexAlignFile)
249     {
250       optionsPanel.add(complexExportPanel);
251     }
252
253     if (hasHiddenSeq || hasHiddenCols)
254     {
255       optionsPanel.add(hiddenRegionConfPanel);
256     }
257
258     add(optionsPanel, BorderLayout.NORTH);
259     add(actionPanel, BorderLayout.SOUTH);
260   }
261 }