Changeset 6034


Ignore:
Timestamp:
2003-11-28T17:43:38+13:00 (20 years ago)
Author:
jmt12
Message:

Prototype of new file associations dialog, hurried through so the new strings are ready before final submission to UNESCO

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/gui/FileAssociationDialog.java

    r5593 r6034  
    4343import javax.swing.*;
    4444import javax.swing.event.*;
     45import javax.swing.table.*;
    4546import org.greenstone.gatherer.Dictionary;
    4647import org.greenstone.gatherer.Gatherer;
     
    4849import org.greenstone.gatherer.gui.GComboBox;
    4950import org.greenstone.gatherer.gui.ModalDialog;
     51import org.greenstone.gatherer.gui.NonWhitespaceField;
     52import org.greenstone.gatherer.gui.OpenCollectionDialog;
    5053import org.greenstone.gatherer.gui.SimpleMenuBar;
    5154import org.greenstone.gatherer.util.Utility;
    5255import org.outerj.pollo.util.*;
    5356
    54 /** 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.
     57/** The file association allows the entry of new file associations and the modification of existing ones.
    5558 * @author John Thompson, Greenstone Digital Library, University of Waikato
    5659 * @version 2.3
     
    5861public class FileAssociationDialog
    5962    extends ModalDialog {
    60     /** <i>true</i> iff this addition action been cancelled by the user. */
    61     private boolean cancelled = false;
    62     /** <i>true</i> iff we should ignore any current changes to the extension list. */
    63     private boolean ignore = false;
    64     /** <i>true</i> iff the extension has not changed recently, but the command has. */
    65     private boolean save_required = false;
    66     /** A reference to ourselves so that our inner classes can dispose of us. */
    67     private FileAssociationDialog self;
    68     /** A reference to the manager in charge of storing all the file association information. */
    69     private FileAssociationManager manager;
    70     /** The button used to open a file browser for simplier executable selection. */
    71     private JButton browse;
    72     /** The button used to cancel this dialog without commiting any changes. */
    73     private JButton cancel;
    74     /** The button used to hide this dialog after updating or adding file associations as necessary. */
    75     private JButton ok;
    76     /** The combobox used to select what extension you wish to change. */
    77     private GComboBox extension;
    78     /** A field for entering the command string. */
    79     private JTextField command;
    80     /** The extension last chosen from the combobox. This way we can determine if the extension has been modified by the user. */
    81     private String previous_extension;
     63
    8264    /** The default size of a label. */
    8365    static final private Dimension LABEL_SIZE = new Dimension(150, 25);
    8466    /** The default size for the dialog. */
    85     static final private Dimension SIZE = new Dimension(600, 270);
     67    static final private Dimension SIZE = new Dimension(600, 450);
     68
     69    private boolean ignore = false;
     70    private FileAssociationDialog self;
     71    private FileAssociationManager file_association_manager;
     72    private JButton add_button;
     73    private JButton browse_button;
     74    private JButton close_button;
     75    private JButton remove_button;
     76    private JButton replace_button;
     77    private JTable existing_associations_table;
     78    private JTextField command_field;
     79    private JTextField extension_field;
    8680
    8781    /** Create a new file association dialog.
    8882     * @param manager A reference to the <strong>FileAssociationManager</strong> so we can determine what extensions are already associated.
    89      * @see org.greenstone.gatherer.Configuration
    90      * @see org.greenstone.gatherer.gui.Coloring
    9183     */
    92     public FileAssociationDialog(FileAssociationManager manager) {
     84    public FileAssociationDialog(FileAssociationManager file_association_manager) {
    9385    super(Gatherer.g_man);
    94     this.manager = manager;
     86    this.file_association_manager = file_association_manager;
    9587    this.self = this;
    9688         
     
    9991    setSize(SIZE);
    10092    setJMenuBar(new SimpleMenuBar("fileassociations"));
    101     Dictionary.setText(this, "FileAssociationDialog.Title");
    10293
    10394    JPanel content_pane = (JPanel) getContentPane();
    10495    content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
    105     JPanel control_pane = new JPanel();
    10696
    10797    JTextArea instructions_area = new JTextArea();
     
    112102    Dictionary.setText(instructions_area, "FileAssociationDialog.Instructions");
    113103
     104    JPanel control_pane = new JPanel();
     105    JLabel existing_associations_label = new JLabel();
     106    existing_associations_table = new JTable(file_association_manager);
     107    existing_associations_table.setColumnSelectionAllowed(false);
     108    existing_associations_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     109    TableColumnModel column_model = existing_associations_table.getColumnModel();
     110    TableColumn column = column_model.getColumn(0);
     111    column.setWidth(75);
     112    JPanel lower_pane = new JPanel();
     113    JPanel details_pane = new JPanel();
     114
    114115    JPanel extension_pane = new JPanel();
    115     extension_pane.setOpaque(false);
    116116    JLabel extension_label = new JLabel();
    117     extension_label.setPreferredSize(LABEL_SIZE);
     117    extension_label.setPreferredSize(LABEL_SIZE);   
     118    extension_field = new NonWhitespaceField();
     119
     120    JLabel command_label = new JLabel();
     121    JPanel command_pane = new JPanel();
     122    command_field = new JTextField();
     123    browse_button = new JButton();
     124
     125    JPanel button_pane = new JPanel();
     126    add_button = new JButton();
     127    add_button.setEnabled(false);
     128    replace_button = new JButton();
     129    replace_button.setEnabled(false);
     130    remove_button = new JButton();
     131    remove_button.setEnabled(false);
     132    close_button = new JButton();
     133
     134    // Connection
     135    add_button.addActionListener(new AddButtonListener());
     136    browse_button.addActionListener(new BrowseButtonListener());
     137    close_button.addActionListener(new CloseButtonListener());
     138    remove_button.addActionListener(new RemoveButtonListener());
     139    replace_button.addActionListener(new ReplaceButtonListener());
     140    CommandOrExtensionFieldListener coefl = new CommandOrExtensionFieldListener();
     141    command_field.getDocument().addDocumentListener(coefl);
     142    extension_field.getDocument().addDocumentListener(coefl);
     143    coefl = null;
     144    existing_associations_table.getSelectionModel().addListSelectionListener(new ExistingAssociationsTableListener());
     145    Dictionary.setBoth(add_button, "FileAssociationDialog.Add", "FileAssociationDialog.Add_Tooltip");
     146    Dictionary.setBoth(browse_button, "FileAssociationDialog.Browse", "FileAssociationDialog.Browse_Tooltip");
     147    Dictionary.setBoth(close_button, "FileAssociationDialog.Close", "FileAssociationDialog.Close_Tooltip");
     148    Dictionary.setBoth(remove_button, "FileAssociationDialog.Remove", "FileAssociationDialog.Remove_Tooltip");
     149    Dictionary.setBoth(replace_button, "FileAssociationDialog.Replace", "FileAssociationDialog.Replace_Tooltip");
     150    Dictionary.setText(command_label, "FileAssociationDialog.Command");
    118151    Dictionary.setText(extension_label, "FileAssociationDialog.Extension");
    119 
    120     extension = new GComboBox();
    121     extension.setEditable(true);
    122     extension.setPreferredSize(LABEL_SIZE);
    123     for(int i = 0; i < manager.size(); i++) {
    124         extension.add(manager.getExtension(i));
    125     }
    126     Dictionary.setTooltip(extension, "FileAssociationDialog.Extension_Tooltip");
    127 
    128     JPanel command_pane = new JPanel();
    129     command_pane.setOpaque(false);
    130     JLabel command_label = new JLabel();
    131     command_label.setPreferredSize(LABEL_SIZE);
    132     Dictionary.setText(command_label, "FileAssociationDialog.Command");
    133     JPanel inner_pane = new JPanel();
    134     inner_pane.setOpaque(false);
    135     command = new JTextField();
    136     command.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    137     command.setSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false));
    138     command.setSelectedTextColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false));
    139     if(extension.count() > 0) {
    140         command.setText(manager.getCommandString((String)extension.get(0)));
    141     }
    142     Dictionary.setTooltip(command, "FileAssociationDialog.Command_Tooltip");
    143 
    144     browse = new JButton();
    145     browse.setBackground(Gatherer.config.getColor("coloring.button_background", false));
    146     browse.setMnemonic(KeyEvent.VK_B);
    147     browse.setPreferredSize(LABEL_SIZE);
    148     Dictionary.setBoth(browse, "FileAssociationDialog.Browse", "FileAssociationDialog.Browse_Tooltip");
    149 
    150     JPanel button_pane = new JPanel();
    151     button_pane.setOpaque(false);
    152     ok = new JButton();
    153     ok.setBackground(Gatherer.config.getColor("coloring.button_background", false));
    154     ok.setMnemonic(KeyEvent.VK_O);
    155     Dictionary.setBoth(ok, "General.OK", "General.OK_Tooltip");
    156     cancel = new JButton();
    157     cancel.setBackground(Gatherer.config.getColor("coloring.button_background", false));
    158     cancel.setMnemonic(KeyEvent.VK_C);
    159     Dictionary.setBoth(cancel, "General.Cancel", "General.Pure_Cancel_Tooltip");
    160 
    161     // Connection
    162     browse.addActionListener(new BrowseListener());
    163     cancel.addActionListener(new CancelListener());
    164     ok.addActionListener(new OKListener());
    165     extension.addActionListener(new ExtensionListener());
    166     command.getDocument().addDocumentListener(new CommandListener());
     152    Dictionary.setText(existing_associations_label, "FileAssociationDialog.Existing_Associations");
     153    Dictionary.setText(this, "FileAssociationDialog.Title");
    167154
    168155    // Layout
    169     extension_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
     156    extension_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
    170157    extension_pane.setLayout(new BorderLayout());
    171158    extension_pane.add(extension_label, BorderLayout.WEST);
    172     extension_pane.add(extension, BorderLayout.EAST);
    173 
    174     inner_pane.setLayout(new BorderLayout());
    175     inner_pane.add(command, BorderLayout.CENTER);
    176     inner_pane.add(browse, BorderLayout.EAST);
    177 
    178     command_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
    179     command_pane.setLayout(new GridLayout(2,1));
    180     command_pane.add(command_label);
    181     command_pane.add(inner_pane);
    182 
     159    extension_pane.add(extension_field, BorderLayout.CENTER);
     160
     161    command_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
     162    command_pane.setLayout(new BorderLayout());
     163    command_pane.add(command_field, BorderLayout.CENTER);
     164    command_pane.add(browse_button, BorderLayout.EAST);
     165
     166    details_pane.setBorder(BorderFactory.createTitledBorder(Dictionary.get("FileAssociationDialog.Details")));
     167    details_pane.setLayout(new GridLayout(3,1));
     168    details_pane.add(extension_pane);
     169    details_pane.add(command_label);
     170    details_pane.add(command_pane);
     171
     172    lower_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
     173    button_pane.setLayout(new GridLayout(2,3));
     174    button_pane.add(add_button);
     175    button_pane.add(replace_button);
     176    button_pane.add(remove_button);
     177    button_pane.add(new JPanel());
     178    button_pane.add(new JPanel());
     179    button_pane.add(close_button);
     180
     181    lower_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
     182    lower_pane.setLayout(new BorderLayout());
     183    lower_pane.add(details_pane, BorderLayout.CENTER);
     184    lower_pane.add(button_pane, BorderLayout.SOUTH);
     185
     186    control_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
    183187    control_pane.setLayout(new BorderLayout());
    184     control_pane.add(extension_pane, BorderLayout.NORTH);
    185     control_pane.add(command_pane, BorderLayout.CENTER);
    186 
    187     button_pane.setLayout(new GridLayout(1,2,2,2));
    188     button_pane.add(ok);
    189     button_pane.add(cancel);
    190          
     188    control_pane.add(existing_associations_label, BorderLayout.NORTH);
     189    control_pane.add(new JScrollPane(existing_associations_table), BorderLayout.CENTER);
     190    control_pane.add(lower_pane, BorderLayout.SOUTH);
     191
    191192    content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    192193    content_pane.setLayout(new BorderLayout());
    193194    content_pane.add(new JScrollPane(instructions_area), BorderLayout.NORTH);
    194195    content_pane.add(control_pane, BorderLayout.CENTER);
    195     content_pane.add(button_pane, BorderLayout.SOUTH);
    196 
    197     Dimension screen_size = Gatherer.config.screen_size;
    198     setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
    199     }
    200     /** Destructor to ensure dialog gets garbage collected. */
     196
     197    Rectangle screen = Gatherer.g_man.getBounds(null);
     198    setLocation((int)(screen.getX() + (screen.getWidth() - SIZE.width) / 2), (int)(screen.getY() + (screen.getHeight() - SIZE.height) / 2));
     199    screen = null;
     200    }
     201
    201202    public void destroy() {
     203    // Disconnect
     204    // Clean up
     205    file_association_manager = null;
    202206    self = null;
    203     manager = null;
    204     browse = null;
    205     cancel = null;
    206     ok = null;
    207     extension = null;
    208     command = null;
    209     previous_extension = null;
    210207    }
    211208
     
    214211     */
    215212    public String display(String new_extension) {
     213    // Clear the current selection
     214    existing_associations_table.clearSelection();
    216215    if(new_extension != null) {
    217         Dictionary.setBoth(ok, "FileAssociationDialog.Add", "FileAssociationDialog.Add_Tooltip");
    218         int index = extension.add(new_extension);
    219         extension.setSelectedIndex(index);
    220         extension.setEnabled(false);
    221     }
    222     else {
    223         Dictionary.setBoth(ok, "General.OK", "General.OK_Tooltip");
    224         extension.setEnabled(true);
     216        extension_field.setText(new_extension);
    225217    }
    226218    setVisible(true);
    227     if(save_required) {
    228         setCommand((String)extension.getSelectedItem(), (String)command.getText(), true);
    229         save_required = false;
    230     }
    231     if(!cancelled) {
    232         return setCommand((String)extension.getSelectedItem(), (String)command.getText(), false);
    233     }
    234     else {
    235         return null;
    236     }
    237     }
    238 
    239     private String setCommand(String extension, String command, boolean process) {
    240     if(command.indexOf(FileAssociationManager.FILENAME_ARG) == -1) {
    241         command = command + " " + FileAssociationManager.FILENAME_ARG;
    242     }
    243     if(process) {
    244         manager.setCommand(extension, command);
    245     }
    246     return command;
     219    if(new_extension != null) {
     220        return file_association_manager.getCommandString(new_extension);
     221    }
     222    return null;
     223    }
     224
     225    private class AddButtonListener
     226    implements ActionListener {
     227   
     228    public void actionPerformed(ActionEvent event) {
     229        String extension_str = extension_field.getText();
     230        file_association_manager.setCommand(extension_str, command_field.getText());
     231        // Select the appropriate entry in the table
     232        int index = -1;
     233        for(int i = 0; index == -1 && i < file_association_manager.size(); i++) {
     234        if(file_association_manager.getExtension(i).equals(extension_str)) {
     235            index = i;
     236        }
     237        }
     238        if(index > -1) {
     239        existing_associations_table.setRowSelectionInterval(index, index);
     240        }
     241        // And update buttons
     242        add_button.setEnabled(false);
     243        remove_button.setEnabled(true);
     244    }
    247245    }
    248246
    249247    /** 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. */
    250     private class BrowseListener
     248    private class BrowseButtonListener
    251249    implements ActionListener {
    252250    /** Open up a simple JFileChooser when the user clicks the button.
     
    255253    public void actionPerformed(ActionEvent event) {
    256254        JFileChooser chooser = new JFileChooser(new File(Utility.BASE_DIR));
     255        OpenCollectionDialog.disableRename(chooser);
    257256        chooser.setDialogTitle(Dictionary.get("FileAssociationDialog.Browse_Title"));
    258257        chooser.setFileFilter(new ExtensionFileFilter(".bat", Dictionary.get("FileAssociationDialog.Batch_File")));
     
    260259        chooser.setFileFilter(new ExtensionFileFilter(".exe", Dictionary.get("FileAssociationDialog.Executable_File")));
    261260        chooser.setAcceptAllFileFilterUsed(true);
    262         int return_val = chooser.showOpenDialog(null);
    263         if(return_val == JFileChooser.APPROVE_OPTION) {
    264         command.setText(chooser.getSelectedFile().getAbsolutePath());
    265         save_required = true;
    266         }
    267     }
    268     }
    269 
    270     /** Listens for actions apon the cancel button, and if detected disposes of the dialog without saving changes. */
    271     private class CancelListener
     261        if(chooser.showOpenDialog(Gatherer.g_man) == JFileChooser.APPROVE_OPTION) {
     262        command_field.setText(chooser.getSelectedFile().getAbsolutePath());
     263        }
     264    }
     265    }
     266
     267    private class CloseButtonListener
    272268    implements ActionListener {
    273     /** Listens for actions apon the cancel button, and if detected disposes of the dialog without saving changes.
    274      * @param event An <strong>ActionEvent</strong> containing further information about the action.
    275             */
    276269    public void actionPerformed(ActionEvent event) {
    277         cancelled = true;
    278         save_required = false;
     270        existing_associations_table.clearSelection();
     271        add_button.setEnabled(false);
     272        remove_button.setEnabled(false);
     273        replace_button.setEnabled(false);
    279274        self.dispose();
    280275    }
    281276    }
    282277
    283     /** 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. */
    284     private class CommandListener
     278    private class CommandOrExtensionFieldListener
    285279    implements DocumentListener {
    286280    /** Gives notification that an attribute or set of attributes changed. */
    287281    public void changedUpdate(DocumentEvent e) {
    288         save_required = !ignore && true;
     282        changed();
    289283    }
    290284    /** Gives notification that there was an insert into the document. */
    291285    public void insertUpdate(DocumentEvent e) {
    292         save_required = !ignore && true;
    293     }
    294          
     286        changed();
     287    }
    295288    /** Gives notification that a portion of the document has been removed. */
    296289    public void removeUpdate(DocumentEvent e) {
    297         save_required = !ignore && true;
    298     }
    299     }
    300 
    301     /** 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). */
    302     private class ExtensionListener
     290        changed();
     291    }
     292
     293    private void changed() {
     294        ignore = true;
     295        String extension_str = extension_field.getText();
     296        String command_str = command_field.getText();
     297        // Determine if there is currently an association selected
     298        int selected_index = -1;
     299        if((selected_index = existing_associations_table.getSelectionModel().getMinSelectionIndex()) != -1) {
     300        String current_extension_str = file_association_manager.getExtension(selected_index);
     301        String current_command_str = file_association_manager.getCommandString(current_extension_str);
     302        // What buttons are enabled depends a lot on the file extension, taken to be the 'key'
     303        if(extension_str.equals(current_extension_str)) {
     304            // If the extensions are the same then remove is enabled
     305            add_button.setEnabled(false);
     306            remove_button.setEnabled(true);
     307            // But if the command is different, then enable replace
     308            if(!command_str.equals(current_command_str)) {
     309            replace_button.setEnabled(true);
     310            }
     311            else {
     312            replace_button.setEnabled(false);
     313            }
     314        }
     315        // We can add it, but we first clear the selection
     316        else {
     317            existing_associations_table.clearSelection();
     318            add_button.setEnabled(true);
     319            remove_button.setEnabled(false);
     320            replace_button.setEnabled(false);
     321        }
     322        }
     323        // If not, we must first test if the extension is in use
     324        else {
     325        int index = -1;
     326        for(int i = 0; index == -1 && i < file_association_manager.size(); i++) {
     327            String existing_extension_str = file_association_manager.getExtension(i);
     328            if(existing_extension_str.equals(extension_str)) {
     329            index = i;
     330            }
     331        }
     332        if(index != -1) {
     333            // Selection that index
     334            existing_associations_table.setRowSelectionInterval(index, index);
     335            // Set replace and remove enabled
     336            add_button.setEnabled(false);
     337            remove_button.setEnabled(true);
     338            replace_button.setEnabled(true);
     339        }
     340        // Otherwise if there is some text in both extension and command, enable add only
     341        else if(extension_str.length() > 0 && command_str.length() > 0) {
     342            add_button.setEnabled(true);
     343            remove_button.setEnabled(false);
     344            replace_button.setEnabled(false);
     345        }
     346        // Otherwise disable everything
     347        else {
     348            add_button.setEnabled(false);
     349            remove_button.setEnabled(false);
     350            replace_button.setEnabled(false);
     351        }
     352        }
     353        ignore = false;
     354    }
     355    }
     356
     357    private class ExistingAssociationsTableListener
     358    implements ListSelectionListener {
     359
     360    public void valueChanged(ListSelectionEvent event) {
     361        if(!event.getValueIsAdjusting() && !ignore) {
     362        int selected_index = -1;
     363        if((selected_index = existing_associations_table.getSelectionModel().getMinSelectionIndex()) != -1) {
     364            // Propagate the details of the selection down into the fields
     365            String extension_str = file_association_manager.getExtension(selected_index);
     366            extension_field.setText(extension_str);
     367            command_field.setText(file_association_manager.getCommandString(extension_str));
     368            extension_str = null;
     369            remove_button.setEnabled(true);
     370        }
     371        else {
     372            // Clear the fields
     373            extension_field.setText("");
     374            command_field.setText("");
     375            remove_button.setEnabled(false);
     376        }
     377        add_button.setEnabled(false);
     378        replace_button.setEnabled(false);
     379        }
     380    }
     381    }
     382
     383    private class RemoveButtonListener
    303384    implements ActionListener {
    304     /** 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.
    305      * @param event An <strong>ItemEvent</strong> encompassing everything you ever wanted to know about the list selectio, but were afraid to ask.
    306      * @see org.greenstone.gatherer.file.FileAssociationManager
    307      */
    308385    public void actionPerformed(ActionEvent event) {
    309         String ext = (String) extension.getSelectedItem();
    310         if(!ignore && ext != null && ext.length() > 0) {
    311         ignore = true;
    312         // Save the previous extension if necessary
    313         if(save_required && previous_extension != null) {
    314             setCommand(previous_extension, command.getText(), true);
    315             save_required = false;
    316         }
    317         command.setText(manager.getCommandString(ext));
    318         previous_extension = ext;
    319         ignore = false;
    320         }
    321     }
    322     }
    323 
    324     /** Listen for clicks on the ok button, and dispose when detected. */
    325     private class OKListener
     386        file_association_manager.setCommand(extension_field.getText(), null);
     387        // And update buttons
     388        add_button.setEnabled(true);
     389        remove_button.setEnabled(false);
     390    }
     391    }
     392
     393    private class ReplaceButtonListener
    326394    implements ActionListener {
    327     /** When a click on OK is detected, save the current information, then dispose.
    328      * @param event An <strong>ActionEvent</strong> with details about the button press.
    329      */
    330395    public void actionPerformed(ActionEvent event) {
    331         if(save_required) {
    332         setCommand(extension.getSelectedItem().toString(), command.getText(), true);
    333         save_required = false;
    334         }
    335         self.dispose();
     396        file_association_manager.setCommand(extension_field.getText(), command_field.getText());
     397        // And update buttons
     398        replace_button.setEnabled(false);
    336399    }
    337400    }
    338401}
     402
     403
     404
     405
     406
     407
Note: See TracChangeset for help on using the changeset viewer.