KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > browser > VFSBrowser


1 /*
2  * VFSBrowser.java - VFS browser
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2000, 2003 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit.browser;
24
25 //{{{ Imports
26
import bsh.*;
27 import javax.swing.border.EmptyBorder JavaDoc;
28 import javax.swing.event.*;
29 import javax.swing.*;
30 import java.awt.event.*;
31 import java.awt.*;
32 import java.io.File JavaDoc;
33 import java.util.*;
34 import java.util.List JavaDoc;
35
36 import org.gjt.sp.jedit.io.*;
37 import org.gjt.sp.jedit.gui.*;
38 import org.gjt.sp.jedit.msg.*;
39 import org.gjt.sp.jedit.search.*;
40 import org.gjt.sp.jedit.*;
41 import org.gjt.sp.jedit.buffer.JEditBuffer;
42 import org.gjt.sp.util.Log;
43 //}}}
44

45 /**
46  * The main class of the VFS browser.
47  * @author Slava Pestov
48  * @version $Id: VFSBrowser.java 8287 2006-12-30 13:06:24Z kpouer $
49  */

50 public class VFSBrowser extends JPanel implements EBComponent, DefaultFocusComponent
51 {
52     public static final String JavaDoc NAME = "vfs.browser";
53
54     //{{{ Browser types
55
/**
56      * Open file dialog mode. Equals JFileChooser.OPEN_DIALOG for
57      * backwards compatibility.
58      */

59     public static final int OPEN_DIALOG = 0;
60
61     /**
62      * Save file dialog mode. Equals JFileChooser.SAVE_DIALOG for
63      * backwards compatibility.
64      */

65     public static final int SAVE_DIALOG = 1;
66     /**
67      * Choose directory dialog mode.
68      */

69     public static final int BROWSER_DIALOG = 4;
70     /**
71      * Choose directory dialog mode.
72      */

73     public static final int CHOOSE_DIRECTORY_DIALOG = 3;
74
75     /**
76      * Stand-alone browser mode.
77      */

78     public static final int BROWSER = 2;
79     //}}}
80

81     //{{{ browseDirectoryInNewWindow() method
82
/**
83      * Opens the specified directory in a new, floating, file system browser.
84      * @param view The view
85      * @param path The directory's path
86      * @since jEdit 4.1pre2
87      */

88     public static void browseDirectoryInNewWindow(View view, String JavaDoc path)
89     {
90         DockableWindowManager wm = view.getDockableWindowManager();
91         if(path != null)
92         {
93             // this is such a bad way of doing it, but oh well...
94
jEdit.setTemporaryProperty("vfs.browser.path.tmp",path);
95         }
96         wm.floatDockableWindow("vfs.browser");
97         jEdit.unsetProperty("vfs.browser.path.tmp");
98     } //}}}
99

100     //{{{ browseDirectory() method
101
/**
102      * Opens the specified directory in a file system browser.
103      * @param view The view
104      * @param path The directory's path
105      * @since jEdit 4.0pre3
106      */

107     public static void browseDirectory(View view, String JavaDoc path)
108     {
109         DockableWindowManager wm = view.getDockableWindowManager();
110         VFSBrowser browser = (VFSBrowser)wm.getDockable(NAME);
111         if(browser != null)
112         {
113             wm.showDockableWindow(NAME);
114             browser.setDirectory(path);
115         }
116         else
117         {
118             if(path != null)
119             {
120                 // this is such a bad way of doing it, but oh well...
121
jEdit.setTemporaryProperty("vfs.browser.path.tmp",path);
122             }
123             wm.addDockableWindow("vfs.browser");
124             jEdit.unsetProperty("vfs.browser.path.tmp");
125         }
126     } //}}}
127

128     //{{{ getActionContext() method
129
/**
130      * Returns the browser action context.
131      * @since jEdit 4.2pre1
132      */

133     public static ActionContext getActionContext()
134     {
135         return actionContext;
136     } //}}}
137

138     //{{{ VFSBrowser constructor
139
/**
140      * Creates a new VFS browser.
141      * @param view The view to open buffers in by default
142      */

143     public VFSBrowser(View view, String JavaDoc position)
144     {
145         this(view,null,BROWSER,true,position);
146     } //}}}
147

148     //{{{ VFSBrowser constructor
149
/**
150      * Creates a new VFS browser.
151      * @param view The view to open buffers in by default
152      * @param path The path to display
153      * @param mode The browser mode
154      * @param multipleSelection True if multiple selection should be allowed
155      * @param position Where the browser is located
156      * @since jEdit 4.2pre1
157      */

158     public VFSBrowser(View view, String JavaDoc path, int mode,
159         boolean multipleSelection, String JavaDoc position)
160     {
161         super(new BorderLayout());
162
163         listenerList = new EventListenerList();
164
165         this.mode = mode;
166         this.multipleSelection = multipleSelection;
167         this.view = view;
168
169         DockableWindowManager dwm = view.getDockableWindowManager();
170         KeyListener keyListener = dwm.closeListener(NAME);
171         addKeyListener(keyListener);
172         
173         currentEncoding = jEdit.getProperty("buffer.encoding",
174             System.getProperty("file.encoding"));
175         autoDetectEncoding = jEdit.getBooleanProperty(
176             "buffer.encodingAutodetect");
177
178         ActionHandler actionHandler = new ActionHandler();
179
180         Box topBox = new Box(BoxLayout.Y_AXIS);
181
182         horizontalLayout = (mode != BROWSER
183             || DockableWindowManager.TOP.equals(position)
184             || DockableWindowManager.BOTTOM.equals(position));
185
186         toolbarBox = new Box(horizontalLayout
187             ? BoxLayout.X_AXIS
188             : BoxLayout.Y_AXIS);
189
190         topBox.add(toolbarBox);
191
192         GridBagLayout layout = new GridBagLayout();
193         pathAndFilterPanel = new JPanel(layout);
194
195         GridBagConstraints cons = new GridBagConstraints();
196         cons.gridwidth = cons.gridheight = 1;
197         cons.gridx = cons.gridy = 0;
198         cons.fill = GridBagConstraints.BOTH;
199         cons.anchor = GridBagConstraints.EAST;
200         JLabel label = new JLabel(jEdit.getProperty("vfs.browser.path"),
201             SwingConstants.RIGHT);
202         label.setBorder(new EmptyBorder JavaDoc(0,0,0,12));
203         layout.setConstraints(label,cons);
204         pathAndFilterPanel.add(label);
205
206         pathField = new HistoryTextField("vfs.browser.path");
207         pathField.addKeyListener(keyListener);
208         pathField.setInstantPopups(true);
209         pathField.setEnterAddsToHistory(false);
210         pathField.setSelectAllOnFocus(true);
211
212         // because its preferred size can be quite wide, we
213
// don't want it to make the browser way too big,
214
// so set the preferred width to 0.
215
Dimension prefSize = pathField.getPreferredSize();
216         prefSize.width = 0;
217         pathField.setPreferredSize(prefSize);
218         pathField.addActionListener(actionHandler);
219         cons.gridx = 1;
220         cons.weightx = 1;
221         cons.gridwidth = GridBagConstraints.REMAINDER;
222
223         layout.setConstraints(pathField,cons);
224         pathAndFilterPanel.add(pathField);
225
226         filterCheckbox = new JCheckBox(jEdit.getProperty("vfs.browser.filter"));
227         filterCheckbox.setMargin(new Insets(0,0,0,0));
228         filterCheckbox.setRequestFocusEnabled(false);
229         filterCheckbox.setBorder(new EmptyBorder JavaDoc(0,0,0,12));
230         filterCheckbox.setSelected(jEdit.getBooleanProperty(
231             "vfs.browser.filter-enabled"));
232
233         filterCheckbox.addActionListener(actionHandler);
234         filterCheckbox.addKeyListener(keyListener);
235         if(mode != CHOOSE_DIRECTORY_DIALOG)
236         {
237             cons.gridwidth = 1;
238             cons.gridx = 0;
239             cons.weightx = 0;
240             cons.gridy = 1;
241             layout.setConstraints(filterCheckbox,cons);
242             pathAndFilterPanel.add(filterCheckbox);
243         }
244
245         filterField = new JComboBox();
246         filterEditor = new HistoryComboBoxEditor("vfs.browser.filter");
247         filterEditor.setInstantPopups(true);
248         filterEditor.setSelectAllOnFocus(true);
249         filterEditor.addActionListener(actionHandler);
250         filterEditor.addKeyListener(keyListener);
251         String JavaDoc filter;
252         if(mode == BROWSER || !jEdit.getBooleanProperty(
253             "vfs.browser.currentBufferFilter"))
254         {
255             filter = jEdit.getProperty("vfs.browser.last-filter");
256             if(filter == null)
257                 filter = jEdit.getProperty("vfs.browser.default-filter");
258         }
259         else
260         {
261             String JavaDoc ext = MiscUtilities.getFileExtension(
262                 view.getBuffer().getName());
263             if(ext.length() == 0)
264                 filter = jEdit.getProperty("vfs.browser.default-filter");
265             else
266                 filter = '*' + ext;
267         }
268
269         // filterField.getEditor().setItem(new GlobVFSFileFilter(filter));
270
// filterField.addItem(filterField.getEditor().getItem());
271
filterEditor.setItem(new GlobVFSFileFilter(filter));
272         filterField.addItem(filterEditor.getItem());
273         filterField.addItemListener(actionHandler);
274         filterField.setRenderer(new VFSFileFilterRenderer());
275
276         // loads the registered VFSFileFilter services.
277
String JavaDoc[] _filters = ServiceManager.getServiceNames(VFSFileFilter.SERVICE_NAME);
278         for (int i = 0; i < _filters.length; i++)
279         {
280             VFSFileFilter _filter = (VFSFileFilter)
281                 ServiceManager.getService(VFSFileFilter.SERVICE_NAME, _filters[i]);
282             filterField.addItem(_filter);
283         }
284
285         if(mode != CHOOSE_DIRECTORY_DIALOG)
286         {
287             cons.gridwidth = GridBagConstraints.REMAINDER;
288             cons.fill = GridBagConstraints.HORIZONTAL;
289             cons.gridx = 1;
290             cons.weightx = 1;
291             if (filterField.getItemCount() > 1)
292             {
293                 filterField.setEditor(filterEditor);
294                 filterField.setEditable(true);
295                 layout.setConstraints(filterField,cons);
296                 pathAndFilterPanel.add(filterField);
297             }
298             else
299             {
300                 layout.setConstraints(filterEditor,cons);
301                 pathAndFilterPanel.add(filterEditor);
302             }
303         }
304
305         topBox.add(pathAndFilterPanel);
306         add(BorderLayout.NORTH,topBox);
307
308         add(BorderLayout.CENTER,browserView = new BrowserView(this));
309
310         propertiesChanged();
311
312         updateFilterEnabled();
313
314         setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
315         // see VFSBrowser.browseDirectory()
316
if(path == null)
317             path = jEdit.getProperty("vfs.browser.path.tmp");
318
319         if(path == null || path.length() == 0)
320         {
321             String JavaDoc userHome = System.getProperty("user.home");
322             String JavaDoc defaultPath = jEdit.getProperty("vfs.browser.defaultPath");
323             if(defaultPath.equals("home"))
324                 path = userHome;
325             else if(defaultPath.equals("working"))
326                 path = System.getProperty("user.dir");
327             else if(defaultPath.equals("buffer"))
328             {
329                 Buffer buffer = view.getBuffer();
330                 path = buffer.getDirectory();
331             }
332             else if(defaultPath.equals("last"))
333             {
334                 HistoryModel pathModel = HistoryModel.getModel("vfs.browser.path");
335                 if(pathModel.getSize() == 0)
336                     path = "~";
337                 else
338                     path = pathModel.getItem(0);
339             }
340             else if(defaultPath.equals("favorites"))
341                 path = "favorites:";
342             else
343             {
344                 // unknown value??!!!
345
path = userHome;
346             }
347         }
348
349         final String JavaDoc _path = path;
350
351         SwingUtilities.invokeLater(new Runnable JavaDoc()
352         {
353             public void run()
354             {
355                 setDirectory(_path);
356             }
357         });
358     } //}}}
359

360     //{{{ focusOnDefaultComponent() method
361
public void focusOnDefaultComponent()
362     {
363         pathField.requestFocus();
364     // browserView.focusOnFileView();
365
} //}}}
366

367     //{{{ addNotify() method
368
public void addNotify()
369     {
370         super.addNotify();
371         EditBus.addToBus(this);
372     } //}}}
373

374     //{{{ removeNotify() method
375
public void removeNotify()
376     {
377         super.removeNotify();
378         jEdit.setBooleanProperty("vfs.browser.filter-enabled",
379             filterCheckbox.isSelected());
380         if(mode == BROWSER || !jEdit.getBooleanProperty(
381             "vfs.browser.currentBufferFilter"))
382         {
383             VFSFileFilter selectedFilter =
384                 (VFSFileFilter) filterField.getSelectedItem();
385             if (selectedFilter instanceof GlobVFSFileFilter)
386                 jEdit.setProperty("vfs.browser.last-filter",
387                     ((GlobVFSFileFilter)selectedFilter).getGlob());
388         }
389         EditBus.removeFromBus(this);
390     } //}}}
391

392     //{{{ handleMessage() method
393
public void handleMessage(EBMessage msg)
394     {
395         if(msg instanceof PropertiesChanged)
396             propertiesChanged();
397         else if(msg instanceof BufferUpdate)
398         {
399             BufferUpdate bmsg = (BufferUpdate)msg;
400             if(bmsg.getWhat() == BufferUpdate.CREATED
401                 || bmsg.getWhat() == BufferUpdate.CLOSED)
402                 browserView.updateFileView();
403         }
404         else if(msg instanceof PluginUpdate)
405         {
406             PluginUpdate pmsg = (PluginUpdate)msg;
407             if((pmsg.getWhat() == PluginUpdate.LOADED ||
408                pmsg.getWhat() == PluginUpdate.UNLOADED) &&
409                 plugins != null /* plugins can be null if the VFSBrowser menu bar is hidden */)
410             {
411                 plugins.updatePopupMenu();
412             }
413         }
414         else if(msg instanceof VFSUpdate)
415         {
416             maybeReloadDirectory(((VFSUpdate)msg).getPath());
417         }
418     } //}}}
419

420     //{{{ getView() method
421
public View getView()
422     {
423         return view;
424     } //}}}
425

426     //{{{ getMode() method
427
public int getMode()
428     {
429         return mode;
430     } //}}}
431

432     //{{{ isMultipleSelectionEnabled() method
433
public boolean isMultipleSelectionEnabled()
434     {
435         return multipleSelection;
436     } //}}}
437

438     //{{{ isHorizontalLayout() method
439
public boolean isHorizontalLayout()
440     {
441         return horizontalLayout;
442     } //}}}
443

444     //{{{ getShowHiddenFiles() method
445
public boolean getShowHiddenFiles()
446     {
447         return showHiddenFiles;
448     } //}}}
449

450     //{{{ setShowHiddenFiles() method
451
public void setShowHiddenFiles(boolean showHiddenFiles)
452     {
453         this.showHiddenFiles = showHiddenFiles;
454     } //}}}
455

456     //{{{ getFilenameFilter() method
457
/**
458      * Returns the file name filter glob.
459      * @since jEdit 3.2pre2
460      * @deprecated Use {@link #getVFSFileFilter()} instead. This method
461      * might return wrong information since jEdit 4.3pre6.
462      */

463     public String JavaDoc getFilenameFilter()
464     {
465         if(filterCheckbox.isSelected())
466         {
467             String JavaDoc filter = filterField.getSelectedItem().toString();
468             if(filter.length() == 0)
469                 return "*";
470             else
471                 return filter;
472         }
473         else
474             return "*";
475     } //}}}
476

477     //{{{ getVFSFileFilter() method
478
/**
479      * Returns the currently active VFSFileFilter.
480      *
481      * @since jEdit 4.3pre7
482      */

483     public VFSFileFilter getVFSFileFilter()
484     {
485         if (mode == CHOOSE_DIRECTORY_DIALOG)
486             return new DirectoriesOnlyFilter();
487         return (VFSFileFilter) filterField.getSelectedItem();
488     } //}}}
489

490     //{{{ addVFSFileFilter() method
491
/**
492      * Adds a file filter to the browser.
493      *
494      * @since jEdit 4.3pre7
495      */

496     public void addVFSFileFilter(VFSFileFilter filter) {
497         filterField.addItem(filter);
498         if (filterField.getItemCount() == 2)
499         {
500             filterField.setEditor(filterEditor);
501             filterField.setEditable(true);
502
503             GridBagLayout layout = (GridBagLayout) pathAndFilterPanel.getLayout();
504             GridBagConstraints cons =layout.getConstraints(filterEditor);
505             cons.gridwidth = GridBagConstraints.REMAINDER;
506             cons.fill = GridBagConstraints.HORIZONTAL;
507             cons.gridx = 1;
508             cons.weightx = 1;
509
510             pathAndFilterPanel.remove(filterEditor);
511             layout.setConstraints(filterField, cons);
512             pathAndFilterPanel.add(filterField);
513             pathAndFilterPanel.validate();
514             pathAndFilterPanel.repaint();
515         }
516     } //}}}
517

518     //{{{ setFilenameFilter() method
519
public void setFilenameFilter(String JavaDoc filter)
520     {
521         if(filter == null || filter.length() == 0 || filter.equals("*"))
522             filterCheckbox.setSelected(false);
523         else
524         {
525             filterCheckbox.setSelected(true);
526             filterEditor.setItem(new GlobVFSFileFilter(filter));
527         }
528     } //}}}
529

530     //{{{ getDirectoryField() method
531
public HistoryTextField getDirectoryField()
532     {
533         return pathField;
534     } //}}}
535

536     //{{{ getDirectory() method
537
public String JavaDoc getDirectory()
538     {
539         return path;
540     } //}}}
541

542     //{{{ setDirectory() method
543
public void setDirectory(String JavaDoc path)
544     {
545         if(path.startsWith("file:"))
546             path = path.substring(5);
547         path = MiscUtilities.expandVariables(path);
548         pathField.setText(path);
549
550         if(!startRequest())
551             return;
552
553         browserView.saveExpansionState();
554         browserView.loadDirectory(null,path,true);
555         this.path = path;
556
557         VFSManager.runInAWTThread(new Runnable JavaDoc()
558         {
559             public void run()
560             {
561                 endRequest();
562             }
563         });
564     } //}}}
565

566     //{{{ getRootDirectory() method
567
public static String JavaDoc getRootDirectory()
568     {
569         if(OperatingSystem.isMacOS() || OperatingSystem.isDOSDerived())
570             return FileRootsVFS.PROTOCOL + ':';
571         else
572             return "/";
573     } //}}}
574

575     //{{{ rootDirectory() method
576
/**
577      * Goes to the local drives directory.
578      * @since jEdit 4.0pre4
579      */

580     public void rootDirectory()
581     {
582         setDirectory(getRootDirectory());
583     } //}}}
584

585     //{{{ reloadDirectory() method
586
public void reloadDirectory()
587     {
588         // used by FTP plugin to clear directory cache
589
VFSManager.getVFSForPath(path).reloadDirectory(path);
590
591         browserView.saveExpansionState();
592         browserView.loadDirectory(null,path,false);
593     } //}}}
594

595     //{{{ delete() method
596
/**
597      * Note that all files must be on the same VFS.
598      * @since jEdit 4.3pre2
599      */

600     public void delete(VFSFile[] files)
601     {
602         String JavaDoc dialogType;
603
604         if(MiscUtilities.isURL(files[0].getDeletePath())
605             && FavoritesVFS.PROTOCOL.equals(
606             MiscUtilities.getProtocolOfURL(files[0].getDeletePath())))
607         {
608             dialogType = "vfs.browser.delete-favorites";
609         }
610         else
611         {
612             dialogType = "vfs.browser.delete-confirm";
613         }
614
615         StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
616         String JavaDoc typeStr = "files";
617         for(int i = 0; i < files.length; i++)
618         {
619             buf.append(files[i].getPath());
620             buf.append('\n');
621             if (files[i].getType() == VFSFile.DIRECTORY)
622                 typeStr = "directories and their contents";
623         }
624
625         Object JavaDoc[] args = { buf.toString(), typeStr};
626         
627         int result = GUIUtilities.confirm(this,dialogType,args,
628             JOptionPane.YES_NO_OPTION,
629             JOptionPane.WARNING_MESSAGE);
630         if(result != JOptionPane.YES_OPTION)
631             return;
632
633         VFS vfs = VFSManager.getVFSForPath(files[0].getDeletePath());
634
635         if(!startRequest())
636             return;
637
638         for(int i = 0; i < files.length; i++)
639         {
640             Object JavaDoc session = vfs.createVFSSession(files[i].getDeletePath(),this);
641             if(session == null)
642                 continue;
643
644             VFSManager.runInWorkThread(new BrowserIORequest(
645                 BrowserIORequest.DELETE,this,
646                 session,vfs,files[i].getDeletePath(),
647                 null,null));
648         }
649
650         VFSManager.runInAWTThread(new Runnable JavaDoc()
651         {
652             public void run()
653             {
654                 endRequest();
655             }
656         });
657     } //}}}
658

659     //{{{ rename() method
660
public void rename(String JavaDoc from)
661     {
662         VFS vfs = VFSManager.getVFSForPath(from);
663
664         String JavaDoc filename = vfs.getFileName(from);
665         String JavaDoc[] args = { filename };
666         String JavaDoc to = GUIUtilities.input(this,"vfs.browser.rename",
667             args,filename);
668         if(to == null)
669             return;
670
671         to = MiscUtilities.constructPath(vfs.getParentOfPath(from),to);
672
673         Object JavaDoc session = vfs.createVFSSession(from,this);
674         if(session == null)
675             return;
676
677         if(!startRequest())
678             return;
679
680         VFSManager.runInWorkThread(new BrowserIORequest(
681             BrowserIORequest.RENAME,this,
682             session,vfs,from,to,null));
683
684         VFSManager.runInAWTThread(new Runnable JavaDoc()
685         {
686             public void run()
687             {
688                 endRequest();
689             }
690         });
691     } //}}}
692

693     //{{{ mkdir() method
694
public void mkdir()
695     {
696         String JavaDoc newDirectory = GUIUtilities.input(this,"vfs.browser.mkdir",null);
697         if(newDirectory == null)
698             return;
699
700         // if a directory is selected, create new dir in there.
701
// if a file is selected, create new dir inside its parent.
702
VFSFile[] selected = getSelectedFiles();
703         String JavaDoc parent;
704         if(selected.length == 0)
705             parent = path;
706         else if(selected[0].getType() == VFSFile.FILE)
707         {
708             parent = selected[0].getPath();
709             parent = VFSManager.getVFSForPath(parent)
710                 .getParentOfPath(parent);
711         }
712         else
713             parent = selected[0].getPath();
714
715         VFS vfs = VFSManager.getVFSForPath(parent);
716
717         // path is the currently viewed directory in the browser
718
newDirectory = MiscUtilities.constructPath(parent,newDirectory);
719
720         Object JavaDoc session = vfs.createVFSSession(newDirectory,this);
721         if(session == null)
722             return;
723
724         if(!startRequest())
725             return;
726
727         VFSManager.runInWorkThread(new BrowserIORequest(
728             BrowserIORequest.MKDIR,this,
729             session,vfs,newDirectory,null,null));
730
731         VFSManager.runInAWTThread(new Runnable JavaDoc()
732         {
733             public void run()
734             {
735                 endRequest();
736             }
737         });
738     } //}}}
739

740     //{{{ newFile() method
741
/**
742      * Creates a new file in the current directory.
743      * @since jEdit 4.0pre2
744      */

745     public void newFile()
746     {
747         VFSFile[] selected = getSelectedFiles();
748         if(selected.length >= 1)
749         {
750             VFSFile file = selected[0];
751             if(file.getType() == VFSFile.DIRECTORY)
752                 jEdit.newFile(view,file.getPath());
753             else
754             {
755                 VFS vfs = VFSManager.getVFSForPath(file.getPath());
756                 jEdit.newFile(view,vfs.getParentOfPath(file.getPath()));
757             }
758         }
759         else
760             jEdit.newFile(view,path);
761     } //}}}
762

763     //{{{ searchInDirectory() method
764
/**
765      * Opens a directory search in the current directory.
766      * @since jEdit 4.0pre2
767      */

768     public void searchInDirectory()
769     {
770         VFSFile[] selected = getSelectedFiles();
771         if(selected.length >= 1)
772         {
773             VFSFile file = selected[0];
774             searchInDirectory(file.getPath(),file.getType() != VFSFile.FILE);
775         }
776         else
777         {
778             searchInDirectory(path,true);
779         }
780     } //}}}
781

782     //{{{ searchInDirectory() method
783
/**
784      * Opens a directory search in the specified directory.
785      * @param path The path name
786      * @param directory True if the path is a directory, false if it is a file
787      * @since jEdit 4.2pre1
788      */

789     public void searchInDirectory(String JavaDoc path, boolean directory)
790     {
791         String JavaDoc filter;
792         VFSFileFilter vfsff = getVFSFileFilter();
793         if (vfsff instanceof GlobVFSFileFilter)
794             filter = ((GlobVFSFileFilter)vfsff).getGlob();
795         else
796             filter = "*";
797
798         if (!directory)
799         {
800             String JavaDoc name = MiscUtilities.getFileName(path);
801             String JavaDoc ext = MiscUtilities.getFileExtension(name);
802             filter = (ext == null || ext.length() == 0
803                 ? filter : '*' + ext);
804             path = MiscUtilities.getParentOfPath(path);
805         }
806
807         SearchAndReplace.setSearchFileSet(new DirectoryListSet(
808             path,filter,true));
809         SearchDialog.showSearchDialog(view,null,SearchDialog.DIRECTORY);
810     } //}}}
811

812     //{{{ getBrowserView() method
813
public BrowserView getBrowserView()
814     {
815         return browserView;
816     } //}}}
817

818     //{{{ getSelectedFiles() method
819
/**
820      * @since jEdit 4.3pre2
821      */

822     public VFSFile[] getSelectedFiles()
823     {
824         return browserView.getSelectedFiles();
825     } //}}}
826

827     //{{{ locateFile() method
828
/**
829      * Goes to the given file's directory and selects the file in the list.
830      * @param path The file
831      * @since jEdit 4.2pre2
832      */

833     public void locateFile(final String JavaDoc path)
834     {
835         VFSFileFilter filter = getVFSFileFilter();
836         if(!filter.accept(MiscUtilities.getFileName(path)))
837             setFilenameFilter(null);
838
839         setDirectory(MiscUtilities.getParentOfPath(path));
840         VFSManager.runInAWTThread(new Runnable JavaDoc()
841         {
842             public void run()
843             {
844                 browserView.getTable().selectFile(path);
845             }
846         });
847     } //}}}
848

849     //{{{ createPluginsMenu() method
850
public JComponent createPluginsMenu(JComponent pluginMenu, boolean showManagerOptions)
851     {
852         ActionHandler actionHandler = new ActionHandler();
853         if(showManagerOptions && getMode() == BROWSER)
854         {
855             pluginMenu.add(GUIUtilities.loadMenuItem("plugin-manager",false));
856             pluginMenu.add(GUIUtilities.loadMenuItem("plugin-options",false));
857             if (pluginMenu instanceof JMenu)
858                 ((JMenu)pluginMenu).addSeparator();
859             else if (pluginMenu instanceof JPopupMenu)
860                 ((JPopupMenu)pluginMenu).addSeparator();
861
862         }
863         else
864             /* we're in a modal dialog */;
865
866         List JavaDoc<JMenuItem> vec = new ArrayList<JMenuItem>();
867
868         //{{{ old API
869
Enumeration<VFS> e = VFSManager.getFilesystems();
870
871         while(e.hasMoreElements())
872         {
873             VFS vfs = (VFS)e.nextElement();
874             if((vfs.getCapabilities() & VFS.BROWSE_CAP) == 0)
875                 continue;
876
877                 JMenuItem menuItem = new JMenuItem(jEdit.getProperty(
878                         "vfs." + vfs.getName() + ".label"));
879                 menuItem.setActionCommand(vfs.getName());
880                 menuItem.addActionListener(actionHandler);
881                 vec.add(menuItem);
882         } //}}}
883

884         //{{{ new API
885
EditPlugin[] plugins = jEdit.getPlugins();
886         for (int i = 0; i < plugins.length; i++)
887         {
888             JMenuItem menuItem = plugins[i].createBrowserMenuItems();
889             if(menuItem != null)
890                 vec.add(menuItem);
891         } //}}}
892

893         if (!vec.isEmpty())
894         {
895             Collections.sort(vec,new MiscUtilities.MenuItemCompare());
896             for(int i = 0; i < vec.size(); i++)
897                 pluginMenu.add(vec.get(i));
898         }
899         else
900         {
901             JMenuItem mi = new JMenuItem(jEdit.getProperty(
902                     "vfs.browser.plugins.no-plugins.label"));
903             mi.setEnabled(false);
904             pluginMenu.add(mi);
905         }
906
907         return pluginMenu;
908     } //}}}
909

910     //{{{ addBrowserListener() method
911
public void addBrowserListener(BrowserListener l)
912     {
913         listenerList.add(BrowserListener.class,l);
914     } //}}}
915

916     //{{{ removeBrowserListener() method
917
public void removeBrowserListener(BrowserListener l)
918     {
919         listenerList.remove(BrowserListener.class,l);
920     } //}}}
921

922     //{{{ filesActivated() method
923
// canDoubleClickClose set to false when ENTER pressed
924
public static final int M_OPEN = 0;
925     public static final int M_OPEN_NEW_VIEW = 1;
926     public static final int M_OPEN_NEW_PLAIN_VIEW = 2;
927     public static final int M_OPEN_NEW_SPLIT = 3;
928     public static final int M_INSERT = 4;
929
930     /**
931      * This method does the "double-click" handling. It is public so that
932      * <code>browser.actions.xml</code> can bind to it.
933      * @since jEdit 4.2pre2
934      */

935     public void filesActivated(int mode, boolean canDoubleClickClose)
936     {
937         VFSFile[] selectedFiles = browserView.getSelectedFiles();
938
939         Buffer buffer = null;
940
941 check_selected: for(int i = 0; i < selectedFiles.length; i++)
942         {
943             VFSFile file = selectedFiles[i];
944
945             if(file.getType() == VFSFile.DIRECTORY
946                 || file.getType() == VFSFile.FILESYSTEM)
947             {
948                 if(mode == M_OPEN_NEW_VIEW && this.mode == BROWSER)
949                     browseDirectoryInNewWindow(view,file.getPath());
950                 else
951                     setDirectory(file.getPath());
952             }
953             else if(this.mode == BROWSER || this.mode == BROWSER_DIALOG)
954             {
955                 if(mode == M_INSERT)
956                 {
957                     view.getBuffer().insertFile(view,
958                         file.getPath());
959                     continue check_selected;
960                 }
961
962                 Buffer _buffer = jEdit.getBuffer(file.getPath());
963                 if(_buffer == null)
964                 {
965                     Hashtable props = new Hashtable();
966                     props.put(JEditBuffer.ENCODING,currentEncoding);
967                     props.put(Buffer.ENCODING_AUTODETECT,
968                           Boolean.valueOf(autoDetectEncoding));
969                     _buffer = jEdit.openFile(null,null,
970                         file.getPath(),false,props);
971                 }
972                 else if(doubleClickClose && canDoubleClickClose
973                     && this.mode != BROWSER_DIALOG
974                     && selectedFiles.length == 1)
975                 {
976                     // close if this buffer is currently
977
// visible in the view.
978
EditPane[] editPanes = view.getEditPanes();
979                     for(int j = 0; j < editPanes.length; j++)
980                     {
981                         if(editPanes[j].getBuffer() == _buffer)
982                         {
983                             jEdit.closeBuffer(view,_buffer);
984                             return;
985                         }
986                     }
987                 }
988
989                 if(_buffer != null)
990                     buffer = _buffer;
991             }
992             else
993             {
994                 // if a file is selected in OPEN_DIALOG or
995
// SAVE_DIALOG mode, just let the listener(s)
996
// handle it
997
}
998         }
999
1000        if(buffer != null)
1001        {
1002            switch(mode)
1003            {
1004            case M_OPEN:
1005                view.setBuffer(buffer);
1006                break;
1007            case M_OPEN_NEW_VIEW:
1008                jEdit.newView(view,buffer,false);
1009                break;
1010            case M_OPEN_NEW_PLAIN_VIEW:
1011                jEdit.newView(view,buffer,true);
1012                break;
1013            case M_OPEN_NEW_SPLIT:
1014                view.splitHorizontally().setBuffer(buffer);
1015                break;
1016            }
1017        }
1018
1019        Object JavaDoc[] listeners = listenerList.getListenerList();
1020        for(int i = 0; i < listeners.length; i++)
1021        {
1022            if(listeners[i] == BrowserListener.class)
1023            {
1024                BrowserListener l = (BrowserListener)listeners[i+1];
1025                l.filesActivated(this,selectedFiles);
1026            }
1027        }
1028    } //}}}
1029

1030    //{{{ Package-private members
1031
String JavaDoc currentEncoding;
1032    boolean autoDetectEncoding;
1033
1034    //{{{ directoryLoaded() method
1035
void directoryLoaded(Object JavaDoc node, Object JavaDoc[] loadInfo,
1036        boolean addToHistory)
1037    {
1038        VFSManager.runInAWTThread(new DirectoryLoadedAWTRequest(
1039            node,loadInfo,addToHistory));
1040    } //}}}
1041

1042    //{{{ filesSelected() method
1043
void filesSelected()
1044    {
1045        VFSFile[] selectedFiles = browserView.getSelectedFiles();
1046
1047        if(mode == BROWSER)
1048        {
1049            for(int i = 0; i < selectedFiles.length; i++)
1050            {
1051                VFSFile file = selectedFiles[i];
1052                Buffer buffer = jEdit.getBuffer(file.getPath());
1053                if(buffer != null && view != null)
1054                    view.setBuffer(buffer);
1055            }
1056        }
1057
1058        Object JavaDoc[] listeners = listenerList.getListenerList();
1059        for(int i = 0; i < listeners.length; i++)
1060        {
1061            if(listeners[i] == BrowserListener.class)
1062            {
1063                BrowserListener l = (BrowserListener)listeners[i+1];
1064                l.filesSelected(this,selectedFiles);
1065            }
1066        }
1067    } //}}}
1068

1069    //{{{ endRequest() method
1070
void endRequest()
1071    {
1072        requestRunning = false;
1073    } //}}}
1074

1075    //}}}
1076

1077    //{{{ Private members
1078

1079    private static ActionContext actionContext;
1080
1081    static
1082    {
1083        actionContext = new BrowserActionContext();
1084
1085        ActionSet builtInActionSet = new ActionSet(null,null,null,
1086            jEdit.class.getResource("browser.actions.xml"));
1087        builtInActionSet.setLabel(jEdit.getProperty("action-set.browser"));
1088        builtInActionSet.load();
1089        actionContext.addActionSet(builtInActionSet);
1090    }
1091
1092    //{{{ Instance variables
1093
private EventListenerList listenerList;
1094    private View view;
1095    private boolean horizontalLayout;
1096    private String JavaDoc path;
1097    private JPanel pathAndFilterPanel;
1098    private HistoryTextField pathField;
1099    private JCheckBox filterCheckbox;
1100    private HistoryComboBoxEditor filterEditor;
1101    private JComboBox filterField;
1102    private Box toolbarBox;
1103    private FavoritesMenuButton favorites;
1104    private PluginsMenuButton plugins;
1105    private BrowserView browserView;
1106    private int mode;
1107    private boolean multipleSelection;
1108
1109    private boolean showHiddenFiles;
1110    private boolean sortMixFilesAndDirs;
1111    private boolean sortIgnoreCase;
1112    private boolean doubleClickClose;
1113
1114    private boolean requestRunning;
1115    private boolean maybeReloadRequestRunning;
1116    //}}}
1117

1118    //{{{ createMenuBar() method
1119
private JPanel createMenuBar()
1120    {
1121        JPanel menuBar = new JPanel();
1122        menuBar.setLayout(new BoxLayout(menuBar,BoxLayout.X_AXIS));
1123        menuBar.setBorder(new EmptyBorder JavaDoc(0,1,0,3));
1124
1125        menuBar.add(new CommandsMenuButton());
1126        menuBar.add(Box.createHorizontalStrut(3));
1127        menuBar.add(plugins = new PluginsMenuButton());
1128        menuBar.add(Box.createHorizontalStrut(3));
1129        menuBar.add(favorites = new FavoritesMenuButton());
1130
1131        return menuBar;
1132    } //}}}
1133

1134    //{{{ createToolBar() method
1135
private Box createToolBar()
1136    {
1137        if(mode == BROWSER)
1138            return GUIUtilities.loadToolBar(actionContext,
1139                "vfs.browser.toolbar-browser");
1140        else
1141            return GUIUtilities.loadToolBar(actionContext,
1142                "vfs.browser.toolbar-dialog");
1143    } //}}}
1144

1145    //{{{ propertiesChanged() method
1146
private void propertiesChanged()
1147    {
1148        showHiddenFiles = jEdit.getBooleanProperty("vfs.browser.showHiddenFiles");
1149        sortMixFilesAndDirs = jEdit.getBooleanProperty("vfs.browser.sortMixFilesAndDirs");
1150        sortIgnoreCase = jEdit.getBooleanProperty("vfs.browser.sortIgnoreCase");
1151        doubleClickClose = jEdit.getBooleanProperty("vfs.browser.doubleClickClose");
1152
1153        browserView.propertiesChanged();
1154
1155        toolbarBox.removeAll();
1156
1157        if(jEdit.getBooleanProperty("vfs.browser.showToolbar"))
1158        {
1159            Box toolbar = createToolBar();
1160            if(horizontalLayout)
1161                toolbarBox.add(toolbar);
1162            else
1163            {
1164                toolbar.add(Box.createGlue());
1165                toolbarBox.add(toolbar);
1166            }
1167        }
1168
1169        if(jEdit.getBooleanProperty("vfs.browser.showMenubar"))
1170        {
1171            JPanel menubar = createMenuBar();
1172            if(horizontalLayout)
1173            {
1174                toolbarBox.add(Box.createHorizontalStrut(6));
1175                toolbarBox.add(menubar,0);
1176            }
1177            else
1178            {
1179                menubar.add(Box.createGlue());
1180                toolbarBox.add(menubar);
1181            }
1182        }
1183        else
1184        {
1185            plugins = null;
1186            favorites = null;
1187        }
1188
1189        toolbarBox.add(Box.createGlue());
1190
1191        revalidate();
1192
1193        if(path != null)
1194            reloadDirectory();
1195    } //}}}
1196

1197    /* We do this stuff because the browser is not able to handle
1198     * more than one request yet */

1199
1200    //{{{ startRequest() method
1201
private boolean startRequest()
1202    {
1203        if(requestRunning)
1204        {
1205            // dump stack trace for debugging purposes
1206
Log.log(Log.DEBUG,this,new Throwable JavaDoc("For debugging purposes"));
1207
1208            GUIUtilities.error(this,"browser-multiple-io",null);
1209            return false;
1210        }
1211        else
1212        {
1213            requestRunning = true;
1214            return true;
1215        }
1216    } //}}}
1217

1218    //{{{ updateFilterEnabled() method
1219
private void updateFilterEnabled()
1220    {
1221        filterField.setEnabled(filterCheckbox.isSelected());
1222        filterEditor.setEnabled(filterCheckbox.isSelected());
1223    } //}}}
1224

1225    //{{{ maybeReloadDirectory() method
1226
private void maybeReloadDirectory(String JavaDoc dir)
1227    {
1228        if(MiscUtilities.isURL(dir)
1229            && MiscUtilities.getProtocolOfURL(dir).equals(
1230            FavoritesVFS.PROTOCOL))
1231        {
1232            if(favorites != null)
1233                favorites.popup = null;
1234        }
1235
1236        // this is a dirty hack and it relies on the fact
1237
// that updates for parents are sent before updates
1238
// for the changed nodes themselves (if this was not
1239
// the case, the browser wouldn't be updated properly
1240
// on delete, etc).
1241
//
1242
// to avoid causing '> 1 request' errors, don't reload
1243
// directory if request already active
1244
if(maybeReloadRequestRunning)
1245        {
1246            //Log.log(Log.WARNING,this,"VFS update: request already in progress");
1247
return;
1248        }
1249
1250        // save a file -> sends vfs update. if a VFS file dialog box
1251
// is shown from the same event frame as the save, the
1252
// VFSUpdate will be delivered before the directory is loaded,
1253
// and before the path is set.
1254
if(path != null)
1255        {
1256            try
1257            {
1258                maybeReloadRequestRunning = true;
1259
1260                browserView.maybeReloadDirectory(dir);
1261            }
1262            finally
1263            {
1264                VFSManager.runInAWTThread(new Runnable JavaDoc()
1265                {
1266                    public void run()
1267                    {
1268                        maybeReloadRequestRunning = false;
1269                    }
1270                });
1271            }
1272        }
1273    } //}}}
1274

1275    //}}}
1276

1277    //{{{ Inner classes
1278

1279    //{{{ ActionHandler class
1280
class ActionHandler implements ActionListener, ItemListener
1281    {
1282        public void actionPerformed(ActionEvent evt)
1283        {
1284            if (isProcessingEvent)
1285                return;
1286
1287            Object JavaDoc source = evt.getSource();
1288
1289            if (source == pathField
1290                || source == filterCheckbox)
1291            {
1292                isProcessingEvent = true;
1293                resetLater();
1294
1295                updateFilterEnabled();
1296
1297                String JavaDoc p = pathField.getText();
1298                
1299                if(p != null)
1300                    setDirectory(p);
1301                browserView.focusOnFileView();
1302            }
1303
1304            else if (source == filterField.getEditor())
1305            {
1306                // force the editor to refresh.
1307
filterField.getEditor().setItem(
1308                    filterField.getEditor().getItem());
1309            }
1310
1311            // depending on Swing look & feel, filterField.getEditor()
1312
// returns some ComboBoxUI
1313
else if (source == filterEditor)
1314            {
1315                // force the editor to refresh.
1316
filterEditor.setItem(
1317                    filterEditor.getItem());
1318                filterField.setSelectedItem(
1319                    filterEditor.getItem());
1320                // ### ugly:
1321
// itemStateChanged does not seem to get fired
1322
itemStateChanged(new ItemEvent(filterField,
1323                    ItemEvent.ITEM_STATE_CHANGED,
1324                    filterEditor.getItem(),
1325                    ItemEvent.SELECTED));
1326            }
1327        }
1328
1329        public void itemStateChanged(ItemEvent e)
1330        {
1331            if (isProcessingEvent)
1332                return;
1333
1334            if (e.getStateChange() != ItemEvent.SELECTED)
1335                return;
1336
1337            isProcessingEvent = true;
1338            resetLater();
1339
1340            filterField.setEditable(e.getItem() instanceof GlobVFSFileFilter);
1341            updateFilterEnabled();
1342            String JavaDoc path = pathField.getText();
1343            if(path != null)
1344                setDirectory(path);
1345
1346            browserView.focusOnFileView();
1347        }
1348
1349        /**
1350         * Why this method exists: since both actionPerformed()
1351         * and itemStateChanged() above can change the combo box,
1352         * executing one of them can cause a chain reaction causing
1353         * the other method to be called. This would cause the
1354         * VFS subsystem to be called several times, which would
1355         * cause a warning to show up if the first operation is
1356         * still in progress, or cause a second operation to happen
1357         * which is not really wanted especially if we're talking
1358         * about a remove VFS. So the methods set a flag saying
1359         * that something is going on, and this method resets
1360         * the flag after the AWT thread is done with the
1361         * current events.
1362         */

1363        private void resetLater() {
1364            SwingUtilities.invokeLater(
1365                new Runnable JavaDoc()
1366                {
1367                    public void run()
1368                    {
1369                        isProcessingEvent = false;
1370                    }
1371                }
1372            );
1373        }
1374
1375        private boolean isProcessingEvent;
1376
1377    } //}}}
1378

1379    //{{{ CommandsMenuButton class
1380
class CommandsMenuButton extends JButton
1381    {
1382        //{{{ CommandsMenuButton constructor
1383
CommandsMenuButton()
1384        {
1385            setText(jEdit.getProperty("vfs.browser.commands.label"));
1386            setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
1387            setHorizontalTextPosition(SwingConstants.LEADING);
1388
1389            popup = new BrowserCommandsMenu(VFSBrowser.this,null);
1390
1391            CommandsMenuButton.this.setRequestFocusEnabled(false);
1392            setMargin(new Insets(1,1,1,1));
1393            CommandsMenuButton.this.addMouseListener(new MouseHandler());
1394
1395            if(OperatingSystem.isMacOSLF())
1396                CommandsMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
1397        } //}}}
1398

1399        BrowserCommandsMenu popup;
1400
1401        //{{{ MouseHandler class
1402
class MouseHandler extends MouseAdapter
1403        {
1404            public void mousePressed(MouseEvent evt)
1405            {
1406                if(!popup.isVisible())
1407                {
1408                    popup.update();
1409
1410                    GUIUtilities.showPopupMenu(
1411                        popup,CommandsMenuButton.this,0,
1412                        CommandsMenuButton.this.getHeight(),
1413                        false);
1414                }
1415                else
1416                {
1417                    popup.setVisible(false);
1418                }
1419            }
1420        } //}}}
1421
} //}}}
1422

1423    //{{{ PluginsMenuButton class
1424
class PluginsMenuButton extends JButton
1425    {
1426        //{{{ PluginsMenuButton constructor
1427
PluginsMenuButton()
1428        {
1429            setText(jEdit.getProperty("vfs.browser.plugins.label"));
1430            setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
1431            setHorizontalTextPosition(SwingConstants.LEADING);
1432
1433            PluginsMenuButton.this.setRequestFocusEnabled(false);
1434            setMargin(new Insets(1,1,1,1));
1435            PluginsMenuButton.this.addMouseListener(new MouseHandler());
1436
1437            if(OperatingSystem.isMacOSLF())
1438                PluginsMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
1439        } //}}}
1440

1441        JPopupMenu popup;
1442
1443        //{{{ updatePopupMenu() method
1444
void updatePopupMenu()
1445        {
1446            popup = null;
1447        } //}}}
1448

1449        //{{{ createPopupMenu() method
1450
private void createPopupMenu()
1451        {
1452            if(popup != null)
1453                return;
1454
1455            popup = (JPopupMenu)createPluginsMenu(new JPopupMenu(),true);
1456        } //}}}
1457

1458        //{{{ ActionHandler class
1459
class ActionHandler implements ActionListener
1460        {
1461            public void actionPerformed(ActionEvent evt)
1462            {
1463                VFS vfs = VFSManager.getVFSByName(evt.getActionCommand());
1464                String JavaDoc directory = vfs.showBrowseDialog(null,
1465                    VFSBrowser.this);
1466                if(directory != null)
1467                    setDirectory(directory);
1468            }
1469        } //}}}
1470

1471        //{{{ MouseHandler class
1472
class MouseHandler extends MouseAdapter
1473        {
1474            public void mousePressed(MouseEvent evt)
1475            {
1476                createPopupMenu();
1477
1478                if(!popup.isVisible())
1479                {
1480                    GUIUtilities.showPopupMenu(
1481                        popup,PluginsMenuButton.this,0,
1482                        PluginsMenuButton.this.getHeight(),
1483                        false);
1484                }
1485                else
1486                {
1487                    popup.setVisible(false);
1488                }
1489            }
1490        } //}}}
1491
} //}}}
1492

1493    //{{{ FavoritesMenuButton class
1494
class FavoritesMenuButton extends JButton
1495    {
1496        //{{{ FavoritesMenuButton constructor
1497
FavoritesMenuButton()
1498        {
1499            setText(jEdit.getProperty("vfs.browser.favorites.label"));
1500            setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
1501            setHorizontalTextPosition(SwingConstants.LEADING);
1502
1503            FavoritesMenuButton.this.setRequestFocusEnabled(false);
1504            setMargin(new Insets(1,1,1,1));
1505            FavoritesMenuButton.this.addMouseListener(new MouseHandler());
1506
1507            if(OperatingSystem.isMacOSLF())
1508                FavoritesMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
1509        } //}}}
1510

1511        JPopupMenu popup;
1512
1513        //{{{ createPopupMenu() method
1514
void createPopupMenu()
1515        {
1516            popup = new JPopupMenu();
1517            ActionHandler actionHandler = new ActionHandler();
1518
1519            JMenuItem mi = new JMenuItem(
1520                jEdit.getProperty(
1521                "vfs.browser.favorites"
1522                + ".add-to-favorites.label"));
1523            mi.setActionCommand("add-to-favorites");
1524            mi.addActionListener(actionHandler);
1525            popup.add(mi);
1526
1527            mi = new JMenuItem(
1528                jEdit.getProperty(
1529                "vfs.browser.favorites"
1530                + ".edit-favorites.label"));
1531            mi.setActionCommand("dir@favorites:");
1532            mi.addActionListener(actionHandler);
1533            popup.add(mi);
1534
1535            popup.addSeparator();
1536
1537            VFSFile[] favorites = FavoritesVFS.getFavorites();
1538            if(favorites.length == 0)
1539            {
1540                mi = new JMenuItem(
1541                    jEdit.getProperty(
1542                    "vfs.browser.favorites"
1543                    + ".no-favorites.label"));
1544                mi.setEnabled(false);
1545                popup.add(mi);
1546            }
1547            else
1548            {
1549                Arrays.sort(favorites,
1550                    new VFS.DirectoryEntryCompare(
1551                    sortMixFilesAndDirs,
1552                    sortIgnoreCase));
1553                for(int i = 0; i < favorites.length; i++)
1554                {
1555                    VFSFile favorite = favorites[i];
1556                    mi = new JMenuItem(favorite.getPath());
1557                    mi.setIcon(FileCellRenderer
1558                        .getIconForFile(
1559                        favorite,false));
1560                    String JavaDoc cmd = (favorite.getType() ==
1561                        VFSFile.FILE
1562                        ? "file@" : "dir@")
1563                        + favorite.getPath();
1564                    mi.setActionCommand(cmd);
1565                    mi.addActionListener(actionHandler);
1566                    popup.add(mi);
1567                }
1568            }
1569        } //}}}
1570

1571        //{{{ ActionHandler class
1572
class ActionHandler implements ActionListener
1573        {
1574            public void actionPerformed(ActionEvent evt)
1575            {
1576                String JavaDoc actionCommand = evt.getActionCommand();
1577                if(actionCommand.equals("add-to-favorites"))
1578                {
1579                    // if any directories are selected, add
1580
// them, otherwise add current directory
1581
VFSFile[] selected = getSelectedFiles();
1582                    if(selected == null || selected.length == 0)
1583                    {
1584                        if(path.equals(FavoritesVFS.PROTOCOL + ':'))
1585                        {
1586                            GUIUtilities.error(VFSBrowser.this,
1587                                "vfs.browser.recurse-favorites",
1588                                null);
1589                        }
1590                        else
1591                        {
1592                            FavoritesVFS.addToFavorites(path,
1593                                VFSFile.DIRECTORY);
1594                        }
1595                    }
1596                    else
1597                    {
1598                        for(int i = 0; i < selected.length; i++)
1599                        {
1600                            VFSFile file = selected[i];
1601                            FavoritesVFS.addToFavorites(file.getPath(),
1602                                file.getType());
1603                        }
1604                    }
1605                }
1606                else if(actionCommand.startsWith("dir@"))
1607                {
1608                    setDirectory(actionCommand.substring(4));
1609                }
1610                else if(actionCommand.startsWith("file@"))
1611                {
1612                    switch(getMode())
1613                    {
1614                    case BROWSER:
1615                        jEdit.openFile(view,actionCommand.substring(5));
1616                        break;
1617                    default:
1618                        locateFile(actionCommand.substring(5));
1619                        break;
1620                    }
1621                }
1622            }
1623        } //}}}
1624

1625        //{{{ MouseHandler class
1626
class MouseHandler extends MouseAdapter
1627        {
1628            public void mousePressed(MouseEvent evt)
1629            {
1630                if(popup != null && popup.isVisible())
1631                {
1632                    popup.setVisible(false);
1633                    return;
1634                }
1635
1636                if(popup == null)
1637                    createPopupMenu();
1638
1639                GUIUtilities.showPopupMenu(
1640                    popup,FavoritesMenuButton.this,0,
1641                    FavoritesMenuButton.this.getHeight(),
1642                    false);
1643            }
1644        } //}}}
1645
} //}}}
1646

1647    //{{{ DirectoryLoadedAWTRequest class
1648
class DirectoryLoadedAWTRequest implements Runnable JavaDoc
1649    {
1650        private Object JavaDoc node;
1651        private Object JavaDoc[] loadInfo;
1652        private boolean addToHistory;
1653
1654        DirectoryLoadedAWTRequest(Object JavaDoc node, Object JavaDoc[] loadInfo,
1655            boolean addToHistory)
1656        {
1657            this.node = node;
1658            this.loadInfo = loadInfo;
1659            this.addToHistory = addToHistory;
1660        }
1661
1662        public void run()
1663        {
1664            String JavaDoc path = (String JavaDoc)loadInfo[0];
1665            if(path == null)
1666            {
1667                // there was an error
1668
return;
1669            }
1670
1671            VFSFile[] list = (VFSFile[])loadInfo[1];
1672
1673            if(node == null)
1674            {
1675                // This is the new, canonical path
1676
VFSBrowser.this.path = path;
1677                if(!pathField.getText().equals(path))
1678                    pathField.setText(path);
1679                if(path.endsWith("/") ||
1680                    path.endsWith(File.separator))
1681                {
1682                    // ensure consistent history;
1683
// eg we don't want both
1684
// foo/ and foo
1685
path = path.substring(0,
1686                        path.length() - 1);
1687                }
1688
1689                if(addToHistory)
1690                {
1691                    HistoryModel.getModel("vfs.browser.path")
1692                        .addItem(path);
1693                }
1694            }
1695
1696            boolean filterEnabled = filterCheckbox.isSelected();
1697
1698            ArrayList<VFSFile> directoryVector = new ArrayList<VFSFile>();
1699
1700            int directories = 0;
1701            int files = 0;
1702            int invisible = 0;
1703
1704            if(list != null)
1705            {
1706                VFSFileFilter filter = getVFSFileFilter();
1707
1708                for(int i = 0; i < list.length; i++)
1709                {
1710                    VFSFile file = list[i];
1711                    if(file.isHidden() && !showHiddenFiles)
1712                    {
1713                        invisible++;
1714                        continue;
1715                    }
1716
1717                    if (filterEnabled && filter != null
1718                        && !filter.accept(file))
1719                    {
1720                        invisible++;
1721                        continue;
1722                    }
1723
1724                    if(file.getType() == VFSFile.FILE)
1725                        files++;
1726                    else
1727                        directories++;
1728
1729                    directoryVector.add(file);
1730                }
1731
1732                Collections.sort(directoryVector,
1733                    new VFS.DirectoryEntryCompare(
1734                    sortMixFilesAndDirs,
1735                    sortIgnoreCase));
1736            }
1737
1738            browserView.directoryLoaded(node,path,
1739                directoryVector);
1740
1741            // to notify listeners that any existing
1742
// selection has been deactivated
1743

1744            // turns out under some circumstances this
1745
// method can switch the current buffer in
1746
// BROWSER mode.
1747

1748            // in any case, this is only needed for the
1749
// directory chooser (why?), so we add a
1750
// check. otherwise poor Rick will go insane.
1751
if(mode == CHOOSE_DIRECTORY_DIALOG)
1752                filesSelected();
1753        }
1754
1755        public String JavaDoc toString()
1756        {
1757            return (String JavaDoc)loadInfo[0];
1758        }
1759    } //}}}
1760

1761    //{{{ BrowserActionContext class
1762
static class BrowserActionContext extends ActionContext
1763    {
1764        /**
1765         * If event source hierarchy contains a VFSDirectoryEntryTable,
1766         * this is the currently selected files there. Otherwise, this
1767         * is the currently selected item in the parent directory list.
1768         */

1769        private static VFSFile[] getSelectedFiles(EventObject evt,
1770            VFSBrowser browser)
1771        {
1772            Component source = (Component)evt.getSource();
1773
1774            if(GUIUtilities.getComponentParent(source,JList.class)
1775                != null)
1776            {
1777                Object JavaDoc[] selected = browser.getBrowserView()
1778                    .getParentDirectoryList()
1779                    .getSelectedValues();
1780                VFSFile[] returnValue = new VFSFile[
1781                    selected.length];
1782                System.arraycopy(selected,0,returnValue,0,
1783                    selected.length);
1784                return returnValue;
1785            }
1786            else
1787            {
1788                return browser.getSelectedFiles();
1789            }
1790        }
1791
1792        public void invokeAction(EventObject evt, EditAction action)
1793        {
1794            VFSBrowser browser = (VFSBrowser)
1795                GUIUtilities.getComponentParent(
1796                (Component)evt.getSource(),
1797                VFSBrowser.class);
1798
1799            VFSFile[] files = getSelectedFiles(evt,browser);
1800
1801            // in the future we will want something better,
1802
// eg. having an 'evt' object passed to
1803
// EditAction.invoke().
1804

1805            // for now, since all browser actions are
1806
// written in beanshell we set the 'browser'
1807
// variable directly.
1808
NameSpace global = BeanShell.getNameSpace();
1809            try
1810            {
1811                global.setVariable("browser",browser);
1812                global.setVariable("files",files);
1813
1814                View view = browser.getView();
1815                // I guess ideally all browsers
1816
// should have views, but since they
1817
// don't, we just use the active view
1818
// in that case, since some actions
1819
// depend on a view being there and
1820
// I don't want to add checks to
1821
// them all
1822
if(view == null)
1823                    view = jEdit.getActiveView();
1824                action.invoke(view);
1825            }
1826            catch(UtilEvalError err)
1827            {
1828                Log.log(Log.ERROR,this,err);
1829            }
1830            finally
1831            {
1832                try
1833                {
1834                    global.setVariable("browser",null);
1835                    global.setVariable("files",null);
1836                }
1837                catch(UtilEvalError err)
1838                {
1839                    Log.log(Log.ERROR,this,err);
1840                }
1841            }
1842        }
1843    } //}}}
1844

1845    //{{{ HistoryComboBoxEditor class
1846
private static class HistoryComboBoxEditor
1847                extends HistoryTextField
1848                implements ComboBoxEditor
1849    {
1850
1851        HistoryComboBoxEditor(String JavaDoc key)
1852        {
1853            super(key);
1854        }
1855
1856        public Object JavaDoc getItem()
1857        {
1858            if (current == null)
1859            {
1860                current = new GlobVFSFileFilter(getText());
1861            }
1862
1863            if (!current.getGlob().equals(getText()))
1864            {
1865                current.setGlob(getText());
1866            }
1867
1868            return current;
1869        }
1870
1871        public void setItem(Object JavaDoc item)
1872        {
1873            if (item == current)
1874            {
1875                // if we keep the same object, swing
1876
// will cause an event to be fired
1877
// on the default button of the dialog,
1878
// causing a beep since no file is
1879
// selected...
1880
if (item != null)
1881                {
1882                    GlobVFSFileFilter filter = (GlobVFSFileFilter) item;
1883                    current = new GlobVFSFileFilter(filter.getGlob());
1884                    setText(current.getGlob());
1885                }
1886                return;
1887            }
1888
1889            // this happens when changing the selected item
1890
// in the combo; the combo has not yet fired an
1891
// itemStateChanged() event, so it's not put into
1892
// non-editable mode by the handler above.
1893
if (!(item instanceof GlobVFSFileFilter))
1894                return;
1895
1896            if (item != null)
1897            {
1898                GlobVFSFileFilter filter = (GlobVFSFileFilter) item;
1899                filter = new GlobVFSFileFilter(filter.getGlob());
1900                setText(filter.getGlob());
1901                addCurrentToHistory();
1902                current = filter;
1903            }
1904            else
1905            {
1906                setText("*");
1907                current = new GlobVFSFileFilter("*");
1908            }
1909        }
1910
1911        protected void processFocusEvent(FocusEvent e)
1912        {
1913            // AWT will call setItem() when the editor loses
1914
// focus; that can cause weird and unwanted things
1915
// to happen, so ignore lost focus events.
1916
if (e.getID() != FocusEvent.FOCUS_LOST)
1917                super.processFocusEvent(e);
1918            else
1919            {
1920                setCaretPosition(0);
1921                getCaret().setVisible(false);
1922            }
1923        }
1924
1925        public Component getEditorComponent()
1926        {
1927            return this;
1928        }
1929
1930        private GlobVFSFileFilter current;
1931
1932    } //}}}
1933

1934    //{{{ VFSFileFilterRenderer class
1935
private static class VFSFileFilterRenderer extends DefaultListCellRenderer
1936    {
1937
1938        public Component getListCellRendererComponent(JList list,
1939            Object JavaDoc value, int index, boolean isSelected,
1940            boolean cellHasFocus)
1941        {
1942            assert value instanceof VFSFileFilter : "Filter is not a VFSFileFilter";
1943            super.getListCellRendererComponent(
1944                list, value, index, isSelected, cellHasFocus);
1945            setText(((VFSFileFilter)value).getDescription());
1946            return this;
1947        }
1948
1949    } //}}}
1950

1951    //{{{ DirectoriesOnlyFilter class
1952
public static class DirectoriesOnlyFilter implements VFSFileFilter
1953    {
1954
1955        public boolean accept(VFSFile file)
1956        {
1957            return file.getType() == VFSFile.DIRECTORY
1958                || file.getType() == VFSFile.FILESYSTEM;
1959        }
1960
1961        public boolean accept(String JavaDoc url)
1962        {
1963            return false;
1964        }
1965
1966        public String JavaDoc getDescription()
1967        {
1968            return jEdit.getProperty("vfs.browser.file_filter.dir_only");
1969        }
1970
1971    } //}}}
1972

1973    //}}}
1974
}
1975
Popular Tags