/jEdit/tags/jedit-4-4-1/org/gjt/sp/jedit/browser/VFSFileChooserDialog.java

# · Java · 595 lines · 451 code · 60 blank · 84 comment · 91 complexity · a7b23dacd3ac00f6215a04e8335db5a5 MD5 · raw file

  1. /*
  2. * VFSFileChooserDialog.java - VFS file chooser
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2005 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 javax.swing.border.EmptyBorder;
  25. import javax.swing.*;
  26. import java.awt.event.*;
  27. import java.awt.BorderLayout;
  28. import java.awt.Cursor;
  29. import java.awt.Dimension;
  30. import java.awt.Dialog;
  31. import java.awt.Frame;
  32. import java.io.File;
  33. import java.io.IOException;
  34. import java.util.*;
  35. import org.gjt.sp.jedit.gui.EnhancedDialog;
  36. import org.gjt.sp.jedit.io.*;
  37. import org.gjt.sp.jedit.*;
  38. import org.gjt.sp.jedit.buffer.JEditBuffer;
  39. import org.gjt.sp.util.*;
  40. //}}}
  41. /**
  42. * Wraps the VFS browser in a modal dialog.
  43. * Shows up when "File-Open" is used.
  44. * @author Slava Pestov
  45. * @version $Id: VFSFileChooserDialog.java 17393 2010-02-27 12:13:39Z k_satoda $
  46. */
  47. public class VFSFileChooserDialog extends EnhancedDialog
  48. {
  49. //{{{ VFSFileChooserDialog constructor
  50. public VFSFileChooserDialog(View view, String path,
  51. int mode, boolean multipleSelection)
  52. {
  53. this(view,path,mode,multipleSelection,true);
  54. } //}}}
  55. //{{{ VFSFileChooserDialog constructor
  56. /**
  57. * Constructs a new VFSFileChooserDialog. If <code>authoshow</code>
  58. * is true, the dialog will be show automatically and the call
  59. * will only return after the user disposes of the dialog.
  60. *
  61. * @since jEdit 4.3pre7
  62. */
  63. public VFSFileChooserDialog(View view, String path,
  64. int mode, boolean multipleSelection, boolean autoshow)
  65. {
  66. super(view,getDefaultTitle(),true);
  67. setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
  68. _init(view,path,mode,multipleSelection,autoshow);
  69. } //}}}
  70. //{{{ VFSFileChooserDialog constructor
  71. /**
  72. * Constructs a new VFSFileChooserDialog.
  73. * This version can specify a dialog as the parent instead
  74. * of the view.
  75. * @since jEdit 4.3pre10
  76. */
  77. public VFSFileChooserDialog(Dialog parent, View view, String path,
  78. int mode, boolean multipleSelection, boolean autoshow)
  79. {
  80. super(parent,getDefaultTitle(),true);
  81. setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
  82. _init(view,path,mode,multipleSelection,autoshow);
  83. } //}}}
  84. /**
  85. * Constructs a new VFSFileChooserDialog.
  86. * This version can specify a Frame as the parent instead
  87. * of the view.
  88. * @since jEdit 4.3pre10
  89. */
  90. public VFSFileChooserDialog(Frame parent, View view, String path,
  91. int mode, boolean multipleSelection, boolean autoshow)
  92. {
  93. super(parent, getDefaultTitle(),true);
  94. setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
  95. _init(view,path,mode,multipleSelection,autoshow);
  96. } //}}}
  97. //{{{ getBrowser() method
  98. /**
  99. * Returns the VFSBrowser instance used internally.
  100. * @return the VFS browser used in the dialog
  101. * @since jEdit 4.3pre7
  102. */
  103. public VFSBrowser getBrowser()
  104. {
  105. return browser;
  106. } //}}}
  107. //{{{ dispose() method
  108. @Override
  109. public void dispose()
  110. {
  111. GUIUtilities.saveGeometry(this,"vfs.browser.dialog");
  112. VFSManager.getIOThreadPool().removeProgressListener(workThreadHandler);
  113. super.dispose();
  114. } //}}}
  115. //{{{ ok() method
  116. @Override
  117. public void ok()
  118. {
  119. VFSFile[] files = browser.getSelectedFiles();
  120. filename = filenameField.getText();
  121. boolean choosingDir = (browser.getMode() ==
  122. VFSBrowser.CHOOSE_DIRECTORY_DIALOG);
  123. if(files.length != 0)
  124. {
  125. if(choosingDir)
  126. {
  127. isOK = true;
  128. dispose();
  129. }
  130. else
  131. browser.filesActivated(VFSBrowser.M_OPEN,false);
  132. return;
  133. }
  134. else if(choosingDir && (filename == null || filename.length() == 0))
  135. {
  136. isOK = true;
  137. dispose();
  138. return;
  139. }
  140. else if(filename == null || filename.length() == 0)
  141. {
  142. getToolkit().beep();
  143. return;
  144. }
  145. String bufferDir = browser.getView().getBuffer()
  146. .getDirectory();
  147. if(filename.equals("-"))
  148. filename = bufferDir;
  149. else if(filename.startsWith("-/")
  150. || filename.startsWith('-' + File.separator))
  151. {
  152. filename = MiscUtilities.constructPath(
  153. bufferDir,filename.substring(2));
  154. }
  155. final int[] type = { -1 };
  156. filename = MiscUtilities.expandVariables(filename);
  157. final String path = MiscUtilities.constructPath(
  158. browser.getDirectory(),filename);
  159. final VFS vfs = VFSManager.getVFSForPath(path);
  160. Object session = vfs.createVFSSession(path,this);
  161. if(session == null)
  162. return;
  163. VFSManager.runInWorkThread(new GetFileTypeRequest(
  164. vfs,session,path,type));
  165. VFSManager.runInAWTThread(new Runnable()
  166. {
  167. public void run()
  168. {
  169. switch(type[0])
  170. {
  171. case VFSFile.FILE:
  172. if(browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG)
  173. break;
  174. if(vfs instanceof FileVFS)
  175. {
  176. if(doFileExistsWarning(path))
  177. break;
  178. }
  179. isOK = true;
  180. if(browser.getMode() == VFSBrowser.BROWSER_DIALOG)
  181. {
  182. Hashtable props = new Hashtable();
  183. if(browser.currentEncoding != null)
  184. {
  185. props.put(JEditBuffer.ENCODING,browser.currentEncoding);
  186. }
  187. jEdit.openFile(browser.getView(),
  188. browser.getDirectory(),
  189. path,false,props);
  190. }
  191. dispose();
  192. break;
  193. case VFSFile.DIRECTORY:
  194. case VFSFile.FILESYSTEM:
  195. browser.setDirectory(path);
  196. break;
  197. }
  198. }
  199. });
  200. } //}}}
  201. //{{{ cancel() method
  202. @Override
  203. public void cancel()
  204. {
  205. dispose();
  206. } //}}}
  207. //{{{ getSelectedFiles() method
  208. public String[] getSelectedFiles()
  209. {
  210. if(!isOK)
  211. return null;
  212. if(browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG)
  213. {
  214. if(browser.getSelectedFiles().length > 0)
  215. {
  216. return getSelectedFiles(VFSFile.DIRECTORY,
  217. VFSFile.FILESYSTEM);
  218. }
  219. else
  220. return new String[] { browser.getDirectory() };
  221. }
  222. else if(filename != null && filename.length() != 0)
  223. {
  224. String path = browser.getDirectory();
  225. return new String[] { MiscUtilities.constructPath(
  226. path,filename) };
  227. }
  228. else
  229. return getSelectedFiles(VFSFile.FILE,VFSFile.FILE);
  230. } //}}}
  231. //{{{ Private members
  232. //{{{ Instance variables
  233. private VFSBrowser browser;
  234. private VFSFileNameField filenameField;
  235. private String filename;
  236. private JButton ok;
  237. private JButton cancel;
  238. private boolean isOK;
  239. private WorkThreadHandler workThreadHandler;
  240. //}}}
  241. //{{{ getDefaultTitle() method
  242. private static String getDefaultTitle()
  243. {
  244. return jEdit.getProperty("vfs.browser.title");
  245. }// }}}
  246. //{{{ _init method
  247. private void _init(View view, String path,
  248. int mode, boolean multipleSelection, boolean autoshow)
  249. {
  250. JPanel content = new JPanel(new BorderLayout());
  251. setContentPane(content);
  252. String name;
  253. if(mode == VFSBrowser.CHOOSE_DIRECTORY_DIALOG)
  254. name = null;
  255. else if(path == null || path.endsWith(File.separator)
  256. || path.endsWith("/"))
  257. {
  258. name = null;
  259. }
  260. else
  261. {
  262. VFS vfs = VFSManager.getVFSForPath(path);
  263. name = vfs.getFileName(path);
  264. path = vfs.getParentOfPath(path);
  265. if ((vfs.getCapabilities() & VFS.BROWSE_CAP) == 0)
  266. {
  267. path = null;
  268. }
  269. }
  270. browser = new VFSBrowser(view, path, mode, multipleSelection, null);
  271. browser.addBrowserListener(new BrowserHandler());
  272. content.add(BorderLayout.CENTER,browser);
  273. JPanel panel = new JPanel();
  274. panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));
  275. panel.setBorder(new EmptyBorder(12,12,12,12));
  276. filenameField = new VFSFileNameField(browser,null);
  277. filenameField.setText(name);
  278. filenameField.selectAll();
  279. filenameField.setName("filename");
  280. browser.setDefaultFocusComponent(filenameField);
  281. Box box = new Box(BoxLayout.Y_AXIS);
  282. box.add(Box.createGlue());
  283. box.add(filenameField);
  284. box.add(Box.createGlue());
  285. JLabel label = new JLabel(jEdit.getProperty("vfs.browser.dialog.filename"));
  286. label.setDisplayedMnemonic(jEdit.getProperty(
  287. "vfs.browser.dialog.filename.mnemonic").charAt(0));
  288. label.setLabelFor(filenameField);
  289. panel.add(label);
  290. panel.add(Box.createHorizontalStrut(12));
  291. panel.add(box);
  292. panel.add(Box.createHorizontalStrut(12));
  293. ok = new JButton();
  294. ok.setName("ok");
  295. getRootPane().setDefaultButton(ok);
  296. switch(mode)
  297. {
  298. case VFSBrowser.OPEN_DIALOG:
  299. case VFSBrowser.BROWSER_DIALOG:
  300. ok.setText(jEdit.getProperty("vfs.browser.dialog.open"));
  301. break;
  302. case VFSBrowser.CHOOSE_DIRECTORY_DIALOG:
  303. ok.setText(jEdit.getProperty("vfs.browser.dialog.choose-dir"));
  304. // so that it doesn't resize...
  305. Dimension dim = ok.getPreferredSize();
  306. ok.setPreferredSize(dim);
  307. break;
  308. case VFSBrowser.SAVE_DIALOG:
  309. ok.setText(jEdit.getProperty("vfs.browser.dialog.save"));
  310. break;
  311. }
  312. ok.addActionListener(new ActionHandler());
  313. panel.add(ok);
  314. panel.add(Box.createHorizontalStrut(6));
  315. cancel = new JButton(jEdit.getProperty("common.cancel"));
  316. cancel.setName("cancel");
  317. cancel.addActionListener(new ActionHandler());
  318. panel.add(cancel);
  319. content.add(BorderLayout.SOUTH,panel);
  320. VFSManager.getIOThreadPool().addProgressListener(
  321. workThreadHandler = new WorkThreadHandler());
  322. pack();
  323. GUIUtilities.loadGeometry(this,"vfs.browser.dialog");
  324. GUIUtilities.requestFocus(this,filenameField);
  325. if (autoshow)
  326. setVisible(true);
  327. } //}}}
  328. //{{{ doFileExistsWarning() method
  329. private boolean doFileExistsWarning(String filename)
  330. {
  331. if(browser.getMode() == VFSBrowser.SAVE_DIALOG
  332. && new File(filename).exists())
  333. {
  334. String[] args = { MiscUtilities.getFileName(filename) };
  335. int result = GUIUtilities.confirm(browser,
  336. "fileexists",args,
  337. JOptionPane.YES_NO_OPTION,
  338. JOptionPane.WARNING_MESSAGE);
  339. if(result != JOptionPane.YES_OPTION)
  340. return true;
  341. }
  342. return false;
  343. } //}}}
  344. //{{{ getSelectedFiles() method
  345. private String[] getSelectedFiles(int type1, int type2)
  346. {
  347. List<String> l = new ArrayList<String>();
  348. VFSFile[] selectedFiles = browser.getSelectedFiles();
  349. for(int i = 0; i < selectedFiles.length; i++)
  350. {
  351. VFSFile file = selectedFiles[i];
  352. if(file.getType() == type1 || file.getType() == type2)
  353. l.add(file.getPath());
  354. }
  355. return l.toArray(new String[l.size()]);
  356. } //}}}
  357. //}}}
  358. //{{{ Inner classes
  359. //{{{ ActionHandler class
  360. private class ActionHandler implements ActionListener
  361. {
  362. public void actionPerformed(ActionEvent evt)
  363. {
  364. if(evt.getSource() == ok)
  365. ok();
  366. else if(evt.getSource() == cancel)
  367. cancel();
  368. }
  369. } //}}}
  370. //{{{ BrowserHandler class
  371. private class BrowserHandler implements BrowserListener
  372. {
  373. //{{{ filesSelected() method
  374. public void filesSelected(VFSBrowser browser, VFSFile[] files)
  375. {
  376. boolean choosingDir = (browser.getMode()
  377. == VFSBrowser.CHOOSE_DIRECTORY_DIALOG);
  378. if(files.length == 0)
  379. {
  380. if(choosingDir)
  381. {
  382. ok.setText(jEdit.getProperty(
  383. "vfs.browser.dialog.choose-dir"));
  384. }
  385. }
  386. else if(files.length == 1)
  387. {
  388. if(choosingDir)
  389. {
  390. ok.setText(jEdit.getProperty(
  391. "vfs.browser.dialog.choose-dir"));
  392. }
  393. VFSFile file = files[0];
  394. if(file.getType() == VFSFile.FILE)
  395. {
  396. String path = file.getPath();
  397. String directory = browser.getDirectory();
  398. String parent = MiscUtilities
  399. .getParentOfPath(path);
  400. if(MiscUtilities.pathsEqual(parent,directory))
  401. path = file.getName();
  402. filenameField.setText(path);
  403. filenameField.selectAll();
  404. }
  405. }
  406. else
  407. {
  408. if(choosingDir)
  409. {
  410. ok.setText(jEdit.getProperty(
  411. "vfs.browser.dialog.choose-dir"));
  412. }
  413. filenameField.setText(null);
  414. }
  415. } //}}}
  416. //{{{ filesActivated() method
  417. public void filesActivated(VFSBrowser browser, VFSFile[] files)
  418. {
  419. filenameField.selectAll();
  420. if(files.length == 0)
  421. {
  422. // user pressed enter when the vfs table or
  423. // file name field has focus, with nothing
  424. // selected.
  425. ok();
  426. return;
  427. }
  428. for(int i = 0; i < files.length; i++)
  429. {
  430. if(files[i].getType() == VFSFile.FILE)
  431. {
  432. String path = files[i].getPath();
  433. VFS vfs = VFSManager.getVFSForPath(path);
  434. if(browser.getMode() == VFSBrowser.SAVE_DIALOG
  435. && vfs instanceof FileVFS)
  436. {
  437. if(doFileExistsWarning(path))
  438. return;
  439. }
  440. isOK = true;
  441. filenameField.setText(null);
  442. if(browser.getMode() != VFSBrowser.CHOOSE_DIRECTORY_DIALOG)
  443. {
  444. dispose();
  445. }
  446. return;
  447. }
  448. else
  449. return;
  450. }
  451. } //}}}
  452. } //}}}
  453. //{{{ WorkThreadListener class
  454. private class WorkThreadHandler implements WorkThreadProgressListener
  455. {
  456. //{{{ statusUpdate() method
  457. public void statusUpdate(final WorkThreadPool threadPool,
  458. int threadIndex)
  459. {
  460. SwingUtilities.invokeLater(new Runnable()
  461. {
  462. public void run()
  463. {
  464. int requestCount = threadPool.getRequestCount();
  465. if(requestCount == 0)
  466. {
  467. getContentPane().setCursor(
  468. Cursor.getDefaultCursor());
  469. }
  470. else if(requestCount >= 1)
  471. {
  472. getContentPane().setCursor(
  473. Cursor.getPredefinedCursor(
  474. Cursor.WAIT_CURSOR));
  475. }
  476. }
  477. });
  478. } //}}}
  479. //{{{ progressUpdate() method
  480. public void progressUpdate(WorkThreadPool threadPool, int threadIndex)
  481. {
  482. } //}}}
  483. } //}}}
  484. //{{{ GetFileTypeRequest class
  485. private class GetFileTypeRequest implements Runnable
  486. {
  487. VFS vfs;
  488. Object session;
  489. String path;
  490. int[] type;
  491. GetFileTypeRequest(VFS vfs, Object session,
  492. String path, int[] type)
  493. {
  494. this.vfs = vfs;
  495. this.session = session;
  496. this.path = path;
  497. this.type = type;
  498. }
  499. public void run()
  500. {
  501. try
  502. {
  503. VFSFile entry = vfs._getFile(
  504. session,
  505. path,
  506. browser);
  507. if(entry == null)
  508. {
  509. // non-existent file
  510. type[0] = VFSFile.FILE;
  511. }
  512. else
  513. type[0] = entry.getType();
  514. }
  515. catch(IOException e)
  516. {
  517. VFSManager.error(e,path,browser);
  518. }
  519. finally
  520. {
  521. try
  522. {
  523. vfs._endVFSSession(
  524. session,
  525. browser);
  526. }
  527. catch(IOException e)
  528. {
  529. VFSManager.error(e,path,browser);
  530. }
  531. }
  532. }
  533. } //}}}
  534. //}}}
  535. }