/jEdit/tags/jedit-4-3-pre4/org/gjt/sp/jedit/browser/VFSBrowser.java

#
Java | 1699 lines | 1233 code | 212 blank | 254 comment | 242 complexity | 3094103d50a8ef264f8a4ae3658f679e MD5 | raw file

✨ Summary
  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. package org.gjt.sp.jedit.browser;
  23. //{{{ Imports
  24. import bsh.*;
  25. import gnu.regexp.*;
  26. import javax.swing.border.EmptyBorder;
  27. import javax.swing.event.*;
  28. import javax.swing.tree.DefaultMutableTreeNode;
  29. import javax.swing.*;
  30. import java.awt.event.*;
  31. import java.awt.*;
  32. import java.io.File;
  33. import java.util.*;
  34. import org.gjt.sp.jedit.io.*;
  35. import org.gjt.sp.jedit.gui.*;
  36. import org.gjt.sp.jedit.msg.*;
  37. import org.gjt.sp.jedit.search.*;
  38. import org.gjt.sp.jedit.*;
  39. import org.gjt.sp.util.Log;
  40. //}}}
  41. /**
  42. * The main class of the VFS browser.
  43. * @author Slava Pestov
  44. * @version $Id: VFSBrowser.java 5221 2005-05-21 20:51:43Z spestov $
  45. */
  46. public class VFSBrowser extends JPanel implements EBComponent, DefaultFocusComponent
  47. {
  48. public static final String NAME = "vfs.browser";
  49. //{{{ Browser types
  50. /**
  51. * Open file dialog mode. Equals JFileChooser.OPEN_DIALOG for
  52. * backwards compatibility.
  53. */
  54. public static final int OPEN_DIALOG = 0;
  55. /**
  56. * Save file dialog mode. Equals JFileChooser.SAVE_DIALOG for
  57. * backwards compatibility.
  58. */
  59. public static final int SAVE_DIALOG = 1;
  60. /**
  61. * Choose directory dialog mode.
  62. */
  63. public static final int BROWSER_DIALOG = 4;
  64. /**
  65. * Choose directory dialog mode.
  66. */
  67. public static final int CHOOSE_DIRECTORY_DIALOG = 3;
  68. /**
  69. * Stand-alone browser mode.
  70. */
  71. public static final int BROWSER = 2;
  72. //}}}
  73. //{{{ browseDirectoryInNewWindow() method
  74. /**
  75. * Opens the specified directory in a new, floating, file system browser.
  76. * @param view The view
  77. * @param path The directory's path
  78. * @since jEdit 4.1pre2
  79. */
  80. public static void browseDirectoryInNewWindow(View view, String path)
  81. {
  82. DockableWindowManager wm = view.getDockableWindowManager();
  83. if(path != null)
  84. {
  85. // this is such a bad way of doing it, but oh well...
  86. jEdit.setTemporaryProperty("vfs.browser.path.tmp",path);
  87. }
  88. wm.floatDockableWindow("vfs.browser");
  89. jEdit.unsetProperty("vfs.browser.path.tmp");
  90. } //}}}
  91. //{{{ browseDirectory() method
  92. /**
  93. * Opens the specified directory in a file system browser.
  94. * @param view The view
  95. * @param path The directory's path
  96. * @since jEdit 4.0pre3
  97. */
  98. public static void browseDirectory(View view, String path)
  99. {
  100. DockableWindowManager wm = view.getDockableWindowManager();
  101. VFSBrowser browser = (VFSBrowser)wm.getDockable(NAME);
  102. if(browser != null)
  103. {
  104. wm.showDockableWindow(NAME);
  105. browser.setDirectory(path);
  106. }
  107. else
  108. {
  109. if(path != null)
  110. {
  111. // this is such a bad way of doing it, but oh well...
  112. jEdit.setTemporaryProperty("vfs.browser.path.tmp",path);
  113. }
  114. wm.addDockableWindow("vfs.browser");
  115. jEdit.unsetProperty("vfs.browser.path.tmp");
  116. }
  117. } //}}}
  118. //{{{ getActionContext() method
  119. /**
  120. * Returns the browser action context.
  121. * @since jEdit 4.2pre1
  122. */
  123. public static ActionContext getActionContext()
  124. {
  125. return actionContext;
  126. } //}}}
  127. //{{{ VFSBrowser constructor
  128. /**
  129. * Creates a new VFS browser.
  130. * @param view The view to open buffers in by default
  131. */
  132. public VFSBrowser(View view, String position)
  133. {
  134. this(view,null,BROWSER,true,position);
  135. } //}}}
  136. //{{{ VFSBrowser constructor
  137. /**
  138. * Creates a new VFS browser.
  139. * @param view The view to open buffers in by default
  140. * @param path The path to display
  141. * @param mode The browser mode
  142. * @param multipleSelection True if multiple selection should be allowed
  143. * @param position Where the browser is located
  144. * @since jEdit 4.2pre1
  145. */
  146. public VFSBrowser(View view, String path, int mode,
  147. boolean multipleSelection, String position)
  148. {
  149. super(new BorderLayout());
  150. listenerList = new EventListenerList();
  151. this.mode = mode;
  152. this.multipleSelection = multipleSelection;
  153. this.view = view;
  154. currentEncoding = jEdit.getProperty("buffer.encoding",
  155. System.getProperty("file.encoding"));
  156. autoDetectEncoding = jEdit.getBooleanProperty(
  157. "buffer.encodingAutodetect");
  158. ActionHandler actionHandler = new ActionHandler();
  159. Box topBox = new Box(BoxLayout.Y_AXIS);
  160. horizontalLayout = (mode != BROWSER
  161. || DockableWindowManager.TOP.equals(position)
  162. || DockableWindowManager.BOTTOM.equals(position));
  163. toolbarBox = new Box(horizontalLayout
  164. ? BoxLayout.X_AXIS
  165. : BoxLayout.Y_AXIS);
  166. topBox.add(toolbarBox);
  167. GridBagLayout layout = new GridBagLayout();
  168. JPanel pathAndFilterPanel = new JPanel(layout);
  169. GridBagConstraints cons = new GridBagConstraints();
  170. cons.gridwidth = cons.gridheight = 1;
  171. cons.gridx = cons.gridy = 0;
  172. cons.fill = GridBagConstraints.BOTH;
  173. cons.anchor = GridBagConstraints.EAST;
  174. JLabel label = new JLabel(jEdit.getProperty("vfs.browser.path"),
  175. SwingConstants.RIGHT);
  176. label.setBorder(new EmptyBorder(0,0,0,12));
  177. layout.setConstraints(label,cons);
  178. pathAndFilterPanel.add(label);
  179. pathField = new HistoryTextField("vfs.browser.path");
  180. pathField.setInstantPopups(true);
  181. pathField.setEnterAddsToHistory(false);
  182. pathField.setSelectAllOnFocus(true);
  183. // because its preferred size can be quite wide, we
  184. // don't want it to make the browser way too big,
  185. // so set the preferred width to 0.
  186. Dimension prefSize = pathField.getPreferredSize();
  187. prefSize.width = 0;
  188. pathField.setPreferredSize(prefSize);
  189. pathField.addActionListener(actionHandler);
  190. cons.gridx = 1;
  191. cons.weightx = 1.0f;
  192. layout.setConstraints(pathField,cons);
  193. pathAndFilterPanel.add(pathField);
  194. filterCheckbox = new JCheckBox(jEdit.getProperty("vfs.browser.filter"));
  195. filterCheckbox.setMargin(new Insets(0,0,0,0));
  196. filterCheckbox.setRequestFocusEnabled(false);
  197. filterCheckbox.setBorder(new EmptyBorder(0,0,0,12));
  198. filterCheckbox.setSelected(jEdit.getBooleanProperty(
  199. "vfs.browser.filter-enabled"));
  200. filterCheckbox.addActionListener(actionHandler);
  201. if(mode != CHOOSE_DIRECTORY_DIALOG)
  202. {
  203. cons.gridx = 0;
  204. cons.weightx = 0.0f;
  205. cons.gridy = 1;
  206. layout.setConstraints(filterCheckbox,cons);
  207. pathAndFilterPanel.add(filterCheckbox);
  208. }
  209. filterField = new HistoryTextField("vfs.browser.filter");
  210. filterField.setInstantPopups(true);
  211. filterField.setSelectAllOnFocus(true);
  212. filterField.addActionListener(actionHandler);
  213. if(mode != CHOOSE_DIRECTORY_DIALOG)
  214. {
  215. cons.gridx = 1;
  216. cons.weightx = 1.0f;
  217. layout.setConstraints(filterField,cons);
  218. pathAndFilterPanel.add(filterField);
  219. }
  220. topBox.add(pathAndFilterPanel);
  221. add(BorderLayout.NORTH,topBox);
  222. add(BorderLayout.CENTER,browserView = new BrowserView(this));
  223. propertiesChanged();
  224. String filter;
  225. if(mode == BROWSER || !jEdit.getBooleanProperty(
  226. "vfs.browser.currentBufferFilter"))
  227. {
  228. filter = jEdit.getProperty("vfs.browser.last-filter");
  229. if(filter == null)
  230. filter = jEdit.getProperty("vfs.browser.default-filter");
  231. }
  232. else
  233. {
  234. String ext = MiscUtilities.getFileExtension(
  235. view.getBuffer().getName());
  236. if(ext.length() == 0)
  237. filter = jEdit.getProperty("vfs.browser.default-filter");
  238. else
  239. filter = "*" + ext;
  240. }
  241. filterField.setText(filter);
  242. filterField.addCurrentToHistory();
  243. updateFilterEnabled();
  244. // see VFSBrowser.browseDirectory()
  245. if(path == null)
  246. path = jEdit.getProperty("vfs.browser.path.tmp");
  247. if(path == null || path.length() == 0)
  248. {
  249. String userHome = System.getProperty("user.home");
  250. String defaultPath = jEdit.getProperty("vfs.browser.defaultPath");
  251. if(defaultPath.equals("home"))
  252. path = userHome;
  253. else if(defaultPath.equals("working"))
  254. path = System.getProperty("user.dir");
  255. else if(defaultPath.equals("buffer"))
  256. {
  257. if(view != null)
  258. {
  259. Buffer buffer = view.getBuffer();
  260. path = buffer.getDirectory();
  261. }
  262. else
  263. path = userHome;
  264. }
  265. else if(defaultPath.equals("last"))
  266. {
  267. HistoryModel pathModel = HistoryModel.getModel("vfs.browser.path");
  268. if(pathModel.getSize() == 0)
  269. path = "~";
  270. else
  271. path = pathModel.getItem(0);
  272. }
  273. else if(defaultPath.equals("favorites"))
  274. path = "favorites:";
  275. else
  276. {
  277. // unknown value??!!!
  278. path = userHome;
  279. }
  280. }
  281. final String _path = path;
  282. SwingUtilities.invokeLater(new Runnable()
  283. {
  284. public void run()
  285. {
  286. setDirectory(_path);
  287. }
  288. });
  289. } //}}}
  290. //{{{ focusOnDefaultComponent() method
  291. public void focusOnDefaultComponent()
  292. {
  293. browserView.focusOnFileView();
  294. } //}}}
  295. //{{{ addNotify() method
  296. public void addNotify()
  297. {
  298. super.addNotify();
  299. EditBus.addToBus(this);
  300. } //}}}
  301. //{{{ removeNotify() method
  302. public void removeNotify()
  303. {
  304. super.removeNotify();
  305. jEdit.setBooleanProperty("vfs.browser.filter-enabled",
  306. filterCheckbox.isSelected());
  307. if(mode == BROWSER || !jEdit.getBooleanProperty(
  308. "vfs.browser.currentBufferFilter"))
  309. {
  310. jEdit.setProperty("vfs.browser.last-filter",
  311. filterField.getText());
  312. }
  313. EditBus.removeFromBus(this);
  314. } //}}}
  315. //{{{ handleMessage() method
  316. public void handleMessage(EBMessage msg)
  317. {
  318. if(msg instanceof PropertiesChanged)
  319. propertiesChanged();
  320. else if(msg instanceof BufferUpdate)
  321. {
  322. BufferUpdate bmsg = (BufferUpdate)msg;
  323. if(bmsg.getWhat() == BufferUpdate.CREATED
  324. || bmsg.getWhat() == BufferUpdate.CLOSED)
  325. browserView.updateFileView();
  326. }
  327. else if(msg instanceof PluginUpdate)
  328. {
  329. PluginUpdate pmsg = (PluginUpdate)msg;
  330. if(pmsg.getWhat() == PluginUpdate.LOADED
  331. || pmsg.getWhat() == PluginUpdate.UNLOADED)
  332. {
  333. plugins.updatePopupMenu();
  334. }
  335. }
  336. else if(msg instanceof VFSUpdate)
  337. {
  338. maybeReloadDirectory(((VFSUpdate)msg).getPath());
  339. }
  340. } //}}}
  341. //{{{ getView() method
  342. public View getView()
  343. {
  344. return view;
  345. } //}}}
  346. //{{{ getMode() method
  347. public int getMode()
  348. {
  349. return mode;
  350. } //}}}
  351. //{{{ isMultipleSelectionEnabled() method
  352. public boolean isMultipleSelectionEnabled()
  353. {
  354. return multipleSelection;
  355. } //}}}
  356. //{{{ isHorizontalLayout() method
  357. public boolean isHorizontalLayout()
  358. {
  359. return horizontalLayout;
  360. } //}}}
  361. //{{{ getShowHiddenFiles() method
  362. public boolean getShowHiddenFiles()
  363. {
  364. return showHiddenFiles;
  365. } //}}}
  366. //{{{ setShowHiddenFiles() method
  367. public void setShowHiddenFiles(boolean showHiddenFiles)
  368. {
  369. this.showHiddenFiles = showHiddenFiles;
  370. } //}}}
  371. //{{{ getFilenameFilter() method
  372. /**
  373. * Returns the file name filter glob.
  374. * @since jEdit 3.2pre2
  375. */
  376. public String getFilenameFilter()
  377. {
  378. if(filterCheckbox.isSelected())
  379. {
  380. String filter = filterField.getText();
  381. if(filter.length() == 0)
  382. return "*";
  383. else
  384. return filter;
  385. }
  386. else
  387. return "*";
  388. } //}}}
  389. //{{{ setFilenameFilter() method
  390. public void setFilenameFilter(String filter)
  391. {
  392. if(filter == null || filter.length() == 0 || filter.equals("*"))
  393. filterCheckbox.setSelected(false);
  394. else
  395. {
  396. filterCheckbox.setSelected(true);
  397. filterField.setText(filter);
  398. }
  399. } //}}}
  400. //{{{ getDirectoryField() method
  401. public HistoryTextField getDirectoryField()
  402. {
  403. return pathField;
  404. } //}}}
  405. //{{{ getDirectory() method
  406. public String getDirectory()
  407. {
  408. return path;
  409. } //}}}
  410. //{{{ setDirectory() method
  411. public void setDirectory(String path)
  412. {
  413. if(path.startsWith("file:"))
  414. path = path.substring(5);
  415. pathField.setText(path);
  416. if(!startRequest())
  417. return;
  418. updateFilenameFilter();
  419. browserView.saveExpansionState();
  420. browserView.loadDirectory(null,path,true);
  421. this.path = path;
  422. VFSManager.runInAWTThread(new Runnable()
  423. {
  424. public void run()
  425. {
  426. endRequest();
  427. }
  428. });
  429. } //}}}
  430. //{{{ getRootDirectory() method
  431. public static String getRootDirectory()
  432. {
  433. if(OperatingSystem.isMacOS() || OperatingSystem.isDOSDerived())
  434. return FileRootsVFS.PROTOCOL + ":";
  435. else
  436. return "/";
  437. } //}}}
  438. //{{{ rootDirectory() method
  439. /**
  440. * Goes to the local drives directory.
  441. * @since jEdit 4.0pre4
  442. */
  443. public void rootDirectory()
  444. {
  445. setDirectory(getRootDirectory());
  446. } //}}}
  447. //{{{ reloadDirectory() method
  448. public void reloadDirectory()
  449. {
  450. // used by FTP plugin to clear directory cache
  451. VFSManager.getVFSForPath(path).reloadDirectory(path);
  452. updateFilenameFilter();
  453. browserView.saveExpansionState();
  454. browserView.loadDirectory(null,path,false);
  455. } //}}}
  456. //{{{ delete() method
  457. /**
  458. * Note that all files must be on the same VFS.
  459. * @since jEdit 4.3pre2
  460. */
  461. public void delete(VFSFile[] files)
  462. {
  463. String dialogType;
  464. if(MiscUtilities.isURL(files[0].getDeletePath())
  465. && FavoritesVFS.PROTOCOL.equals(
  466. MiscUtilities.getProtocolOfURL(files[0].getDeletePath())))
  467. {
  468. dialogType = "vfs.browser.delete-favorites";
  469. }
  470. else
  471. {
  472. dialogType = "vfs.browser.delete-confirm";
  473. }
  474. StringBuffer buf = new StringBuffer();
  475. for(int i = 0; i < files.length; i++)
  476. {
  477. buf.append(files[i].getPath());
  478. buf.append('\n');
  479. }
  480. Object[] args = { buf.toString() };
  481. int result = GUIUtilities.confirm(this,dialogType,args,
  482. JOptionPane.YES_NO_OPTION,
  483. JOptionPane.WARNING_MESSAGE);
  484. if(result != JOptionPane.YES_OPTION)
  485. return;
  486. VFS vfs = VFSManager.getVFSForPath(files[0].getDeletePath());
  487. if(!startRequest())
  488. return;
  489. for(int i = 0; i < files.length; i++)
  490. {
  491. Object session = vfs.createVFSSession(files[i].getDeletePath(),this);
  492. if(session == null)
  493. continue;
  494. VFSManager.runInWorkThread(new BrowserIORequest(
  495. BrowserIORequest.DELETE,this,
  496. session,vfs,files[i].getDeletePath(),
  497. null,null));
  498. }
  499. VFSManager.runInAWTThread(new Runnable()
  500. {
  501. public void run()
  502. {
  503. endRequest();
  504. }
  505. });
  506. } //}}}
  507. //{{{ rename() method
  508. public void rename(String from)
  509. {
  510. VFS vfs = VFSManager.getVFSForPath(from);
  511. String filename = vfs.getFileName(from);
  512. String[] args = { filename };
  513. String to = GUIUtilities.input(this,"vfs.browser.rename",
  514. args,filename);
  515. if(to == null)
  516. return;
  517. to = MiscUtilities.constructPath(vfs.getParentOfPath(from),to);
  518. Object session = vfs.createVFSSession(from,this);
  519. if(session == null)
  520. return;
  521. if(!startRequest())
  522. return;
  523. VFSManager.runInWorkThread(new BrowserIORequest(
  524. BrowserIORequest.RENAME,this,
  525. session,vfs,from,to,null));
  526. VFSManager.runInAWTThread(new Runnable()
  527. {
  528. public void run()
  529. {
  530. endRequest();
  531. }
  532. });
  533. } //}}}
  534. //{{{ mkdir() method
  535. public void mkdir()
  536. {
  537. String newDirectory = GUIUtilities.input(this,"vfs.browser.mkdir",null);
  538. if(newDirectory == null)
  539. return;
  540. // if a directory is selected, create new dir in there.
  541. // if a file is selected, create new dir inside its parent.
  542. VFSFile[] selected = getSelectedFiles();
  543. String parent;
  544. if(selected.length == 0)
  545. parent = path;
  546. else if(selected[0].getType() == VFSFile.FILE)
  547. {
  548. parent = selected[0].getPath();
  549. parent = VFSManager.getVFSForPath(parent)
  550. .getParentOfPath(parent);
  551. }
  552. else
  553. parent = selected[0].getPath();
  554. VFS vfs = VFSManager.getVFSForPath(parent);
  555. // path is the currently viewed directory in the browser
  556. newDirectory = MiscUtilities.constructPath(parent,newDirectory);
  557. Object session = vfs.createVFSSession(newDirectory,this);
  558. if(session == null)
  559. return;
  560. if(!startRequest())
  561. return;
  562. VFSManager.runInWorkThread(new BrowserIORequest(
  563. BrowserIORequest.MKDIR,this,
  564. session,vfs,newDirectory,null,null));
  565. VFSManager.runInAWTThread(new Runnable()
  566. {
  567. public void run()
  568. {
  569. endRequest();
  570. }
  571. });
  572. } //}}}
  573. //{{{ newFile() method
  574. /**
  575. * Creates a new file in the current directory.
  576. * @since jEdit 4.0pre2
  577. */
  578. public void newFile()
  579. {
  580. VFSFile[] selected = getSelectedFiles();
  581. if(selected.length >= 1)
  582. {
  583. VFSFile file = selected[0];
  584. if(file.getType() == VFSFile.DIRECTORY)
  585. jEdit.newFile(view,file.getPath());
  586. else
  587. {
  588. VFS vfs = VFSManager.getVFSForPath(file.getPath());
  589. jEdit.newFile(view,vfs.getParentOfPath(file.getPath()));
  590. }
  591. }
  592. else
  593. jEdit.newFile(view,path);
  594. } //}}}
  595. //{{{ searchInDirectory() method
  596. /**
  597. * Opens a directory search in the current directory.
  598. * @since jEdit 4.0pre2
  599. */
  600. public void searchInDirectory()
  601. {
  602. VFSFile[] selected = getSelectedFiles();
  603. if(selected.length >= 1)
  604. {
  605. VFSFile file = selected[0];
  606. searchInDirectory(file.getPath(),file.getType() != VFSFile.FILE);
  607. }
  608. else
  609. {
  610. searchInDirectory(this.path,true);
  611. }
  612. } //}}}
  613. //{{{ searchInDirectory() method
  614. /**
  615. * Opens a directory search in the specified directory.
  616. * @param path The path name
  617. * @param directory True if the path is a directory, false if it is a file
  618. * @since jEdit 4.2pre1
  619. */
  620. public void searchInDirectory(String path, boolean directory)
  621. {
  622. String filter;
  623. if(directory)
  624. {
  625. filter = getFilenameFilter();
  626. }
  627. else
  628. {
  629. String name = MiscUtilities.getFileName(path);
  630. String ext = MiscUtilities.getFileExtension(name);
  631. filter = (ext == null || ext.length() == 0
  632. ? getFilenameFilter()
  633. : "*" + ext);
  634. path = MiscUtilities.getParentOfPath(path);
  635. }
  636. SearchAndReplace.setSearchFileSet(new DirectoryListSet(
  637. path,filter,true));
  638. SearchDialog.showSearchDialog(view,null,SearchDialog.DIRECTORY);
  639. } //}}}
  640. //{{{ getBrowserView() method
  641. public BrowserView getBrowserView()
  642. {
  643. return browserView;
  644. } //}}}
  645. //{{{ getSelectedFiles() method
  646. /**
  647. * @since jEdit 4.3pre2
  648. */
  649. public VFSFile[] getSelectedFiles()
  650. {
  651. return browserView.getSelectedFiles();
  652. } //}}}
  653. //{{{ locateFile() method
  654. /**
  655. * Goes to the given file's directory and selects the file in the list.
  656. * @param path The file
  657. * @since jEdit 4.2pre2
  658. */
  659. public void locateFile(final String path)
  660. {
  661. if(!filenameFilter.isMatch(MiscUtilities.getFileName(path)))
  662. setFilenameFilter(null);
  663. setDirectory(MiscUtilities.getParentOfPath(path));
  664. VFSManager.runInAWTThread(new Runnable()
  665. {
  666. public void run()
  667. {
  668. browserView.getTable().selectFile(path);
  669. }
  670. });
  671. } //}}}
  672. //{{{ createPluginsMenu() method
  673. public JComponent createPluginsMenu(JComponent pluginMenu, boolean showManagerOptions)
  674. {
  675. ActionHandler actionHandler = new ActionHandler();
  676. if(showManagerOptions && getMode() == VFSBrowser.BROWSER)
  677. {
  678. pluginMenu.add(GUIUtilities.loadMenuItem("plugin-manager",false));
  679. pluginMenu.add(GUIUtilities.loadMenuItem("plugin-options",false));
  680. if (pluginMenu instanceof JMenu)
  681. ((JMenu)pluginMenu).addSeparator();
  682. else if (pluginMenu instanceof JPopupMenu)
  683. ((JPopupMenu)pluginMenu).addSeparator();
  684. }
  685. else
  686. /* we're in a modal dialog */;
  687. ArrayList vec = new ArrayList();
  688. //{{{ old API
  689. Enumeration e = VFSManager.getFilesystems();
  690. while(e.hasMoreElements())
  691. {
  692. VFS vfs = (VFS)e.nextElement();
  693. if((vfs.getCapabilities() & VFS.BROWSE_CAP) == 0)
  694. continue;
  695. JMenuItem menuItem = new JMenuItem(jEdit.getProperty(
  696. "vfs." + vfs.getName() + ".label"));
  697. menuItem.setActionCommand(vfs.getName());
  698. menuItem.addActionListener(actionHandler);
  699. vec.add(menuItem);
  700. } //}}}
  701. //{{{ new API
  702. EditPlugin[] plugins = jEdit.getPlugins();
  703. for(int i = 0; i < plugins.length; i++)
  704. {
  705. JMenuItem menuItem = plugins[i].createBrowserMenuItems();
  706. if(menuItem != null)
  707. vec.add(menuItem);
  708. } //}}}
  709. if(vec.size() != 0)
  710. {
  711. MiscUtilities.quicksort(vec,new MiscUtilities.MenuItemCompare());
  712. for(int i = 0; i < vec.size(); i++)
  713. pluginMenu.add((JMenuItem)vec.get(i));
  714. }
  715. else
  716. {
  717. JMenuItem mi = new JMenuItem(jEdit.getProperty(
  718. "vfs.browser.plugins.no-plugins.label"));
  719. mi.setEnabled(false);
  720. pluginMenu.add(mi);
  721. }
  722. return pluginMenu;
  723. } //}}}
  724. //{{{ addBrowserListener() method
  725. public void addBrowserListener(BrowserListener l)
  726. {
  727. listenerList.add(BrowserListener.class,l);
  728. } //}}}
  729. //{{{ removeBrowserListener() method
  730. public void removeBrowserListener(BrowserListener l)
  731. {
  732. listenerList.remove(BrowserListener.class,l);
  733. } //}}}
  734. //{{{ filesActivated() method
  735. // canDoubleClickClose set to false when ENTER pressed
  736. public static final int M_OPEN = 0;
  737. public static final int M_OPEN_NEW_VIEW = 1;
  738. public static final int M_OPEN_NEW_PLAIN_VIEW = 2;
  739. public static final int M_OPEN_NEW_SPLIT = 3;
  740. public static final int M_INSERT = 4;
  741. /**
  742. * This method does the "double-click" handling. It is public so that
  743. * <code>browser.actions.xml</code> can bind to it.
  744. * @since jEdit 4.2pre2
  745. */
  746. public void filesActivated(int mode, boolean canDoubleClickClose)
  747. {
  748. VFSFile[] selectedFiles = browserView.getSelectedFiles();
  749. Buffer buffer = null;
  750. check_selected: for(int i = 0; i < selectedFiles.length; i++)
  751. {
  752. VFSFile file = selectedFiles[i];
  753. if(file.getType() == VFSFile.DIRECTORY
  754. || file.getType() == VFSFile.FILESYSTEM)
  755. {
  756. if(mode == M_OPEN_NEW_VIEW && this.mode == BROWSER)
  757. browseDirectoryInNewWindow(view,file.getPath());
  758. else
  759. setDirectory(file.getPath());
  760. }
  761. else if(this.mode == BROWSER || this.mode == BROWSER_DIALOG)
  762. {
  763. if(mode == M_INSERT)
  764. {
  765. view.getBuffer().insertFile(view,
  766. file.getPath());
  767. continue check_selected;
  768. }
  769. Buffer _buffer = jEdit.getBuffer(file.getPath());
  770. if(_buffer == null)
  771. {
  772. Hashtable props = new Hashtable();
  773. props.put(Buffer.ENCODING,currentEncoding);
  774. props.put(Buffer.ENCODING_AUTODETECT,
  775. new Boolean(autoDetectEncoding));
  776. _buffer = jEdit.openFile(null,null,
  777. file.getPath(),false,props);
  778. }
  779. else if(doubleClickClose && canDoubleClickClose
  780. && this.mode != BROWSER_DIALOG
  781. && selectedFiles.length == 1)
  782. {
  783. // close if this buffer is currently
  784. // visible in the view.
  785. EditPane[] editPanes = view.getEditPanes();
  786. for(int j = 0; j < editPanes.length; j++)
  787. {
  788. if(editPanes[j].getBuffer() == _buffer)
  789. {
  790. jEdit.closeBuffer(view,_buffer);
  791. return;
  792. }
  793. }
  794. }
  795. if(_buffer != null)
  796. buffer = _buffer;
  797. }
  798. else
  799. {
  800. // if a file is selected in OPEN_DIALOG or
  801. // SAVE_DIALOG mode, just let the listener(s)
  802. // handle it
  803. }
  804. }
  805. if(buffer != null)
  806. {
  807. switch(mode)
  808. {
  809. case M_OPEN:
  810. view.setBuffer(buffer);
  811. break;
  812. case M_OPEN_NEW_VIEW:
  813. jEdit.newView(view,buffer,false);
  814. break;
  815. case M_OPEN_NEW_PLAIN_VIEW:
  816. jEdit.newView(view,buffer,true);
  817. break;
  818. case M_OPEN_NEW_SPLIT:
  819. view.splitHorizontally().setBuffer(buffer);
  820. break;
  821. }
  822. }
  823. Object[] listeners = listenerList.getListenerList();
  824. for(int i = 0; i < listeners.length; i++)
  825. {
  826. if(listeners[i] == BrowserListener.class)
  827. {
  828. BrowserListener l = (BrowserListener)listeners[i+1];
  829. l.filesActivated(this,selectedFiles);
  830. }
  831. }
  832. } //}}}
  833. //{{{ Package-private members
  834. String currentEncoding;
  835. boolean autoDetectEncoding;
  836. //{{{ updateFilenameFilter() method
  837. void updateFilenameFilter()
  838. {
  839. try
  840. {
  841. String filter = filterField.getText();
  842. if(filter.length() == 0)
  843. filter = "*";
  844. filenameFilter = new RE(MiscUtilities.globToRE(filter),RE.REG_ICASE);
  845. }
  846. catch(Exception e)
  847. {
  848. Log.log(Log.ERROR,VFSBrowser.this,e);
  849. String[] args = { filterField.getText(),
  850. e.getMessage() };
  851. GUIUtilities.error(this,"vfs.browser.bad-filter",args);
  852. }
  853. } //}}}
  854. //{{{ directoryLoaded() method
  855. void directoryLoaded(Object node, Object[] loadInfo,
  856. boolean addToHistory)
  857. {
  858. VFSManager.runInAWTThread(new DirectoryLoadedAWTRequest(
  859. node,loadInfo,addToHistory));
  860. } //}}}
  861. //{{{ filesSelected() method
  862. void filesSelected()
  863. {
  864. VFSFile[] selectedFiles = browserView.getSelectedFiles();
  865. if(mode == BROWSER)
  866. {
  867. for(int i = 0; i < selectedFiles.length; i++)
  868. {
  869. VFSFile file = selectedFiles[i];
  870. Buffer buffer = jEdit.getBuffer(file.getPath());
  871. if(buffer != null && view != null)
  872. view.setBuffer(buffer);
  873. }
  874. }
  875. Object[] listeners = listenerList.getListenerList();
  876. for(int i = 0; i < listeners.length; i++)
  877. {
  878. if(listeners[i] == BrowserListener.class)
  879. {
  880. BrowserListener l = (BrowserListener)listeners[i+1];
  881. l.filesSelected(this,selectedFiles);
  882. }
  883. }
  884. } //}}}
  885. //{{{ endRequest() method
  886. void endRequest()
  887. {
  888. requestRunning = false;
  889. } //}}}
  890. //}}}
  891. //{{{ Private members
  892. private static ActionContext actionContext;
  893. static
  894. {
  895. actionContext = new BrowserActionContext();
  896. ActionSet builtInActionSet = new ActionSet(null,null,null,
  897. jEdit.class.getResource("browser.actions.xml"));
  898. builtInActionSet.setLabel(jEdit.getProperty("action-set.browser"));
  899. builtInActionSet.load();
  900. actionContext.addActionSet(builtInActionSet);
  901. }
  902. //{{{ Instance variables
  903. private EventListenerList listenerList;
  904. private View view;
  905. private boolean horizontalLayout;
  906. private String path;
  907. private HistoryTextField pathField;
  908. private JCheckBox filterCheckbox;
  909. private HistoryTextField filterField;
  910. private Box toolbarBox;
  911. private FavoritesMenuButton favorites;
  912. private PluginsMenuButton plugins;
  913. private BrowserView browserView;
  914. private RE filenameFilter;
  915. private int mode;
  916. private boolean multipleSelection;
  917. private boolean showHiddenFiles;
  918. private boolean sortMixFilesAndDirs;
  919. private boolean sortIgnoreCase;
  920. private boolean doubleClickClose;
  921. private boolean requestRunning;
  922. private boolean maybeReloadRequestRunning;
  923. //}}}
  924. //{{{ createMenuBar() method
  925. private JPanel createMenuBar()
  926. {
  927. JPanel menuBar = new JPanel();
  928. menuBar.setLayout(new BoxLayout(menuBar,BoxLayout.X_AXIS));
  929. menuBar.setBorder(new EmptyBorder(0,1,0,3));
  930. menuBar.add(new CommandsMenuButton());
  931. menuBar.add(Box.createHorizontalStrut(3));
  932. menuBar.add(plugins = new PluginsMenuButton());
  933. menuBar.add(Box.createHorizontalStrut(3));
  934. menuBar.add(favorites = new FavoritesMenuButton());
  935. return menuBar;
  936. } //}}}
  937. //{{{ createToolBar() method
  938. private Box createToolBar()
  939. {
  940. if(mode == BROWSER)
  941. return GUIUtilities.loadToolBar(actionContext,
  942. "vfs.browser.toolbar-browser");
  943. else
  944. return GUIUtilities.loadToolBar(actionContext,
  945. "vfs.browser.toolbar-dialog");
  946. } //}}}
  947. //{{{ propertiesChanged() method
  948. private void propertiesChanged()
  949. {
  950. showHiddenFiles = jEdit.getBooleanProperty("vfs.browser.showHiddenFiles");
  951. sortMixFilesAndDirs = jEdit.getBooleanProperty("vfs.browser.sortMixFilesAndDirs");
  952. sortIgnoreCase = jEdit.getBooleanProperty("vfs.browser.sortIgnoreCase");
  953. doubleClickClose = jEdit.getBooleanProperty("vfs.browser.doubleClickClose");
  954. browserView.propertiesChanged();
  955. toolbarBox.removeAll();
  956. if(jEdit.getBooleanProperty("vfs.browser.showToolbar"))
  957. {
  958. Box toolbar = createToolBar();
  959. if(horizontalLayout)
  960. toolbarBox.add(toolbar);
  961. else
  962. {
  963. toolbar.add(Box.createGlue());
  964. toolbarBox.add(toolbar);
  965. }
  966. }
  967. if(jEdit.getBooleanProperty("vfs.browser.showMenubar"))
  968. {
  969. JPanel menubar = createMenuBar();
  970. if(horizontalLayout)
  971. {
  972. toolbarBox.add(Box.createHorizontalStrut(6));
  973. toolbarBox.add(menubar,0);
  974. }
  975. else
  976. {
  977. menubar.add(Box.createGlue());
  978. toolbarBox.add(menubar);
  979. }
  980. }
  981. else
  982. favorites = null;
  983. toolbarBox.add(Box.createGlue());
  984. revalidate();
  985. if(path != null)
  986. reloadDirectory();
  987. } //}}}
  988. /* We do this stuff because the browser is not able to handle
  989. * more than one request yet */
  990. //{{{ startRequest() method
  991. private boolean startRequest()
  992. {
  993. if(requestRunning)
  994. {
  995. // dump stack trace for debugging purposes
  996. Log.log(Log.DEBUG,this,new Throwable("For debugging purposes"));
  997. GUIUtilities.error(this,"browser-multiple-io",null);
  998. return false;
  999. }
  1000. else
  1001. {
  1002. requestRunning = true;
  1003. return true;
  1004. }
  1005. } //}}}
  1006. //{{{ updateFilterEnabled() method
  1007. private void updateFilterEnabled()
  1008. {
  1009. filterField.setEnabled(filterCheckbox.isSelected());
  1010. } //}}}
  1011. //{{{ maybeReloadDirectory() method
  1012. private void maybeReloadDirectory(String dir)
  1013. {
  1014. if(MiscUtilities.isURL(dir)
  1015. && MiscUtilities.getProtocolOfURL(dir).equals(
  1016. FavoritesVFS.PROTOCOL))
  1017. {
  1018. if(favorites != null)
  1019. favorites.popup = null;
  1020. }
  1021. // this is a dirty hack and it relies on the fact
  1022. // that updates for parents are sent before updates
  1023. // for the changed nodes themselves (if this was not
  1024. // the case, the browser wouldn't be updated properly
  1025. // on delete, etc).
  1026. //
  1027. // to avoid causing '> 1 request' errors, don't reload
  1028. // directory if request already active
  1029. if(maybeReloadRequestRunning)
  1030. {
  1031. //Log.log(Log.WARNING,this,"VFS update: request already in progress");
  1032. return;
  1033. }
  1034. // save a file -> sends vfs update. if a VFS file dialog box
  1035. // is shown from the same event frame as the save, the
  1036. // VFSUpdate will be delivered before the directory is loaded,
  1037. // and before the path is set.
  1038. if(path != null)
  1039. {
  1040. try
  1041. {
  1042. maybeReloadRequestRunning = true;
  1043. browserView.maybeReloadDirectory(dir);
  1044. }
  1045. finally
  1046. {
  1047. VFSManager.runInAWTThread(new Runnable()
  1048. {
  1049. public void run()
  1050. {
  1051. maybeReloadRequestRunning = false;
  1052. }
  1053. });
  1054. }
  1055. }
  1056. } //}}}
  1057. //}}}
  1058. //{{{ Inner classes
  1059. //{{{ ActionHandler class
  1060. class ActionHandler implements ActionListener
  1061. {
  1062. public void actionPerformed(ActionEvent evt)
  1063. {
  1064. Object source = evt.getSource();
  1065. if(source == pathField || source == filterField
  1066. || source == filterCheckbox)
  1067. {
  1068. updateFilterEnabled();
  1069. String path = pathField.getText();
  1070. if(path != null)
  1071. setDirectory(path);
  1072. browserView.focusOnFileView();
  1073. }
  1074. }
  1075. } //}}}
  1076. //{{{ CommandsMenuButton class
  1077. class CommandsMenuButton extends JButton
  1078. {
  1079. //{{{ CommandsMenuButton constructor
  1080. CommandsMenuButton()
  1081. {
  1082. setText(jEdit.getProperty("vfs.browser.commands.label"));
  1083. setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
  1084. setHorizontalTextPosition(SwingConstants.LEADING);
  1085. popup = new BrowserCommandsMenu(VFSBrowser.this,null);
  1086. CommandsMenuButton.this.setRequestFocusEnabled(false);
  1087. setMargin(new Insets(1,1,1,1));
  1088. CommandsMenuButton.this.addMouseListener(new MouseHandler());
  1089. if(OperatingSystem.isMacOSLF())
  1090. CommandsMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
  1091. } //}}}
  1092. BrowserCommandsMenu popup;
  1093. //{{{ MouseHandler class
  1094. class MouseHandler extends MouseAdapter
  1095. {
  1096. public void mousePressed(MouseEvent evt)
  1097. {
  1098. if(!popup.isVisible())
  1099. {
  1100. popup.update();
  1101. GUIUtilities.showPopupMenu(
  1102. popup,CommandsMenuButton.this,0,
  1103. CommandsMenuButton.this.getHeight(),
  1104. false);
  1105. }
  1106. else
  1107. {
  1108. popup.setVisible(false);
  1109. }
  1110. }
  1111. } //}}}
  1112. } //}}}
  1113. //{{{ PluginsMenuButton class
  1114. class PluginsMenuButton extends JButton
  1115. {
  1116. //{{{ PluginsMenuButton constructor
  1117. PluginsMenuButton()
  1118. {
  1119. setText(jEdit.getProperty("vfs.browser.plugins.label"));
  1120. setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
  1121. setHorizontalTextPosition(SwingConstants.LEADING);
  1122. PluginsMenuButton.this.setRequestFocusEnabled(false);
  1123. setMargin(new Insets(1,1,1,1));
  1124. PluginsMenuButton.this.addMouseListener(new MouseHandler());
  1125. if(OperatingSystem.isMacOSLF())
  1126. PluginsMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
  1127. } //}}}
  1128. JPopupMenu popup;
  1129. //{{{ updatePopupMenu() method
  1130. void updatePopupMenu()
  1131. {
  1132. popup = null;
  1133. } //}}}
  1134. //{{{ createPopupMenu() method
  1135. private void createPopupMenu()
  1136. {
  1137. if(popup != null)
  1138. return;
  1139. popup = (JPopupMenu)createPluginsMenu(new JPopupMenu(),true);
  1140. } //}}}
  1141. //{{{ ActionHandler class
  1142. class ActionHandler implements ActionListener
  1143. {
  1144. public void actionPerformed(ActionEvent evt)
  1145. {
  1146. VFS vfs = VFSManager.getVFSByName(evt.getActionCommand());
  1147. String directory = vfs.showBrowseDialog(null,
  1148. VFSBrowser.this);
  1149. if(directory != null)
  1150. setDirectory(directory);
  1151. }
  1152. } //}}}
  1153. //{{{ MouseHandler class
  1154. class MouseHandler extends MouseAdapter
  1155. {
  1156. public void mousePressed(MouseEvent evt)
  1157. {
  1158. createPopupMenu();
  1159. if(!popup.isVisible())
  1160. {
  1161. GUIUtilities.showPopupMenu(
  1162. popup,PluginsMenuButton.this,0,
  1163. PluginsMenuButton.this.getHeight(),
  1164. false);
  1165. }
  1166. else
  1167. {
  1168. popup.setVisible(false);
  1169. }
  1170. }
  1171. } //}}}
  1172. } //}}}
  1173. //{{{ FavoritesMenuButton class
  1174. class FavoritesMenuButton extends JButton
  1175. {
  1176. //{{{ FavoritesMenuButton constructor
  1177. FavoritesMenuButton()
  1178. {
  1179. setText(jEdit.getProperty("vfs.browser.favorites.label"));
  1180. setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
  1181. setHorizontalTextPosition(SwingConstants.LEADING);
  1182. FavoritesMenuButton.this.setRequestFocusEnabled(false);
  1183. setMargin(new Insets(1,1,1,1));
  1184. FavoritesMenuButton.this.addMouseListener(new MouseHandler());
  1185. if(OperatingSystem.isMacOSLF())
  1186. FavoritesMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
  1187. } //}}}
  1188. JPopupMenu popup;
  1189. //{{{ createPopupMenu() method
  1190. void createPopupMenu()
  1191. {
  1192. popup = new JPopupMenu();
  1193. ActionHandler actionHandler = new ActionHandler();
  1194. JMenuItem mi = new JMenuItem(
  1195. jEdit.getProperty(
  1196. "vfs.browser.favorites"
  1197. + ".add-to-favorites.label"));
  1198. mi.setActionCommand("add-to-favorites");
  1199. mi.addActionListener(actionHandler);
  1200. popup.add(mi);
  1201. mi = new JMenuItem(
  1202. jEdit.getProperty(
  1203. "vfs.browser.favorites"
  1204. + ".edit-favorites.label"));
  1205. mi.setActionCommand("dir@favorites:");
  1206. mi.addActionListener(actionHandler);
  1207. popup.add(mi);
  1208. popup.addSeparator();
  1209. VFSFile[] favorites = FavoritesVFS.getFavorites();
  1210. if(favorites.length == 0)
  1211. {
  1212. mi = new JMenuItem(
  1213. jEdit.getProperty(
  1214. "vfs.browser.favorites"
  1215. + ".no-favorites.label"));
  1216. mi.setEnabled(false);
  1217. popup.add(mi);
  1218. }
  1219. else
  1220. {
  1221. MiscUtilities.quicksort(favorites,
  1222. new VFS.DirectoryEntryCompare(
  1223. sortMixFilesAndDirs,
  1224. sortIgnoreCase));
  1225. for(int i = 0; i < favorites.length; i++)
  1226. {
  1227. VFSFile favorite = favorites[i];
  1228. mi = new JMenuItem(favorite.getPath());
  1229. mi.setIcon(FileCellRenderer
  1230. .getIconForFile(
  1231. favorite,false));
  1232. String cmd = (favorite.getType() ==
  1233. VFSFile.FILE
  1234. ? "file@" : "dir@")
  1235. + favorite.getPath();
  1236. mi.setActionCommand(cmd);
  1237. mi.addActionListener(actionHandler);
  1238. popup.add(mi);
  1239. }
  1240. }
  1241. } //}}}
  1242. //{{{ ActionHandler class
  1243. class ActionHandler implements ActionListener
  1244. {
  1245. public void actionPerformed(ActionEvent evt)
  1246. {
  1247. String actionCommand = evt.getActionCommand();
  1248. if(actionCommand.equals("add-to-favorites"))
  1249. {
  1250. // if any directories are selected, add
  1251. // them, otherwise add current directory
  1252. VFSFile[] selected = getSelectedFiles();
  1253. if(selected == null || selected.length == 0)
  1254. {
  1255. if(path.equals(FavoritesVFS.PROTOCOL + ":"))
  1256. {
  1257. GUIUtilities.error(VFSBrowser.this,
  1258. "vfs.browser.recurse-favorites",
  1259. null);
  1260. }
  1261. else
  1262. {
  1263. FavoritesVFS.addToFavorites(path,
  1264. VFSFile.DIRECTORY);
  1265. }
  1266. }
  1267. else
  1268. {
  1269. for(int i = 0; i < selected.length; i++)
  1270. {
  1271. VFSFile file = selected[i];
  1272. FavoritesVFS.addToFavorites(file.getPath(),
  1273. file.getType());
  1274. }
  1275. }
  1276. }
  1277. else if(actionCommand.startsWith("dir@"))
  1278. {
  1279. setDirectory(actionCommand.substring(4));
  1280. }
  1281. else if(actionCommand.startsWith("file@"))
  1282. {
  1283. switch(getMode())
  1284. {
  1285. case BROWSER:
  1286. jEdit.openFile(view,actionCommand.substring(5));
  1287. break;
  1288. default:
  1289. locateFile(actionCommand.substring(5));
  1290. break;
  1291. }
  1292. }
  1293. }
  1294. } //}}}
  1295. //{{{ MouseHandler class
  1296. class MouseHandler extends MouseAdapter
  1297. {
  1298. public void mousePressed(MouseEvent evt)
  1299. {
  1300. if(popup != null && popup.isVisible())
  1301. {
  1302. popup.setVisible(false);
  1303. return;
  1304. }
  1305. if(popup == null)
  1306. createPopupMenu();
  1307. GUIUtilities.showPopupMenu(
  1308. popup,FavoritesMenuButton.this,0,
  1309. FavoritesMenuButton.this.getHeight(),
  1310. false);
  1311. }
  1312. } //}}}
  1313. } //}}}
  1314. //{{{ DirectoryLoadedAWTRequest class
  1315. class DirectoryLoadedAWTRequest implements Runnable
  1316. {
  1317. private Object node;
  1318. private Object[] loadInfo;
  1319. private boolean addToHistory;
  1320. DirectoryLoadedAWTRequest(Object node, Object[] loadInfo,
  1321. boolean addToHistory)
  1322. {
  1323. this.node = node;
  1324. this.loadInfo = loadInfo;
  1325. this.addToHistory = addToHistory;
  1326. }
  1327. public void run()
  1328. {
  1329. String path = (String)loadInfo[0];
  1330. if(path == null)
  1331. {
  1332. // there was an error
  1333. return;
  1334. }
  1335. VFSFile[] list = (VFSFile[])loadInfo[1];
  1336. if(node == null)
  1337. {
  1338. // This is the new, canonical path
  1339. VFSBrowser.this.path = path;
  1340. if(!pathField.getText().equals(path))
  1341. pathField.setText(path);
  1342. if(path.endsWith("/") ||
  1343. path.endsWith(File.separator))
  1344. {
  1345. // ensure consistent history;
  1346. // eg we don't want both
  1347. // foo/ and foo
  1348. path = path.substring(0,
  1349. path.length() - 1);
  1350. }
  1351. if(addToHistory)
  1352. {
  1353. HistoryModel.getModel("vfs.browser.path")
  1354. .addItem(path);
  1355. }
  1356. }
  1357. boolean filterEnabled = filterCheckbox.isSelected();
  1358. ArrayList directoryVector = new ArrayList();
  1359. int directories = 0;
  1360. int files = 0;
  1361. int invisible = 0;
  1362. if(list != null)
  1363. {
  1364. for(int i = 0; i < list.length; i++)
  1365. {
  1366. VFSFile file = list[i];
  1367. if(file.isHidden() && !showHiddenFiles)
  1368. {
  1369. invisible++;
  1370. continue;
  1371. }
  1372. if(file.getType() == VFSFile.FILE
  1373. && filterEnabled
  1374. && filenameFilter != null
  1375. && !filenameFilter.isMatch(file.getName()))
  1376. {
  1377. invisible++;
  1378. continue;
  1379. }
  1380. if(file.getType() == VFSFile.FILE)
  1381. files++;
  1382. else
  1383. directories++;
  1384. directoryVector.add(file);
  1385. }
  1386. MiscUtilities.quicksort(directoryVector,
  1387. new VFS.DirectoryEntryCompare(
  1388. sortMixFilesAndDirs,
  1389. sortIgnoreCase));
  1390. }
  1391. browserView.directoryLoaded(node,path,
  1392. directoryVector);
  1393. // to notify listeners that any existing
  1394. // selection has been deactivated
  1395. // turns out under some circumstances this
  1396. // method can switch the current buffer in
  1397. // BROWSER mode.
  1398. // in any case, this is only needed for the
  1399. // directory chooser (why?), so we add a
  1400. // check. otherwise poor Rick will go insane.
  1401. if(mode == CHOOSE_DIRECTORY_DIALOG)
  1402. filesSelected();
  1403. }
  1404. public String toString()
  1405. {
  1406. return (String)loadInfo[0];
  1407. }
  1408. } //}}}
  1409. //{{{ BrowserActionContext class
  1410. static class BrowserActionContext extends ActionContext
  1411. {
  1412. /**
  1413. * If event source hierarchy contains a VFSDirectoryEntryTable,
  1414. * this is the currently selected files there. Otherwise, this
  1415. * is the currently selected item in the parent directory list.
  1416. */
  1417. private VFSFile[] getSelectedFiles(EventObject evt,
  1418. VFSBrowser browser)
  1419. {
  1420. Component source = (Component)evt.getSource();
  1421. if(GUIUtilities.getComponentParent(source,JList.class)
  1422. != null)
  1423. {
  1424. Object[] selected = browser.getBrowserView()
  1425. .getParentDirectoryList()
  1426. .getSelectedValues();
  1427. VFSFile[] returnValue = new VFSFile[
  1428. selected.length];
  1429. System.arraycopy(selected,0,returnValue,0,
  1430. selected.length);
  1431. return returnValue;
  1432. }
  1433. else
  1434. {
  1435. return browser.getSelectedFiles();
  1436. }
  1437. }
  1438. public void invokeAction(EventObject evt, EditAction action)
  1439. {
  1440. VFSBrowser browser = (VFSBrowser)
  1441. GUIUtilities.getComponentParent(
  1442. (Component)evt.getSource(),
  1443. VFSBrowser.class);
  1444. VFSFile[] files = getSelectedFiles(evt,browser);
  1445. // in the future we will want something better,
  1446. // eg. having an 'evt' object passed to
  1447. // EditAction.invoke().
  1448. // for now, since all browser actions are
  1449. // written in beanshell we set the 'browser'
  1450. // variable directly.
  1451. NameSpace global = BeanShell.getNameSpace();
  1452. try
  1453. {
  1454. global.setVariable("browser",browser);
  1455. global.setVariable("files",files);
  1456. View view = browser.getView();
  1457. // I guess ideally all browsers
  1458. // should have views, but since they
  1459. // don't, we just use the active view
  1460. // in that case, since some actions
  1461. // depend on a view being there and
  1462. // I don't want to add checks to
  1463. // them all
  1464. if(view == null)
  1465. view = jEdit.getActiveView();
  1466. action.invoke(view);
  1467. }
  1468. catch(UtilEvalError err)
  1469. {
  1470. Log.log(Log.ERROR,this,err);
  1471. }
  1472. finally
  1473. {
  1474. try
  1475. {
  1476. global.setVariable("browser",null);
  1477. global.setVariable("files",null);
  1478. }
  1479. catch(UtilEvalError err)
  1480. {
  1481. Log.log(Log.ERROR,this,err);
  1482. }
  1483. }
  1484. }
  1485. } //}}}
  1486. //}}}
  1487. }