f@0: /* f@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool f@0: f@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) f@0: f@0: This program is free software: you can redistribute it and/or modify f@0: it under the terms of the GNU General Public License as published by f@0: the Free Software Foundation, either version 3 of the License, or f@0: (at your option) any later version. f@0: f@0: This program is distributed in the hope that it will be useful, f@0: but WITHOUT ANY WARRANTY; without even the implied warranty of f@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the f@0: GNU General Public License for more details. f@0: f@0: You should have received a copy of the GNU General Public License f@0: along with this program. If not, see . f@0: */ f@0: f@0: package uk.ac.qmul.eecs.ccmi.gui.filechooser; f@0: f@0: import java.awt.Component; f@0: import java.awt.GridBagLayout; f@0: import java.awt.event.ItemEvent; f@0: import java.awt.event.ItemListener; f@0: import java.io.File; f@0: import java.text.MessageFormat; f@0: import java.util.ResourceBundle; f@0: f@0: import javax.swing.DefaultComboBoxModel; f@0: import javax.swing.JButton; f@0: import javax.swing.JComboBox; f@0: import javax.swing.JDialog; f@0: import javax.swing.JLabel; f@0: import javax.swing.JPanel; f@0: import javax.swing.JScrollPane; f@0: import javax.swing.filechooser.FileFilter; f@0: f@0: import uk.ac.qmul.eecs.ccmi.gui.SpeechOptionPane; f@0: import uk.ac.qmul.eecs.ccmi.speech.NarratorFactory; f@0: import uk.ac.qmul.eecs.ccmi.speech.SpeechUtilities; f@0: import uk.ac.qmul.eecs.ccmi.utils.GridBagUtilities; f@0: f@0: /* f@0: * An accessible file chooser. Users can browse the file system only using hearing as f@0: * in the same fashion as they do when exploring a diagram. f@0: * f@0: */ f@0: @SuppressWarnings("serial") f@0: class SpeechFileChooser extends JPanel implements FileChooser { f@0: SpeechFileChooser(){ f@0: super(new GridBagLayout()); f@0: initComponents(); f@0: addComponents(); f@0: } f@0: f@0: private void addComponents() { f@0: GridBagUtilities gridBag = new GridBagUtilities(); f@0: JScrollPane scrollPane = new JScrollPane(tree); f@0: add(scrollPane,gridBag.all()); f@0: add(fileNameLabel,gridBag.label()); f@0: add(fileNameTextField, gridBag.field()); f@0: add(fileTypeLabel, gridBag.label()); f@0: add(fileTypeComboBox, gridBag.field()); f@0: } f@0: f@0: private void initComponents(){ f@0: resources = ResourceBundle.getBundle(this.getClass().getName()); f@0: /* file name components */ f@0: fileNameLabel = new JLabel(resources.getString("dialog.file_chooser.file_name")); f@0: fileNameTextField = new TreeSelectionTextField(); f@0: fileNameTextField.setColumns(20); f@0: fileNameLabel.setLabelFor(fileNameTextField); f@0: fileNameTextField.addKeyListener(SpeechUtilities.getSpeechKeyListener(true)); f@0: fileTypeLabel = new JLabel(resources.getString("dialog.file_chooser.file_type")); f@0: f@0: /* file type components */ f@0: Object [] items = {new AllFileFilter(resources.getString("all_file_filter.label"))}; f@0: fileTypeComboBox = new JComboBox(items); f@0: fileTypeLabel.setLabelFor(fileTypeComboBox); f@0: f@0: /* set up the listener binding the tree with the file name and file type components */ f@0: tree = new FileSystemTree((FileFilter)fileTypeComboBox.getSelectedItem()); f@0: tree.addTreeSelectionListener(fileNameTextField); f@0: fileTypeComboBox.addItemListener(new ItemListener(){ f@0: @Override f@0: public void itemStateChanged(ItemEvent evt) { f@0: if(evt.getStateChange() == ItemEvent.SELECTED) f@0: tree.applyFilter((FileFilter)evt.getItem()); f@0: } f@0: }); f@0: } f@0: f@0: @Override f@0: public void setSelectedFile(File file){ f@0: selectedFile = file; f@0: if(file == null) f@0: return; f@0: tree.setSelectionPath(file); f@0: } f@0: f@0: @Override f@0: public File getSelectedFile(){ f@0: return selectedFile; f@0: } f@0: f@0: @Override f@0: public void setFileFilter(FileFilter filter){ f@0: if(filter != null){ f@0: FileFilter wrap = new WrapFileFilter(filter); f@0: ((DefaultComboBoxModel)fileTypeComboBox.getModel()).insertElementAt(wrap, 0); f@0: fileTypeComboBox.getModel().setSelectedItem(wrap); f@0: } f@0: } f@0: f@0: @Override f@0: public void resetChoosableFileFilters(){ f@0: if(fileTypeComboBox.getItemCount() == 2) f@0: ((DefaultComboBoxModel)fileTypeComboBox.getModel()).removeElementAt(0); f@0: } f@0: f@0: @Override f@0: public void setCurrentDirectory(File dir){ f@0: currentDir = dir; f@0: if(dir == null) f@0: return; f@0: tree.setSelectionPath(dir); f@0: } f@0: f@0: @Override f@0: public File getCurrentDirectory(){ f@0: return currentDir; f@0: } f@0: f@0: @Override f@0: public int showOpenDialog(Component parent){ f@0: FileSystemTreeNode treeNode = (FileSystemTreeNode)tree.getSelectionPath().getLastPathComponent(); f@0: NarratorFactory.getInstance().speak( f@0: MessageFormat.format( f@0: resources.getString("dialog.open.message"), f@0: treeNode.spokenText())); f@0: return showDialog(parent,true); f@0: } f@0: f@0: @Override f@0: public int showSaveDialog(Component parent){ f@0: FileSystemTreeNode treeNode = (FileSystemTreeNode)tree.getSelectionPath().getLastPathComponent(); f@0: NarratorFactory.getInstance().speak( f@0: MessageFormat.format( f@0: resources.getString("dialog.save.message"), f@0: treeNode.spokenText())); f@0: return showDialog(parent,false); f@0: } f@0: f@0: private int showDialog(Component parent, boolean isOpenFileDialog){ f@0: /* overrides on close so that, before closing the dialog it checks that a file name has actually * f@0: * been entered by the user. If not, the dialog won't close and a error will be notified through the narrator */ f@0: SpeechOptionPane optionPane = new SpeechOptionPane(resources.getString("dialog.open.title")){ f@0: @Override f@0: protected void onClose(JDialog dialog, JButton source){ f@0: if(source.equals(getOkButton())){ f@0: if(fileNameTextField.getText().isEmpty()){ f@0: NarratorFactory.getInstance().speak(resources.getString("dialog.error.no_file_name")); f@0: return; f@0: } f@0: } f@0: super.onClose(dialog, source); f@0: } f@0: }; f@0: f@0: if(isOpenFileDialog) f@0: optionPane.getOkButton().setText(resources.getString("open_button.label")); f@0: else f@0: optionPane.getOkButton().setText(resources.getString("save_button.label")); f@0: optionPane.getCancelButton().setText(resources.getString("cancel_button.label")); f@0: f@0: /* add the speech listener just before showing up and then remove it, otherwise it will talk when filters are added/removed */ f@0: fileTypeComboBox.addItemListener(SpeechUtilities.getSpeechComboBoxItemListener()); f@0: int result = optionPane.showDialog(parent, this); f@0: fileTypeComboBox.removeItemListener(SpeechUtilities.getSpeechComboBoxItemListener()); f@0: f@0: if(result == SpeechOptionPane.OK_OPTION){ f@0: FileSystemTreeNode treeNode = (FileSystemTreeNode)tree.getSelectionPath().getLastPathComponent(); f@0: /* user has made his choice. The returned file will be the directory selected in the tree * f@0: * or the parent directory of the selected file if a file is selected + the string entered in the JTextField */ f@0: File directory = treeNode.getFile(); f@0: if(!directory.isDirectory()) f@0: directory = directory.getParentFile(); f@0: f@0: selectedFile = new File(directory,fileNameTextField.getText()); f@0: return APPROVE_OPTION; f@0: }else{ f@0: return CANCEL_OPTION; f@0: } f@0: } f@0: f@0: private ResourceBundle resources; f@0: f@0: private JLabel fileNameLabel; f@0: private TreeSelectionTextField fileNameTextField; f@0: private JLabel fileTypeLabel; f@0: private JComboBox fileTypeComboBox; f@0: private FileSystemTree tree; f@0: private File selectedFile; f@0: private File currentDir; f@0: } f@0: f@0: class AllFileFilter extends FileFilter { f@0: AllFileFilter(String description){ f@0: this.description = description; f@0: } f@0: f@0: @Override f@0: public boolean accept(File file) { f@0: return true; f@0: } f@0: f@0: @Override f@0: public String getDescription() { f@0: return description; f@0: } f@0: f@0: @Override f@0: public String toString(){ f@0: return description; f@0: } f@0: String description; f@0: } f@0: f@0: class WrapFileFilter extends FileFilter { f@0: WrapFileFilter(FileFilter delegate){ f@0: this.delegate = delegate; f@0: } f@0: f@0: @Override f@0: public boolean accept(File f) { f@0: return delegate.accept(f); f@0: } f@0: f@0: @Override f@0: public String getDescription() { f@0: return delegate.getDescription(); f@0: } f@0: f@0: @Override f@0: public String toString(){ f@0: return delegate.getDescription(); f@0: } f@0: f@0: FileFilter delegate; f@0: } f@0: