source: trunk/gli/src/org/greenstone/gatherer/cdm/FormatManager.java@ 5655

Last change on this file since 5655 was 5651, checked in by jmt12, 21 years ago

Workaround for [ and ] bug, plus ensuring collection released, configuration saved etc

  • Property svn:keywords set to Author Date Id Revision
File size: 28.0 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 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29/**************************************************************************************
30 * Written: 06/05/02
31 * Revised: 04/10/02 - Commented
32 * 14/07/03 - DOM support
33 **************************************************************************************/
34import java.awt.*;
35import java.awt.event.*;
36import java.util.*;
37import javax.swing.*;
38import javax.swing.event.*;
39import org.greenstone.gatherer.Dictionary;
40import org.greenstone.gatherer.Gatherer;
41import org.greenstone.gatherer.cdm.Classifier;
42import org.greenstone.gatherer.cdm.ClassifierManager;
43import org.greenstone.gatherer.cdm.CollectionConfiguration;
44import org.greenstone.gatherer.cdm.CollectionDesignManager;
45import org.greenstone.gatherer.cdm.CommandTokenizer;
46import org.greenstone.gatherer.cdm.Control;
47import org.greenstone.gatherer.cdm.DOMProxyListModel;
48import org.greenstone.gatherer.cdm.Format;
49import org.greenstone.gatherer.msm.ElementWrapper;
50import org.greenstone.gatherer.util.Utility;
51import org.w3c.dom.*;
52
53/** This class maintains a list of format statements, and allows the addition and removal of these statements.
54 * @author John Thompson, Greenstone Digital Library, University of Waikato
55 * @version 2.3
56 */
57public class FormatManager
58 extends DOMProxyListModel {
59
60 static final private String BLANK = "blank";
61 static final private String FLAG = "flag";
62 static final private String VALUE = "value";
63
64 /** This flag is set if some change has occured to the format commands. When a collection has been built for previewing, and the greenstone local library server is used, then we have to send commands to remove then add the new collection. */
65 private boolean formats_changed = false;
66 /** The controls used to edit the format commands. */
67 private Control controls = null;
68 /** A reference to ourselves so inner classes can get at the model. */
69 private DOMProxyListModel model = null;
70
71 /** Constructor. */
72 public FormatManager() {
73 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.FORMAT_ELEMENT, new Format());
74 this.model = this;
75 Gatherer.println("FormatManager: parsed " + getSize() + " format statements.");
76 // Establish all of the format objects, so that classifier indexes are initially correct (subsequent refreshes of the model will be sufficient to keep these up to date, as long as we start with a live reference to a classifier.
77 int size = getSize();
78 for(int i = 0; i < size; i++) {
79 getElementAt(i);
80 }
81 }
82
83 /** Method to add a new format to this manager.
84 * @param format The <strong>Format</strong> to add.
85 */
86 public void addFormat(Format format) {
87 if(!contains(format)) {
88 Element element = format.getElement();
89 // Locate where we should insert this new classifier.
90 Node target_node = CollectionConfiguration.findInsertionPoint(element);
91 add(root, format, target_node);
92 Gatherer.c_man.configurationChanged();
93 formats_changed = true;
94 }
95 }
96
97 public void destroy() {
98 if(controls != null) {
99 controls.destroy();
100 controls = null;
101 }
102 }
103
104 /** Have the formats changed since the last save. */
105 public boolean formatsChanged() {
106 return formats_changed;
107 }
108
109 /** Gets the format indicated by the index.
110 * @param index The location of the desired format, as an <i>int</i>.
111 */
112 public Format getFormat(int index) {
113 Format result = null;
114 if(0 < index && index < getSize()) {
115 result = (Format) getElementAt(index);
116 }
117 return result;
118 }
119
120 public Format getFormat(String name) {
121 int model_size = getSize();
122 for(int index = 0; index < model_size; index++) {
123 Format format = (Format) getElementAt(index);
124 if(format.getName().equals(name)) {
125 return format;
126 }
127 }
128 return null;
129 }
130
131 /** Method to retrieve this managers controls.
132 * @return the Control for this collection.
133 */
134 public Control getControls() {
135 if(controls == null) {
136 controls = new FormatControl();
137 }
138 return controls;
139 }
140
141 /** Method to remove a format.
142 * @param format The <strong>Format</strong> to remove.
143 */
144 public void removeFormat(Format format) {
145 remove(format);
146 Gatherer.c_man.configurationChanged();
147 formats_changed = true;
148 }
149
150 /** Set the state of the formats changed flag.
151 * @param state the new state as a boolean
152 */
153 public void setFormatsChanged(boolean state) {
154 formats_changed = state;
155 }
156
157 private HashMap buildDefaultMappings(ArrayList features_model, ArrayList parts_model) {
158 System.err.println("buildDefaultMappings(): replace me with something that reads in a data xml file.");
159 return new HashMap();
160 }
161
162 private ArrayList buildFeatureModel() {
163 // Rebuild feature model.
164 ArrayList feature_model = new ArrayList();
165 // Add the set options
166 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) {
167 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i]));
168 }
169 // Now the classifiers.
170 for(int j = 0; j < CollectionDesignManager.classifier_manager.getSize(); j++) {
171 feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j)));
172 }
173 Collections.sort(feature_model);
174 return feature_model;
175 }
176
177 private ArrayList buildPartModel() {
178 System.err.println("buildPartModel(): replace me with something that reads in a data xml file.");
179 ArrayList part_model = new ArrayList();
180 part_model.add("");
181 part_model.add("DateList");
182 part_model.add("HList");
183 part_model.add("Invisible");
184 part_model.add("VList");
185 return part_model;
186 }
187
188 private ArrayList buildVariableModel() {
189 System.err.println("buildVariableModel(): replace me with something that reads in a data xml file.");
190 ArrayList variable_model = new ArrayList();
191 variable_model.add("[Text]");
192 variable_model.add("[link]");
193 variable_model.add("[/link]");
194 variable_model.add("[icon]");
195 variable_model.add("[num]");
196 variable_model.add("[parent():_]");
197 variable_model.add("[parent(Top):_]");
198 variable_model.add("[parent(All'_'):_]");
199 Vector elements = Gatherer.c_man.getCollection().msm.getAssignedElements();
200 for(int i = 0; i < elements.size(); i++) {
201 variable_model.add("[" + ((ElementWrapper)elements.get(i)).getName() + "]");
202 }
203 Collections.sort(variable_model);
204 return variable_model;
205 }
206
207 private class FormatControl
208 extends JPanel
209 implements Control {
210
211 private ArrayList feature_model;
212 private ArrayList part_model;
213 private ArrayList variable_model;
214 private boolean ignore_event = false;
215 private boolean ready = false; // Are these controls available to be refreshed
216 private CardLayout card_layout;
217 private HashMap default_mappings;
218 private JButton add_button;
219 private JButton insert_button;
220 private JButton remove_button;
221 private JButton replace_button;
222 private JCheckBox enabled_checkbox;
223 private JComboBox feature_combobox;
224 private JComboBox part_combobox;
225 private JComboBox variable_combobox;
226 private JList format_list;
227 private JTextArea instructions_textarea;
228 private JTextArea editor_textarea;
229 private JPanel control_pane;
230 private JPanel part_pane;
231 private JPanel selection_pane;
232 private String view_type;
233
234 public FormatControl() {
235 feature_model = buildFeatureModel();
236 part_model = buildPartModel();
237 variable_model = buildVariableModel();
238 default_mappings = buildDefaultMappings(feature_model, part_model);
239
240 // Create
241 JPanel instructions_pane = new JPanel();
242 JLabel title_label = new JLabel();
243 title_label.setHorizontalAlignment(JLabel.CENTER);
244 title_label.setOpaque(true);
245 Dictionary.registerText(title_label, "CDM.FormatManager.Title");
246
247 instructions_textarea = new JTextArea();
248 instructions_textarea.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
249 instructions_textarea.setEditable(false);
250 instructions_textarea.setLineWrap(true);
251 instructions_textarea.setRows(6);
252 instructions_textarea.setWrapStyleWord(true);
253 Dictionary.registerText(instructions_textarea, "CDM.FormatManager.Instructions");
254
255 JLabel format_label = new JLabel();
256 Dictionary.registerText(format_label, "CDM.FormatManager.Assigned_Formats");
257 format_list = new JList(model);
258
259 selection_pane = new JPanel();
260 JPanel feature_pane = new JPanel();
261 JLabel feature_label = new JLabel();
262 feature_label.setPreferredSize(Utility.LABEL_SIZE);
263 Dictionary.registerText(feature_label, "CDM.FormatManager.Feature");
264 feature_combobox = new JComboBox(feature_model.toArray());
265 feature_combobox.setEditable(false);
266 Dictionary.registerTooltip(feature_combobox, "CDM.FormatManager.Feature_Tooltip");
267
268 part_pane = new JPanel();
269 JLabel part_label = new JLabel();
270 part_label.setPreferredSize(Utility.LABEL_SIZE);
271 Dictionary.registerText(part_label, "CDM.FormatManager.Part");
272
273 part_combobox = new JComboBox(part_model.toArray());
274 part_combobox.setEditable(false);
275 Dictionary.registerTooltip(part_combobox, "CDM.FormatManager.Part_Tooltip");
276
277 JPanel center_pane = new JPanel();
278
279 card_layout = new CardLayout();
280 control_pane = new JPanel();
281
282 JPanel blank_pane = new JPanel();
283
284 JPanel editor_pane = new JPanel();
285 JPanel editor_header_pane = new JPanel();
286 JLabel editor_label = new JLabel();
287 Dictionary.registerText(editor_label, "CDM.FormatManager.Editor");
288
289 editor_textarea = new JTextArea();
290 editor_textarea.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
291 editor_textarea.setCaretPosition(0);
292 editor_textarea.setLineWrap(true);
293 editor_textarea.setRows(6);
294 editor_textarea.setWrapStyleWord(false);
295 Dictionary.registerTooltip(editor_textarea, "CDM.FormatManager.Editor_Tooltip");
296
297 JPanel variable_pane = new JPanel();
298 JLabel variable_label = new JLabel();
299 Dictionary.registerText(variable_label, "CDM.FormatManager.Variable");
300 variable_combobox = new JComboBox(variable_model.toArray());
301 Dictionary.registerTooltip(variable_combobox, "CDM.FormatManager.Variable_Tooltip");
302
303 insert_button = new JButton();
304 insert_button.setMnemonic(KeyEvent.VK_I);
305 Dictionary.registerBoth(insert_button, "CDM.FormatManager.Insert", "CDM.FormatManager.Insert_Tooltip");
306
307 JPanel flag_pane = new JPanel();
308 enabled_checkbox = new JCheckBox();
309 Dictionary.registerText(enabled_checkbox, "CDM.FormatManager.Enabled");
310
311 JPanel button_pane = new JPanel();
312 add_button = new JButton();
313 add_button.setEnabled(false);
314 add_button.setMnemonic(KeyEvent.VK_A);
315 Dictionary.registerBoth(add_button, "CDM.FormatManager.Add", "CDM.FormatManager.Add_Tooltip");
316 replace_button = new JButton();
317 replace_button.setEnabled(false);
318 replace_button.setMnemonic(KeyEvent.VK_C);
319 Dictionary.registerBoth(replace_button, "CDM.FormatManager.Replace", "CDM.FormatManager.Replace_Tooltip");
320 remove_button = new JButton();
321 remove_button.setEnabled(false);
322 remove_button.setMnemonic(KeyEvent.VK_R);
323 Dictionary.registerBoth(remove_button, "CDM.FormatManager.Remove", "CDM.FormatManager.Remove_Tooltip");
324
325 // Connect
326 add_button.addActionListener(new AddListener());
327 insert_button.addActionListener(new InsertListener());
328 remove_button.addActionListener(new RemoveListener());
329 replace_button.addActionListener(new ReplaceListener());
330 enabled_checkbox.addActionListener(new EnabledListener());
331 feature_combobox.addActionListener(new FeatureListener());
332 part_combobox.addActionListener(new PartListener());
333 editor_textarea.getDocument().addDocumentListener(new EditorListener());
334 format_list.addListSelectionListener(new FormatListListener());
335
336 // Layout
337 instructions_pane.setLayout(new BorderLayout());
338 instructions_pane.add(title_label, BorderLayout.NORTH);
339 instructions_pane.add(new JScrollPane(instructions_textarea), BorderLayout.CENTER);
340 instructions_pane.add(format_label, BorderLayout.SOUTH);
341
342 feature_pane.setLayout(new BorderLayout());
343 feature_pane.add(feature_label, BorderLayout.WEST);
344 feature_pane.add(feature_combobox, BorderLayout.CENTER);
345
346 part_pane.setLayout(new BorderLayout());
347 part_pane.add(part_label, BorderLayout.WEST);
348 part_pane.add(part_combobox, BorderLayout.CENTER);
349
350 selection_pane.setLayout(new GridLayout(2,1,0,2));
351 selection_pane.add(feature_pane);
352 selection_pane.add(part_pane);
353
354 flag_pane.add(enabled_checkbox);
355
356 editor_header_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
357 editor_header_pane.setLayout(new GridLayout(1,3));
358 editor_header_pane.add(editor_label);
359 editor_header_pane.add(new JPanel());
360
361 variable_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
362 variable_pane.setLayout(new GridLayout(1,3));
363 variable_pane.add(variable_label);
364 variable_pane.add(variable_combobox);
365 variable_pane.add(insert_button);
366
367 editor_pane.setLayout(new BorderLayout());
368 editor_pane.add(editor_header_pane, BorderLayout.NORTH);
369 editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER);
370 editor_pane.add(variable_pane, BorderLayout.SOUTH);
371
372 control_pane.setLayout(card_layout);
373 control_pane.add(flag_pane, FLAG);
374 control_pane.add(editor_pane, VALUE);
375 control_pane.add(blank_pane, BLANK);
376
377 button_pane.setLayout(new GridLayout(1,3));
378 button_pane.add(add_button);
379 button_pane.add(replace_button);
380 button_pane.add(remove_button);
381
382 center_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("CDM.FormatManager.Editing_Controls")), BorderFactory.createEmptyBorder(2,2,2,2)));
383 center_pane.setLayout(new BorderLayout());
384 center_pane.add(selection_pane, BorderLayout.NORTH);
385 center_pane.add(control_pane, BorderLayout.CENTER);
386 center_pane.add(button_pane, BorderLayout.SOUTH);
387
388 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
389 setLayout(new BorderLayout());
390 add(instructions_pane, BorderLayout.NORTH);
391 add(new JScrollPane(format_list), BorderLayout.CENTER);
392 add(center_pane, BorderLayout.SOUTH);
393 ready = true;
394 }
395
396 public void destroy() {
397 }
398
399 /** Overriden to ensure that the instructions pane is scrolled to the top.
400 */
401 public void gainFocus() {
402 // This is only necessary if the components have been realized
403 if(ready) {
404 formats_changed = false;
405 model.refresh();
406 feature_model = buildFeatureModel();
407 // Remember the current selection
408 Object selected_object = feature_combobox.getSelectedItem();
409 feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray()));
410 // Now restore the selected object as best as possible
411 feature_combobox.setSelectedItem(selected_object);
412 selected_object = null;
413 if(instructions_textarea != null) {
414 instructions_textarea.setCaretPosition(0);
415 }
416 }
417 }
418
419 public void loseFocus() {
420 // Force all of the Formats to update their names with the correct values.
421 int size = model.getSize();
422 for(int i = 0; i < size; i++) {
423 Format format = (Format) model.getElementAt(i);
424 format.update();
425 format = null;
426 }
427 }
428
429 /** Listens for clicks on the add button, and if the relevant details are provided adds a new format. Note that formats are responsible for codecing the values into something that can be a) stored in a DOM and b) written to file */
430 private class AddListener
431 implements ActionListener {
432 public void actionPerformed(ActionEvent event) {
433 ignore_event = true; // Prevent format_list excetera propagating events
434 Entry entry = (Entry)feature_combobox.getSelectedItem();
435 Object f = entry.getFeature();
436 String p = (String)part_combobox.getSelectedItem();
437 Format format = null;
438 if(view_type.equals(FLAG)) {
439 format = new Format(f, p, enabled_checkbox.isSelected());
440 }
441 else {
442 format = new Format(f, p, editor_textarea.getText());
443 }
444 addFormat(format);
445 add_button.setEnabled(false);
446 replace_button.setEnabled(false);
447 remove_button.setEnabled(true);
448 // Update list selection
449 format_list.setSelectedValue(format, true);
450 format = null;
451 p = null;
452 f = null;
453 entry = null;
454 ignore_event = false;
455 }
456 }
457
458 private class EditorListener
459 implements DocumentListener {
460
461 public void changedUpdate(DocumentEvent e) {
462 update();
463 }
464
465 public void insertUpdate(DocumentEvent e) {
466 update();
467 }
468
469 public void removeUpdate(DocumentEvent e) {
470 update();
471 }
472
473 public void update() {
474 // Determine if replace should be enabled
475 if(!format_list.isSelectionEmpty()) {
476 Format format = (Format)format_list.getSelectedValue();
477 replace_button.setEnabled(!format.isParamType() && editor_textarea.getText() != format.getValue());
478 }
479 else {
480 replace_button.setEnabled(false);
481 }
482 }
483 }
484
485 private class EnabledListener
486 implements ActionListener {
487
488 public void actionPerformed(ActionEvent event) {
489 // If there is a current format selected, and the value of enable_checkbox is now different than to value in it, then enable to replace button.
490 if(!format_list.isSelectionEmpty()) {
491 Format format = (Format)format_list.getSelectedValue();
492 replace_button.setEnabled(format.isParamType() && enabled_checkbox.isSelected() != format.getState());
493 }
494 // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed.
495 }
496 }
497
498 private class FeatureListener
499 implements ActionListener {
500 public void actionPerformed(ActionEvent event) {
501 if(!ignore_event) {
502 ignore_event = true;
503 // Step one: reset part
504 part_combobox.setSelectedIndex(0);
505 // Step two: the rest
506 Entry entry = (Entry) feature_combobox.getSelectedItem();
507 String name = entry.toString();
508 if(Format.isParamType(name)) {
509 // Flags first.
510 selection_pane.remove(part_pane);
511 card_layout.show(control_pane, FLAG);
512 view_type = FLAG;
513 }
514 else {
515 selection_pane.add(part_pane);
516 card_layout.show(control_pane, VALUE);
517 view_type = VALUE;
518 }
519 control_pane.updateUI();
520 // Add is only enabled if there isn't already a format for the choosen feature and part. Create a dummy format and test if itsa already in the model
521 Object f = entry.getFeature();
522 String p = (String)part_combobox.getSelectedItem();
523 // You can never add anything to blank-blank
524 if(f.toString().length() == 0 && p.length() == 0) {
525 add_button.setEnabled(false);
526 replace_button.setEnabled(false);
527 remove_button.setEnabled(false);
528 }
529 else {
530 name = Format.generateName(f, p);
531 Format format = getFormat(name);
532 // If there is an existing feature, select it.
533 if(format != null) {
534 format_list.setSelectedValue(format, true);
535 // Now use type to determine what controls are visible, and what have initial values.
536 if(format.isParamType()) {
537 // Flags first.
538 selection_pane.remove(part_pane);
539 card_layout.show(control_pane, FLAG);
540 view_type = FLAG;
541 // Initial value
542 enabled_checkbox.setSelected(format.getState());
543 }
544 else {
545 selection_pane.add(part_pane);
546 card_layout.show(control_pane, VALUE);
547 view_type = VALUE;
548 // Initial value
549 editor_textarea.setText(format.getValue());
550 }
551 control_pane.updateUI();
552 remove_button.setEnabled(true);
553 }
554 else {
555 format_list.clearSelection();
556 if(Format.isParamType(name)) {
557 // Flags first.
558 selection_pane.remove(part_pane);
559 card_layout.show(control_pane, FLAG);
560 view_type = FLAG;
561 // Initial value
562 enabled_checkbox.setSelected(false);
563 }
564 else {
565 selection_pane.add(part_pane);
566 card_layout.show(control_pane, VALUE);
567 view_type = VALUE;
568 // Initial value
569 editor_textarea.setText("");
570 }
571 add_button.setEnabled(true);
572 }
573 format = null;
574 name = null;
575 }
576 p = null;
577 f = null;
578 replace_button.setEnabled(false);
579 name = null;
580 entry = null;
581 ignore_event = false;
582 }
583 }
584 }
585
586 private class FormatListListener
587 implements ListSelectionListener {
588 public void valueChanged(ListSelectionEvent event) {
589 if(!ignore_event) {
590 if(!format_list.isSelectionEmpty()) {
591 ignore_event = true;
592 Format format = (Format)format_list.getSelectedValue();
593 // Try to match the target, remembering the entries within are Entry's
594 Entry an_entry = new Entry(format.getFeature());
595 feature_combobox.setSelectedItem(an_entry);
596 // If we didn't match anything, add it and select it again
597 Entry result_entry = (Entry) feature_combobox.getSelectedItem();
598 if(!an_entry.equals(result_entry)) {
599 feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount());
600 feature_combobox.setSelectedItem(an_entry);
601 }
602
603 if(format.canHavePart()) {
604 part_combobox.setEnabled(true);
605 // Try to match the part.
606 String part_entry = format.getPart();
607 part_combobox.setSelectedItem(part_entry);
608 // If we didn't match anything, add it and select it again
609 String selected_part = (String)part_combobox.getSelectedItem();
610 if(!part_entry.equals(selected_part)) {
611 part_combobox.insertItemAt(part_entry, part_combobox.getItemCount());
612 part_combobox.setSelectedItem(part_entry);
613 }
614 }
615 else {
616 part_combobox.setEnabled(false);
617 }
618 // Now use type to determine what controls are visible, and what have initial values.
619 if(format.isParamType()) {
620 // Flags first.
621 selection_pane.remove(part_pane);
622 card_layout.show(control_pane, FLAG);
623 view_type = FLAG;
624 // Initial value
625 enabled_checkbox.setSelected(format.getState());
626 }
627 else {
628 selection_pane.add(part_pane);
629 card_layout.show(control_pane, VALUE);
630 view_type = VALUE;
631 // Initial value
632 editor_textarea.setText(format.getValue());
633 }
634 control_pane.updateUI();
635 remove_button.setEnabled(true);
636 ignore_event = false;
637 }
638 else {
639 remove_button.setEnabled(false);
640 }
641 add_button.setEnabled(false);
642 replace_button.setEnabled(false);
643 }
644 }
645 }
646
647 private class InsertListener
648 implements ActionListener {
649 public void actionPerformed(ActionEvent event) {
650 editor_textarea.insert((String)variable_combobox.getSelectedItem(), editor_textarea.getCaretPosition());
651 }
652 }
653
654 private class PartListener
655 implements ActionListener {
656 public void actionPerformed(ActionEvent event) {
657 if(!ignore_event) {
658 // Add is only enabled if there isn't already a format for the choosen feature and part. Create a dummy format and test if itsa already in the model
659 Entry entry = (Entry) feature_combobox.getSelectedItem();
660 Object f = entry.getFeature();
661 String p = (String)part_combobox.getSelectedItem();
662 // You can never add anything to blank-blank
663 if(f.toString().length() == 0 && p.length() == 0) {
664 add_button.setEnabled(false);
665 replace_button.setEnabled(false);
666 remove_button.setEnabled(false);
667 }
668 else {
669 String name = Format.generateName(f, p);
670 Format format = getFormat(name);
671 // If there is an existing feature, select it.
672 if(format != null) {
673 format_list.setSelectedValue(format, true);
674 // Now use type to determine what controls are visible, and what have initial values.
675 if(format.isParamType()) {
676 // Flags first.
677 selection_pane.remove(part_pane);
678 card_layout.show(control_pane, FLAG);
679 view_type = FLAG;
680 // Initial value
681 enabled_checkbox.setSelected(format.getState());
682 }
683 else {
684 selection_pane.add(part_pane);
685 card_layout.show(control_pane, VALUE);
686 view_type = VALUE;
687 // Initial value
688 editor_textarea.setText(format.getValue());
689 }
690 control_pane.updateUI();
691 remove_button.setEnabled(true);
692 }
693 else {
694 format_list.clearSelection();
695 if(Format.isParamType(name)) {
696 // Flags first.
697 selection_pane.remove(part_pane);
698 card_layout.show(control_pane, FLAG);
699 view_type = FLAG;
700 // Initial value
701 enabled_checkbox.setSelected(false);
702 }
703 else {
704 selection_pane.add(part_pane);
705 card_layout.show(control_pane, VALUE);
706 view_type = VALUE;
707 // Initial value
708 editor_textarea.setText("");
709 }
710 add_button.setEnabled(true);
711 }
712 format = null;
713 name = null;
714 }
715 p = null;
716 f = null;
717 entry = null;
718 replace_button.setEnabled(false);
719 }
720 }
721 }
722
723 private class RemoveListener
724 implements ActionListener {
725 public void actionPerformed(ActionEvent event) {
726 if(!format_list.isSelectionEmpty()) {
727 removeFormat((Format)format_list.getSelectedValue());
728 // Change buttons
729 add_button.setEnabled(true);
730 replace_button.setEnabled(false);
731 }
732 remove_button.setEnabled(false);
733 }
734 }
735
736 private class ReplaceListener
737 implements ActionListener {
738
739 public void actionPerformed(ActionEvent event) {
740 ignore_event = true; // Prevent format_list excetera propagating events
741
742 if(!format_list.isSelectionEmpty()) {
743
744 // Remove the current format
745 removeFormat((Format)format_list.getSelectedValue());
746
747 Entry entry = (Entry)feature_combobox.getSelectedItem();
748 Object f = entry.getFeature();
749 String p = (String)part_combobox.getSelectedItem();
750 Format format = null;
751 if(view_type.equals(FLAG)) {
752 format = new Format(f, p, enabled_checkbox.isSelected());
753 }
754 else {
755 format = new Format(f, p, editor_textarea.getText());
756 }
757 addFormat(format);
758 add_button.setEnabled(false);
759 remove_button.setEnabled(true);
760 // Update list selection
761 format_list.setSelectedValue(format, true);
762 format = null;
763 p = null;
764 f = null;
765 entry = null;
766 }
767 replace_button.setEnabled(false);
768 ignore_event = false;
769 }
770 }
771 }
772
773 /** This object provides a wrapping around an entry in the format target control, which is tranparent as to whether it is backed by a String or a Classifier. */
774 private class Entry
775 implements Comparable {
776 private Classifier classifier = null;
777 private String text = null;
778
779 public Entry(Object object) {
780 if(object instanceof Classifier) {
781 classifier = (Classifier)object;
782 }
783 else if(object instanceof String) {
784 text = (String)object;
785 }
786 else {
787 text = "";
788 }
789 }
790
791 public Entry(String text) {
792 this.text = text;
793 }
794
795 public int compareTo(Object object) {
796 if(object == null) {
797 return 1;
798 }
799 if(toString() == null) {
800 return -1;
801 }
802 else {
803 String object_str = object.toString();
804 if(object_str == null) {
805 return 1;
806 }
807 return toString().compareTo(object_str);
808 }
809 }
810
811 public boolean equals(Object object) {
812 if(compareTo(object) == 0) {
813 return true;
814 }
815 return false;
816 }
817
818 public Classifier getClassifier() {
819 return classifier;
820 }
821
822 public Object getFeature() {
823 if(classifier != null) {
824 return classifier;
825 }
826 return text;
827 }
828
829 public String toString() {
830 if(classifier != null) {
831 // Return the classifier - less the 'classify ' prefix
832 return classifier.toString().substring(9);
833 }
834 return text;
835 }
836 }
837}
Note: See TracBrowser for help on using the repository browser.