source: trunk/gli/src/org/greenstone/gatherer/gui/FileAssociationDialog.java@ 6209

Last change on this file since 6209 was 6209, checked in by jmt12, 20 years ago

Replaced pollo.FileExtensionFilter with my own

  • Property svn:keywords set to Author Date Id Revision
File size: 17.3 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.io.File;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.event.*;
45import javax.swing.filechooser.*;
46import javax.swing.table.*;
47import org.greenstone.gatherer.Dictionary;
48import org.greenstone.gatherer.Gatherer;
49import org.greenstone.gatherer.file.FileAssociationManager;
50import org.greenstone.gatherer.gui.GComboBox;
51import org.greenstone.gatherer.gui.ModalDialog;
52import org.greenstone.gatherer.gui.NonWhitespaceField;
53import org.greenstone.gatherer.gui.OpenCollectionDialog;
54import org.greenstone.gatherer.gui.SimpleMenuBar;
55import org.greenstone.gatherer.util.TableUtils;
56import org.greenstone.gatherer.util.Utility;
57
58/** The file association allows the entry of new file associations and the modification of existing ones.
59 * @author John Thompson, Greenstone Digital Library, University of Waikato
60 * @version 2.3
61 */
62public class FileAssociationDialog
63 extends ModalDialog {
64
65 /** The default size of a label. */
66 static final private Dimension LABEL_SIZE = new Dimension(150, 25);
67 /** The default size for the dialog. */
68 static final private Dimension SIZE = new Dimension(600, 450);
69
70 private boolean ignore = false;
71 private FileAssociationDialog self;
72 private FileAssociationManager file_association_manager;
73 private JButton add_button;
74 private JButton browse_button;
75 private JButton close_button;
76 private JButton remove_button;
77 private JButton replace_button;
78 private JTable existing_associations_table;
79 private JTextField command_field;
80 private JTextField extension_field;
81
82 /** Create a new file association dialog.
83 * @param manager A reference to the <strong>FileAssociationManager</strong> so we can determine what extensions are already associated.
84 */
85 public FileAssociationDialog(FileAssociationManager file_association_manager) {
86 super(Gatherer.g_man);
87 this.file_association_manager = file_association_manager;
88 this.self = this;
89
90 // Creation
91 setModal(true);
92 setSize(SIZE);
93 setJMenuBar(new SimpleMenuBar("fileassociations"));
94
95 JPanel content_pane = (JPanel) getContentPane();
96 content_pane.setBackground(Gatherer.config.getColor("coloring.collection_heading_background", false));
97
98 JTextArea instructions_area = new JTextArea();
99 instructions_area.setEditable(false);
100 instructions_area.setLineWrap(true);
101 instructions_area.setRows(5);
102 instructions_area.setWrapStyleWord(true);
103 Dictionary.setText(instructions_area, "FileAssociationDialog.Instructions");
104
105 JPanel control_pane = new JPanel();
106 JLabel existing_associations_label = new JLabel();
107 existing_associations_table = new JTable(file_association_manager);
108 existing_associations_table.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
109 existing_associations_table.setColumnSelectionAllowed(false);
110 existing_associations_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
111 JPanel lower_pane = new JPanel();
112 JPanel details_pane = new JPanel();
113
114 JPanel extension_pane = new JPanel();
115 JLabel extension_label = new JLabel();
116 extension_label.setPreferredSize(LABEL_SIZE);
117 extension_field = new NonWhitespaceField();
118
119 JLabel command_label = new JLabel();
120 JPanel command_pane = new JPanel();
121 command_field = new JTextField();
122 browse_button = new JButton();
123
124 JPanel button_pane = new JPanel();
125 add_button = new JButton();
126 add_button.setEnabled(false);
127 replace_button = new JButton();
128 replace_button.setEnabled(false);
129 remove_button = new JButton();
130 remove_button.setEnabled(false);
131 close_button = new JButton();
132
133 // Connection
134 add_button.addActionListener(new AddButtonListener());
135 browse_button.addActionListener(new BrowseButtonListener());
136 close_button.addActionListener(new CloseButtonListener());
137 remove_button.addActionListener(new RemoveButtonListener());
138 replace_button.addActionListener(new ReplaceButtonListener());
139 CommandOrExtensionFieldListener coefl = new CommandOrExtensionFieldListener();
140 command_field.getDocument().addDocumentListener(coefl);
141 extension_field.getDocument().addDocumentListener(coefl);
142 coefl = null;
143 existing_associations_table.getSelectionModel().addListSelectionListener(new ExistingAssociationsTableListener());
144 Dictionary.setBoth(add_button, "FileAssociationDialog.Add", "FileAssociationDialog.Add_Tooltip");
145 Dictionary.setBoth(browse_button, "FileAssociationDialog.Browse", "FileAssociationDialog.Browse_Tooltip");
146 Dictionary.setBoth(close_button, "FileAssociationDialog.Close", "FileAssociationDialog.Close_Tooltip");
147 Dictionary.setBoth(remove_button, "FileAssociationDialog.Remove", "FileAssociationDialog.Remove_Tooltip");
148 Dictionary.setBoth(replace_button, "FileAssociationDialog.Replace", "FileAssociationDialog.Replace_Tooltip");
149 Dictionary.setText(command_label, "FileAssociationDialog.Command");
150 Dictionary.setText(extension_label, "FileAssociationDialog.Extension");
151 Dictionary.setText(existing_associations_label, "FileAssociationDialog.Existing_Associations");
152 Dictionary.setText(this, "FileAssociationDialog.Title");
153
154 // Layout
155 extension_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
156 extension_pane.setLayout(new BorderLayout());
157 extension_pane.add(extension_label, BorderLayout.WEST);
158 extension_pane.add(extension_field, BorderLayout.CENTER);
159
160 command_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
161 command_pane.setLayout(new BorderLayout());
162 command_pane.add(command_field, BorderLayout.CENTER);
163 command_pane.add(browse_button, BorderLayout.EAST);
164
165 details_pane.setBorder(BorderFactory.createTitledBorder(Dictionary.get("FileAssociationDialog.Details")));
166 details_pane.setLayout(new GridLayout(3,1));
167 details_pane.add(extension_pane);
168 details_pane.add(command_label);
169 details_pane.add(command_pane);
170
171 lower_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
172 button_pane.setLayout(new GridLayout(2,3));
173 button_pane.add(add_button);
174 button_pane.add(replace_button);
175 button_pane.add(remove_button);
176 button_pane.add(new JPanel());
177 button_pane.add(new JPanel());
178 button_pane.add(close_button);
179
180 lower_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
181 lower_pane.setLayout(new BorderLayout());
182 lower_pane.add(details_pane, BorderLayout.CENTER);
183 lower_pane.add(button_pane, BorderLayout.SOUTH);
184
185 control_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
186 control_pane.setLayout(new BorderLayout());
187 control_pane.add(existing_associations_label, BorderLayout.NORTH);
188 control_pane.add(new JScrollPane(existing_associations_table), BorderLayout.CENTER);
189 control_pane.add(lower_pane, BorderLayout.SOUTH);
190
191 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
192 content_pane.setLayout(new BorderLayout());
193 content_pane.add(new JScrollPane(instructions_area), BorderLayout.NORTH);
194 content_pane.add(control_pane, BorderLayout.CENTER);
195
196 Rectangle screen = Gatherer.g_man.getBounds(null);
197 setLocation((int)(screen.getX() + (screen.getWidth() - SIZE.width) / 2), (int)(screen.getY() + (screen.getHeight() - SIZE.height) / 2));
198 screen = null;
199 }
200
201 public void destroy() {
202 // Disconnect
203 // Clean up
204 file_association_manager = null;
205 self = null;
206 }
207
208 /** 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.
209 * @param new_extension The extension code as a <strong>String</strong>.
210 */
211 public String display(String new_extension) {
212 // Clear the current selection
213 existing_associations_table.clearSelection();
214 if(new_extension != null) {
215 extension_field.setText(new_extension);
216 }
217 setVisible(true);
218 if(new_extension != null) {
219 return file_association_manager.getCommandString(new_extension);
220 }
221 return null;
222 }
223
224 protected void processWindowEvent(WindowEvent event) {
225 if(event.getID() == WindowEvent.WINDOW_ACTIVATED) {
226 TableUtils.fixColumnToPreferredWidth(existing_associations_table, 0);
227 }
228 else {
229 super.processWindowEvent(event);
230 }
231 }
232
233 private class AddButtonListener
234 implements ActionListener {
235
236 public void actionPerformed(ActionEvent event) {
237 String extension_str = extension_field.getText();
238 file_association_manager.setCommand(extension_str, command_field.getText());
239 // Select the appropriate entry in the table
240 int index = -1;
241 for(int i = 0; index == -1 && i < file_association_manager.size(); i++) {
242 if(file_association_manager.getExtension(i).equals(extension_str)) {
243 index = i;
244 }
245 }
246 if(index > -1) {
247 existing_associations_table.setRowSelectionInterval(index, index);
248 }
249 // And update buttons
250 add_button.setEnabled(false);
251 remove_button.setEnabled(true);
252 }
253 }
254
255 /** Batch filter shows only files ending in bat. Based on ImageFilter.java which is a 1.4 example used by FileChooserDemo2.java. */
256 private class BatchFileFilter
257 extends FileFilter {
258
259 /** Accept all .exe files
260 * @param file a File
261 * @return true is this file should be shown, false otherwise
262 */
263 public boolean accept(File file) {
264 return file.getName().toLowerCase().endsWith(".bat");
265 }
266
267 /** The description of this filter
268 * @return a String
269 */
270 public String getDescription() {
271 return Dictionary.get("FileAssociationDialog.Batch_File");
272 }
273 }
274
275 /** 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. */
276 private class BrowseButtonListener
277 implements ActionListener {
278 /** Open up a simple JFileChooser when the user clicks the button.
279 * @param event An <strong>ActionEvent</strong> containing information about the event.
280 */
281 public void actionPerformed(ActionEvent event) {
282 JFileChooser chooser = new JFileChooser(new File(Utility.BASE_DIR));
283 OpenCollectionDialog.disableRename(chooser);
284 chooser.setDialogTitle(Dictionary.get("FileAssociationDialog.Browse_Title"));
285 chooser.setFileFilter(new BatchFileFilter());
286 chooser.setFileFilter(new CoreObjectModelFileFilter());
287 chooser.setFileFilter(new ExecutableFileFilter());
288 chooser.setAcceptAllFileFilterUsed(true);
289 if(chooser.showOpenDialog(Gatherer.g_man) == JFileChooser.APPROVE_OPTION) {
290 command_field.setText(chooser.getSelectedFile().getAbsolutePath());
291 }
292 }
293 }
294
295 private class CloseButtonListener
296 implements ActionListener {
297 public void actionPerformed(ActionEvent event) {
298 existing_associations_table.clearSelection();
299 add_button.setEnabled(false);
300 remove_button.setEnabled(false);
301 replace_button.setEnabled(false);
302 self.dispose();
303 }
304 }
305
306 /** Command filter shows only files ending in com. Based on ImageFilter.java which is a 1.4 example used by FileChooserDemo2.java. */
307 private class CoreObjectModelFileFilter
308 extends FileFilter {
309
310 /** Accept all .exe files
311 * @param file a File
312 * @return true is this file should be shown, false otherwise
313 */
314 public boolean accept(File file) {
315 return file.getName().toLowerCase().endsWith(".com");
316 }
317
318 /** The description of this filter
319 * @return a String
320 */
321 public String getDescription() {
322 return Dictionary.get("FileAssociationDialog.Command_File");
323 }
324 }
325
326 private class CommandOrExtensionFieldListener
327 implements DocumentListener {
328 /** Gives notification that an attribute or set of attributes changed. */
329 public void changedUpdate(DocumentEvent e) {
330 changed();
331 }
332 /** Gives notification that there was an insert into the document. */
333 public void insertUpdate(DocumentEvent e) {
334 changed();
335 }
336 /** Gives notification that a portion of the document has been removed. */
337 public void removeUpdate(DocumentEvent e) {
338 changed();
339 }
340
341 private void changed() {
342 ignore = true;
343 String extension_str = extension_field.getText();
344 String command_str = command_field.getText();
345 // Determine if there is currently an association selected
346 int selected_index = -1;
347 if((selected_index = existing_associations_table.getSelectionModel().getMinSelectionIndex()) != -1) {
348 String current_extension_str = file_association_manager.getExtension(selected_index);
349 String current_command_str = file_association_manager.getCommandString(current_extension_str);
350 // What buttons are enabled depends a lot on the file extension, taken to be the 'key'
351 if(extension_str.equals(current_extension_str)) {
352 // If the extensions are the same then remove is enabled
353 remove_button.setEnabled(true);
354 // But if the command is different, then enable replace
355 if(current_command_str.length() == 0) {
356 add_button.setEnabled(true);
357 replace_button.setEnabled(false);
358 }
359 else if(!command_str.equals(current_command_str)) {
360 add_button.setEnabled(false);
361 replace_button.setEnabled(true);
362 }
363 else {
364 add_button.setEnabled(false);
365 replace_button.setEnabled(false);
366 }
367 }
368 // We can add it, but we first clear the selection
369 else {
370 existing_associations_table.clearSelection();
371 add_button.setEnabled(true);
372 remove_button.setEnabled(false);
373 replace_button.setEnabled(false);
374 }
375 }
376 // If not, we must first test if the extension is in use
377 else {
378 int index = -1;
379 for(int i = 0; index == -1 && i < file_association_manager.size(); i++) {
380 String existing_extension_str = file_association_manager.getExtension(i);
381 if(existing_extension_str.equals(extension_str)) {
382 index = i;
383 }
384 }
385 if(index != -1) {
386 // Selection that index
387 existing_associations_table.setRowSelectionInterval(index, index);
388 // Set replace and remove enabled
389 add_button.setEnabled(false);
390 remove_button.setEnabled(true);
391 replace_button.setEnabled(true);
392 }
393 // Otherwise if there is some text in both extension and command, enable add only
394 else if(extension_str.length() > 0 && command_str.length() > 0) {
395 add_button.setEnabled(true);
396 remove_button.setEnabled(false);
397 replace_button.setEnabled(false);
398 }
399 // Otherwise disable everything
400 else {
401 add_button.setEnabled(false);
402 remove_button.setEnabled(false);
403 replace_button.setEnabled(false);
404 }
405 }
406 ignore = false;
407 }
408 }
409
410 /** Executable filter shows only files ending in exe. Based on ImageFilter.java which is a 1.4 example used by FileChooserDemo2.java. */
411 private class ExecutableFileFilter
412 extends FileFilter {
413
414 /** Accept all .exe files
415 * @param file a File
416 * @return true is this file should be shown, false otherwise
417 */
418 public boolean accept(File file) {
419 return file.getName().toLowerCase().endsWith(".exe");
420 }
421
422 /** The description of this filter
423 * @return a String
424 */
425 public String getDescription() {
426 return Dictionary.get("FileAssociationDialog.Executable_File");
427 }
428 }
429
430 private class ExistingAssociationsTableListener
431 implements ListSelectionListener {
432
433 public void valueChanged(ListSelectionEvent event) {
434 if(!event.getValueIsAdjusting() && !ignore) {
435 int selected_index = -1;
436 if((selected_index = existing_associations_table.getSelectionModel().getMinSelectionIndex()) != -1) {
437 // Propagate the details of the selection down into the fields
438 String extension_str = file_association_manager.getExtension(selected_index);
439 extension_field.setText(extension_str);
440 command_field.setText(file_association_manager.getCommandString(extension_str));
441 extension_str = null;
442 remove_button.setEnabled(true);
443 }
444 else {
445 // Clear the fields
446 extension_field.setText("");
447 command_field.setText("");
448 remove_button.setEnabled(false);
449 }
450 add_button.setEnabled(false);
451 replace_button.setEnabled(false);
452 }
453 }
454 }
455
456 private class RemoveButtonListener
457 implements ActionListener {
458 public void actionPerformed(ActionEvent event) {
459 file_association_manager.setCommand(extension_field.getText(), null);
460 // And update buttons
461 add_button.setEnabled(true);
462 remove_button.setEnabled(false);
463 }
464 }
465
466 private class ReplaceButtonListener
467 implements ActionListener {
468 public void actionPerformed(ActionEvent event) {
469 file_association_manager.setCommand(extension_field.getText(), command_field.getText());
470 // And update buttons
471 replace_button.setEnabled(false);
472 }
473 }
474}
475
476
477
478
479
480
Note: See TracBrowser for help on using the repository browser.