source: gli/branches/rtl-gli/src/org/greenstone/gatherer/gui/FileAssociationDialog.java@ 18297

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

interface updated to display right to left for rtl languages. This code is thanks to Amin Hejazi. It seems to be only partially complete. Amin was working with Greenstone 3 so might have missed some panels

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