Bug 6615 fixed: ui(get|put)file did not center the file dialog on the last focused...
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / filechooser / SwingScilabFileChooser.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Vincent Couvert
4  * Copyright (C) 2008 - DIGITEO - Sylvestre KOUMAR
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11  *
12  */
13
14 package org.scilab.modules.gui.bridge.filechooser;
15
16 import java.awt.Component;
17 import java.awt.KeyboardFocusManager;
18 import java.io.File;
19 import java.util.StringTokenizer;
20
21 import javax.swing.ImageIcon;
22 import javax.swing.JFileChooser;
23 import javax.swing.JFrame;
24 import javax.swing.JOptionPane;
25 import javax.swing.SwingUtilities;
26
27 import org.scilab.modules.gui.filechooser.FileChooserInfos;
28 import org.scilab.modules.gui.filechooser.SimpleFileChooser;
29 import org.scilab.modules.gui.utils.ConfigManager;
30 import org.scilab.modules.gui.utils.SciFileFilter;
31 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
32 import org.scilab.modules.localization.Messages;
33
34 /**
35  * Swing implementation of a Scilab File ChooserS
36  * @author Vincent COUVERT
37  * @author Sylvestre KOUMAR
38  */
39 public class SwingScilabFileChooser extends JFileChooser implements SimpleFileChooser {
40
41     private static final long serialVersionUID = 1L;
42
43     private String[] selection; // Path + filenames
44     private String selectionPath; // Path
45     private String[] selectionFileNames; // Filenames
46     private int selectionSize;
47     private int filterIndex;
48     private int maskSize;
49     private int dialogType;
50
51     private String[] maskDescription;
52     private JFrame parent;
53
54     /**
55      * Default constructor
56      */
57     public SwingScilabFileChooser() {
58         super();
59
60         //System.out.println("[Constructor] SwingScilabFileChooser");
61         /** Bug 3231 fixed: do not explore all zip files on desktop under Windows */
62         //putClientProperty("FileChooser.useShellFolder", Boolean.FALSE);
63         /**
64          * Bug 4187 fixed: uigetdir() opens on "Desktop" and not on "Computer" on windows
65          * No need to use 'putClientProperty' anymore (bug 3231)
66          */
67         /* Bug 5111 : The Current directory have to be set before */
68         super.setCurrentDirectory(new File(ConfigManager.getLastOpenedDirectory()));
69     }
70
71     /**
72      * Set the title of the file chooser
73      * @param title the title to set
74      */
75     @Override
76     public void setTitle(String title) {
77         super.setDialogTitle(title);
78     }
79
80     /**
81      * Set the mask & the mask description for the filechooser
82      * @param mask the mask to set
83      * @param fileMaskDescription the maskDescription to set
84      */
85     public void addMask(String[] mask, String[] fileMaskDescription) {
86
87         //size of the mask list
88         maskSize = mask.length;
89
90         //If the mask description is empty we allocate description
91         //according to the extensions given
92         if (fileMaskDescription == null || fileMaskDescription.length == 0) {
93             for (int i = 0; i < mask.length; i++) {
94                 super.addChoosableFileFilter(new SciFileFilter(mask[i], null, i/*, maskSize*/));
95             }
96         } else {
97             //If the mask description is filled
98             //we use those descriptions given by the user
99             this.maskDescription = fileMaskDescription;
100             for (int i = 0; i < mask.length; i++) {
101                 super.addChoosableFileFilter(new SciFileFilter(mask[i], maskDescription[i], i/*, maskSize*/));
102             }
103         }
104     }
105
106     /**
107      * Set the initial directory used for file search
108      * @param path the default path
109      */
110     @Override
111     public void setInitialDirectory(String path) {
112         // When empty string given
113         if (path.length() == 0) {
114             return;
115         }
116         // Replace beginning of the path if is an environment variable
117         String newPath = path;
118         StringTokenizer tok = new StringTokenizer(path, File.separator);
119         if (tok.hasMoreTokens()) {
120             /* It is possible that we don't have any more token here when
121                                           Scilab is started from / for example */
122             String firstToken = tok.nextToken();
123             if (firstToken != null && System.getenv(firstToken) != null)  {
124                 newPath = newPath.replaceFirst(firstToken, System.getenv(firstToken));
125             }
126         }
127         super.setCurrentDirectory(new File(newPath));
128     }
129
130     /**
131      * Set the parent frame
132      * @param parent the parent frame
133      */
134     public void setParentFrame(JFrame parent) {
135         this.parent = parent;
136     }
137
138     /**
139      * Display this chooser and wait for user selection
140      */
141     @Override
142     public void displayAndWait() {
143         JFrame parentFrame = null;
144         if (parent == null) {
145             Component focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
146             if (focused != null) {
147                 parentFrame = (JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, focused);
148             }
149             if (parentFrame == null) {
150                 parentFrame = new JFrame();
151             }
152         } else {
153             parentFrame = parent;
154         }
155
156         int returnValue = 0;
157         if (maskSize > 0) {
158             setFileFilter(getChoosableFileFilters()[maskSize]);
159         }
160         if (this.dialogType == JFileChooser.SAVE_DIALOG) {
161             returnValue = this.showSaveDialog(parentFrame);
162         } else {
163             returnValue = this.showOpenDialog(parentFrame);
164         }
165
166         //User validate the uigetfile
167         if (returnValue == APPROVE_OPTION) {
168             if (this.isMultiSelectionEnabled()) {
169                 File[] files = this.getSelectedFiles();
170                 selection = new String[files.length];
171                 selectionFileNames = new String[files.length];
172                 selectionSize = files.length;
173                 for (int i = 0; i < files.length; i++) {
174                     selection[i] = files[i].getAbsolutePath();
175                     selectionPath = files[i].getParentFile().getPath();
176                     selectionFileNames[i] = files[i].getName();
177                 }
178             } else {
179                 File file = this.getSelectedFile();
180
181                 if (this.dialogType == JFileChooser.SAVE_DIALOG) {
182                     //Test if there is a file with the same name
183                     if (file.exists()) {
184                         int actionDialog = JOptionPane.showConfirmDialog(this,
185                                            Messages.gettext("Replace existing file?"),
186                                            Messages.gettext("File already exists"),
187                                            JOptionPane.YES_NO_OPTION);
188
189                         if (actionDialog != JOptionPane.YES_OPTION) {
190                             // Same as cancel case
191                             selection = new String[1];
192                             selection[0] = "";
193                             selectionSize = 0;
194                             selectionPath = "";
195                             selectionFileNames = new String[1];
196                             selectionFileNames[0] = "";
197                             //set the filter index of the JFileChooser at 0 if "cancel" button was selected
198                             filterIndex = 0;
199
200                             //return the filechooser's information
201                             //they are stocked into FileChooserInfos
202                             FileChooserInfos.getInstance().setSelection(selection);
203                             FileChooserInfos.getInstance().setSelectionPathName(selectionPath);
204                             FileChooserInfos.getInstance().setSelectionFileNames(selectionFileNames);
205                             FileChooserInfos.getInstance().setSelectionSize(selectionSize);
206                             FileChooserInfos.getInstance().setFilterIndex(filterIndex);
207                             return;
208                         }
209                     }
210                 }
211
212                 selection = new String[1];
213                 selection[0] = file.getAbsolutePath();
214                 if (getFileSelectionMode() == DIRECTORIES_ONLY) {
215                     selectionPath = file.getPath();
216                 } else {
217                     selectionPath = file.getParentFile().getPath();
218                 }
219                 selectionFileNames = new String[1];
220                 selectionFileNames[0] = file.getName();
221                 selectionSize = 1;
222             }
223
224             //return the filechooser's information
225             //they are stocked into FileChooserInfos
226             FileChooserInfos.getInstance().setSelection(selection);
227             FileChooserInfos.getInstance().setSelectionPathName(selectionPath);
228             FileChooserInfos.getInstance().setSelectionFileNames(selectionFileNames);
229             FileChooserInfos.getInstance().setSelectionSize(selectionSize);
230
231             //set the filter index at the last index
232             //of the list box if the mask "All files" is selected
233             javax.swing.filechooser.FileFilter allFilesSelected = getFileFilter();
234             if (allFilesSelected.getDescription().equals("All Files")) {
235                 FileChooserInfos.getInstance().setFilterIndex(maskSize + 1);
236             }
237             //TODO
238             ConfigManager.saveLastOpenedDirectory(selectionPath);
239             //User cancel the uigetfile
240         } else {
241             selection = new String[1];
242             selection[0] = "";
243             selectionSize = 0;
244             selectionPath = "";
245             selectionFileNames = new String[1];
246             selectionFileNames[0] = "";
247             //set the filter index of the JFileChooser at 0 if "cancel" button was selected
248             filterIndex = 0;
249
250             //return the filechooser's information
251             //they are stocked into FileChooserInfos
252             FileChooserInfos.getInstance().setSelection(selection);
253             FileChooserInfos.getInstance().setSelectionPathName(selectionPath);
254             FileChooserInfos.getInstance().setSelectionFileNames(selectionFileNames);
255             FileChooserInfos.getInstance().setSelectionSize(selectionSize);
256             FileChooserInfos.getInstance().setFilterIndex(filterIndex);
257         }
258
259
260
261     }
262
263     /**
264      * Get the number of files selected
265      * @return the number of files selected
266      */
267     @Override
268     public int getSelectionSize() {
269         return selectionSize;
270     }
271
272     /**
273      * Get the names of selected files
274      * @return the names of selected files
275      */
276     @Override
277     public String[] getSelection() {
278         return selection;
279     }
280
281     /**
282      * Set the flag indicating that we want only select directories
283      */
284     @Override
285     public void setDirectorySelectionOnly() {
286         setFileSelectionMode(DIRECTORIES_ONLY);
287     }
288
289     /**
290      * Set the flag indicating that we can select multiple files
291      * @param multipleSelection is enable or not
292      */
293     @Override
294     public void setMultipleSelection(boolean multipleSelection) {
295         setMultiSelectionEnabled(multipleSelection);
296     }
297
298     /**
299      * Get the path of selected files
300      * @return selectionPath selected file(s) path
301      */
302     @Override
303     public String getSelectionPathName() {
304         return selectionPath;
305     }
306
307     /**
308      * Get the names of selected files
309      * @return selectionFileNnames selected file(s) path
310      */
311     @Override
312     public String[] getSelectionFileNames() {
313         return selectionFileNames;
314     }
315
316     /**
317      * Get the filter index
318      * @return this.getFilterIndex() filter index
319      */
320     @Override
321     public int getFilterIndex() {
322         return getFilterIndex();
323     }
324
325     /**
326      * Set the flag indicating the filter index
327      * @param filterIndex index of the filter
328      */
329     public void setFilterIndex(int filterIndex) {
330         setFilterIndex(filterIndex);
331     }
332
333     /**
334      * Set the dialog type (save or open a file ?)
335      * @param dialogType the dialog type
336      */
337     @Override
338     public void setUiDialogType(int dialogType) {
339         this.dialogType = dialogType;
340     }
341 }