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

Last change on this file since 20957 was 18412, checked in by kjdon, 15 years ago

more modifications for RTL GLI, thanks to Amin Hedjazi

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