PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre14/org/gjt/sp/jedit/browser/VFSBrowser.java

#
Java | 1693 lines | 1225 code | 209 blank | 259 comment | 239 complexity | 0988d1a391919a3aa71cc7eebaff1d95 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  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 5053 2004-05-29 01:55:26Z 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. // hacked BufferIORequest to send VFSUpdates in case
  327. // two stage save is off now...
  328. /* else if(bmsg.getWhat() == BufferUpdate.SAVED)
  329. {
  330. maybeReloadDirectory(MiscUtilities.getParentOfPath(
  331. bmsg.getBuffer().getPath()));
  332. } */
  333. }
  334. else if(msg instanceof PluginUpdate)
  335. {
  336. PluginUpdate pmsg = (PluginUpdate)msg;
  337. if(pmsg.getWhat() == PluginUpdate.LOADED
  338. || pmsg.getWhat() == PluginUpdate.UNLOADED)
  339. {
  340. plugins.updatePopupMenu();
  341. }
  342. }
  343. else if(msg instanceof VFSUpdate)
  344. {
  345. maybeReloadDirectory(((VFSUpdate)msg).getPath());
  346. }
  347. } //}}}
  348. //{{{ getView() method
  349. public View getView()
  350. {
  351. return view;
  352. } //}}}
  353. //{{{ getMode() method
  354. public int getMode()
  355. {
  356. return mode;
  357. } //}}}
  358. //{{{ isMultipleSelectionEnabled() method
  359. public boolean isMultipleSelectionEnabled()
  360. {
  361. return multipleSelection;
  362. } //}}}
  363. //{{{ isHorizontalLayout() method
  364. public boolean isHorizontalLayout()
  365. {
  366. return horizontalLayout;
  367. } //}}}
  368. //{{{ getShowHiddenFiles() method
  369. public boolean getShowHiddenFiles()
  370. {
  371. return showHiddenFiles;
  372. } //}}}
  373. //{{{ setShowHiddenFiles() method
  374. public void setShowHiddenFiles(boolean showHiddenFiles)
  375. {
  376. this.showHiddenFiles = showHiddenFiles;
  377. } //}}}
  378. //{{{ getFilenameFilter() method
  379. /**
  380. * Returns the file name filter glob.
  381. * @since jEdit 3.2pre2
  382. */
  383. public String getFilenameFilter()
  384. {
  385. if(filterCheckbox.isSelected())
  386. {
  387. String filter = filterField.getText();
  388. if(filter.length() == 0)
  389. return "*";
  390. else
  391. return filter;
  392. }
  393. else
  394. return "*";
  395. } //}}}
  396. //{{{ setFilenameFilter() method
  397. public void setFilenameFilter(String filter)
  398. {
  399. if(filter == null || filter.length() == 0 || filter.equals("*"))
  400. filterCheckbox.setSelected(false);
  401. else
  402. {
  403. filterCheckbox.setSelected(true);
  404. filterField.setText(filter);
  405. }
  406. } //}}}
  407. //{{{ getDirectoryField() method
  408. public HistoryTextField getDirectoryField()
  409. {
  410. return pathField;
  411. } //}}}
  412. //{{{ getDirectory() method
  413. public String getDirectory()
  414. {
  415. return path;
  416. } //}}}
  417. //{{{ setDirectory() method
  418. public void setDirectory(String path)
  419. {
  420. if(path.startsWith("file:"))
  421. path = path.substring(5);
  422. pathField.setText(path);
  423. if(!startRequest())
  424. return;
  425. updateFilenameFilter();
  426. browserView.saveExpansionState();
  427. browserView.loadDirectory(null,path);
  428. this.path = path;
  429. VFSManager.runInAWTThread(new Runnable()
  430. {
  431. public void run()
  432. {
  433. endRequest();
  434. }
  435. });
  436. } //}}}
  437. //{{{ rootDirectory() method
  438. /**
  439. * Goes to the local drives directory.
  440. * @since jEdit 4.0pre4
  441. */
  442. public void rootDirectory()
  443. {
  444. if(OperatingSystem.isMacOS() || OperatingSystem.isDOSDerived())
  445. setDirectory(FileRootsVFS.PROTOCOL + ":");
  446. else
  447. setDirectory("/");
  448. } //}}}
  449. //{{{ reloadDirectory() method
  450. public void reloadDirectory()
  451. {
  452. // used by FTP plugin to clear directory cache
  453. VFSManager.getVFSForPath(path).reloadDirectory(path);
  454. updateFilenameFilter();
  455. browserView.saveExpansionState();
  456. browserView.loadDirectory(null,path);
  457. } //}}}
  458. //{{{ delete() method
  459. /**
  460. * Note that all files must be on the same VFS.
  461. */
  462. public void delete(VFS.DirectoryEntry[] files)
  463. {
  464. String dialogType;
  465. if(MiscUtilities.isURL(files[0].deletePath)
  466. && FavoritesVFS.PROTOCOL.equals(
  467. MiscUtilities.getProtocolOfURL(files[0].deletePath)))
  468. {
  469. dialogType = "vfs.browser.delete-favorites";
  470. }
  471. else
  472. {
  473. dialogType = "vfs.browser.delete-confirm";
  474. }
  475. StringBuffer buf = new StringBuffer();
  476. for(int i = 0; i < files.length; i++)
  477. {
  478. buf.append(files[i].path);
  479. buf.append('\n');
  480. }
  481. Object[] args = { buf.toString() };
  482. int result = GUIUtilities.confirm(this,dialogType,args,
  483. JOptionPane.YES_NO_OPTION,
  484. JOptionPane.WARNING_MESSAGE);
  485. if(result != JOptionPane.YES_OPTION)
  486. return;
  487. VFS vfs = VFSManager.getVFSForPath(files[0].deletePath);
  488. if(!startRequest())
  489. return;
  490. for(int i = 0; i < files.length; i++)
  491. {
  492. Object session = vfs.createVFSSession(files[i].deletePath,this);
  493. if(session == null)
  494. continue;
  495. VFSManager.runInWorkThread(new BrowserIORequest(
  496. BrowserIORequest.DELETE,this,
  497. session,vfs,files[i].deletePath,
  498. null,null));
  499. }
  500. VFSManager.runInAWTThread(new Runnable()
  501. {
  502. public void run()
  503. {
  504. endRequest();
  505. }
  506. });
  507. } //}}}
  508. //{{{ rename() method
  509. public void rename(String from)
  510. {
  511. VFS vfs = VFSManager.getVFSForPath(from);
  512. String filename = vfs.getFileName(from);
  513. String[] args = { filename };
  514. String to = GUIUtilities.input(this,"vfs.browser.rename",
  515. args,filename);
  516. if(to == null)
  517. return;
  518. to = MiscUtilities.constructPath(vfs.getParentOfPath(from),to);
  519. Object session = vfs.createVFSSession(from,this);
  520. if(session == null)
  521. return;
  522. if(!startRequest())
  523. return;
  524. VFSManager.runInWorkThread(new BrowserIORequest(
  525. BrowserIORequest.RENAME,this,
  526. session,vfs,from,to,null));
  527. VFSManager.runInAWTThread(new Runnable()
  528. {
  529. public void run()
  530. {
  531. endRequest();
  532. }
  533. });
  534. } //}}}
  535. //{{{ mkdir() method
  536. public void mkdir()
  537. {
  538. String newDirectory = GUIUtilities.input(this,"vfs.browser.mkdir",null);
  539. if(newDirectory == null)
  540. return;
  541. // if a directory is selected, create new dir in there.
  542. // if a file is selected, create new dir inside its parent.
  543. VFS.DirectoryEntry[] selected = getSelectedFiles();
  544. String parent;
  545. if(selected.length == 0)
  546. parent = path;
  547. else if(selected[0].type == VFS.DirectoryEntry.FILE)
  548. {
  549. parent = selected[0].path;
  550. parent = VFSManager.getVFSForPath(parent)
  551. .getParentOfPath(parent);
  552. }
  553. else
  554. parent = selected[0].path;
  555. VFS vfs = VFSManager.getVFSForPath(parent);
  556. // path is the currently viewed directory in the browser
  557. newDirectory = MiscUtilities.constructPath(parent,newDirectory);
  558. Object session = vfs.createVFSSession(newDirectory,this);
  559. if(session == null)
  560. return;
  561. if(!startRequest())
  562. return;
  563. VFSManager.runInWorkThread(new BrowserIORequest(
  564. BrowserIORequest.MKDIR,this,
  565. session,vfs,newDirectory,null,null));
  566. VFSManager.runInAWTThread(new Runnable()
  567. {
  568. public void run()
  569. {
  570. endRequest();
  571. }
  572. });
  573. } //}}}
  574. //{{{ newFile() method
  575. /**
  576. * Creates a new file in the current directory.
  577. * @since jEdit 4.0pre2
  578. */
  579. public void newFile()
  580. {
  581. VFS.DirectoryEntry[] selected = getSelectedFiles();
  582. if(selected.length >= 1)
  583. {
  584. VFS.DirectoryEntry file = selected[0];
  585. if(file.type == VFS.DirectoryEntry.DIRECTORY)
  586. jEdit.newFile(view,file.path);
  587. else
  588. {
  589. VFS vfs = VFSManager.getVFSForPath(file.path);
  590. jEdit.newFile(view,vfs.getParentOfPath(file.path));
  591. }
  592. }
  593. else
  594. jEdit.newFile(view,path);
  595. } //}}}
  596. //{{{ searchInDirectory() method
  597. /**
  598. * Opens a directory search in the current directory.
  599. * @since jEdit 4.0pre2
  600. */
  601. public void searchInDirectory()
  602. {
  603. VFS.DirectoryEntry[] selected = getSelectedFiles();
  604. if(selected.length >= 1)
  605. {
  606. VFS.DirectoryEntry file = selected[0];
  607. searchInDirectory(file.path,file.type != VFS.DirectoryEntry.FILE);
  608. }
  609. else
  610. {
  611. searchInDirectory(this.path,true);
  612. }
  613. } //}}}
  614. //{{{ searchInDirectory() method
  615. /**
  616. * Opens a directory search in the specified directory.
  617. * @param path The path name
  618. * @param directory True if the path is a directory, false if it is a file
  619. * @since jEdit 4.2pre1
  620. */
  621. public void searchInDirectory(String path, boolean directory)
  622. {
  623. String filter;
  624. if(directory)
  625. {
  626. filter = getFilenameFilter();
  627. }
  628. else
  629. {
  630. String name = MiscUtilities.getFileName(path);
  631. String ext = MiscUtilities.getFileExtension(name);
  632. filter = (ext == null || ext.length() == 0
  633. ? getFilenameFilter()
  634. : "*" + ext);
  635. path = MiscUtilities.getParentOfPath(path);
  636. }
  637. SearchAndReplace.setSearchFileSet(new DirectoryListSet(
  638. path,filter,true));
  639. SearchDialog.showSearchDialog(view,null,SearchDialog.DIRECTORY);
  640. } //}}}
  641. //{{{ getBrowserView() method
  642. public BrowserView getBrowserView()
  643. {
  644. return browserView;
  645. } //}}}
  646. //{{{ getSelectedFiles() method
  647. public VFS.DirectoryEntry[] getSelectedFiles()
  648. {
  649. return browserView.getSelectedFiles();
  650. } //}}}
  651. //{{{ locateFile() method
  652. /**
  653. * Goes to the given file's directory and selects the file in the list.
  654. * @param path The file
  655. * @since jEdit 4.2pre2
  656. */
  657. public void locateFile(final String path)
  658. {
  659. if(!filenameFilter.isMatch(MiscUtilities.getFileName(path)))
  660. setFilenameFilter(null);
  661. setDirectory(MiscUtilities.getParentOfPath(path));
  662. VFSManager.runInAWTThread(new Runnable()
  663. {
  664. public void run()
  665. {
  666. browserView.getTable().selectFile(path);
  667. }
  668. });
  669. } //}}}
  670. //{{{ addBrowserListener() method
  671. public void addBrowserListener(BrowserListener l)
  672. {
  673. listenerList.add(BrowserListener.class,l);
  674. } //}}}
  675. //{{{ removeBrowserListener() method
  676. public void removeBrowserListener(BrowserListener l)
  677. {
  678. listenerList.remove(BrowserListener.class,l);
  679. } //}}}
  680. //{{{ filesActivated() method
  681. // canDoubleClickClose set to false when ENTER pressed
  682. public static final int M_OPEN = 0;
  683. public static final int M_OPEN_NEW_VIEW = 1;
  684. public static final int M_OPEN_NEW_PLAIN_VIEW = 2;
  685. public static final int M_OPEN_NEW_SPLIT = 3;
  686. public static final int M_INSERT = 4;
  687. /**
  688. * This method does the "double-click" handling. It is public so that
  689. * <code>browser.actions.xml</code> can bind to it.
  690. * @since jEdit 4.2pre2
  691. */
  692. public void filesActivated(int mode, boolean canDoubleClickClose)
  693. {
  694. VFS.DirectoryEntry[] selectedFiles = browserView.getSelectedFiles();
  695. Buffer buffer = null;
  696. check_selected: for(int i = 0; i < selectedFiles.length; i++)
  697. {
  698. VFS.DirectoryEntry file = selectedFiles[i];
  699. if(file.type == VFS.DirectoryEntry.DIRECTORY
  700. || file.type == VFS.DirectoryEntry.FILESYSTEM)
  701. {
  702. if(mode == M_OPEN_NEW_VIEW && this.mode == BROWSER)
  703. browseDirectoryInNewWindow(view,file.path);
  704. else
  705. setDirectory(file.path);
  706. }
  707. else if(this.mode == BROWSER || this.mode == BROWSER_DIALOG)
  708. {
  709. if(mode == M_INSERT)
  710. {
  711. view.getBuffer().insertFile(view,
  712. file.path);
  713. continue check_selected;
  714. }
  715. Buffer _buffer = jEdit.getBuffer(file.path);
  716. if(_buffer == null)
  717. {
  718. Hashtable props = new Hashtable();
  719. props.put(Buffer.ENCODING,currentEncoding);
  720. props.put(Buffer.ENCODING_AUTODETECT,
  721. Boolean.valueOf(autoDetectEncoding));
  722. _buffer = jEdit.openFile(null,null,
  723. file.path,false,props);
  724. }
  725. else if(doubleClickClose && canDoubleClickClose
  726. && this.mode != BROWSER_DIALOG
  727. && selectedFiles.length == 1)
  728. {
  729. // close if this buffer is currently
  730. // visible in the view.
  731. EditPane[] editPanes = view.getEditPanes();
  732. for(int j = 0; j < editPanes.length; j++)
  733. {
  734. if(editPanes[j].getBuffer() == _buffer)
  735. {
  736. jEdit.closeBuffer(view,_buffer);
  737. return;
  738. }
  739. }
  740. }
  741. if(_buffer != null)
  742. buffer = _buffer;
  743. }
  744. else
  745. {
  746. // if a file is selected in OPEN_DIALOG or
  747. // SAVE_DIALOG mode, just let the listener(s)
  748. // handle it
  749. }
  750. }
  751. if(buffer != null)
  752. {
  753. switch(mode)
  754. {
  755. case M_OPEN:
  756. view.setBuffer(buffer);
  757. break;
  758. case M_OPEN_NEW_VIEW:
  759. jEdit.newView(view,buffer,false);
  760. break;
  761. case M_OPEN_NEW_PLAIN_VIEW:
  762. jEdit.newView(view,buffer,true);
  763. break;
  764. case M_OPEN_NEW_SPLIT:
  765. view.splitHorizontally().setBuffer(buffer);
  766. break;
  767. }
  768. }
  769. Object[] listeners = listenerList.getListenerList();
  770. for(int i = 0; i < listeners.length; i++)
  771. {
  772. if(listeners[i] == BrowserListener.class)
  773. {
  774. BrowserListener l = (BrowserListener)listeners[i+1];
  775. l.filesActivated(this,selectedFiles);
  776. }
  777. }
  778. } //}}}
  779. //{{{ Package-private members
  780. String currentEncoding;
  781. boolean autoDetectEncoding;
  782. //{{{ pathsEqual() method
  783. /**
  784. * This will be made public at some stage, in the io package, but not
  785. * yet.
  786. */
  787. static boolean pathsEqual(String p1, String p2)
  788. {
  789. if(p1.endsWith("/") || p1.endsWith(File.separator))
  790. p1 = p1.substring(0,p1.length() - 1);
  791. if(p2.endsWith("/") || p2.endsWith(File.separator))
  792. p2 = p2.substring(0,p2.length() - 1);
  793. return p1.equals(p2);
  794. } //}}}
  795. //{{{ updateFilenameFilter() method
  796. void updateFilenameFilter()
  797. {
  798. try
  799. {
  800. String filter = filterField.getText();
  801. if(filter.length() == 0)
  802. filter = "*";
  803. filenameFilter = new RE(MiscUtilities.globToRE(filter),RE.REG_ICASE);
  804. }
  805. catch(Exception e)
  806. {
  807. Log.log(Log.ERROR,VFSBrowser.this,e);
  808. String[] args = { filterField.getText(),
  809. e.getMessage() };
  810. GUIUtilities.error(this,"vfs.browser.bad-filter",args);
  811. }
  812. } //}}}
  813. //{{{ directoryLoaded() method
  814. void directoryLoaded(Object node, Object[] loadInfo)
  815. {
  816. VFSManager.runInAWTThread(new DirectoryLoadedAWTRequest(
  817. node,loadInfo));
  818. } //}}}
  819. //{{{ filesSelected() method
  820. void filesSelected()
  821. {
  822. VFS.DirectoryEntry[] selectedFiles = browserView.getSelectedFiles();
  823. if(mode == BROWSER)
  824. {
  825. for(int i = 0; i < selectedFiles.length; i++)
  826. {
  827. VFS.DirectoryEntry file = selectedFiles[i];
  828. Buffer buffer = jEdit.getBuffer(file.path);
  829. if(buffer != null && view != null)
  830. view.setBuffer(buffer);
  831. }
  832. }
  833. Object[] listeners = listenerList.getListenerList();
  834. for(int i = 0; i < listeners.length; i++)
  835. {
  836. if(listeners[i] == BrowserListener.class)
  837. {
  838. BrowserListener l = (BrowserListener)listeners[i+1];
  839. l.filesSelected(this,selectedFiles);
  840. }
  841. }
  842. } //}}}
  843. //{{{ endRequest() method
  844. void endRequest()
  845. {
  846. requestRunning = false;
  847. } //}}}
  848. //}}}
  849. //{{{ Private members
  850. private static ActionContext actionContext;
  851. static
  852. {
  853. actionContext = new BrowserActionContext();
  854. ActionSet builtInActionSet = new ActionSet(null,null,null,
  855. jEdit.class.getResource("browser.actions.xml"));
  856. builtInActionSet.setLabel(jEdit.getProperty("action-set.browser"));
  857. builtInActionSet.load();
  858. actionContext.addActionSet(builtInActionSet);
  859. }
  860. //{{{ Instance variables
  861. private EventListenerList listenerList;
  862. private View view;
  863. private boolean horizontalLayout;
  864. private String path;
  865. private HistoryTextField pathField;
  866. private JCheckBox filterCheckbox;
  867. private HistoryTextField filterField;
  868. private Box toolbarBox;
  869. private FavoritesMenuButton favorites;
  870. private PluginsMenuButton plugins;
  871. private BrowserView browserView;
  872. private RE filenameFilter;
  873. private int mode;
  874. private boolean multipleSelection;
  875. private boolean showHiddenFiles;
  876. private boolean sortMixFilesAndDirs;
  877. private boolean sortIgnoreCase;
  878. private boolean doubleClickClose;
  879. private boolean requestRunning;
  880. private boolean maybeReloadRequestRunning;
  881. //}}}
  882. //{{{ createMenuBar() method
  883. private JPanel createMenuBar()
  884. {
  885. JPanel menuBar = new JPanel();
  886. menuBar.setLayout(new BoxLayout(menuBar,BoxLayout.X_AXIS));
  887. menuBar.setBorder(new EmptyBorder(0,1,0,3));
  888. menuBar.add(new CommandsMenuButton());
  889. menuBar.add(Box.createHorizontalStrut(3));
  890. menuBar.add(plugins = new PluginsMenuButton());
  891. menuBar.add(Box.createHorizontalStrut(3));
  892. menuBar.add(favorites = new FavoritesMenuButton());
  893. return menuBar;
  894. } //}}}
  895. //{{{ createToolBar() method
  896. private Box createToolBar()
  897. {
  898. if(mode == BROWSER)
  899. return GUIUtilities.loadToolBar(actionContext,
  900. "vfs.browser.toolbar-browser");
  901. else
  902. return GUIUtilities.loadToolBar(actionContext,
  903. "vfs.browser.toolbar-dialog");
  904. } //}}}
  905. //{{{ propertiesChanged() method
  906. private void propertiesChanged()
  907. {
  908. showHiddenFiles = jEdit.getBooleanProperty("vfs.browser.showHiddenFiles");
  909. sortMixFilesAndDirs = jEdit.getBooleanProperty("vfs.browser.sortMixFilesAndDirs");
  910. sortIgnoreCase = jEdit.getBooleanProperty("vfs.browser.sortIgnoreCase");
  911. doubleClickClose = jEdit.getBooleanProperty("vfs.browser.doubleClickClose");
  912. browserView.propertiesChanged();
  913. toolbarBox.removeAll();
  914. if(jEdit.getBooleanProperty("vfs.browser.showToolbar"))
  915. {
  916. Box toolbar = createToolBar();
  917. if(horizontalLayout)
  918. toolbarBox.add(toolbar);
  919. else
  920. {
  921. toolbar.add(Box.createGlue());
  922. toolbarBox.add(toolbar);
  923. }
  924. }
  925. if(jEdit.getBooleanProperty("vfs.browser.showMenubar"))
  926. {
  927. JPanel menubar = createMenuBar();
  928. if(horizontalLayout)
  929. {
  930. toolbarBox.add(Box.createHorizontalStrut(6));
  931. toolbarBox.add(menubar,0);
  932. }
  933. else
  934. {
  935. menubar.add(Box.createGlue());
  936. toolbarBox.add(menubar);
  937. }
  938. }
  939. else
  940. favorites = null;
  941. toolbarBox.add(Box.createGlue());
  942. revalidate();
  943. if(path != null)
  944. reloadDirectory();
  945. } //}}}
  946. /* We do this stuff because the browser is not able to handle
  947. * more than one request yet */
  948. //{{{ startRequest() method
  949. private boolean startRequest()
  950. {
  951. if(requestRunning)
  952. {
  953. // dump stack trace for debugging purposes
  954. Log.log(Log.DEBUG,this,new Throwable("For debugging purposes"));
  955. GUIUtilities.error(this,"browser-multiple-io",null);
  956. return false;
  957. }
  958. else
  959. {
  960. requestRunning = true;
  961. return true;
  962. }
  963. } //}}}
  964. //{{{ updateFilterEnabled() method
  965. private void updateFilterEnabled()
  966. {
  967. filterField.setEnabled(filterCheckbox.isSelected());
  968. } //}}}
  969. //{{{ maybeReloadDirectory() method
  970. private void maybeReloadDirectory(String dir)
  971. {
  972. if(MiscUtilities.isURL(dir)
  973. && MiscUtilities.getProtocolOfURL(dir).equals(
  974. FavoritesVFS.PROTOCOL))
  975. {
  976. if(favorites != null)
  977. favorites.popup = null;
  978. }
  979. // this is a dirty hack and it relies on the fact
  980. // that updates for parents are sent before updates
  981. // for the changed nodes themselves (if this was not
  982. // the case, the browser wouldn't be updated properly
  983. // on delete, etc).
  984. //
  985. // to avoid causing '> 1 request' errors, don't reload
  986. // directory if request already active
  987. if(maybeReloadRequestRunning)
  988. {
  989. //Log.log(Log.WARNING,this,"VFS update: request already in progress");
  990. return;
  991. }
  992. // save a file -> sends vfs update. if a VFS file dialog box
  993. // is shown from the same event frame as the save, the
  994. // VFSUpdate will be delivered before the directory is loaded,
  995. // and before the path is set.
  996. if(path != null)
  997. {
  998. try
  999. {
  1000. maybeReloadRequestRunning = true;
  1001. browserView.maybeReloadDirectory(dir);
  1002. }
  1003. finally
  1004. {
  1005. VFSManager.runInAWTThread(new Runnable()
  1006. {
  1007. public void run()
  1008. {
  1009. maybeReloadRequestRunning = false;
  1010. }
  1011. });
  1012. }
  1013. }
  1014. } //}}}
  1015. //}}}
  1016. //{{{ Inner classes
  1017. //{{{ ActionHandler class
  1018. class ActionHandler implements ActionListener
  1019. {
  1020. public void actionPerformed(ActionEvent evt)
  1021. {
  1022. Object source = evt.getSource();
  1023. if(source == pathField || source == filterField
  1024. || source == filterCheckbox)
  1025. {
  1026. updateFilterEnabled();
  1027. String path = pathField.getText();
  1028. if(path != null)
  1029. setDirectory(path);
  1030. browserView.focusOnFileView();
  1031. }
  1032. }
  1033. } //}}}
  1034. //{{{ CommandsMenuButton class
  1035. class CommandsMenuButton extends JButton
  1036. {
  1037. //{{{ CommandsMenuButton constructor
  1038. CommandsMenuButton()
  1039. {
  1040. setText(jEdit.getProperty("vfs.browser.commands.label"));
  1041. setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
  1042. setHorizontalTextPosition(SwingConstants.LEADING);
  1043. popup = new BrowserCommandsMenu(VFSBrowser.this,null);
  1044. CommandsMenuButton.this.setRequestFocusEnabled(false);
  1045. setMargin(new Insets(1,1,1,1));
  1046. CommandsMenuButton.this.addMouseListener(new MouseHandler());
  1047. if(OperatingSystem.isMacOSLF())
  1048. CommandsMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
  1049. } //}}}
  1050. BrowserCommandsMenu popup;
  1051. //{{{ MouseHandler class
  1052. class MouseHandler extends MouseAdapter
  1053. {
  1054. public void mousePressed(MouseEvent evt)
  1055. {
  1056. if(!popup.isVisible())
  1057. {
  1058. popup.update();
  1059. GUIUtilities.showPopupMenu(
  1060. popup,CommandsMenuButton.this,0,
  1061. CommandsMenuButton.this.getHeight(),
  1062. false);
  1063. }
  1064. else
  1065. {
  1066. popup.setVisible(false);
  1067. }
  1068. }
  1069. } //}}}
  1070. } //}}}
  1071. //{{{ PluginsMenuButton class
  1072. class PluginsMenuButton extends JButton
  1073. {
  1074. //{{{ PluginsMenuButton constructor
  1075. PluginsMenuButton()
  1076. {
  1077. setText(jEdit.getProperty("vfs.browser.plugins.label"));
  1078. setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
  1079. setHorizontalTextPosition(SwingConstants.LEADING);
  1080. PluginsMenuButton.this.setRequestFocusEnabled(false);
  1081. setMargin(new Insets(1,1,1,1));
  1082. PluginsMenuButton.this.addMouseListener(new MouseHandler());
  1083. if(OperatingSystem.isMacOSLF())
  1084. PluginsMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
  1085. } //}}}
  1086. JPopupMenu popup;
  1087. //{{{ updatePopupMenu() method
  1088. void updatePopupMenu()
  1089. {
  1090. popup = null;
  1091. } //}}}
  1092. //{{{ createPopupMenu() method
  1093. private void createPopupMenu()
  1094. {
  1095. if(popup != null)
  1096. return;
  1097. popup = new JPopupMenu();
  1098. ActionHandler actionHandler = new ActionHandler();
  1099. if(getMode() == BROWSER)
  1100. {
  1101. popup.add(GUIUtilities.loadMenuItem("plugin-manager",false));
  1102. popup.add(GUIUtilities.loadMenuItem("plugin-options",false));
  1103. popup.addSeparator();
  1104. }
  1105. else
  1106. /* we're in a modal dialog */;
  1107. ArrayList vec = new ArrayList();
  1108. //{{{ old API
  1109. Enumeration e = VFSManager.getFilesystems();
  1110. while(e.hasMoreElements())
  1111. {
  1112. VFS vfs = (VFS)e.nextElement();
  1113. if((vfs.getCapabilities() & VFS.BROWSE_CAP) == 0)
  1114. continue;
  1115. JMenuItem menuItem = new JMenuItem(jEdit.getProperty(
  1116. "vfs." + vfs.getName() + ".label"));
  1117. menuItem.setActionCommand(vfs.getName());
  1118. menuItem.addActionListener(actionHandler);
  1119. vec.add(menuItem);
  1120. } //}}}
  1121. //{{{ new API
  1122. EditPlugin[] plugins = jEdit.getPlugins();
  1123. for(int i = 0; i < plugins.length; i++)
  1124. {
  1125. JMenuItem menuItem = plugins[i].createBrowserMenuItems();
  1126. if(menuItem != null)
  1127. vec.add(menuItem);
  1128. } //}}}
  1129. if(vec.size() != 0)
  1130. {
  1131. MiscUtilities.quicksort(vec,new MiscUtilities.MenuItemCompare());
  1132. for(int i = 0; i < vec.size(); i++)
  1133. popup.add((JMenuItem)vec.get(i));
  1134. }
  1135. else
  1136. {
  1137. JMenuItem mi = new JMenuItem(jEdit.getProperty(
  1138. "vfs.browser.plugins.no-plugins.label"));
  1139. mi.setEnabled(false);
  1140. popup.add(mi);
  1141. }
  1142. } //}}}
  1143. //{{{ ActionHandler class
  1144. class ActionHandler implements ActionListener
  1145. {
  1146. public void actionPerformed(ActionEvent evt)
  1147. {
  1148. VFS vfs = VFSManager.getVFSByName(evt.getActionCommand());
  1149. String directory = vfs.showBrowseDialog(null,
  1150. VFSBrowser.this);
  1151. if(directory != null)
  1152. setDirectory(directory);
  1153. }
  1154. } //}}}
  1155. //{{{ MouseHandler class
  1156. class MouseHandler extends MouseAdapter
  1157. {
  1158. public void mousePressed(MouseEvent evt)
  1159. {
  1160. createPopupMenu();
  1161. if(!popup.isVisible())
  1162. {
  1163. GUIUtilities.showPopupMenu(
  1164. popup,PluginsMenuButton.this,0,
  1165. PluginsMenuButton.this.getHeight(),
  1166. false);
  1167. }
  1168. else
  1169. {
  1170. popup.setVisible(false);
  1171. }
  1172. }
  1173. } //}}}
  1174. } //}}}
  1175. //{{{ FavoritesMenuButton class
  1176. class FavoritesMenuButton extends JButton
  1177. {
  1178. //{{{ FavoritesMenuButton constructor
  1179. FavoritesMenuButton()
  1180. {
  1181. setText(jEdit.getProperty("vfs.browser.favorites.label"));
  1182. setIcon(GUIUtilities.loadIcon("ToolbarMenu.gif"));
  1183. setHorizontalTextPosition(SwingConstants.LEADING);
  1184. FavoritesMenuButton.this.setRequestFocusEnabled(false);
  1185. setMargin(new Insets(1,1,1,1));
  1186. FavoritesMenuButton.this.addMouseListener(new MouseHandler());
  1187. if(OperatingSystem.isMacOSLF())
  1188. FavoritesMenuButton.this.putClientProperty("JButton.buttonType","toolbar");
  1189. } //}}}
  1190. JPopupMenu popup;
  1191. //{{{ createPopupMenu() method
  1192. void createPopupMenu()
  1193. {
  1194. popup = new JPopupMenu();
  1195. ActionHandler actionHandler = new ActionHandler();
  1196. JMenuItem mi = new JMenuItem(
  1197. jEdit.getProperty(
  1198. "vfs.browser.favorites"
  1199. + ".add-to-favorites.label"));
  1200. mi.setActionCommand("add-to-favorites");
  1201. mi.addActionListener(actionHandler);
  1202. popup.add(mi);
  1203. mi = new JMenuItem(
  1204. jEdit.getProperty(
  1205. "vfs.browser.favorites"
  1206. + ".edit-favorites.label"));
  1207. mi.setActionCommand("dir@favorites:");
  1208. mi.addActionListener(actionHandler);
  1209. popup.add(mi);
  1210. popup.addSeparator();
  1211. VFS.DirectoryEntry[] favorites
  1212. = FavoritesVFS.getFavorites();
  1213. if(favorites.length == 0)
  1214. {
  1215. mi = new JMenuItem(
  1216. jEdit.getProperty(
  1217. "vfs.browser.favorites"
  1218. + ".no-favorites.label"));
  1219. mi.setEnabled(false);
  1220. popup.add(mi);
  1221. }
  1222. else
  1223. {
  1224. MiscUtilities.quicksort(favorites,
  1225. new VFS.DirectoryEntryCompare(
  1226. sortMixFilesAndDirs,
  1227. sortIgnoreCase));
  1228. for(int i = 0; i < favorites.length; i++)
  1229. {
  1230. VFS.DirectoryEntry favorite
  1231. = favorites[i];
  1232. mi = new JMenuItem(favorite.path);
  1233. mi.setIcon(FileCellRenderer
  1234. .getIconForFile(
  1235. favorite,false));
  1236. String cmd = (favorite.type ==
  1237. VFS.DirectoryEntry.FILE
  1238. ? "file@" : "dir@")
  1239. + favorite.path;
  1240. mi.setActionCommand(cmd);
  1241. mi.addActionListener(actionHandler);
  1242. popup.add(mi);
  1243. }
  1244. }
  1245. } //}}}
  1246. //{{{ ActionHandler class
  1247. class ActionHandler implements ActionListener
  1248. {
  1249. public void actionPerformed(ActionEvent evt)
  1250. {
  1251. String actionCommand = evt.getActionCommand();
  1252. if(actionCommand.equals("add-to-favorites"))
  1253. {
  1254. // if any directories are selected, add
  1255. // them, otherwise add current directory
  1256. ArrayList toAdd = new ArrayList();
  1257. VFS.DirectoryEntry[] selected = getSelectedFiles();
  1258. if(selected == null || selected.length == 0)
  1259. {
  1260. if(path.equals(FavoritesVFS.PROTOCOL + ":"))
  1261. {
  1262. GUIUtilities.error(VFSBrowser.this,
  1263. "vfs.browser.recurse-favorites",
  1264. null);
  1265. }
  1266. else
  1267. {
  1268. FavoritesVFS.addToFavorites(path,
  1269. VFS.DirectoryEntry.DIRECTORY);
  1270. }
  1271. }
  1272. else
  1273. {
  1274. for(int i = 0; i < selected.length; i++)
  1275. {
  1276. VFS.DirectoryEntry file
  1277. = selected[i];
  1278. FavoritesVFS.addToFavorites(file.path,file.type);
  1279. }
  1280. }
  1281. }
  1282. else if(actionCommand.startsWith("dir@"))
  1283. {
  1284. setDirectory(actionCommand.substring(4));
  1285. }
  1286. else if(actionCommand.startsWith("file@"))
  1287. {
  1288. switch(getMode())
  1289. {
  1290. case BROWSER:
  1291. jEdit.openFile(view,actionCommand.substring(5));
  1292. break;
  1293. default:
  1294. locateFile(actionCommand.substring(5));
  1295. break;
  1296. }
  1297. }
  1298. }
  1299. } //}}}
  1300. //{{{ MouseHandler class
  1301. class MouseHandler extends MouseAdapter
  1302. {
  1303. public void mousePressed(MouseEvent evt)
  1304. {
  1305. if(popup != null && popup.isVisible())
  1306. {
  1307. popup.setVisible(false);
  1308. return;
  1309. }
  1310. if(popup == null)
  1311. createPopupMenu();
  1312. GUIUtilities.showPopupMenu(
  1313. popup,FavoritesMenuButton.this,0,
  1314. FavoritesMenuButton.this.getHeight(),
  1315. false);
  1316. }
  1317. } //}}}
  1318. } //}}}
  1319. //{{{ DirectoryLoadedAWTRequest class
  1320. class DirectoryLoadedAWTRequest implements Runnable
  1321. {
  1322. Object node;
  1323. Object[] loadInfo;
  1324. DirectoryLoadedAWTRequest(Object node, Object[] loadInfo)
  1325. {
  1326. this.node = node;
  1327. this.loadInfo = loadInfo;
  1328. }
  1329. public void run()
  1330. {
  1331. String path = (String)loadInfo[0];
  1332. VFS.DirectoryEntry[] list = (VFS.DirectoryEntry[])
  1333. loadInfo[1];
  1334. if(node == null)
  1335. {
  1336. // This is the new, canonical path
  1337. VFSBrowser.this.path = path;
  1338. if(!pathField.getText().equals(path))
  1339. pathField.setText(path);
  1340. if(path.endsWith("/") ||
  1341. path.endsWith(File.separator))
  1342. {
  1343. // ensure consistent history;
  1344. // eg we don't want both
  1345. // foo/ and foo
  1346. path = path.substring(0,
  1347. path.length() - 1);
  1348. }
  1349. HistoryModel.getModel("vfs.browser.path")
  1350. .addItem(path);
  1351. }
  1352. boolean filterEnabled = filterCheckbox.isSelected();
  1353. ArrayList directoryVector = new ArrayList();
  1354. int directories = 0;
  1355. int files = 0;
  1356. int invisible = 0;
  1357. if(list != null)
  1358. {
  1359. for(int i = 0; i < list.length; i++)
  1360. {
  1361. VFS.DirectoryEntry file = list[i];
  1362. if(file.hidden && !showHiddenFiles)
  1363. {
  1364. invisible++;
  1365. continue;
  1366. }
  1367. if(file.type == VFS.DirectoryEntry.FILE
  1368. && filterEnabled
  1369. && filenameFilter != null
  1370. && !filenameFilter.isMatch(file.name))
  1371. {
  1372. invisible++;
  1373. continue;
  1374. }
  1375. if(file.type == VFS.DirectoryEntry.FILE)
  1376. files++;
  1377. else
  1378. directories++;
  1379. directoryVector.add(file);
  1380. }
  1381. MiscUtilities.quicksort(directoryVector,
  1382. new VFS.DirectoryEntryCompare(
  1383. sortMixFilesAndDirs,
  1384. sortIgnoreCase));
  1385. }
  1386. browserView.directoryLoaded(node,path,
  1387. directoryVector);
  1388. // to notify listeners that any existing
  1389. // selection has been deactivated
  1390. // turns out under some circumstances this
  1391. // method can switch the current buffer in
  1392. // BROWSER mode.
  1393. // in any case, this is only needed for the
  1394. // directory chooser (why?), so we add a
  1395. // check. otherwise poor Rick will go insane.
  1396. if(mode == CHOOSE_DIRECTORY_DIALOG)
  1397. filesSelected();
  1398. }
  1399. public String toString()
  1400. {
  1401. return (String)loadInfo[0];
  1402. }
  1403. } //}}}
  1404. //{{{ BrowserActionContext class
  1405. static class BrowserActionContext extends ActionContext
  1406. {
  1407. /**
  1408. * If event source hierarchy contains a VFSDirectoryEntryTable,
  1409. * this is the currently selected files there. Otherwise, this
  1410. * is the currently selected item in the parent directory list.
  1411. */
  1412. private VFS.DirectoryEntry[] getSelectedFiles(EventObject evt,
  1413. VFSBrowser browser)
  1414. {
  1415. Component source = (Component)evt.getSource();
  1416. if(GUIUtilities.getComponentParent(source,JList.class)
  1417. != null)
  1418. {
  1419. Object[] selected = browser.getBrowserView()
  1420. .getParentDirectoryList()
  1421. .getSelectedValues();
  1422. VFS.DirectoryEntry[] returnValue
  1423. = new VFS.DirectoryEntry[
  1424. selected.length];
  1425. System.arraycopy(selected,0,returnValue,0,
  1426. selected.length);
  1427. return returnValue;
  1428. }
  1429. else
  1430. {
  1431. return browser.getSelectedFiles();
  1432. }
  1433. }
  1434. public void invokeAction(EventObject evt, EditAction action)
  1435. {
  1436. VFSBrowser browser = (VFSBrowser)
  1437. GUIUtilities.getComponentParent(
  1438. (Component)evt.getSource(),
  1439. VFSBrowser.class);
  1440. VFS.DirectoryEntry[] files = getSelectedFiles(evt,
  1441. browser);
  1442. // in the future we will want something better,
  1443. // eg. having an 'evt' object passed to
  1444. // EditAction.invoke().
  1445. // for now, since all browser actions are
  1446. // written in beanshell we set the 'browser'
  1447. // variable directly.
  1448. NameSpace global = BeanShell.getNameSpace();
  1449. try
  1450. {
  1451. global.setVariable("browser",browser);
  1452. global.setVariable("files",files);
  1453. View view = browser.getView();
  1454. // I guess ideally all browsers
  1455. // should have views, but since they
  1456. // don't, we just use the active view
  1457. // in that case, since some actions
  1458. // depend on a view being there and
  1459. // I don't want to add checks to
  1460. // them all
  1461. if(view == null)
  1462. view = jEdit.getActiveView();
  1463. action.invoke(view);
  1464. }
  1465. catch(UtilEvalError err)
  1466. {
  1467. Log.log(Log.ERROR,this,err);
  1468. }
  1469. finally
  1470. {
  1471. try
  1472. {
  1473. global.setVariable("browser",null);
  1474. global.setVariable("files",null);
  1475. }
  1476. catch(UtilEvalError err)
  1477. {
  1478. Log.log(Log.ERROR,this,err);
  1479. }
  1480. }
  1481. }
  1482. } //}}}
  1483. //}}}
  1484. }