source: gli/branches/2.75/src/org/greenstone/gatherer/cdm/ArgumentControl.java@ 14784

Last change on this file since 14784 was 14784, checked in by anna, 16 years ago

If a plugin option has a display name, use the displayName instead of option name, such as process_expression instead of process_exp.

  • Property svn:keywords set to Author Date Id Revision
File size: 19.7 KB
Line 
1package org.greenstone.gatherer.cdm;
2
3import java.awt.*;
4import java.awt.event.*;
5import javax.swing.*;
6import javax.swing.event.*;
7
8import java.io.File;
9import java.util.ArrayList;
10import java.util.Collections;
11import java.util.Map;
12import java.util.Iterator;
13
14import org.greenstone.gatherer.Configuration;
15import org.greenstone.gatherer.DebugStream;
16import org.greenstone.gatherer.Dictionary;
17import org.greenstone.gatherer.Gatherer;
18import org.greenstone.gatherer.gui.GComboBox;
19import org.greenstone.gatherer.util.StaticStrings;
20import org.greenstone.gatherer.util.Utility;
21import org.greenstone.gatherer.metadata.MetadataElement;
22import org.greenstone.gatherer.metadata.MetadataSet;
23import org.greenstone.gatherer.metadata.MetadataSetManager;
24import org.greenstone.gatherer.metadata.MetadataTools;
25
26/** This class encapsulates all the technical difficulty of creating a specific control based on an Argument. */
27public class ArgumentControl
28extends JPanel {
29
30 static protected Dimension LABEL_SIZE = new Dimension(175, 25);
31 static protected Dimension ROW_SIZE = new Dimension(400, 30);
32 /** The Argument this control will be based on. */
33 private Argument argument = null;
34
35 /** A checkbox to allow enabling or diabling of this Argument. */
36 private JCheckBox enabled = null;
37 /** Some form of editor component, such as a JComboBox or JTextField, used to set parameters to an Argument. */
38 private JComponent value_control = null;
39
40 /** Constructor.
41 */
42 public ArgumentControl(Argument argument, boolean is_enabled, String preset_value) {
43 this.argument = argument;
44
45 String tip = "<html>" + argument.getName()+": "+argument.getDescription() + "</html>";
46 tip = Utility.formatHTMLWidth(tip, 80);
47
48 setBackground(Configuration.getColor("coloring.collection_tree_background", false));
49 setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
50 setLayout(new BorderLayout());
51 setPreferredSize(ROW_SIZE);
52
53 // display the name set in the disp option if there is one
54 // otherwise display name option value instead
55 String dispName = argument.getDisplayName();
56 if(dispName.equals("")){
57 dispName = argument.getName();
58 }
59
60 if (argument.isRequired()) {
61 //JLabel label = new JLabel(argument.getName());
62 JLabel label = new JLabel(dispName);
63
64 label.setOpaque(false);
65 label.setPreferredSize(LABEL_SIZE);
66 label.setToolTipText(tip);
67 add(label, BorderLayout.WEST);
68 } else {
69 //enabled = new JCheckBox(argument.getName());
70 enabled = new JCheckBox(dispName);
71
72 enabled.setOpaque(false);
73 enabled.setPreferredSize(LABEL_SIZE);
74 enabled.setToolTipText(tip);
75 add(enabled, BorderLayout.WEST);
76 }
77
78 String initial_value;
79 if (preset_value != null && !preset_value.equals("")) {
80 initial_value = preset_value;
81 }
82 else {
83 initial_value = argument.getValue();
84 }
85 if (initial_value == null || initial_value.equals("")) {
86 initial_value = argument.getDefaultValue();
87 }
88 if (initial_value == null) {
89 initial_value = "";
90 }
91
92 switch(argument.getType()) {
93 case Argument.ENUM:
94 ArrayList option_list = argument.getOptions();
95 value_control = new GComboBox(option_list.toArray(), false, false);
96 selectValue((JComboBox)value_control, initial_value); // also sets the tooltip
97 ((JComboBox)value_control).addActionListener(new ToolTipUpdater());
98 break;
99
100 case Argument.FLAG:
101 // Only need the check box.
102 break;
103
104 case Argument.INTEGER:
105 // Build a spinner
106 int initial_int=0;
107 // If there was an original value, set it.
108 try {
109 initial_int = Integer.parseInt(initial_value);
110 } catch (Exception error) {
111 DebugStream.println("ArgumentControl Error: "+error);
112 }
113 if (initial_int < argument.getMinimum()) {
114 initial_int = argument.getMinimum();
115 } else if (initial_int > argument.getMaximum()) {
116 initial_int = argument.getMaximum();
117 }
118
119 JSpinner spinner = new JSpinner(new SpinnerNumberModel(initial_int, argument.getMinimum(), argument.getMaximum(), 1));
120
121 // And remember it
122 value_control = spinner;
123 break;
124
125 case Argument.REGEXP:
126 case Argument.STRING:
127 value_control = new JTextField(initial_value);
128 break;
129
130 case Argument.LANGUAGE:
131 value_control = new GComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray(), false);
132 // we want to display the language name not the code
133 ((JComboBox)value_control).setRenderer(new LanguageListCellRenderer());
134 // Now ensure we have the existing value or default value selected if either exist in our known languages
135 String lang_name = CollectionDesignManager.language_manager.getLanguageName(initial_value);
136 if (lang_name != null) {
137 ((JComboBox)value_control).setSelectedItem(initial_value);
138 }
139 break;
140
141 case Argument.METADATUM:
142 case Argument.METADATA:
143 value_control = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
144
145 // Editable for advanced modes (allows things like dc.Title,ex.Title)
146 if (Configuration.getMode() > Configuration.ASSISTANT_MODE) {
147 ((JComboBox) value_control).setEditable(true);
148 }
149 // Now ensure we have the existing value or default value selected if either exist.
150 String existing_value = preset_value;
151 if (existing_value == null || existing_value.length() == 0) {
152 existing_value = argument.getValue();
153 }
154 if (existing_value != null && existing_value.length() > 0) {
155 boolean found = selectValue((JComboBox) value_control, existing_value);
156 // It's possible that this is a custom value and so doesn't exist in the combobox
157 if (!found) {
158 // If so, add it then select it
159 ((JComboBox) value_control).addItem(existing_value);
160 ((JComboBox) value_control).setSelectedItem(existing_value);
161 }
162 }
163 else {
164 String default_value = argument.getDefaultValue();
165 if (default_value != null) {
166 // if no namespace for default value, add ex.
167 // won't work if we want to set a non-metadata value
168 if (MetadataTools.getMetadataSetNamespace(default_value).equals("")) {
169 default_value = StaticStrings.EXTRACTED_NAMESPACE+default_value;
170 }
171 selectValue((JComboBox) value_control, default_value);
172 }
173 }
174 break;
175
176 case Argument.METADATA_SET_NAMESPACE:
177 value_control = new JComboBox();
178 // !! Hack for exploding metadata databases: add the (empty) exploded metadata set
179 File exploded_metadata_set_file = new File(Gatherer.getGLIMetadataDirectoryPath() + "exp" + StaticStrings.METADATA_SET_EXTENSION);
180 MetadataSet exploded_metadata_set = new MetadataSet(exploded_metadata_set_file);
181 Gatherer.c_man.importMetadataSet(exploded_metadata_set);
182
183 // All the loaded metadata sets except the extracted metadata set are applicable
184 ArrayList metadata_sets = MetadataSetManager.getMetadataSets();
185 for (int i = metadata_sets.size() - 1; i >= 0; i--) {
186 MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
187 if (!(metadata_set.getNamespace().equals(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE))) {
188 ((JComboBox)value_control).addItem(metadata_set);
189 }
190 }
191
192 selectValue((JComboBox) value_control, initial_value);
193
194 } // end of switch
195
196 // Enable or disable as necessary.
197 if(argument.isRequired() || argument.isAssigned() || is_enabled) {
198 if (enabled != null) {
199 enabled.setSelected(true);
200 }
201 if(value_control != null) {
202 value_control.setOpaque(true);
203 value_control.setBackground(Color.white);
204 value_control.setEnabled(true);
205 if(value_control instanceof JSpinner) {
206 // Set enabled
207 JComponent c = ((JSpinner)value_control).getEditor();
208 if ( c instanceof JSpinner.DefaultEditor ) {
209 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
210 JFormattedTextField field = editor.getTextField();
211 field.setEditable(true);
212 field.setBackground(Color.white);
213 }
214 }
215 }
216 }
217 else {
218 if (enabled != null) {
219 enabled.setSelected(false);
220 }
221 if(value_control != null) {
222 value_control.setOpaque(true);
223 value_control.setBackground(Color.lightGray);
224 value_control.setEnabled(false);
225 if(value_control instanceof JSpinner) {
226 // Set enabled
227 JComponent c = ((JSpinner)value_control).getEditor();
228 if ( c instanceof JSpinner.DefaultEditor ) {
229 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
230 JFormattedTextField field = editor.getTextField();
231 field.setEditable(false);
232 field.setBackground(Color.lightGray);
233 }
234 }
235 }
236 }
237
238 // Listener
239 if(value_control != null) {
240 if (argument.getType() != Argument.ENUM) {
241 // enums have already set tooltips based on option value
242 value_control.setToolTipText(tip);
243 }
244 add(value_control, BorderLayout.CENTER);
245 if (!argument.isRequired()) {
246 enabled.addActionListener(new EnabledListener(value_control));
247 }
248 }
249 }
250
251 public Argument getArgument() {
252 return argument;
253 }
254
255 public String getArgumentName() {
256 return argument.getName();
257 }
258
259 public String getValue() {
260 if(value_control == null) {
261 return null;
262 }
263 if (value_control instanceof JSpinner) {
264 return ((JSpinner)value_control).getValue().toString();
265 }
266 if(value_control instanceof JComboBox) {
267 Object selected_item = ((JComboBox)value_control).getSelectedItem();
268 if (selected_item != null) {
269 if (argument.getType() == Argument.METADATA_SET_NAMESPACE) {
270 return ((MetadataSet) selected_item).getNamespace();
271 }
272 if (selected_item instanceof Argument.ArgumentOption) {
273 return ((Argument.ArgumentOption)selected_item).name;
274 }
275 if (selected_item instanceof MetadataElement) {
276 return ((MetadataElement) selected_item).getFullName();
277 }
278 return selected_item.toString();
279 }
280 return null;
281 }
282 if(value_control instanceof JTextField) {
283 return ((JTextField)value_control).getText();
284 }
285 return null;
286 }
287 /** Retrieve the control used for storing values.
288 * @return JComponent
289 */
290 public JComponent getValueControl() {
291 return value_control;
292 }
293
294 public boolean isEnabled() {
295 if (enabled == null) {
296 return true; // always enabled
297 }
298 return enabled.isSelected();
299 }
300
301
302 /** Identifies this control by returning the name of the Argument it is based on.
303 * @return The name of the Argument as a <strong>String</strong>.
304 * @see org.greenstone.gatherer.cdm.Argument
305 */
306 public String toString() {
307 return argument.getName();
308 }
309 /** Updates the enwrapped Argument using the values provided by the controls.
310 * @return <i>true</i> if the update was successful, <i>false</i> otherwise.
311 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.Argument.ArgumentOption
312 * @see org.greenstone.gatherer.cdm.Language
313 */
314 public boolean updateArgument() {
315 if(argument.isRequired() || enabled.isSelected() ) {
316 argument.setAssigned(false);
317 String result = null;
318 switch(argument.getType()) {
319 case Argument.ENUM:
320 Argument.ArgumentOption option = (Argument.ArgumentOption)((JComboBox)value_control).getSelectedItem();
321 if(option != null && option.name.length() > 0) {
322 argument.setValue(option.name);
323 }
324 else {
325 String args[] = new String[1];
326 args[0] = argument.getName();
327 if(argument.isRequired()) {
328 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
329 }
330 // They've left the field blank
331 else {
332 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
333 argument.setValue(null);
334 }
335 args = null;
336 return false;
337 }
338 argument.setAssigned(true);
339 return true;
340 case Argument.FLAG:
341 // Should have already been handled above.
342 argument.setAssigned(true);
343 return true;
344 case Argument.INTEGER:
345 result = ((JSpinner)value_control).getValue().toString();
346 if(result.length() > 0) {
347 // Test if the value entered is a valid int.
348 try {
349 int x = Integer.parseInt(result);
350 }
351 catch(NumberFormatException nfe) {
352 String args[] = new String[2];
353 args[0] = argument.getName();
354 args[1] = result;
355 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Bad_Integer", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
356 args = null;
357 return false;
358 }
359 argument.setValue(result);
360 }
361 else {
362 String args[] = new String[1];
363 args[0] = argument.getName();
364 if(argument.isRequired()) {
365 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
366 }
367 // They've left the field blank
368 else {
369 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
370 argument.setValue(null);
371 }
372 args = null;
373 return false;
374 }
375 argument.setAssigned(true);
376 return true;
377 case Argument.LANGUAGE:
378 String language = (((JComboBox)value_control).getSelectedItem()).toString();
379 argument.setValue(language);
380 // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
381 argument.setAssigned(true);
382 return true;
383 case Argument.METADATUM:
384 case Argument.METADATA:
385 Object new_value_raw = ((JComboBox) value_control).getSelectedItem();
386 if (new_value_raw instanceof MetadataElement) {
387 argument.setValue(((MetadataElement) new_value_raw).getFullName());
388 }
389 else {
390 // But we have to be careful as an arbitary string object could be zero length
391 String new_value = new_value_raw.toString();
392 ///ystem.err.println("The current value is: " + new_value);
393 if(new_value.length() > 0) {
394 argument.setValue(new_value);
395 }
396 else {
397 String args[] = new String[1];
398 args[0] = argument.getName();
399 if(argument.isRequired()) {
400 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
401 }
402 // They've left the field blank
403 else {
404 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
405 argument.setValue(null);
406 }
407 args = null;
408 return false;
409 }
410 }
411 argument.setAssigned(true);
412 return true;
413 case Argument.REGEXP:
414 case Argument.STRING:
415 result = ((JTextField)value_control).getText();
416 if(result.length() > 0) {
417 argument.setValue(result);
418 }
419 else {
420 String args[] = new String[1];
421 args[0] = argument.getName();
422 if(argument.isRequired()) {
423 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
424 }
425 // They've left the field blank
426 else {
427 JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
428 argument.setValue(null);
429 }
430 args = null;
431 return false;
432 }
433 argument.setAssigned(true);
434 return true;
435 }
436 return false;
437 }
438 else {
439 argument.setAssigned(false);
440 return true;
441 }
442 }
443
444
445 public boolean updateArgument(boolean checkRequired) {
446
447
448 if (checkRequired){
449 return updateArgument();
450 }
451 else{
452 if (argument.getType() == Argument.STRING){
453 String result = ((JTextField)value_control).getText();
454
455 if(result.length() > 0) {
456 argument.setValue(result);
457 argument.setAssigned(true);
458 }
459 }
460 }
461
462 return true;
463
464 }
465
466
467
468 /** Method to ensure that a certain value is selected, if it exists within that combobox to begin with.
469 * @param combobox The <strong>JComboBox</strong> whose selection we are trying to preset.
470 * @param target The desired value of the selection as a <strong>String</strong>.
471 * @return true if the item was found and selected, false otherwise
472 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.Argument.ArgumentOption
473 */
474 public static boolean selectValue(JComboBox combobox, String target)
475 {
476 for (int i = 0; i < combobox.getItemCount(); i++) {
477 Object object = combobox.getItemAt(i);
478
479 if (object instanceof Argument.ArgumentOption) {
480 Argument.ArgumentOption opt = (Argument.ArgumentOption) object;
481 if (opt.name.startsWith(target)) {
482 combobox.setSelectedIndex(i);
483 combobox.setToolTipText(opt.getToolTip());
484 return true;
485 }
486 }
487 else if (object instanceof MetadataElement) {
488 if(((MetadataElement)object).getFullName().equals(target)) {
489 combobox.setSelectedIndex(i);
490 return true;
491 }
492 }
493 else if (object.toString().equals(target)) {
494 combobox.setSelectedIndex(i);
495 return true;
496 }
497 }
498
499 return false;
500 }
501
502
503 /** Forces the control into an 'enabled' mode. */
504 public void setEnabled() {
505 enabled.setSelected(true);
506 }
507 /** Explicitly sets the value of a JTextField type control to the given String.
508 * @param value_str The new value of the control as a <strong>String</strong>.
509 */
510 public void setValue(String value_str) {
511 ((JTextField)value_control).setText(value_str);
512 }
513
514 /** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */
515 private class EnabledListener
516 implements ActionListener {
517 /** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */
518 private JComponent target = null;
519
520 /** Constructor. */
521 public EnabledListener(JComponent target) {
522 this.target = target;
523 }
524
525 /** Any implementation of ActionListener must include this method so that we can be informed when an action has been performed on or registered check box, prompting us to change the state of the other controls as per the users request.
526 * @param event An <strong>ActionEvent</strong> containing information about the click.
527 */
528 public void actionPerformed(ActionEvent event) {
529 if (this.target == null) {
530 return;
531 }
532 JCheckBox source = (JCheckBox)event.getSource();
533 if(source.isSelected()) {
534 target.setBackground(Color.white);
535 target.setEnabled(true);
536 }
537 else {
538 target.setBackground(Color.lightGray);
539 target.setEnabled(false);
540 }
541 // Special case of stupid JSpinners who don't let their backgrounds change properly.
542 if(target instanceof JSpinner) {
543 JSpinner spinner = (JSpinner) target;
544 JComponent c = spinner.getEditor();
545 if ( c instanceof JSpinner.DefaultEditor ) {
546 JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
547 JFormattedTextField field = editor.getTextField();
548 field.setEditable(source.isSelected());
549 if(source.isSelected()) {
550 field.setBackground(Color.white);
551 }
552 else {
553 field.setBackground(Color.lightGray);
554 }
555 }
556 }
557 }
558 }
559
560
561 /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
562 private class ToolTipUpdater
563 implements ActionListener {
564 /** Any implementation of an ActionListener must include this method so that we can be informed when the selection in a combobox has changed and update the tooltip accordingly.
565 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call.
566 */
567 public void actionPerformed(ActionEvent event) {
568 JComboBox source = (JComboBox)event.getSource();
569 Object object = source.getSelectedItem();
570 if(object instanceof Argument.ArgumentOption) {
571 Argument.ArgumentOption opt = (Argument.ArgumentOption)object;
572 if(opt != null) {
573 source.setToolTipText(opt.getToolTip());
574 }
575 else {
576 source.setToolTipText(StaticStrings.EMPTY_STR);
577 }
578 }
579 }
580 }
581}
Note: See TracBrowser for help on using the repository browser.