ae199891ff346c3a46df4e7cbff8896be9f596e2
[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
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.gui.bridge.pushbutton.SwingScilabPushButton;
32 import org.scilab.modules.gui.events.callback.CallBack;
33 import org.scilab.modules.gui.pushbutton.PushButton;
34 import org.scilab.modules.gui.pushbutton.ScilabPushButton;
35
36 /**
37  * The File Browser history
38  * @author Calixte DENIZET
39  */
40 public class ScilabFileBrowserHistory {
41
42     private static final String PREVIOUSICON = System.getenv("SCI") + "/modules/gui/images/icons/16x16/filebrowser/go-previous.png";
43     private static final String NEXTICON = System.getenv("SCI") + "/modules/gui/images/icons/16x16/filebrowser/go-next.png";
44
45     private SwingScilabTreeTable stt;
46     private List<String> history = new ArrayList<String>();
47     private int position = -1;
48     private PushButton previous;
49     private PushButton next;
50     private JPopupMenu popup;
51     private Timer timer;
52
53     /**
54      * Default constructor
55      * @param stt the treetable associated with this history
56      */
57     public ScilabFileBrowserHistory(SwingScilabTreeTable stt) {
58         this.stt = stt;
59         this.popup = new JPopupMenu();
60         this.popup.setBorderPainted(true);
61
62         previous = ScilabPushButton.createPushButton();
63         previous.setIcon(PREVIOUSICON);
64
65         final SwingScilabPushButton swingPrevious = (SwingScilabPushButton) previous.getAsSimplePushButton();
66         swingPrevious.addMouseListener(new MouseAdapter() {
67                 public void mousePressed(MouseEvent e) {
68                     if (timer == null) {
69                         timer = new Timer();
70                         timer.schedule(new TimerTask() {
71                                 public void run() {
72                                     if (!popup.isVisible() || popup.getInvoker() != next) {
73                                         showPopup(true);
74                                     }
75                                 }
76                             }, 1000);
77                     }
78                 }
79
80                 public void mouseReleased(MouseEvent e) {
81                     if (timer != null) {
82                         timer.cancel();
83                         timer = null;
84                     }
85                 }
86
87                 public void mouseClicked(MouseEvent e) {
88                     if (SwingUtilities.isRightMouseButton(e) && previous.isEnabled() && (!popup.isVisible() || popup.getInvoker() != swingPrevious)) {
89                         showPopup(true);
90                     } else if (SwingUtilities.isLeftMouseButton(e) && !popup.isVisible() && previous.isEnabled()) {
91                         ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(position - 1), false);
92                         setPositionInHistory(position - 1);
93                     }
94                 }
95             });
96
97         next = ScilabPushButton.createPushButton();
98         next.setIcon(NEXTICON);
99
100         final SwingScilabPushButton swingNext = (SwingScilabPushButton) next.getAsSimplePushButton();
101         swingNext.addMouseListener(new MouseAdapter() {
102                 public void mousePressed(MouseEvent e) {
103                     if (timer == null) {
104                         timer = new Timer();
105                         timer.schedule(new TimerTask() {
106                                 public void run() {
107                                     if (!popup.isVisible() || popup.getInvoker() != next) {
108                                         showPopup(false);
109                                     }
110                                 }
111                             }, 1000);
112                     }
113                 }
114
115                 public void mouseReleased(MouseEvent e) {
116                     if (timer != null) {
117                         timer.cancel();
118                         timer = null;
119                     }
120                 }
121
122                 public void mouseClicked(MouseEvent e) {
123                     if (SwingUtilities.isRightMouseButton(e) && next.isEnabled() && (!popup.isVisible() || popup.getInvoker() != swingNext)) {
124                         showPopup(false);
125                     } else if (SwingUtilities.isLeftMouseButton(e) && !popup.isVisible() && next.isEnabled()) {
126                         ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(position + 1), false);
127                         setPositionInHistory(position + 1);
128                     }
129                 }
130             });
131
132         updateButton(0);
133     }
134
135     /**
136      * Show the popup under the button
137      * @param prev if true, the popup is show under the previous button
138      */
139     private void showPopup(boolean prev) {
140         popup.removeAll();
141         if (prev) {
142             for (int i = position - 1; i >= 0; i--) {
143                 JMenuItem item = new JMenuItem(history.get(i));
144                 final int j = i;
145                 item.addActionListener(new CallBack(null) {
146                         public void callBack() {
147                             ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(j), false);
148                             setPositionInHistory(j);
149                         }
150                     });
151                 popup.add(item);
152             }
153         } else {
154             for (int i = position + 1; i < history.size(); i++) {
155                 JMenuItem item = new JMenuItem(history.get(i));
156                 final int j = i;
157                 item.addActionListener(new CallBack(null) {
158                         public void callBack() {
159                             ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(j), false);
160                             setPositionInHistory(j);
161                         }
162                     });
163                 popup.add(item);
164             }
165         }
166         popup.pack();
167
168         SwingScilabPushButton button;
169         if (prev) {
170             button = (SwingScilabPushButton) previous.getAsSimplePushButton();
171         } else {
172             button = (SwingScilabPushButton) next.getAsSimplePushButton();
173         }
174
175         popup.show(button, 0, button.getBounds(null).height);
176     }
177
178     /**
179      * Add a path in the history
180      * @param path the path to add
181      */
182     public void addPathInHistory(String path) {
183         history.add(path);
184         setPositionInHistory(position + 1);
185     }
186
187     /**
188      * @return the previous button
189      */
190     public PushButton getPreviousButton() {
191         return previous;
192     }
193
194     /**
195      * @return the next button
196      */
197     public PushButton getNextButton() {
198         return next;
199     }
200
201     /**
202      * Set the current position in the history
203      * @param pos the new position
204      */
205     private void setPositionInHistory(int pos) {
206         position = pos;
207         updateButton(pos);
208     }
209
210     /**
211      * Update the buttons state according to the position
212      * @param pos the position
213      */
214     private void updateButton(int pos) {
215         previous.setEnabled(history.size() >= 2 && pos != 0);
216         next.setEnabled(history.size() >= 2 && pos != history.size() - 1);
217     }
218 }