/**
*#########################################################################
*
* A component of the Gatherer application, part of the Greenstone digital
* library suite from the New Zealand Digital Library Project at the
* University of Waikato, New Zealand.
*
*
*
* Author: John Thompson, Greenstone Digital Library, University of Waikato
*
*
*
* Copyright (C) 1999 New Zealand Digital Library Project
*
*
*
* 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
* (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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*########################################################################
*/
package org.greenstone.gatherer.gui;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.file.FileAssociationManager;
import org.greenstone.gatherer.gui.GComboBox;
import org.greenstone.gatherer.gui.ModalDialog;
import org.greenstone.gatherer.gui.SimpleMenuBar;
import org.greenstone.gatherer.util.Utility;
import org.outerj.pollo.util.*;
/** The file association allows the entry of new file associations and the modification of existing ones. This is done via a list of known extensions, and two fields to fill out relevant details.
* @author John Thompson, Greenstone Digital Library, University of Waikato
* @version 2.3
*/
public class FileAssociationDialog
extends ModalDialog {
/** true iff this addition action been cancelled by the user. */
private boolean cancelled = false;
/** true iff we should ignore any current changes to the extension list. */
private boolean ignore = false;
/** true iff the extension has not changed recently, but the command has. */
private boolean save_required = false;
/** A reference to ourselves so that our inner classes can dispose of us. */
private FileAssociationDialog self;
/** A reference to the manager in charge of storing all the file association information. */
private FileAssociationManager manager;
/** The button used to open a file browser for simplier executable selection. */
private JButton browse;
/** The button used to cancel this dialog without commiting any changes. */
private JButton cancel;
/** The button used to hide this dialog after updating or adding file associations as necessary. */
private JButton ok;
/** The combobox used to select what extension you wish to change. */
private GComboBox extension;
/** A field for entering the command string. */
private JTextField command;
/** The extension last chosen from the combobox. This way we can determine if the extension has been modified by the user. */
private String previous_extension;
/** The default size of a label. */
static final private Dimension LABEL_SIZE = new Dimension(150, 25);
/** The default size for the dialog. */
static final private Dimension SIZE = new Dimension(600, 270);
/** Create a new file association dialog.
* @param manager A reference to the FileAssociationManager so we can determine what extensions are already associated.
* @see org.greenstone.gatherer.Configuration
* @see org.greenstone.gatherer.gui.Coloring
*/
public FileAssociationDialog(FileAssociationManager manager) {
super(Gatherer.g_man);
this.manager = manager;
this.self = this;
// Creation
setModal(true);
setSize(SIZE);
setJMenuBar(new SimpleMenuBar("fileassociations"));
Dictionary.setText(this, "FileAssociationDialog.Title");
JPanel content_pane = (JPanel) getContentPane();
content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
JPanel control_pane = new JPanel();
JTextArea instructions_area = new JTextArea();
instructions_area.setEditable(false);
instructions_area.setLineWrap(true);
instructions_area.setRows(5);
instructions_area.setWrapStyleWord(true);
Dictionary.setText(instructions_area, "FileAssociationDialog.Instructions");
JPanel extension_pane = new JPanel();
extension_pane.setOpaque(false);
JLabel extension_label = new JLabel();
extension_label.setPreferredSize(LABEL_SIZE);
Dictionary.setText(extension_label, "FileAssociationDialog.Extension");
extension = new GComboBox();
extension.setEditable(true);
extension.setPreferredSize(LABEL_SIZE);
for(int i = 0; i < manager.size(); i++) {
extension.add(manager.getExtension(i));
}
Dictionary.setTooltip(extension, "FileAssociationDialog.Extension_Tooltip");
JPanel command_pane = new JPanel();
command_pane.setOpaque(false);
JLabel command_label = new JLabel();
command_label.setPreferredSize(LABEL_SIZE);
Dictionary.setText(command_label, "FileAssociationDialog.Command");
JPanel inner_pane = new JPanel();
inner_pane.setOpaque(false);
command = new JTextField();
command.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
command.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
command.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
if(extension.count() > 0) {
command.setText(manager.getCommandString((String)extension.get(0)));
}
Dictionary.setTooltip(command, "FileAssociationDialog.Command_Tooltip");
browse = new JButton();
browse.setBackground(Gatherer.config.getColor("coloring.button_background", false));
browse.setMnemonic(KeyEvent.VK_B);
browse.setPreferredSize(LABEL_SIZE);
Dictionary.setBoth(browse, "FileAssociationDialog.Browse", "FileAssociationDialog.Browse_Tooltip");
JPanel button_pane = new JPanel();
button_pane.setOpaque(false);
ok = new JButton();
ok.setBackground(Gatherer.config.getColor("coloring.button_background", false));
ok.setMnemonic(KeyEvent.VK_O);
Dictionary.setBoth(ok, "General.OK", "General.OK_Tooltip");
cancel = new JButton();
cancel.setBackground(Gatherer.config.getColor("coloring.button_background", false));
cancel.setMnemonic(KeyEvent.VK_C);
Dictionary.setBoth(cancel, "General.Cancel", "General.Pure_Cancel_Tooltip");
// Connection
browse.addActionListener(new BrowseListener());
cancel.addActionListener(new CancelListener());
ok.addActionListener(new OKListener());
extension.addActionListener(new ExtensionListener());
command.getDocument().addDocumentListener(new CommandListener());
// Layout
extension_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
extension_pane.setLayout(new BorderLayout());
extension_pane.add(extension_label, BorderLayout.WEST);
extension_pane.add(extension, BorderLayout.EAST);
inner_pane.setLayout(new BorderLayout());
inner_pane.add(command, BorderLayout.CENTER);
inner_pane.add(browse, BorderLayout.EAST);
command_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
command_pane.setLayout(new GridLayout(2,1));
command_pane.add(command_label);
command_pane.add(inner_pane);
control_pane.setLayout(new BorderLayout());
control_pane.add(extension_pane, BorderLayout.NORTH);
control_pane.add(command_pane, BorderLayout.CENTER);
button_pane.setLayout(new GridLayout(1,2,2,2));
button_pane.add(ok);
button_pane.add(cancel);
content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
content_pane.setLayout(new BorderLayout());
content_pane.add(new JScrollPane(instructions_area), BorderLayout.NORTH);
content_pane.add(control_pane, BorderLayout.CENTER);
content_pane.add(button_pane, BorderLayout.SOUTH);
Dimension screen_size = Gatherer.config.screen_size;
setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
}
/** Destructor to ensure dialog gets garbage collected. */
public void destroy() {
self = null;
manager = null;
browse = null;
cancel = null;
ok = null;
extension = null;
command = null;
previous_extension = null;
}
/** Redisplay the dialog, ensuring that the details (or lack thereof) for a certain extension is apparent. In fact if an extension is provided force the user to add it or cancel.
* @param new_extension The extension code as a String.
*/
public String display(String new_extension) {
if(new_extension != null) {
Dictionary.setBoth(ok, "FileAssociationDialog.Add", "FileAssociationDialog.Add_Tooltip");
int index = extension.add(new_extension);
extension.setSelectedIndex(index);
extension.setEnabled(false);
}
else {
Dictionary.setBoth(ok, "General.OK", "General.OK_Tooltip");
extension.setEnabled(true);
}
setVisible(true);
if(save_required) {
setCommand((String)extension.getSelectedItem(), (String)command.getText(), true);
save_required = false;
}
if(!cancelled) {
return setCommand((String)extension.getSelectedItem(), (String)command.getText(), false);
}
else {
return null;
}
}
private String setCommand(String extension, String command, boolean process) {
if(command.indexOf(FileAssociationManager.FILENAME_ARG) == -1) {
command = command + " " + FileAssociationManager.FILENAME_ARG;
}
if(process) {
manager.setCommand(extension, command);
}
return command;
}
/** Whenever the user clicks the browse button, we should open up a file browser to allow them to select an executable file from somewhere in the file system. */
private class BrowseListener
implements ActionListener {
/** Open up a simple JFileChooser when the user clicks the button.
* @param event An ActionEvent containing information about the event.
*/
public void actionPerformed(ActionEvent event) {
JFileChooser chooser = new JFileChooser(new File(Utility.BASE_DIR));
chooser.setDialogTitle(Dictionary.newget("FileAssociationDialog.Browse_Title"));
chooser.setFileFilter(new ExtensionFileFilter(".bat", Dictionary.newget("FileAssociationDialog.Batch_File")));
chooser.setFileFilter(new ExtensionFileFilter(".com", Dictionary.newget("FileAssociationDialog.Command_File")));
chooser.setFileFilter(new ExtensionFileFilter(".exe", Dictionary.newget("FileAssociationDialog.Executable_File")));
chooser.setAcceptAllFileFilterUsed(true);
int return_val = chooser.showOpenDialog(null);
if(return_val == JFileChooser.APPROVE_OPTION) {
command.setText(chooser.getSelectedFile().getAbsolutePath());
save_required = true;
}
}
}
/** Listens for actions apon the cancel button, and if detected disposes of the dialog without saving changes. */
private class CancelListener
implements ActionListener {
/** Listens for actions apon the cancel button, and if detected disposes of the dialog without saving changes.
* @param event An ActionEvent containing further information about the action.
*/
public void actionPerformed(ActionEvent event) {
cancelled = true;
save_required = false;
self.dispose();
}
}
/** If any changes occur to the command field, mark it as needing saving before we can change extensions, or dispose of this dialog (other than cancelling. */
private class CommandListener
implements DocumentListener {
/** Gives notification that an attribute or set of attributes changed. */
public void changedUpdate(DocumentEvent e) {
save_required = !ignore && true;
}
/** Gives notification that there was an insert into the document. */
public void insertUpdate(DocumentEvent e) {
save_required = !ignore && true;
}
/** Gives notification that a portion of the document has been removed. */
public void removeUpdate(DocumentEvent e) {
save_required = !ignore && true;
}
}
/** Whenever the user selects an extension, we should fill out the command field with whatever value has been previously entered for the command (if any). */
private class ExtensionListener
implements ActionListener {
/** This method is called whenever the selection in the extension list changes, so that we can save any old details, then load up the information for the new selection.
* @param event An ItemEvent encompassing everything you ever wanted to know about the list selectio, but were afraid to ask.
* @see org.greenstone.gatherer.file.FileAssociationManager
*/
public void actionPerformed(ActionEvent event) {
String ext = (String) extension.getSelectedItem();
if(!ignore && ext != null && ext.length() > 0) {
ignore = true;
// Save the previous extension if necessary
if(save_required && previous_extension != null) {
setCommand(previous_extension, command.getText(), true);
save_required = false;
}
command.setText(manager.getCommandString(ext));
previous_extension = ext;
ignore = false;
}
}
}
/** Listen for clicks on the ok button, and dispose when detected. */
private class OKListener
implements ActionListener {
/** When a click on OK is detected, save the current information, then dispose.
* @param event An ActionEvent with details about the button press.
*/
public void actionPerformed(ActionEvent event) {
if(save_required) {
setCommand(extension.getSelectedItem().toString(), command.getText(), true);
save_required = false;
}
self.dispose();
}
}
}