[ui_data] prevent spurious FileBrowser ScrollBar reset after 93c93ccf
[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  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 package org.scilab.modules.ui_data.filebrowser;
17
18 import java.awt.event.MouseAdapter;
19 import java.awt.event.MouseEvent;
20 import java.io.File;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Timer;
24 import java.util.TimerTask;
25
26 import javax.swing.ImageIcon;
27 import javax.swing.JButton;
28 import javax.swing.JMenuItem;
29 import javax.swing.JPopupMenu;
30 import javax.swing.SwingUtilities;
31
32 import org.scilab.modules.action_binding.InterpreterManagement;
33 import org.scilab.modules.commons.gui.FindIconHelper;
34 import org.scilab.modules.commons.gui.ScilabLAF;
35 import org.scilab.modules.gui.events.callback.CommonCallBack;
36 import org.scilab.modules.ui_data.utils.UiDataMessages;
37
38 /**
39  * The File Browser history
40  * @author Calixte DENIZET
41  */
42 @SuppressWarnings(value = { "serial" })
43 public class ScilabFileBrowserHistory {
44
45     private static final String PREVIOUSICON = FindIconHelper.findIcon("go-previous");
46     private static final String NEXTICON = FindIconHelper.findIcon("go-next");
47
48     private final SwingScilabTreeTable stt;
49     private final List<String> history = new ArrayList<String>();
50     private int position = -1;
51     private final JButton previous;
52     private final JButton next;
53     private final JPopupMenu popup;
54     private Timer timer;
55
56     /**
57      * Default constructor
58      * @param stt the treetable associated with this history
59      */
60     public ScilabFileBrowserHistory(SwingScilabTreeTable stt) {
61         this.stt = stt;
62         this.popup = new JPopupMenu();
63         this.popup.setBorderPainted(true);
64
65         previous = new JButton();
66         previous.setIcon(new ImageIcon(PREVIOUSICON));
67         ScilabLAF.setDefaultProperties(previous);
68
69         previous.setToolTipText(UiDataMessages.PREVIOUSDIR);
70         previous.addMouseListener(new MouseAdapter() {
71             @Override
72             public void mousePressed(MouseEvent e) {
73                 if (timer == null) {
74                     timer = new Timer();
75                     timer.schedule(new TimerTask() {
76                         @Override
77                         public void run() {
78                             if (!popup.isVisible() || popup.getInvoker() != next) {
79                                 showPopup(true);
80                             }
81                         }
82                     }, 1000);
83                 }
84             }
85
86             @Override
87             public void mouseReleased(MouseEvent e) {
88                 if (timer != null) {
89                     timer.cancel();
90                     timer = null;
91                 }
92             }
93
94             @Override
95             public void mouseClicked(MouseEvent e) {
96                 if (SwingUtilities.isRightMouseButton(e) && previous.isEnabled() && (!popup.isVisible() || popup.getInvoker() != previous)) {
97                     showPopup(true);
98                 } else if (SwingUtilities.isLeftMouseButton(e) && !popup.isVisible() && previous.isEnabled()) {
99                     ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(position - 1), false);
100                     chDir(history.get(position - 1));
101                     setPositionInHistory(position - 1);
102                 }
103             }
104         });
105
106         next = new JButton();
107         next.setIcon(new ImageIcon(NEXTICON));
108         ScilabLAF.setDefaultProperties(next);
109
110         next.setToolTipText(UiDataMessages.NEXTDIR);
111         next.addMouseListener(new MouseAdapter() {
112             @Override
113             public void mousePressed(MouseEvent e) {
114                 if (timer == null) {
115                     timer = new Timer();
116                     timer.schedule(new TimerTask() {
117                         @Override
118                         public void run() {
119                             if (!popup.isVisible() || popup.getInvoker() != next) {
120                                 showPopup(false);
121                             }
122                         }
123                     }, 1000);
124                 }
125             }
126
127             @Override
128             public void mouseReleased(MouseEvent e) {
129                 if (timer != null) {
130                     timer.cancel();
131                     timer = null;
132                 }
133             }
134
135             @Override
136             public void mouseClicked(MouseEvent e) {
137                 if (SwingUtilities.isRightMouseButton(e) && next.isEnabled() && (!popup.isVisible() || popup.getInvoker() != next)) {
138                     showPopup(false);
139                 } else if (SwingUtilities.isLeftMouseButton(e) && !popup.isVisible() && next.isEnabled()) {
140                     ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(position + 1), false);
141                     chDir(history.get(position + 1));
142                     setPositionInHistory(position + 1);
143                 }
144             }
145         });
146
147         updateButton(0);
148     }
149
150     /**
151      * Show the popup under the button
152      * @param prev if true, the popup is show under the previous button
153      */
154     private void showPopup(boolean prev) {
155         popup.removeAll();
156         if (prev) {
157             for (int i = position - 1; i >= 0; i--) {
158                 JMenuItem item = new JMenuItem(history.get(i));
159                 final int j = i;
160                 item.addActionListener(new CommonCallBack(null) {
161                     @Override
162                     public void callBack() {
163                         ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(j), false);
164                         chDir(history.get(j));
165                         setPositionInHistory(j);
166                     }
167                 });
168                 popup.add(item);
169             }
170         } else {
171             for (int i = position + 1; i < history.size(); i++) {
172                 JMenuItem item = new JMenuItem(history.get(i));
173                 final int j = i;
174                 item.addActionListener(new CommonCallBack(null) {
175                     @Override
176                     public void callBack() {
177                         ScilabFileBrowserHistory.this.stt.setBaseDir(history.get(j), false);
178                         chDir(history.get(j));
179                         setPositionInHistory(j);
180                     }
181                 });
182                 popup.add(item);
183             }
184         }
185         popup.pack();
186
187         JButton button;
188         if (prev) {
189             button = previous;
190         } else {
191             button = next;
192         }
193
194         popup.show(button, 0, button.getBounds(null).height);
195     }
196
197     private static final void chDir(String path) {
198         File f = new File(path);
199         if (f.exists() && f.isDirectory() && f.canRead()) {
200             InterpreterManagement.requestScilabExec("chdir('" + path + "');");
201         }
202     }
203
204     /**
205      * Add a path in the history
206      * @param path the path to add
207      */
208     public void addPathInHistory(String path) {
209         history.add(path);
210         setPositionInHistory(position + 1);
211     }
212
213     /**
214      * @return the previous button
215      */
216     public JButton getPreviousButton() {
217         return previous;
218     }
219
220     /**
221      * @return the next button
222      */
223     public JButton getNextButton() {
224         return next;
225     }
226
227     /**
228      * Set the current position in the history
229      * @param pos the new position
230      */
231     private void setPositionInHistory(int pos) {
232         position = pos;
233         updateButton(pos);
234     }
235
236     /**
237      * Update the buttons state according to the position
238      * @param pos the position
239      */
240     private void updateButton(int pos) {
241         previous.setEnabled(history.size() >= 2 && pos != 0);
242         next.setEnabled(history.size() >= 2 && pos != history.size() - 1);
243     }
244 }