001: /*
002: * VFSFileChooserDialog.java - VFS file chooser
003: * :tabSize=8:indentSize=8:noTabs=false:
004: * :folding=explicit:collapseFolds=1:
005: *
006: * Copyright (C) 2000, 2005 Slava Pestov
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: */
022:
023: package org.gjt.sp.jedit.browser;
024:
025: //{{{ Imports
026: import javax.swing.border.EmptyBorder;
027: import javax.swing.*;
028: import java.awt.event.*;
029: import java.awt.BorderLayout;
030: import java.awt.Cursor;
031: import java.awt.Dimension;
032: import java.awt.Dialog;
033: import java.awt.Frame;
034: import java.awt.Window;
035: import java.io.File;
036: import java.io.IOException;
037: import java.util.*;
038: import org.gjt.sp.jedit.gui.EnhancedDialog;
039: import org.gjt.sp.jedit.io.*;
040: import org.gjt.sp.jedit.*;
041: import org.gjt.sp.util.*;
042:
043: //}}}
044:
045: /**
046: * Wraps the VFS browser in a modal dialog.
047: * @author Slava Pestov
048: * @version $Id: VFSFileChooserDialog.java 9938 2007-07-07 06:22:10Z ezust $
049: */
050: public class VFSFileChooserDialog extends EnhancedDialog {
051:
052: //{{{ VFSFileChooserDialog constructor
053: public VFSFileChooserDialog(View view, String path, int mode,
054: boolean multipleSelection) {
055: this (view, path, mode, multipleSelection, true);
056: } //}}}
057:
058: //{{{ VFSFileChooserDialog constructor
059: /**
060: * Constructs a new VFSFileChooserDialog. If <code>authoshow</code>
061: * is true, the dialog will be show automatically and the call
062: * will only return after the user disposes of the dialog.
063: *
064: * @since jEdit 4.3pre7
065: */
066: public VFSFileChooserDialog(View view, String path, int mode,
067: boolean multipleSelection, boolean autoshow) {
068: super (view, getDefaultTitle(), true);
069: _init(view, path, mode, multipleSelection, autoshow);
070: } //}}}
071:
072: //{{{ VFSFileChooserDialog constructor
073: /**
074: * Constructs a new VFSFileChooserDialog.
075: * This version can specify a dialog as the parent instead
076: * of the view.
077: * @since jEdit 4.3pre10
078: */
079: public VFSFileChooserDialog(Dialog parent, View view, String path,
080: int mode, boolean multipleSelection, boolean autoshow) {
081: super (parent, getDefaultTitle(), true);
082: _init(view, path, mode, multipleSelection, autoshow);
083: } //}}}
084:
085: /**
086: * Constructs a new VFSFileChooserDialog.
087: * This version can specify a Frame as the parent instead
088: * of the view.
089: * @since jEdit 4.3pre10
090: */
091: public VFSFileChooserDialog(Frame parent, View view, String path,
092: int mode, boolean multipleSelection, boolean autoshow) {
093: super (parent, getDefaultTitle(), true);
094: _init(view, path, mode, multipleSelection, autoshow);
095: } //}}}
096:
097: //{{{ getBrowser() method
098: /**
099: * Returns the VFSBrowser instance used internally.
100: *
101: * @since jEdit 4.3pre7
102: */
103: public VFSBrowser getBrowser() {
104: return browser;
105: } //}}}
106:
107: //{{{ dispose() method
108: public void dispose() {
109: GUIUtilities.saveGeometry(this , "vfs.browser.dialog");
110: VFSManager.getIOThreadPool().removeProgressListener(
111: workThreadHandler);
112: super .dispose();
113: } //}}}
114:
115: //{{{ ok() method
116: public void ok() {
117: VFSFile[] files = browser.getSelectedFiles();
118: filename = filenameField.getText();
119: boolean choosingDir = (browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG);
120:
121: if (files.length != 0) {
122: if (files.length > 1 && choosingDir) {
123: isOK = true;
124: dispose();
125: } else
126: browser.filesActivated(VFSBrowser.M_OPEN, false);
127: return;
128: } else if (choosingDir
129: && (filename == null || filename.length() == 0)) {
130: isOK = true;
131: dispose();
132: return;
133: } else if (filename == null || filename.length() == 0) {
134: getToolkit().beep();
135: return;
136: }
137:
138: String bufferDir = browser.getView().getBuffer().getDirectory();
139: if (filename.equals("-"))
140: filename = bufferDir;
141: else if (filename.startsWith("-/")
142: || filename.startsWith("-" + File.separator)) {
143: filename = MiscUtilities.constructPath(bufferDir, filename
144: .substring(2));
145: }
146:
147: final int[] type = { -1 };
148: filename = MiscUtilities.expandVariables(filename);
149: final String path = MiscUtilities.constructPath(browser
150: .getDirectory(), filename);
151: final VFS vfs = VFSManager.getVFSForPath(path);
152: Object session = vfs.createVFSSession(path, this );
153: if (session == null)
154: return;
155:
156: VFSManager.runInWorkThread(new GetFileTypeRequest(vfs, session,
157: path, type));
158: VFSManager.runInAWTThread(new Runnable() {
159: public void run() {
160: switch (type[0]) {
161: case VFSFile.FILE:
162: if (browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG)
163: break;
164:
165: if (vfs instanceof FileVFS) {
166: if (doFileExistsWarning(path))
167: break;
168: }
169: isOK = true;
170: if (browser.getMode() == VFSBrowser.BROWSER_DIALOG) {
171: Hashtable props = new Hashtable();
172: props.put(Buffer.ENCODING,
173: browser.currentEncoding);
174: jEdit.openFile(browser.getView(), browser
175: .getDirectory(), path, false, props);
176: }
177: dispose();
178: break;
179: case VFSFile.DIRECTORY:
180: case VFSFile.FILESYSTEM:
181: browser.setDirectory(path);
182: break;
183: }
184: }
185: });
186: } //}}}
187:
188: //{{{ cancel() method
189: public void cancel() {
190: dispose();
191: } //}}}
192:
193: //{{{ getSelectedFiles() method
194: public String[] getSelectedFiles() {
195: if (!isOK)
196: return null;
197:
198: if (browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG) {
199: if (browser.getSelectedFiles().length > 0) {
200: return getSelectedFiles(VFSFile.DIRECTORY,
201: VFSFile.FILESYSTEM);
202: } else
203: return new String[] { browser.getDirectory() };
204: } else if (filename != null && filename.length() != 0) {
205: String path = browser.getDirectory();
206: return new String[] { MiscUtilities.constructPath(path,
207: filename) };
208: } else
209: return getSelectedFiles(VFSFile.FILE, VFSFile.FILE);
210: } //}}}
211:
212: //{{{ Private members
213:
214: //{{{ Instance variables
215: private VFSBrowser browser;
216: private VFSFileNameField filenameField;
217: private String filename;
218: private JButton ok;
219: private JButton cancel;
220: private boolean isOK;
221: private WorkThreadHandler workThreadHandler;
222:
223: //}}}
224:
225: //{{{ getDefaultTitle() method
226: private static String getDefaultTitle() {
227: return jEdit.getProperty("vfs.browser.title");
228: }// }}}
229:
230: //{{{ _init method
231: private void _init(View view, String path, int mode,
232: boolean multipleSelection, boolean autoshow) {
233: JPanel content = new JPanel(new BorderLayout());
234: content.setBorder(new EmptyBorder(12, 12, 12, 12));
235: setContentPane(content);
236:
237: String name;
238: if (mode == VFSBrowser.CHOOSE_DIRECTORY_DIALOG)
239: name = null;
240: else if (path == null || path.endsWith(File.separator)
241: || path.endsWith("/")) {
242: name = null;
243: } else {
244: VFS vfs = VFSManager.getVFSForPath(path);
245: name = vfs.getFileName(path);
246: path = vfs.getParentOfPath(path);
247: }
248:
249: browser = new VFSBrowser(view, path, mode, multipleSelection,
250: null);
251: browser.getBrowserView().getTable().setRequestFocusEnabled(
252: false);
253: browser.getBrowserView().getParentDirectoryList()
254: .setRequestFocusEnabled(false);
255: /* browser.getBrowserView().getTable().addKeyListener(new KeyHandler()); */
256: browser.addBrowserListener(new BrowserHandler());
257: content.add(BorderLayout.CENTER, browser);
258:
259: JPanel panel = new JPanel();
260: panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
261: panel.setBorder(new EmptyBorder(12, 0, 0, 0));
262:
263: filenameField = new VFSFileNameField(browser, null);
264: filenameField.setText(name);
265: filenameField.selectAll();
266: Box box = new Box(BoxLayout.Y_AXIS);
267: box.add(Box.createGlue());
268: box.add(filenameField);
269: box.add(Box.createGlue());
270:
271: JLabel label = new JLabel(jEdit
272: .getProperty("vfs.browser.dialog.filename"));
273: label.setDisplayedMnemonic(jEdit.getProperty(
274: "vfs.browser.dialog.filename.mnemonic").charAt(0));
275: label.setLabelFor(filenameField);
276: panel.add(label);
277: panel.add(Box.createHorizontalStrut(12));
278:
279: panel.add(box);
280:
281: panel.add(Box.createHorizontalStrut(12));
282:
283: ok = new JButton();
284: getRootPane().setDefaultButton(ok);
285:
286: switch (mode) {
287: case VFSBrowser.OPEN_DIALOG:
288: case VFSBrowser.BROWSER_DIALOG:
289: ok.setText(jEdit.getProperty("vfs.browser.dialog.open"));
290: break;
291: case VFSBrowser.CHOOSE_DIRECTORY_DIALOG:
292: ok.setText(jEdit
293: .getProperty("vfs.browser.dialog.choose-dir"));
294: // so that it doesn't resize...
295: Dimension dim = ok.getPreferredSize();
296: ok.setPreferredSize(dim);
297: break;
298: case VFSBrowser.SAVE_DIALOG:
299: ok.setText(jEdit.getProperty("vfs.browser.dialog.save"));
300: break;
301: }
302:
303: ok.addActionListener(new ActionHandler());
304: panel.add(ok);
305: panel.add(Box.createHorizontalStrut(6));
306: cancel = new JButton(jEdit.getProperty("common.cancel"));
307: cancel.addActionListener(new ActionHandler());
308: panel.add(cancel);
309:
310: content.add(BorderLayout.SOUTH, panel);
311:
312: VFSManager.getIOThreadPool().addProgressListener(
313: workThreadHandler = new WorkThreadHandler());
314:
315: pack();
316: GUIUtilities.loadGeometry(this , "vfs.browser.dialog");
317: GUIUtilities.requestFocus(this , filenameField);
318: if (autoshow)
319: setVisible(true);
320: } //}}}
321:
322: //{{{ doFileExistsWarning() method
323: private boolean doFileExistsWarning(String filename) {
324: if (browser.getMode() == VFSBrowser.SAVE_DIALOG
325: && new File(filename).exists()) {
326: String[] args = { MiscUtilities.getFileName(filename) };
327: int result = GUIUtilities.confirm(browser, "fileexists",
328: args, JOptionPane.YES_NO_OPTION,
329: JOptionPane.WARNING_MESSAGE);
330: if (result != JOptionPane.YES_OPTION)
331: return true;
332: }
333:
334: return false;
335: } //}}}
336:
337: //{{{ getSelectedFiles() method
338: private String[] getSelectedFiles(int type1, int type2) {
339: List l = new ArrayList();
340: VFSFile[] selectedFiles = browser.getSelectedFiles();
341: for (int i = 0; i < selectedFiles.length; i++) {
342: VFSFile file = selectedFiles[i];
343: if (file.getType() == type1 || file.getType() == type2)
344: l.add(file.getPath());
345: }
346: return (String[]) l.toArray(new String[l.size()]);
347: } //}}}
348:
349: //}}}
350:
351: //{{{ Inner classes
352:
353: //{{{ ActionHandler class
354: class ActionHandler implements ActionListener {
355: public void actionPerformed(ActionEvent evt) {
356: if (evt.getSource() == ok) {
357: if (!browser.getDirectory().equals(
358: browser.getDirectoryField().getText())) {
359: browser.setDirectory(browser.getDirectoryField()
360: .getText());
361: } else
362: ok();
363: } else if (evt.getSource() == cancel)
364: cancel();
365: }
366: } //}}}
367:
368: //{{{ BrowserHandler class
369: class BrowserHandler implements BrowserListener {
370: //{{{ filesSelected() method
371: public void filesSelected(VFSBrowser browser, VFSFile[] files) {
372: boolean choosingDir = (browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG);
373:
374: if (files.length == 0) {
375: if (choosingDir) {
376: ok
377: .setText(jEdit
378: .getProperty("vfs.browser.dialog.choose-dir"));
379: }
380: return;
381: } else if (files.length == 1) {
382: if (choosingDir) {
383: ok.setText(jEdit
384: .getProperty("vfs.browser.dialog.open"));
385: }
386:
387: VFSFile file = files[0];
388: if (file.getType() == VFSFile.FILE) {
389: String path = file.getPath();
390: String directory = browser.getDirectory();
391: String parent = MiscUtilities.getParentOfPath(path);
392: if (MiscUtilities.pathsEqual(parent, directory))
393: path = file.getName();
394:
395: filenameField.setText(path);
396: filenameField.selectAll();
397: }
398: } else {
399: if (choosingDir) {
400: ok
401: .setText(jEdit
402: .getProperty("vfs.browser.dialog.choose-dir"));
403: }
404:
405: filenameField.setText(null);
406: }
407: } //}}}
408:
409: //{{{ filesActivated() method
410: public void filesActivated(VFSBrowser browser, VFSFile[] files) {
411: filenameField.selectAll();
412:
413: if (files.length == 0) {
414: // user pressed enter when the vfs table or
415: // file name field has focus, with nothing
416: // selected.
417: ok();
418: return;
419: }
420:
421: for (int i = 0; i < files.length; i++) {
422: if (files[i].getType() == VFSFile.FILE) {
423: String path = files[i].getPath();
424: VFS vfs = VFSManager.getVFSForPath(path);
425: if (browser.getMode() == VFSBrowser.SAVE_DIALOG
426: && vfs instanceof FileVFS) {
427: if (doFileExistsWarning(path))
428: return;
429: }
430:
431: isOK = true;
432: filenameField.setText(null);
433: if (browser.getMode() != VFSBrowser.CHOOSE_DIRECTORY_DIALOG) {
434: dispose();
435: }
436: return;
437: } else
438: return;
439: }
440: } //}}}
441: } //}}}
442:
443: //{{{ KeyHandler class
444: class KeyHandler extends KeyAdapter {
445: public void keyTyped(KeyEvent evt) {
446: switch (evt.getKeyChar()) {
447: case '/':
448: case '-':
449: case '~':
450: filenameField.processKeyEvent(evt);
451: filenameField.requestFocus();
452: break;
453: }
454: }
455: } //}}}
456:
457: //{{{ WorkThreadListener class
458: class WorkThreadHandler implements WorkThreadProgressListener {
459: //{{{ statusUpdate() method
460: public void statusUpdate(final WorkThreadPool threadPool,
461: final int threadIndex) {
462: SwingUtilities.invokeLater(new Runnable() {
463: public void run() {
464: int requestCount = threadPool.getRequestCount();
465: if (requestCount == 0) {
466: getContentPane().setCursor(
467: Cursor.getDefaultCursor());
468: } else if (requestCount >= 1) {
469: getContentPane()
470: .setCursor(
471: Cursor
472: .getPredefinedCursor(Cursor.WAIT_CURSOR));
473: }
474: }
475: });
476: } //}}}
477:
478: //{{{ progressUpdate() method
479: public void progressUpdate(WorkThreadPool threadPool,
480: int threadIndex) {
481: } //}}}
482: } //}}}
483:
484: //{{{ GetFileTypeRequest class
485: class GetFileTypeRequest implements Runnable {
486: VFS vfs;
487: Object session;
488: String path;
489: int[] type;
490:
491: GetFileTypeRequest(VFS vfs, Object session, String path,
492: int[] type) {
493: this .vfs = vfs;
494: this .session = session;
495: this .path = path;
496: this .type = type;
497: }
498:
499: public void run() {
500: try {
501: VFSFile entry = vfs._getFile(session, path, browser);
502: if (entry == null) {
503: // non-existent file
504: type[0] = VFSFile.FILE;
505: } else
506: type[0] = entry.getType();
507: } catch (IOException e) {
508: VFSManager.error(e, path, browser);
509: return;
510: } finally {
511: try {
512: vfs._endVFSSession(session, browser);
513: } catch (IOException e) {
514: VFSManager.error(e, path, browser);
515: return;
516: }
517: }
518: }
519: } //}}}
520:
521: //}}}
522: }
|