applied copyright 2008
[jalview.git] / src / jalview / io / JalviewFileChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 //////////////////////////////////////////////////////////////////
20 package jalview.io;
21
22 import java.io.*;
23 import java.util.*;
24
25 import java.awt.*;
26 import java.awt.event.*;
27 import javax.swing.*;
28 /**
29  * Enhanced file chooser dialog box.
30  * 
31  * NOTE: bug on Windows systems when filechooser opened on directory to view files with colons in title.
32  * 
33  * @author AMW
34  *
35  */
36 public class JalviewFileChooser
37     extends JFileChooser
38 {
39   public JalviewFileChooser(String dir)
40   {
41     super(safePath(dir));
42     setAccessory(new RecentlyOpened());
43   }
44
45   private static File safePath(String dir)
46   {
47     if (dir==null)
48     { return null;
49     }
50      
51     File f = new File(dir);
52     if (f.getName().indexOf(':')>-1)
53     {
54       return null;
55     }
56     return f;
57   }
58
59   public JalviewFileChooser(String dir,
60                             String[] suffix,
61                             String[] desc,
62                             String selected,
63                             boolean selectAll)
64   {
65     super(safePath(dir));
66     init(suffix, desc, selected, selectAll);
67   }
68
69   public JalviewFileChooser(String dir,
70                             String[] suffix,
71                             String[] desc,
72                             String selected)
73   {
74     super(safePath(dir));
75     init(suffix, desc, selected, true);
76   }
77
78   void init(String[] suffix,
79             String[] desc,
80             String selected,
81             boolean selectAll)
82   {
83
84     JalviewFileFilter chosen = null;
85
86     //SelectAllFilter needs to be set first before adding further
87     //file filters to fix bug on Mac OSX
88     setAcceptAllFileFilterUsed(selectAll);
89
90     for (int i = 0; i < suffix.length; i++)
91     {
92       JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);
93       addChoosableFileFilter(jvf);
94
95       if ( (selected != null) && selected.equalsIgnoreCase(desc[i]))
96       {
97         chosen = jvf;
98       }
99     }
100
101     if (chosen != null)
102     {
103       setFileFilter(chosen);
104     }
105
106     setAccessory(new RecentlyOpened());
107   }
108
109   public void setFileFilter(javax.swing.filechooser.FileFilter filter)
110   {
111     super.setFileFilter(filter);
112
113     try
114     {
115       if (getUI() instanceof javax.swing.plaf.basic.BasicFileChooserUI)
116       {
117         final javax.swing.plaf.basic.BasicFileChooserUI ui = (javax.swing.plaf.
118             basic.BasicFileChooserUI) getUI();
119         final String name = ui.getFileName().trim();
120
121         if ( (name == null) || (name.length() == 0))
122         {
123           return;
124         }
125
126         EventQueue.invokeLater(new Thread()
127         {
128           public void run()
129           {
130             String currentName = ui.getFileName();
131             if ( (currentName == null) || (currentName.length() == 0))
132             {
133               ui.setFileName(name);
134             }
135           }
136         });
137       }
138     }
139     catch (Exception ex)
140     {
141       ex.printStackTrace();
142       // Some platforms do not have BasicFileChooserUI
143     }
144   }
145
146   public String getSelectedFormat()
147   {
148     if (getFileFilter() == null)
149     {
150       return null;
151     }
152
153     String format = getFileFilter().getDescription();
154
155     if (format.toUpperCase().startsWith("JALVIEW"))
156     {
157       format = "Jalview";
158     }
159     else if (format.toUpperCase().startsWith("FASTA"))
160     {
161       format = "FASTA";
162     }
163     else if (format.toUpperCase().startsWith("MSF"))
164     {
165       format = "MSF";
166     }
167     else if (format.toUpperCase().startsWith("CLUSTAL"))
168     {
169       format = "CLUSTAL";
170     }
171     else if (format.toUpperCase().startsWith("BLC"))
172     {
173       format = "BLC";
174     }
175     else if (format.toUpperCase().startsWith("PIR"))
176     {
177       format = "PIR";
178     }
179     else if (format.toUpperCase().startsWith("PFAM"))
180     {
181       format = "PFAM";
182     }
183
184     return format;
185   }
186
187   public int showSaveDialog(Component parent)
188       throws HeadlessException
189   {
190     this.setAccessory(null);
191
192     setDialogType(SAVE_DIALOG);
193
194     int ret = showDialog(parent, "Save");
195
196     if (getFileFilter() instanceof JalviewFileFilter)
197     {
198       JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();
199
200       if (!jvf.accept(getSelectedFile()))
201       {
202         String withExtension = getSelectedFile() + "." +
203             jvf.getAcceptableExtension();
204         setSelectedFile(new File(withExtension));
205       }
206     }
207     // TODO: ENSURE THAT FILES SAVED WITH A ':' IN THE NAME ARE REFUSED AND THE USER PROMPTED FOR A NEW FILENAME
208     if ( (ret == JalviewFileChooser.APPROVE_OPTION) &&
209         getSelectedFile().exists())
210     {
211       int confirm = JOptionPane.showConfirmDialog(parent,
212                                                   "Overwrite existing file?",
213                                                   "File exists",
214                                                   JOptionPane.YES_NO_OPTION);
215
216       if (confirm != JOptionPane.YES_OPTION)
217       {
218         ret = JalviewFileChooser.CANCEL_OPTION;
219       }
220     }
221
222     return ret;
223   }
224
225   void recentListSelectionChanged(String selection)
226   {
227     setSelectedFile(null);
228
229     File file = new File(selection);
230     if (getFileFilter() instanceof JalviewFileFilter)
231     {
232       JalviewFileFilter jvf = (JalviewFileFilter)this.getFileFilter();
233
234       if (!jvf.accept(file))
235       {
236         setFileFilter(getChoosableFileFilters()[0]);
237       }
238     }
239
240     setSelectedFile(file);
241   }
242
243   class RecentlyOpened
244       extends JPanel
245   {
246     JList list;
247     public RecentlyOpened()
248     {
249       String historyItems = jalview.bin.Cache.getProperty("RECENT_FILE");
250       StringTokenizer st;
251       Vector recent = new Vector();
252
253       if (historyItems != null)
254       {
255         st = new StringTokenizer(historyItems, "\t");
256
257         while (st.hasMoreTokens())
258         {
259           recent.addElement(st.nextElement());
260         }
261       }
262
263       list = new JList(recent);
264
265       DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
266       dlcr.setHorizontalAlignment(DefaultListCellRenderer.RIGHT);
267       list.setCellRenderer(dlcr);
268
269       list.addMouseListener(new MouseAdapter()
270       {
271         public void mousePressed(MouseEvent evt)
272         {
273           recentListSelectionChanged(list.getSelectedValue().toString());
274         }
275       });
276
277       this.setBorder(new javax.swing.border.TitledBorder("Recently Opened"));
278
279       final JScrollPane scroller = new JScrollPane(list);
280       scroller.setPreferredSize(new Dimension(130, 200));
281       this.add(scroller);
282
283       javax.swing.SwingUtilities.invokeLater(new Runnable()
284       {
285         public void run()
286         {
287           scroller.getHorizontalScrollBar().setValue(
288               scroller.getHorizontalScrollBar().getMaximum());
289         }
290       });
291
292     }
293
294   }
295 }