Mercurial > hg > ccmieditor
view java/src/uk/ac/qmul/eecs/ccmi/gui/FileService.java @ 6:1c5af356bb99
added 64 bit native narrator
allow hapitic native dll to load only on 32 bit JVM
refactored DiagramEditorApp for better inheritance
fixed Java 7 bug: NullPointerException when typing
minor bug fixes
added splashscreen
author | Fiore Martin <fiore@eecs.qmul.ac.uk> |
---|---|
date | Mon, 17 Dec 2012 18:39:40 +0000 |
parents | d66dd5880081 |
children |
line wrap: on
line source
/* CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) 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 3 of the License, or (at your option) 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, see <http://www.gnu.org/licenses/>. */ package uk.ac.qmul.eecs.ccmi.gui; import java.awt.Frame; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ResourceBundle; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import uk.ac.qmul.eecs.ccmi.gui.filechooser.FileChooser; import uk.ac.qmul.eecs.ccmi.gui.filechooser.FileChooserFactory; import uk.ac.qmul.eecs.ccmi.sound.SoundEvent; import uk.ac.qmul.eecs.ccmi.sound.SoundFactory; import uk.ac.qmul.eecs.ccmi.utils.PreferencesService; /** * A Utility class providing inner classes and interfaces for handling * files. */ public abstract class FileService { /** * An Open object encapsulates the stream, name and path of the file that the user selected for opening. */ public interface Open { /** * Gets the input stream corresponding to the user selection. * @return the input stream, or null if the user cancels the file selection task */ InputStream getInputStream(); /** * Gets the name of the file that the user selected. * @return the file name, or null if the user cancels the file selection task */ String getName(); /** * Gets the path of the file that the user selected. * @return the file path , or null if the user cancels the file selection task */ String getPath(); } /** * A Save object encapsulates the stream and name of the file that the user selected for saving. */ public interface Save { /** * Gets the output stream corresponding to the user selection. * @return the output stream, or null if the user cancels the file selection task */ OutputStream getOutputStream(); /** * Gets the name of the file that the user selected. * @return the file name, or null if the user cancels the file selection task */ String getName(); /** * Gets the path of the file that the user selected. * @return the file path, or null if the user cancels the file selection task */ String getPath(); } /** * This class returns a FileService for opening and saving files, with either a JFileChooser or a * SpeechFileChooser */ public static class ChooserService { /** * Creates a new {@code ChooserService}. * * @param initialDirectory the directory displayed when the files service is displayed */ public ChooserService(File initialDirectory){ useAccessible = Boolean.parseBoolean(PreferencesService.getInstance().get("use_accessible_filechooser", "true")); fileChooser = FileChooserFactory.getFileChooser(useAccessible); fileChooser.setCurrentDirectory(initialDirectory); } /** * Returns a {@code FileService.Open} out of a file chosen by the user. The user is prompted * with either a normal or an accessible file choser. * * @param defaultDirectory the directory to open the file chooser, prompted to the user * @param defaultFile the file selected when the file chooser is prompted to the user * @param filter an {@code ExtensionFilter} to filter the filed displayed on the file chooser * @param frame the frame where the file chooser is displayed * @return an {@code FileService.Open} to handle the file selected by the user * @throws IOException if the file chosen by the uses doesn't exist. */ public FileService.Open open(String defaultDirectory, String defaultFile, ExtensionFilter filter, Frame frame) throws IOException { checkChangedOption(); fileChooser.resetChoosableFileFilters(); fileChooser.setFileFilter(filter); if (defaultDirectory != null) fileChooser.setCurrentDirectory(new File(defaultDirectory)); if (defaultFile == null) fileChooser.setSelectedFile(null); else fileChooser.setSelectedFile(new File(defaultFile)); int response = fileChooser.showOpenDialog(frame); if (response == JFileChooser.APPROVE_OPTION) return new OpenImpl(fileChooser.getSelectedFile()); else{ /* If the user cancels the task (presses cancel button or the X at the top left corner) * * the CANCEl sound is played (together with the registered playerListeenr if any) */ if(useAccessible) SoundFactory.getInstance().play(SoundEvent.CANCEL); return new OpenImpl(null); } } /** * Returns a {@code FileService.Save} out of a file chosen by the user. The user is prompted * with either a normal or an accessible file chooser. * * @param defaultDirectory the directory to open the file chooser, prompted to the user * @param defaultFile the file selected when the file chooser is prompted to the user * @param filter an {@code ExtensionFilter} to filter the filed displayed on the file chooser * @param removeExtension the extension to be removed from the chosen file name. Use {@code null} for removing no extension * @param addExtension the extension to be added to the chosen file name. * @param currentTabs an array of already open files names. If the selected file matches any of these, then an * Exception is thrown. If {@code null} is passed, then this parameter will be ignored and no check will be done. * @return an {@code FileService.Save} to handle the file selected by the user * @throws IOException if the file chosen by the uses doesn't exist or has a file name that's already * in {@code currentTabs}. */ public FileService.Save save(String defaultDirectory, String defaultFile, ExtensionFilter filter, String removeExtension, String addExtension, String[] currentTabs) throws IOException { checkChangedOption(); fileChooser.resetChoosableFileFilters(); fileChooser.setFileFilter(filter); if (defaultDirectory == null) fileChooser.setCurrentDirectory(new File(".")); else fileChooser.setCurrentDirectory(new File(defaultDirectory)); if (defaultFile != null){ File f = new File(editExtension(defaultFile, removeExtension, addExtension)); if(f.exists()) fileChooser.setSelectedFile(f); else fileChooser.setSelectedFile(null); }else fileChooser.setSelectedFile(null); int response = fileChooser.showSaveDialog(null); if (response == JFileChooser.APPROVE_OPTION){ ResourceBundle resources = ResourceBundle.getBundle(EditorFrame.class.getName()); File f = fileChooser.getSelectedFile(); if (addExtension != null && f.getName().indexOf(".") < 0) // no extension supplied f = new File(f.getPath() + addExtension); String fileName = getFileNameFromPath(f.getAbsolutePath(),false); /* check the name against the names of already open tabs */ if(currentTabs != null){ for(String tab : currentTabs){ if(fileName.equals(tab)) throw new IOException(resources.getString("dialog.error.same_file_name")); } } if (!f.exists()) // file doesn't exits return the new SaveImpl with no problems return new SaveImpl(f); /* file with this name already exists, we must ask the user to confirm */ if(useAccessible){ int result = SpeechOptionPane.showConfirmDialog( null, resources.getString("dialog.overwrite"), SpeechOptionPane.YES_NO_OPTION); if (result == SpeechOptionPane.YES_OPTION) return new SaveImpl(f); }else{ int result = JOptionPane.showConfirmDialog( null, resources.getString("dialog.overwrite"), null, JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) return new SaveImpl(f); } } /* If the user cancels the task (presses cancel button or the X at the top left) * * the CANCEl sound is played (together with the registered playerListeenr if any) */ if(useAccessible) SoundFactory.getInstance().play(SoundEvent.CANCEL); /* returned if the user doesn't want to overwrite the file */ return new SaveImpl(null); } /* check if the user has changed the configuration since the last time a the fileChooser was shown */ private void checkChangedOption(){ boolean useAccessible = Boolean.parseBoolean(PreferencesService.getInstance().get("use_accessible_filechooser", "true")); if(this.useAccessible != useAccessible){ this.useAccessible = useAccessible; File currentDir = fileChooser.getCurrentDirectory(); fileChooser = FileChooserFactory.getFileChooser(useAccessible); fileChooser.setCurrentDirectory(currentDir); } } private FileChooser fileChooser; private boolean useAccessible; } /** * A file service which doesn't show any dialog to let * the user choose which file to open or save. */ public static class DirectService { /** * Creates a {@code FileService.Open} out of the file passed as argument. * * @param file the file to open * @return a new {@code FileService.Open} instance * @throws IOException if {@code file} cannot be found */ public FileService.Open open(File file) throws IOException{ return new OpenImpl(file); } /** * Creates a {@code FileService.Save} out of the file passed as argument. * * @param file the file to save * @return a new {@code FileService.Save} instance * @throws IOException if {@code file} cannot be found */ public FileService.Save save(File file) throws IOException{ return new SaveImpl(file); } } private static class SaveImpl implements FileService.Save{ public SaveImpl(File f) throws FileNotFoundException{ if (f != null){ path = f.getPath(); name = getFileNameFromPath(path,false); out = new BufferedOutputStream(new FileOutputStream(f)); } } @Override public String getName() { return name; } @Override public String getPath() {return path; } @Override public OutputStream getOutputStream() { return out; } private String name; private String path; private OutputStream out; } private static class OpenImpl implements FileService.Open{ public OpenImpl(File f) throws FileNotFoundException{ if (f != null){ path = f.getPath(); name = getFileNameFromPath(path,false); in = new BufferedInputStream(new FileInputStream(f)); } } @Override public String getName() { return name; } @Override public String getPath() { return path; } @Override public InputStream getInputStream() { return in; } private String path; private String name; private InputStream in; } /** * Edits the file path so that it ends in the desired * extension. * @param original the file to use as a starting point * @param toBeRemoved the extension that is to be * removed before adding the desired extension. Use * null if nothing needs to be removed. * @param desired the desired extension (e.g. ".png"), * or a | separated list of extensions * @return original if it already has the desired * extension, or a new file with the edited file path */ public static String editExtension(String original, String toBeRemoved, String desired){ if (original == null) return null; int n = desired.indexOf('|'); if (n >= 0) desired = desired.substring(0, n); String path = original; if (!path.toLowerCase().endsWith(desired.toLowerCase())){ if (toBeRemoved != null && path.toLowerCase().endsWith( toBeRemoved.toLowerCase())) path = path.substring(0, path.length() - toBeRemoved.length()); path = path + desired; } return path; } /** * Returns the single file name from a file path * * @param path the path to extract the file name from * @param keepExtension whether to keep the extension of the file * in the returned string * @return the name of the file identified by {@code path} */ public static String getFileNameFromPath(String path,boolean keepExtension){ int index = path.lastIndexOf(System.getProperty("file.separator")); String name; if(index == -1) name = path; else name = path.substring(index+1); if(!keepExtension){ index = name.lastIndexOf('.'); if(index != -1) name = name.substring(0, index); } return name; } }