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

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

Fix 203B017. Completely rewrote format manager view so that it used the consistant add/replace/remove buttons rather than the confusing live idea. Also added code to release/reload collections within the Greenstone local library server - thus changes to the format commands are viewable without having to restart GLI.

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