fiore@0: package uk.ac.qmul.eecs.ccmi.gui; fiore@0: fiore@0: import java.awt.Frame; fiore@0: import java.io.BufferedInputStream; fiore@0: import java.io.BufferedOutputStream; fiore@0: import java.io.File; fiore@0: import java.io.FileInputStream; fiore@0: import java.io.FileNotFoundException; fiore@0: import java.io.FileOutputStream; fiore@0: import java.io.IOException; fiore@0: import java.io.InputStream; fiore@0: import java.io.OutputStream; fiore@0: import java.util.ResourceBundle; fiore@0: fiore@0: import javax.swing.JFileChooser; fiore@0: import javax.swing.JOptionPane; fiore@0: fiore@0: import uk.ac.qmul.eecs.ccmi.gui.filechooser.FileChooser; fiore@0: import uk.ac.qmul.eecs.ccmi.gui.filechooser.FileChooserFactory; fiore@0: import uk.ac.qmul.eecs.ccmi.sound.SoundEvent; fiore@0: import uk.ac.qmul.eecs.ccmi.sound.SoundFactory; fiore@0: import uk.ac.qmul.eecs.ccmi.utils.PreferencesService; fiore@0: fiore@0: public abstract class FileService fiore@0: { fiore@0: fiore@0: /** fiore@0: * An Open object encapsulates the stream, name and path of the file that the user selected for opening. fiore@0: */ fiore@0: public interface Open fiore@0: { fiore@0: /** fiore@0: * Gets the input stream corresponding to the user selection. fiore@0: * @return the input stream, or null if the user cancels the file selection task fiore@0: */ fiore@0: InputStream getInputStream() throws IOException ; fiore@0: /** fiore@0: * Gets the name of the file that the user selected. fiore@0: * @return the file name, or null if the user cancels the file selection task fiore@0: */ fiore@0: String getName() throws IOException ; fiore@0: fiore@0: /** fiore@0: * Gets the path of the file that the user selected. fiore@0: * @return the file path , or null if the user cancels the file selection task fiore@0: */ fiore@0: String getPath() throws IOException; fiore@0: fiore@0: } fiore@0: fiore@0: /** fiore@0: * A Save object encapsulates the stream and name of the file that the user selected for saving. fiore@0: */ fiore@0: public interface Save fiore@0: { fiore@0: /** fiore@0: * Gets the output stream corresponding to the user selection. fiore@0: * @return the output stream, or null if the user cancels the file selection task fiore@0: */ fiore@0: OutputStream getOutputStream(); fiore@0: /** fiore@0: * Gets the name of the file that the user selected. fiore@0: * @return the file name, or null if the user cancels the file selection task fiore@0: */ fiore@0: String getName(); fiore@0: /** fiore@0: * Gets the path of the file that the user selected. fiore@0: * @return the file path, or null if the user cancels the file selection task fiore@0: */ fiore@0: String getPath(); fiore@0: } fiore@0: fiore@0: /** fiore@0: * This class implements a FileService with a JFileChooser fiore@0: */ fiore@0: public static class ChooserService fiore@0: { fiore@0: public ChooserService(File initialDirectory){ fiore@0: useAccessible = Boolean.parseBoolean(PreferencesService.getInstance().get("use_accessible_filechooser", "true")); fiore@0: fileChooser = FileChooserFactory.getFileChooser(useAccessible); fiore@0: fileChooser.setCurrentDirectory(initialDirectory); fiore@0: } fiore@0: fiore@0: /* If the user cancels the task (presses cancel button or the X at the top left) * fiore@0: * the CANCEl sound is played (together with the registered playerListeenr if any) */ fiore@0: public FileService.Open open(String defaultDirectory, String defaultFile, fiore@0: ExtensionFilter filter, Frame frame) throws FileNotFoundException { fiore@0: fileChooser.resetChoosableFileFilters(); fiore@0: fileChooser.setFileFilter(filter); fiore@0: if (defaultDirectory != null) fiore@0: fileChooser.setCurrentDirectory(new File(defaultDirectory)); fiore@0: if (defaultFile == null) fiore@0: fileChooser.setSelectedFile(null); fiore@0: else fiore@0: fileChooser.setSelectedFile(new File(defaultFile)); fiore@0: int response = fileChooser.showOpenDialog(frame); fiore@0: if (response == JFileChooser.APPROVE_OPTION) fiore@0: return new OpenImpl(fileChooser.getSelectedFile()); fiore@0: else{ fiore@0: if(useAccessible) fiore@0: SoundFactory.getInstance().play(SoundEvent.CANCEL); fiore@0: return new OpenImpl(null); fiore@0: } fiore@0: } fiore@0: fiore@0: fiore@0: /* If the user cancels the task (presses cancel button or the X at the top left) * fiore@0: * the CANCEl sound is played (together with the registered playerListeenr if any) */ fiore@0: public FileService.Save save(String defaultDirectory, String defaultFile, fiore@0: ExtensionFilter filter, String removeExtension, String addExtension) throws FileNotFoundException { fiore@0: fileChooser.resetChoosableFileFilters(); fiore@0: fileChooser.setFileFilter(filter); fiore@0: if (defaultDirectory == null) fiore@0: fileChooser.setCurrentDirectory(new File(".")); fiore@0: else fiore@0: fileChooser.setCurrentDirectory(new File(defaultDirectory)); fiore@0: if (defaultFile != null){ fiore@0: File f = new File(editExtension(defaultFile, removeExtension, addExtension)); fiore@0: if(f.exists()) fiore@0: fileChooser.setSelectedFile(f); fiore@0: else fiore@0: fileChooser.setSelectedFile(null); fiore@0: }else fiore@0: fileChooser.setSelectedFile(null); fiore@0: int response = fileChooser.showSaveDialog(null); fiore@0: if (response == JFileChooser.APPROVE_OPTION){ fiore@0: File f = fileChooser.getSelectedFile(); fiore@0: if (addExtension != null && f.getName().indexOf(".") < 0) // no extension supplied fiore@0: f = new File(f.getPath() + addExtension); fiore@0: if (!f.exists()) return new SaveImpl(f); fiore@0: fiore@0: /* file with this name already exists, we must ask the user to confirm */ fiore@0: ResourceBundle resources = ResourceBundle.getBundle(EditorFrame.class.getName()); fiore@0: if(useAccessible){ fiore@0: int result = SpeechOptionPane.showConfirmDialog( fiore@0: null, fiore@0: resources.getString("dialog.overwrite"), fiore@0: SpeechOptionPane.YES_NO_OPTION); fiore@0: if (result == SpeechOptionPane.YES_OPTION) fiore@0: return new SaveImpl(f); fiore@0: }else{ fiore@0: int result = JOptionPane.showConfirmDialog( fiore@0: null, fiore@0: resources.getString("dialog.overwrite"), fiore@0: null, fiore@0: JOptionPane.YES_NO_OPTION); fiore@0: if (result == JOptionPane.YES_OPTION) fiore@0: return new SaveImpl(f); fiore@0: } fiore@0: } fiore@0: if(useAccessible) fiore@0: SoundFactory.getInstance().play(SoundEvent.CANCEL); fiore@0: return new SaveImpl(null); fiore@0: } fiore@0: fiore@0: private FileChooser fileChooser; fiore@0: private boolean useAccessible; fiore@0: } fiore@0: fiore@0: public static class DirectService { fiore@0: public Open open(File file) throws IOException{ fiore@0: return new OpenImpl(file); fiore@0: } fiore@0: fiore@0: public Save save(File file) throws IOException{ fiore@0: return new SaveImpl(file); fiore@0: } fiore@0: } fiore@0: fiore@0: private static class SaveImpl implements FileService.Save{ fiore@0: public SaveImpl(File f) throws FileNotFoundException{ fiore@0: if (f != null){ fiore@0: path = f.getPath(); fiore@0: name = getFileNameFromPath(path,false); fiore@0: out = new BufferedOutputStream(new FileOutputStream(f)); fiore@0: } fiore@0: } fiore@0: fiore@0: @Override fiore@0: public String getName() { return name; } fiore@0: @Override fiore@0: public String getPath() {return path; } fiore@0: @Override fiore@0: public OutputStream getOutputStream() { return out; } fiore@0: fiore@0: private String name; fiore@0: private String path; fiore@0: private OutputStream out; fiore@0: } fiore@0: fiore@0: private static class OpenImpl implements FileService.Open fiore@0: { fiore@0: public OpenImpl(File f) throws FileNotFoundException{ fiore@0: if (f != null){ fiore@0: path = f.getPath(); fiore@0: name = getFileNameFromPath(path,false); fiore@0: in = new BufferedInputStream(new FileInputStream(f)); fiore@0: } fiore@0: } fiore@0: fiore@0: @Override fiore@0: public String getName() { return name; } fiore@0: @Override fiore@0: public String getPath() { return path; } fiore@0: @Override fiore@0: public InputStream getInputStream() { return in; } fiore@0: fiore@0: private String path; fiore@0: private String name; fiore@0: private InputStream in; fiore@0: } fiore@0: fiore@0: /** fiore@0: Edits the file path so that it ends in the desired fiore@0: extension. fiore@0: @param original the file to use as a starting point fiore@0: @param toBeRemoved the extension that is to be fiore@0: removed before adding the desired extension. Use fiore@0: null if nothing needs to be removed. fiore@0: @param desired the desired extension (e.g. ".png"), fiore@0: or a | separated list of extensions fiore@0: @return original if it already has the desired fiore@0: extension, or a new file with the edited file path fiore@0: */ fiore@0: public static String editExtension(String original, fiore@0: String toBeRemoved, String desired){ fiore@0: if (original == null) return null; fiore@0: int n = desired.indexOf('|'); fiore@0: if (n >= 0) desired = desired.substring(0, n); fiore@0: String path = original; fiore@0: if (!path.toLowerCase().endsWith(desired.toLowerCase())){ fiore@0: if (toBeRemoved != null && path.toLowerCase().endsWith( fiore@0: toBeRemoved.toLowerCase())) fiore@0: path = path.substring(0, path.length() - toBeRemoved.length()); fiore@0: path = path + desired; fiore@0: } fiore@0: return path; fiore@0: } fiore@0: fiore@0: public static String getFileNameFromPath(String path,boolean keepExtension){ fiore@0: int index = path.lastIndexOf(System.getProperty("file.separator")); fiore@0: String name; fiore@0: if(index == -1) fiore@0: name = path; fiore@0: else fiore@0: name = path.substring(index+1); fiore@0: if(!keepExtension){ fiore@0: index = name.lastIndexOf('.'); fiore@0: if(index != -1) fiore@0: name = name.substring(0, index); fiore@0: } fiore@0: return name; fiore@0: } fiore@0: }