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

Last change on this file since 7360 was 7151, checked in by kjdon, 20 years ago

fixed some more static label sizes and deleted a lot of commented out stuff

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