/* * VFSFileChooserDialog.java - VFS file chooser * :tabSize=4:indentSize=4:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2000, 2005 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.gjt.sp.jedit.browser; //{{{ Imports import javax.swing.border.EmptyBorder; import javax.swing.*; import java.awt.event.*; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Dialog; import java.awt.Frame; import java.io.File; import java.io.IOException; import java.util.*; import org.gjt.sp.jedit.gui.EnhancedDialog; import org.gjt.sp.jedit.io.*; import org.gjt.sp.jedit.*; import org.gjt.sp.jedit.buffer.JEditBuffer; import org.gjt.sp.jedit.bufferio.IoTask; import org.gjt.sp.util.*; //}}} /** * Wraps the VFS browser in a modal dialog. * Shows up when "File-Open" is used. * @author Slava Pestov * @version $Id: VFSFileChooserDialog.java 23222 2013-09-29 20:43:34Z shlomy $ */ public class VFSFileChooserDialog extends EnhancedDialog { //{{{ VFSFileChooserDialog constructor public VFSFileChooserDialog(View view, String path, int mode, boolean multipleSelection) { this(view,path,mode,multipleSelection,true); } //}}} //{{{ VFSFileChooserDialog constructor /** * Constructs a new VFSFileChooserDialog. If <code>authoshow</code> * is true, the dialog will be show automatically and the call * will only return after the user disposes of the dialog. * * @since jEdit 4.3pre7 */ public VFSFileChooserDialog(View view, String path, int mode, boolean multipleSelection, boolean autoshow) { super(view,getTitle(mode),true); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); _init(view,path,mode,multipleSelection,autoshow); } //}}} //{{{ VFSFileChooserDialog constructor /** * Constructs a new VFSFileChooserDialog. * This version can specify a dialog as the parent instead * of the view. * @since jEdit 4.3pre10 */ public VFSFileChooserDialog(Dialog parent, View view, String path, int mode, boolean multipleSelection, boolean autoshow) { super(parent,getTitle(mode),true); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); _init(view,path,mode,multipleSelection,autoshow); } //}}} //{{{ VFSFileChooserDialog constructor /** * Constructs a new VFSFileChooserDialog. * This version can specify a Frame as the parent instead * of the view. * @since jEdit 4.3pre10 */ public VFSFileChooserDialog(Frame parent, View view, String path, int mode, boolean multipleSelection, boolean autoshow) { super(parent,getTitle(mode),true); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); _init(view,path,mode,multipleSelection,autoshow); } //}}} //{{{ getBrowser() method /** * Returns the VFSBrowser instance used internally. * @return the VFS browser used in the dialog * @since jEdit 4.3pre7 */ public VFSBrowser getBrowser() { return browser; } //}}} //{{{ dispose() method @Override public void dispose() { GUIUtilities.saveGeometry(this,"vfs.browser.dialog"); TaskManager.instance.removeTaskListener(ioTaskHandler); super.dispose(); } //}}} //{{{ ok() method @Override public void ok() { VFSFile[] files = browser.getSelectedFiles(); filename = filenameField.getText(); boolean choosingDir = (browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG); if(files.length != 0) { if(choosingDir) { isOK = true; dispose(); } else browser.filesActivated(VFSBrowser.M_OPEN,false); return; } else if(choosingDir && (filename == null || filename.length() == 0)) { isOK = true; dispose(); return; } else if(filename == null || filename.length() == 0) { getToolkit().beep(); return; } String bufferDir = browser.getView().getBuffer() .getDirectory(); if(filename.equals("-")) filename = bufferDir; else if(filename.startsWith("-/") || filename.startsWith('-' + File.separator)) { filename = MiscUtilities.constructPath( bufferDir,filename.substring(2)); } final int[] type = { -1 }; filename = MiscUtilities.expandVariables(filename); final String path = MiscUtilities.constructPath( browser.getDirectory(),filename); final VFS vfs = VFSManager.getVFSForPath(path); Object session = vfs.createVFSSession(path,this); if(session == null) return; ThreadUtilities.runInBackground(new GetFileTypeRequest( vfs,session,path,type)); AwtRunnableQueue.INSTANCE.runAfterIoTasks(new Runnable() { public void run() { switch(type[0]) { case VFSFile.FILE: if(browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG) break; if(vfs instanceof FileVFS) { if(doFileExistsWarning(path)) break; } isOK = true; if(browser.getMode() == VFSBrowser.BROWSER_DIALOG) { Hashtable props = new Hashtable(); if(browser.currentEncoding != null) { props.put(JEditBuffer.ENCODING,browser.currentEncoding); } jEdit.openFile(browser.getView(), browser.getDirectory(), path,false,props); } dispose(); break; case VFSFile.DIRECTORY: case VFSFile.FILESYSTEM: browser.setDirectory(path); break; } } }); } //}}} //{{{ cancel() method @Override public void cancel() { dispose(); } //}}} //{{{ getSelectedFiles() method public String[] getSelectedFiles() { if(!isOK) return null; if(browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG) { if(browser.getSelectedFiles().length > 0) { return getSelectedFiles(VFSFile.DIRECTORY, VFSFile.FILESYSTEM); } else return new String[] { browser.getDirectory() }; } else if(filename != null && filename.length() != 0) { String path = browser.getDirectory(); return new String[] { MiscUtilities.constructPath( path,filename) }; } else return getSelectedFiles(VFSFile.FILE,VFSFile.FILE); } //}}} //{{{ Private members //{{{ Instance variables private VFSBrowser browser; private VFSFileNameField filenameField; private String filename; private JButton ok; private JButton cancel; private boolean isOK; private TaskListener ioTaskHandler; //}}} //{{{ getDefaultTitle() method private static String getDefaultTitle() { return jEdit.getProperty("vfs.browser.title"); }// }}} //{{{ getTitle() method private static String getTitle(int mode) { switch(mode) { case VFSBrowser.OPEN_DIALOG: return jEdit.getProperty("vfs.browser.title.open"); case VFSBrowser.SAVE_DIALOG: return jEdit.getProperty("vfs.browser.title.save"); case VFSBrowser.BROWSER: return jEdit.getProperty("vfs.browser.title"); case VFSBrowser.CHOOSE_DIRECTORY_DIALOG: return jEdit.getProperty("vfs.browser.title"); case VFSBrowser.BROWSER_DIALOG: return jEdit.getProperty("vfs.browser.title.dialog"); default: return jEdit.getProperty("vfs.browser.title"); } }// }}} //{{{ _init method private void _init(View view, String path, int mode, boolean multipleSelection, boolean autoshow) { JPanel content = new JPanel(new BorderLayout()); setContentPane(content); String name; if(mode == VFSBrowser.CHOOSE_DIRECTORY_DIALOG) name = null; else if(path == null || path.endsWith(File.separator) || path.endsWith("/")) { name = null; } else { VFS vfs = VFSManager.getVFSForPath(path); name = vfs.getFileName(path); path = vfs.getParentOfPath(path); if ((vfs.getCapabilities() & VFS.BROWSE_CAP) == 0) { path = null; } } browser = new VFSBrowser(view, path, mode, multipleSelection, null); browser.addBrowserListener(new BrowserHandler()); content.add(BorderLayout.CENTER,browser); JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS)); panel.setBorder(new EmptyBorder(12,12,12,12)); filenameField = new VFSFileNameField(browser,null); filenameField.setText(name); filenameField.selectAll(); filenameField.setName("filename"); browser.setDefaultFocusComponent(filenameField); Box box = new Box(BoxLayout.Y_AXIS); box.add(Box.createGlue()); box.add(filenameField); box.add(Box.createGlue()); JLabel label = new JLabel(jEdit.getProperty("vfs.browser.dialog.filename")); label.setDisplayedMnemonic(jEdit.getProperty( "vfs.browser.dialog.filename.mnemonic").charAt(0)); label.setLabelFor(filenameField); panel.add(label); panel.add(Box.createHorizontalStrut(12)); panel.add(box); panel.add(Box.createHorizontalStrut(12)); ok = new JButton(); ok.setName("ok"); getRootPane().setDefaultButton(ok); switch(mode) { case VFSBrowser.OPEN_DIALOG: case VFSBrowser.BROWSER_DIALOG: ok.setText(jEdit.getProperty("vfs.browser.dialog.open")); break; case VFSBrowser.CHOOSE_DIRECTORY_DIALOG: ok.setText(jEdit.getProperty("vfs.browser.dialog.choose-dir")); // so that it doesn't resize... Dimension dim = ok.getPreferredSize(); ok.setPreferredSize(dim); break; case VFSBrowser.SAVE_DIALOG: ok.setText(jEdit.getProperty("vfs.browser.dialog.save")); break; } ok.addActionListener(new ActionHandler()); panel.add(ok); panel.add(Box.createHorizontalStrut(6)); cancel = new JButton(jEdit.getProperty("common.cancel")); cancel.setName("cancel"); cancel.addActionListener(new ActionHandler()); panel.add(cancel); content.add(BorderLayout.SOUTH,panel); TaskManager.instance.addTaskListener( ioTaskHandler = new IoTaskHandler()); pack(); GUIUtilities.loadGeometry(this,"vfs.browser.dialog"); GUIUtilities.requestFocus(this,filenameField); if (autoshow) setVisible(true); } //}}} //{{{ doFileExistsWarning() method private boolean doFileExistsWarning(String filename) { if(browser.getMode() == VFSBrowser.SAVE_DIALOG && new File(filename).exists()) { String[] args = { MiscUtilities.getFileName(filename) }; int result = GUIUtilities.confirm(browser, "fileexists",args, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if(result != JOptionPane.YES_OPTION) return true; } return false; } //}}} //{{{ getSelectedFiles() method private String[] getSelectedFiles(int type1, int type2) { List<String> l = new ArrayList<String>(); VFSFile[] selectedFiles = browser.getSelectedFiles(); for (VFSFile file : selectedFiles) { if (file.getType() == type1 || file.getType() == type2) l.add(file.getPath()); } return l.toArray(new String[l.size()]); } //}}} //}}} //{{{ Inner classes //{{{ ActionHandler class private class ActionHandler implements ActionListener { public void actionPerformed(ActionEvent evt) { if(evt.getSource() == ok) ok(); else if(evt.getSource() == cancel) cancel(); } } //}}} //{{{ BrowserHandler class private class BrowserHandler implements BrowserListener { //{{{ filesSelected() method public void filesSelected(VFSBrowser browser, VFSFile[] files) { boolean choosingDir = (browser.getMode() == VFSBrowser.CHOOSE_DIRECTORY_DIALOG); if(files.length == 0) { if(choosingDir) { ok.setText(jEdit.getProperty( "vfs.browser.dialog.choose-dir")); } } else if(files.length == 1) { if(choosingDir) { ok.setText(jEdit.getProperty( "vfs.browser.dialog.choose-dir")); } VFSFile file = files[0]; if(file.getType() == VFSFile.FILE) { String path = file.getPath(); String directory = browser.getDirectory(); String parent = MiscUtilities .getParentOfPath(path); if(MiscUtilities.pathsEqual(parent,directory)) path = file.getName(); filenameField.setText(path); filenameField.selectAll(); } } else { if(choosingDir) { ok.setText(jEdit.getProperty( "vfs.browser.dialog.choose-dir")); } filenameField.setText(null); } } //}}} //{{{ filesActivated() method public void filesActivated(VFSBrowser browser, VFSFile[] files) { filenameField.selectAll(); if(files.length == 0) { // user pressed enter when the vfs table or // file name field has focus, with nothing // selected. ok(); return; } for(int i = 0, n = files.length; i < n; i++) { if(files[i].getType() == VFSFile.FILE) { String path = files[i].getPath(); VFS vfs = VFSManager.getVFSForPath(path); if(browser.getMode() == VFSBrowser.SAVE_DIALOG && vfs instanceof FileVFS) { if(doFileExistsWarning(path)) return; } isOK = true; filenameField.setText(null); if(browser.getMode() != VFSBrowser.CHOOSE_DIRECTORY_DIALOG) { dispose(); } return; } else return; } } //}}} } //}}} //{{{ IoTaskListener class private class IoTaskHandler implements TaskListener { private final Runnable cursorStatus = new Runnable() { public void run() { int requestCount = TaskManager.instance.countIoTasks(); if(requestCount == 0) { getContentPane().setCursor( Cursor.getDefaultCursor()); } else if(requestCount >= 1) { getContentPane().setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR)); } } }; //{{{ waiting() method public void waiting(Task task) { SwingUtilities.invokeLater(cursorStatus); } //}}} //{{{ running() method public void running(Task task) { SwingUtilities.invokeLater(cursorStatus); } //}}} //{{{ done() method public void done(Task task) { SwingUtilities.invokeLater(cursorStatus); } //}}} //{{{ statusUpdated() method public void statusUpdated(Task task) { } //}}} //{{{ maximumUpdated() method public void maximumUpdated(Task task) { } //}}} //{{{ progressUpdate() method public void valueUpdated(Task task) { SwingUtilities.invokeLater(cursorStatus); } //}}} } //}}} //{{{ GetFileTypeRequest class private class GetFileTypeRequest extends IoTask { VFS vfs; Object session; String path; int[] type; GetFileTypeRequest(VFS vfs, Object session, String path, int[] type) { super(); this.vfs = vfs; this.session = session; this.path = path; this.type = type; } public void _run() { try { VFSFile entry = vfs._getFile( session, path, browser); if(entry == null) { // non-existent file type[0] = VFSFile.FILE; } else type[0] = entry.getType(); } catch(IOException e) { VFSManager.error(e,path,browser); } finally { try { vfs._endVFSSession( session, browser); } catch(IOException e) { VFSManager.error(e,path,browser); } } } } //}}} //}}} }