File Browser: add an entry in the main menu
[scilab.git] / scilab / modules / ui_data / src / java / org / scilab / modules / ui_data / filebrowser / ScilabFileBrowserHistory.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2011 - DIGITEO - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.ui_data.filebrowser;
14
15 import java.awt.Rectangle;
16 import java.awt.event.MouseAdapter;
17 import java.awt.event.MouseEvent;
18 import java.io.File;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Timer;
22 import java.util.TimerTask;
23
24 import javax.swing.Icon;
25 import javax.swing.ImageIcon;
26 import javax.swing.JComboBox;
27 import javax.swing.JMenuItem;
28 import javax.swing.JPopupMenu;
29 import javax.swing.SwingUtilities;
30
31 import org.scilab.modules.action_binding.InterpreterManagement;
32 import org.scilab.modules.gui.bridge.pushbutton.SwingScilabPushButton;
33 import org.scilab.modules.gui.events.callback.CallBack;
34 import org.scilab.modules.gui.pushbutton.PushButton;
35 import org.scilab.modules.gui.pushbutton.ScilabPushButton;
36
37 /**
38  * The File Browser history
39  * @author Calixte DENIZET
40  */
41 public class ScilabFileBrowserHistory {
42
43     private static final String PREVIOUSICON = System.getenv("SCI") + "/modules/gui/images/icons/16x16/filebrowser/go-previous.png";
44     private static final String NEXTICON = System.getenv("SCI") + "/modules/gui/images/icons/16x16/filebrowser/go-next.png";
45
46     private SwingScilabTreeTable stt;
47     private List<String> history = new ArrayList<String>();
48     private int position = -1;
49     private PushButton previous;
50     private PushButton next;
51     private JPopupMenu popup;
52     private Timer timer;
53
54     /**
55      * Default constructor
56      * @param stt the treetable associated with this history
57      */
58     public ScilabFileBrowserHistory(SwingScilabTreeTable stt) {
59         this.stt = stt;
60         this.popup = new JPopupMenu();
61         this.popup.setBorderPainted(true);
62
63         previous = ScilabPushButton.createPushButton();
64         previous.setIcon(PREVIOUSICON);
65
66         final SwingScilabPushButton swingPrevious = (SwingScilabPushButton) previous.getAsSimplePushButton();
67         swingPrevious.addMouseListener(new MouseAdapter() {
68                 public void mousePressed(MouseEvent e) {
69                     if (timer == null) {
70                         timer = new Timer();
71                         timer.schedule(new TimerTask() {
72                                 public void run() {
73                                     if (!popup.isVisible() || popup.getInvoker() != next) {
74                                         showPopup(true);
75                                     }
76                                 }
77                             }, 1000);
78                     }
79                 }
80
81                 public void mouseReleased(MouseEvent e) {
82                     if (timer != null) {
83                         timer.cancel();
84                         timer = null;
85                     }
86                 }
87
88                 public void mouseClicked(MouseEvent e) {
89                     if (SwingUtilities.isRightMouseButton(e) && previous.isEnabled() && (!popup.isVisible() || popup.getInvoker() != swingPrevious)) {
90                         showPopup(true);
91                     } else if (SwingUtilities.isLeftMouseButton(e) && !popup.isVisible() && previous.isEnabled()) {
92                         ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(position - 1), false);
93                         setPositionInHistory(position - 1);
94                     }
95                 }
96             });
97
98         next = ScilabPushButton.createPushButton();
99         next.setIcon(NEXTICON);
100
101         final SwingScilabPushButton swingNext = (SwingScilabPushButton) next.getAsSimplePushButton();
102         swingNext.addMouseListener(new MouseAdapter() {
103                 public void mousePressed(MouseEvent e) {
104                     if (timer == null) {
105                         timer = new Timer();
106                         timer.schedule(new TimerTask() {
107                                 public void run() {
108                                     if (!popup.isVisible() || popup.getInvoker() != next) {
109                                         showPopup(false);
110                                     }
111                                 }
112                             }, 1000);
113                     }
114                 }
115
116                 public void mouseReleased(MouseEvent e) {
117                     if (timer != null) {
118                         timer.cancel();
119                         timer = null;
120                     }
121                 }
122
123                 public void mouseClicked(MouseEvent e) {
124                     if (SwingUtilities.isRightMouseButton(e) && next.isEnabled() && (!popup.isVisible() || popup.getInvoker() != swingNext)) {
125                         showPopup(false);
126                     } else if (SwingUtilities.isLeftMouseButton(e) && !popup.isVisible() && next.isEnabled()) {
127                         ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(position + 1), false);
128                         setPositionInHistory(position + 1);
129                     }
130                 }
131             });
132
133         updateButton(0);
134     }
135
136     /**
137      * Show the popup under the button
138      * @param prev if true, the popup is show under the previous button
139      */
140     private void showPopup(boolean prev) {
141         popup.removeAll();
142         if (prev) {
143             for (int i = position - 1; i >= 0; i--) {
144                 JMenuItem item = new JMenuItem(history.get(i));
145                 final int j = i;
146                 item.addActionListener(new CallBack(null) {
147                         public void callBack() {
148                             ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(j), false);
149                             chDir(history.get(j));
150                             setPositionInHistory(j);
151                         }
152                     });
153                 popup.add(item);
154             }
155         } else {
156             for (int i = position + 1; i < history.size(); i++) {
157                 JMenuItem item = new JMenuItem(history.get(i));
158                 final int j = i;
159                 item.addActionListener(new CallBack(null) {
160                         public void callBack() {
161                             ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(j), false);
162                             chDir(history.get(j));
163                             setPositionInHistory(j);
164                         }
165                     });
166                 popup.add(item);
167             }
168         }
169         popup.pack();
170
171         SwingScilabPushButton button;
172         if (prev) {
173             button = (SwingScilabPushButton) previous.getAsSimplePushButton();
174         } else {
175             button = (SwingScilabPushButton) next.getAsSimplePushButton();
176         }
177
178         popup.show(button, 0, button.getBounds(null).height);
179     }
180
181     private static final void chDir(String path) {
182         File f = new File(path);
183         if (f.exists() && f.isDirectory() && f.canRead()) {
184             InterpreterManagement.requestScilabExec("chdir('" + path + "')");
185         }
186     }
187
188     /**
189      * Add a path in the history
190      * @param path the path to add
191      */
192     public void addPathInHistory(String path) {
193         history.add(path);
194         setPositionInHistory(position + 1);
195     }
196
197     /**
198      * @return the previous button
199      */
200     public PushButton getPreviousButton() {
201         return previous;
202     }
203
204     /**
205      * @return the next button
206      */
207     public PushButton getNextButton() {
208         return next;
209     }
210
211     /**
212      * Set the current position in the history
213      * @param pos the new position
214      */
215     private void setPositionInHistory(int pos) {
216         position = pos;
217         updateButton(pos);
218     }
219
220     /**
221      * Update the buttons state according to the position
222      * @param pos the position
223      */
224     private void updateButton(int pos) {
225         previous.setEnabled(history.size() >= 2 && pos != 0);
226         next.setEnabled(history.size() >= 2 && pos != history.size() - 1);
227     }
228 }