d5e3bc6ba13b507a04e24629d2ea27ed24dc6b81
[scilab.git] / scilab / modules / preferences / src / java / org / scilab / modules / preferences / Component / FileSelector.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2011 - Pierre GRADIT
4  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
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-en.txt
11  *
12  */
13
14 package org.scilab.modules.preferences.Component;
15
16 import java.awt.BorderLayout;
17 import java.awt.Color;
18 import java.awt.Dimension;
19 import java.awt.GridBagConstraints;
20 import java.awt.GridBagLayout;
21
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.io.File;
25
26 import javax.swing.GroupLayout;
27 import javax.swing.JButton;
28 import javax.swing.JFrame;
29 import javax.swing.JPanel;
30 import javax.swing.JTextField;
31 import javax.swing.SwingUtilities;
32 import javax.swing.event.DocumentEvent;
33 import javax.swing.event.DocumentListener;
34
35 import org.scilab.modules.preferences.XCommonManager;
36 import org.scilab.modules.preferences.XComponent;
37 import org.scilab.modules.preferences.XChooser;
38 import org.scilab.modules.preferences.XConfigManager;
39 import org.scilab.modules.gui.bridge.filechooser.SwingScilabFileChooser;
40
41 import org.w3c.dom.Node;
42
43 /** Implementation of Entry compliant with extended management.
44  *
45  * @author Calixte DENIZET
46  *
47  */
48 public class FileSelector extends Panel implements XComponent, XChooser, DocumentListener {
49
50     /** Universal identifier for serialization.
51      *
52      */
53     private static final long serialVersionUID = -7007541669965737408L;
54
55     private static final Color NORMALCOLOR = Color.BLACK;
56     private static final Color ERRORCOLOR = Color.RED;
57
58     private ActionListener actionListener;
59     private JTextField textField;
60     private JButton button;
61     private String currentDir = System.getProperty("user.home");
62     private boolean dirSelection;
63     private String previousPath;
64
65     /** Constructor.
66      *
67      * @param peer : associated view DOM node.
68      */
69     public FileSelector(final Node peer) {
70         super(peer);
71         setLayout(new GridBagLayout());
72
73         textField = new JTextField();
74         textField.setEditable(true);
75         textField.getDocument().addDocumentListener(this);
76
77         button = new JButton("...");
78         button.setPreferredSize(new Dimension(button.getPreferredSize().width, textField.getPreferredSize().height));
79         button.addActionListener(new ActionListener() {
80             public void actionPerformed(ActionEvent e) {
81                 JFrame frame = (JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, FileSelector.this);
82                 SwingScilabFileChooser fileChooser = new SwingScilabFileChooser();
83                 fileChooser.setInitialDirectory(currentDir);
84                 fileChooser.setParentFrame(frame);
85                 fileChooser.setMultipleSelection(false);
86                 fileChooser.setFileSelectionMode(dirSelection ? SwingScilabFileChooser.DIRECTORIES_ONLY : SwingScilabFileChooser.FILES_ONLY);
87                 String mask = XCommonManager.getAttribute(peer, "mask");
88                 String desc = XCommonManager.getAttribute(peer, "desc");
89                 if (!mask.equals(XCommonManager.NAV) && !desc.equals(XCommonManager.NAV)) {
90                     fileChooser.addMask(new String[] {mask}, new String[] {desc});
91                 }
92                 fileChooser.displayAndWait();
93
94                 String[] paths = fileChooser.getSelection();
95                 if (paths != null && paths.length != 0 && !paths[0].isEmpty()) {
96                     File file = new File(paths[0]);
97                     if (file.exists()) {
98                         if (dirSelection) {
99                             currentDir = file.getAbsolutePath();
100                         } else {
101                             currentDir = file.getParentFile().getAbsolutePath();
102                         }
103
104                         textField.setText(file.getAbsolutePath());
105                     }
106                 }
107             }
108         });
109
110         GridBagConstraints gbc = new GridBagConstraints();
111         gbc.gridx = 0;
112         gbc.gridy = 0;
113         gbc.weightx = 1;
114         gbc.fill = GridBagConstraints.HORIZONTAL;
115         add(textField, gbc);
116         gbc.gridx = 1;
117         gbc.weightx = 0;
118         add(button, gbc);
119
120         textField.setRequestFocusEnabled(true);
121         textField.setFocusable(true);
122         button.setRequestFocusEnabled(true);
123         button.setFocusable(true);
124
125         String href = XConfigManager.getAttribute(peer, "href");
126         href(href);
127
128         String dirsel = XCommonManager.getAttribute(peer, "dir-selection", "false");
129         dirSelection = dirsel.equals("true");
130     }
131
132     public void addDocumentListener(DocumentListener listener) {
133         textField.getDocument().addDocumentListener(listener);
134     }
135
136     /** Define the set of actuators.
137      *
138      * @return array of actuator names.
139      */
140     public final String[] actuators() {
141         String[] actuators = {"enable", "href", "desc", "mask", "dir-selection"};
142         return actuators;
143     }
144
145     /** Refresh the component by the use of actuators.
146      *
147      * @param peer the corresponding view DOM node
148      */
149     public final void refresh(final Node peer) {
150         String href = XCommonManager.getAttribute(peer , "href");
151         if (!href.equals(href())) {
152             href(href);
153         }
154
155         String dirsel = XCommonManager.getAttribute(peer , "dir-selection", "false");
156         dirSelection = dirsel.equals("true");
157
158         String enable = XConfigManager.getAttribute(peer , "enable", "true");
159         textField.setEnabled(enable.equals("true"));
160         button.setEnabled(enable.equals("true"));
161     }
162
163     /** Sensor for 'href' attribute.
164      *
165      * @return the attribute value.
166      */
167     public final String href() {
168         if (checkPath()) {
169             return textField.getText();
170         }
171
172         return null;
173     }
174
175     /** Actuator for 'href' attribute.
176      *
177      * @param text : the attribute value.
178      */
179     public final void href(final String href) {
180         if (!href.equals(XCommonManager.NAV)) {
181             textField.setText(href);
182         }
183     }
184
185     /**
186      * {@inheritDoc}
187      */
188     public void changedUpdate(DocumentEvent e) { }
189
190     /**
191      * {@inheritDoc}
192      */
193     public void insertUpdate(DocumentEvent e) {
194         update();
195     }
196
197     /**
198      * {@inheritDoc}
199      */
200     public void removeUpdate(DocumentEvent e) {
201         update();
202     }
203
204     private void update() {
205         if (checkPath() && actionListener != null) {
206             ActionEvent transmit = new ActionEvent(this, 0, "File change", System.currentTimeMillis(), 0);
207             actionListener.actionPerformed(transmit);
208         }
209     }
210
211     private boolean checkPath() {
212         String path = textField.getText();
213         if (path.isEmpty()) {
214             return false;
215         }
216
217         File file = new File(path);
218         boolean ok = false;
219         if (file.exists()) {
220             if (dirSelection) {
221                 ok = file.isDirectory();
222             } else {
223                 ok = file.isFile();
224             }
225         }
226
227         if (ok) {
228             textField.setForeground(NORMALCOLOR);
229         } else {
230             textField.setForeground(ERRORCOLOR);
231         }
232
233         return ok;
234     }
235
236     /** Actual response read by the listener.
237      *
238      * @return response read by the listener.
239      */
240     public final Object choose() {
241         return href();
242     }
243
244     /** Developer serialization method.
245      *
246      * @return equivalent signature.
247      */
248     public final String toString() {
249         String signature = "FileSelector";
250         String href = href();
251         if (href != null && !href.equals(XCommonManager.NAV)) {
252             signature += " href='" + href + "'";
253         }
254
255         return signature;
256     }
257
258     /** Registration of a single listener.
259      * @param listener for the unique actionListener.
260      */
261     public final void addActionListener(final ActionListener listener) {
262         actionListener = listener;
263     }
264
265 }
266