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

Last change on this file since 6540 was 6539, checked in by jmt12, 20 years ago

Heres a bunch of other changed files. If it wasn't a Friday afternoon I might be bothered finding out what I actually changed in them. Such changes include: a new option or three on preferences, a bug fix for the GDM classes, several changes to CDM to allow for G2.39 configuration files, a fix to Codec to allow for quotes in format strings and more work on CommandTokenizer to allow for stupid, stupid, stupid collectionextra's starting with speech marks then a new line. Plus other stuff. And things. Peace Out.

  • Property svn:keywords set to Author Date Id Revision
File size: 33.5 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * 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.gui.GLIButton;
50import org.greenstone.gatherer.msm.ElementWrapper;
51import org.greenstone.gatherer.util.StaticStrings;
52import org.greenstone.gatherer.util.Utility;
53import org.w3c.dom.*;
54
55/** This class maintains a list of format statements, and allows the addition and removal of these statements.
56 * @author John Thompson, Greenstone Digital Library, University of Waikato
57 * @version 2.3
58 */
59public class FormatManager
60 extends DOMProxyListModel {
61
62 static final private String BLANK = "blank";
63 static final private String FLAG = "flag";
64 static final private String VALUE = "value";
65
66 /** 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. */
67 private boolean formats_changed = false;
68 /** The controls used to edit the format commands. */
69 private Control controls = null;
70 /** A reference to ourselves so inner classes can get at the model. */
71 private DOMProxyListModel model = null;
72
73 /** Constructor. */
74 public FormatManager() {
75 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.FORMAT_ELEMENT, new Format());
76 this.model = this;
77 Gatherer.println("FormatManager: parsed " + getSize() + " format statements.");
78 // 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.
79 int size = getSize();
80 for(int i = 0; i < size; i++) {
81 getElementAt(i);
82 }
83
84 // Ensure the default formats for DateList, HList and VList are assigned
85 if(getFormat("DateList") == null) {
86 addFormat(new Format("","DateList","<td>[link][icon][/link]</td><td>[highlight]{Or}{[dls.Title],[dc.Title],[Title],Untitled}[/highlight]</td><td>[Date]</td>"));
87 }
88
89 if(getFormat("HList") == null) {
90 addFormat(new Format("","HList","[link][highlight]{Or}{[dls.Title],[dc.Title],[Title],Untitled}[/highlight][/link]"));
91 }
92
93 if(getFormat("VList") == null) {
94 addFormat(new Format("","VList","<td valign=top>[link][icon][/link]</td><td valign=top>[srclink]{Or}{[thumbicon],[srcicon]}[/srclink]</td><td valign=top>[highlight]{Or}{[dls.Title],[dc.Title],[Title],Untitled}[/highlight]{If}{[Source],<br><i>([Source])</i>}</td>"));
95 }
96 }
97
98 /** Method to add a new format to this manager.
99 * @param format The <strong>Format</strong> to add.
100 */
101 public void addFormat(Format format) {
102 if(!contains(format)) {
103 Element element = format.getElement();
104 // Locate where we should insert this new classifier.
105 Node target_node = CollectionConfiguration.findInsertionPoint(element);
106 add(root, format, target_node);
107 Gatherer.c_man.configurationChanged();
108 formats_changed = true;
109 }
110 }
111
112 public void destroy() {
113 if(controls != null) {
114 controls.destroy();
115 controls = null;
116 }
117 }
118
119 /** Have the formats changed since the last save. */
120 public boolean formatsChanged() {
121 return formats_changed;
122 }
123
124 /** Gets the format indicated by the index.
125 * @param index The location of the desired format, as an <i>int</i>.
126 */
127 public Format getFormat(int index) {
128 Format result = null;
129 if(0 < index && index < getSize()) {
130 result = (Format) getElementAt(index);
131 }
132 return result;
133 }
134
135 public Format getFormat(String name) {
136 int model_size = getSize();
137 for(int index = 0; index < model_size; index++) {
138 Format format = (Format) getElementAt(index);
139 if(format.getName().equals(name)) {
140 return format;
141 }
142 }
143 return null;
144 }
145
146 /** Method to retrieve this managers controls.
147 * @return the Control for this collection.
148 */
149 public Control getControls() {
150 if(controls == null) {
151 controls = new FormatControl();
152 }
153 return controls;
154 }
155
156 /** Method to remove a format.
157 * @param format The <strong>Format</strong> to remove.
158 */
159 public void removeFormat(Format format) {
160 remove(format);
161 Gatherer.c_man.configurationChanged();
162 formats_changed = true;
163 }
164
165 /** Set the state of the formats changed flag.
166 * @param state the new state as a boolean
167 */
168 public void setFormatsChanged(boolean state) {
169 formats_changed = state;
170 }
171
172 private HashMap buildDefaultMappings(ArrayList features_model, ArrayList parts_model) {
173 Gatherer.println("buildDefaultMappings(): replace me with something that reads in a data xml file.");
174 return new HashMap();
175 }
176
177 private ArrayList buildFeatureModel() {
178 // Rebuild feature model.
179 ArrayList feature_model = new ArrayList();
180 // Add the set options
181 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) {
182 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i]));
183 }
184 // Now the classifiers.
185 for(int j = 0; j < CollectionDesignManager.classifier_manager.getSize(); j++) {
186 feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j)));
187 }
188 Collections.sort(feature_model);
189 return feature_model;
190 }
191
192 private ArrayList buildPartModel() {
193 Gatherer.println("buildPartModel(): replace me with something that reads in a data xml file.");
194 ArrayList part_model = new ArrayList();
195 part_model.add(new Part("", ""));
196 part_model.add(new Part("DateList", "<td>[link][icon][/link]</td><td>[highlight]{Or}{[Title],Untitled}[/highlight]</td><td>[Date]</td>"));
197 part_model.add(new Part("HList", "[link][highlight][Title][/highlight][/link]"));
198 part_model.add(new Part("Invisible", ""));
199 part_model.add(new Part("VList", "<td valign=top>[link][icon][/link]</td><td valign=top>[srclink]{Or}{[thumbicon],[srcicon]}[/srclink]</td><td valign=top>[highlight]{Or}{[Title],[dc.Title],[dls.Title],Untitled}[/highlight]{If}{[Source],<br><i>([Source])</i>}</td>"));
200 return part_model;
201 }
202
203 private ArrayList buildVariableModel() {
204 Gatherer.println("buildVariableModel(): replace me with something that reads in a data xml file.");
205 ArrayList variable_model = new ArrayList();
206 variable_model.add("[Text]");
207 variable_model.add("[link]");
208 variable_model.add("[/link]");
209 variable_model.add("[icon]");
210 variable_model.add("[num]");
211 variable_model.add("[parent():_]");
212 variable_model.add("[parent(Top):_]");
213 variable_model.add("[parent(All'_'):_]");
214 Vector elements = Gatherer.c_man.getCollection().msm.getAssignedElements();
215 for(int i = 0; i < elements.size(); i++) {
216 variable_model.add("[" + ((ElementWrapper)elements.get(i)).getName() + "]");
217 }
218 Collections.sort(variable_model);
219 return variable_model;
220 }
221
222 private class FormatControl
223 extends JPanel
224 implements Control {
225
226 private ArrayList feature_model;
227 private ArrayList part_model;
228 private ArrayList variable_model;
229 private boolean ignore_event = false;
230 private boolean ready = false; // Are these controls available to be refreshed
231 private CardLayout card_layout;
232 private HashMap default_mappings;
233 private JButton add_button;
234 //private JButton default_button;
235 private JButton insert_button;
236 private JButton remove_button;
237 private JButton replace_button;
238 private JCheckBox enabled_checkbox;
239 private JComboBox feature_combobox;
240 private JComboBox part_combobox;
241 private JComboBox variable_combobox;
242 private JList format_list;
243 private JTextArea instructions_textarea;
244 private JTextArea editor_textarea;
245 private JPanel blank_pane;
246 private JPanel control_pane;
247 private JPanel part_pane;
248 private JPanel selection_pane;
249 private String view_type;
250
251 public FormatControl() {
252 feature_model = buildFeatureModel();
253 part_model = buildPartModel();
254 variable_model = buildVariableModel();
255 default_mappings = buildDefaultMappings(feature_model, part_model);
256
257 // Create
258 JPanel instructions_pane = new JPanel();
259 JLabel title_label = new JLabel();
260 title_label.setHorizontalAlignment(JLabel.CENTER);
261 title_label.setOpaque(true);
262 Dictionary.registerText(title_label, "CDM.FormatManager.Title");
263
264 instructions_textarea = new JTextArea();
265 instructions_textarea.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
266 instructions_textarea.setEditable(false);
267 instructions_textarea.setLineWrap(true);
268 instructions_textarea.setRows(6);
269 instructions_textarea.setWrapStyleWord(true);
270 Dictionary.registerText(instructions_textarea, "CDM.FormatManager.Instructions");
271
272 JLabel format_label = new JLabel();
273 Dictionary.registerText(format_label, "CDM.FormatManager.Assigned_Formats");
274 format_list = new JList(model);
275
276 selection_pane = new JPanel();
277 JPanel feature_pane = new JPanel();
278 JLabel feature_label = new JLabel();
279 feature_label.setPreferredSize(Utility.LABEL_SIZE);
280 Dictionary.registerText(feature_label, "CDM.FormatManager.Feature");
281 feature_combobox = new JComboBox(feature_model.toArray());
282 feature_combobox.setEditable(false);
283 Dictionary.registerTooltip(feature_combobox, "CDM.FormatManager.Feature_Tooltip");
284
285 part_pane = new JPanel();
286 JLabel part_label = new JLabel();
287 part_label.setPreferredSize(Utility.LABEL_SIZE);
288 Dictionary.registerText(part_label, "CDM.FormatManager.Part");
289
290 part_combobox = new JComboBox(part_model.toArray());
291 part_combobox.setEditable(false);
292 Dictionary.registerTooltip(part_combobox, "CDM.FormatManager.Part_Tooltip");
293
294 blank_pane = new JPanel();
295
296 JPanel center_pane = new JPanel();
297
298 card_layout = new CardLayout();
299 control_pane = new JPanel();
300
301 JPanel blank_pane = new JPanel();
302
303 JPanel editor_pane = new JPanel();
304 JPanel editor_header_pane = new JPanel();
305 JLabel editor_label = new JLabel();
306 Dictionary.registerText(editor_label, "CDM.FormatManager.Editor");
307
308 //default_button = new GLIButton();
309 //default_button.setEnabled(false);
310 //default_button.setMnemonic(KeyEvent.VK_D);
311 //Dictionary.registerBoth(default_button, "CDM.FormatManager.Default_Format", "CDM.FormatManager.Default_Format_Tooltip");
312
313 editor_textarea = new JTextArea();
314 editor_textarea.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
315 editor_textarea.setCaretPosition(0);
316 editor_textarea.setLineWrap(true);
317 editor_textarea.setRows(6);
318 editor_textarea.setWrapStyleWord(false);
319 Dictionary.registerTooltip(editor_textarea, "CDM.FormatManager.Editor_Tooltip");
320
321 JPanel variable_pane = new JPanel();
322 JLabel variable_label = new JLabel();
323 Dictionary.registerText(variable_label, "CDM.FormatManager.Variable");
324 variable_combobox = new JComboBox(variable_model.toArray());
325 Dictionary.registerTooltip(variable_combobox, "CDM.FormatManager.Variable_Tooltip");
326
327 insert_button = new GLIButton();
328 insert_button.setMnemonic(KeyEvent.VK_I);
329 Dictionary.registerBoth(insert_button, "CDM.FormatManager.Insert", "CDM.FormatManager.Insert_Tooltip");
330
331 JPanel flag_pane = new JPanel();
332 enabled_checkbox = new JCheckBox();
333 Dictionary.registerText(enabled_checkbox, "CDM.FormatManager.Enabled");
334
335 JPanel button_pane = new JPanel();
336 add_button = new GLIButton();
337 add_button.setEnabled(false);
338 add_button.setMnemonic(KeyEvent.VK_A);
339 Dictionary.registerBoth(add_button, "CDM.FormatManager.Add", "CDM.FormatManager.Add_Tooltip");
340 replace_button = new GLIButton();
341 replace_button.setEnabled(false);
342 replace_button.setMnemonic(KeyEvent.VK_C);
343 Dictionary.registerBoth(replace_button, "CDM.FormatManager.Replace", "CDM.FormatManager.Replace_Tooltip");
344 remove_button = new GLIButton();
345 remove_button.setEnabled(false);
346 remove_button.setMnemonic(KeyEvent.VK_R);
347 Dictionary.registerBoth(remove_button, "CDM.FormatManager.Remove", "CDM.FormatManager.Remove_Tooltip");
348
349 // Connect
350 add_button.addActionListener(new AddListener());
351 insert_button.addActionListener(new InsertListener());
352 remove_button.addActionListener(new RemoveListener());
353 replace_button.addActionListener(new ReplaceListener());
354 enabled_checkbox.addActionListener(new EnabledListener());
355 feature_combobox.addActionListener(new FeatureListener());
356 part_combobox.addActionListener(new PartListener());
357 editor_textarea.getDocument().addDocumentListener(new EditorListener());
358 format_list.addListSelectionListener(new FormatListListener());
359
360 // Layout
361 instructions_pane.setLayout(new BorderLayout());
362 instructions_pane.add(title_label, BorderLayout.NORTH);
363 instructions_pane.add(new JScrollPane(instructions_textarea), BorderLayout.CENTER);
364 instructions_pane.add(format_label, BorderLayout.SOUTH);
365
366 feature_pane.setLayout(new BorderLayout());
367 feature_pane.add(feature_label, BorderLayout.WEST);
368 feature_pane.add(feature_combobox, BorderLayout.CENTER);
369
370 part_pane.setLayout(new BorderLayout());
371 part_pane.add(part_label, BorderLayout.WEST);
372 part_pane.add(part_combobox, BorderLayout.CENTER);
373
374 //selection_pane.setLayout(new GridLayout(2,1,0,2));
375 //selection_pane.add(feature_pane);
376 //selection_pane.add(part_pane);
377
378 flag_pane.add(enabled_checkbox);
379
380 editor_header_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
381 editor_header_pane.setLayout(new GridLayout(1,3));
382 editor_header_pane.add(editor_label);
383
384 variable_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
385 variable_pane.setLayout(new GridLayout(1,3));
386 variable_pane.add(variable_label);
387 variable_pane.add(variable_combobox);
388 variable_pane.add(insert_button);
389
390 editor_pane.setLayout(new BorderLayout());
391 editor_pane.add(editor_header_pane, BorderLayout.NORTH);
392 editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER);
393 //editor_pane.add(variable_pane, BorderLayout.SOUTH);
394
395 selection_pane.setLayout(new BorderLayout());
396 selection_pane.add(part_pane, BorderLayout.NORTH);
397 selection_pane.add(editor_pane, BorderLayout.CENTER);
398 selection_pane.add(variable_pane, BorderLayout.SOUTH);
399
400 control_pane.setLayout(card_layout);
401 control_pane.add(flag_pane, FLAG);
402 control_pane.add(selection_pane, VALUE);
403 control_pane.add(blank_pane, BLANK);
404
405 button_pane.setLayout(new GridLayout(1,3));
406 button_pane.add(add_button);
407 button_pane.add(replace_button);
408 button_pane.add(remove_button);
409
410 center_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("CDM.FormatManager.Editing_Controls")), BorderFactory.createEmptyBorder(2,2,2,2)));
411 center_pane.setLayout(new BorderLayout());
412 center_pane.add(feature_pane, BorderLayout.NORTH);
413 center_pane.add(control_pane, BorderLayout.CENTER);
414 center_pane.add(button_pane, BorderLayout.SOUTH);
415
416 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
417 setLayout(new BorderLayout());
418 add(instructions_pane, BorderLayout.NORTH);
419 add(new JScrollPane(format_list), BorderLayout.CENTER);
420 add(center_pane, BorderLayout.SOUTH);
421 ready = true;
422 }
423
424 public void destroy() {
425 }
426
427 /** Overriden to ensure that the instructions pane is scrolled to the top.
428 */
429 public void gainFocus() {
430 // This is only necessary if the components have been realized
431 if(ready) {
432 formats_changed = false;
433 model.refresh();
434 feature_model = buildFeatureModel();
435 // Remember the current selection
436 Object selected_object = feature_combobox.getSelectedItem();
437 feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray()));
438 // Now restore the selected object as best as possible
439 feature_combobox.setSelectedItem(selected_object);
440 selected_object = null;
441 if(instructions_textarea != null) {
442 instructions_textarea.setCaretPosition(0);
443 }
444 }
445 }
446
447 public void loseFocus() {
448 // Force all of the Formats to update their names with the correct values.
449 int size = model.getSize();
450 for(int i = 0; i < size; i++) {
451 Format format = (Format) model.getElementAt(i);
452 format.update();
453 format = null;
454 }
455 }
456
457 /** 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 */
458 private class AddListener
459 implements ActionListener {
460 public void actionPerformed(ActionEvent event) {
461 ignore_event = true; // Prevent format_list excetera propagating events
462 Entry entry = (Entry)feature_combobox.getSelectedItem();
463 Object f = entry.getFeature();
464 String p = part_combobox.getSelectedItem().toString();
465 Format format = null;
466 if(view_type.equals(FLAG)) {
467 format = new Format(f, p, enabled_checkbox.isSelected());
468 }
469 else {
470 format = new Format(f, p, editor_textarea.getText());
471 }
472 addFormat(format);
473 add_button.setEnabled(false);
474 replace_button.setEnabled(false);
475 remove_button.setEnabled(true);
476 // Update list selection
477 format_list.setSelectedValue(format, true);
478 format = null;
479 p = null;
480 f = null;
481 entry = null;
482 ignore_event = false;
483 }
484 }
485
486 private class EditorListener
487 implements DocumentListener {
488
489 public void changedUpdate(DocumentEvent e) {
490 update();
491 }
492
493 public void insertUpdate(DocumentEvent e) {
494 update();
495 }
496
497 public void removeUpdate(DocumentEvent e) {
498 update();
499 }
500
501 public void update() {
502 // Determine if replace should be enabled
503 if(!format_list.isSelectionEmpty()) {
504 Format format = (Format)format_list.getSelectedValue();
505 replace_button.setEnabled(!format.isParamType() && editor_textarea.getText() != format.getValue());
506 }
507 else {
508 replace_button.setEnabled(false);
509 }
510 }
511 }
512
513 private class EnabledListener
514 implements ActionListener {
515
516 public void actionPerformed(ActionEvent event) {
517 // 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.
518 if(!format_list.isSelectionEmpty()) {
519 Format format = (Format)format_list.getSelectedValue();
520 replace_button.setEnabled(format.isParamType() && enabled_checkbox.isSelected() != format.getState());
521 }
522 // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed.
523 }
524 }
525
526 private class FeatureListener
527 implements ActionListener {
528 public void actionPerformed(ActionEvent event) {
529 if(!ignore_event) {
530 ignore_event = true;
531 // Step one: reset part
532 part_combobox.setSelectedIndex(4);
533 // Step two: the rest
534 Entry entry = (Entry) feature_combobox.getSelectedItem();
535 String name = entry.toString();
536 // 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
537 Object f = entry.getFeature();
538 Part part = (Part)part_combobox.getSelectedItem();
539 String pname = part.getName();
540 // You can never add anything to blank-blank
541 if(f.toString().length() == 0 && pname.length() == 0) {
542 add_button.setEnabled(false);
543 replace_button.setEnabled(false);
544 remove_button.setEnabled(false);
545 }
546 else {
547 Format format = getFormat(Format.generateName(f, pname));
548 // If there is an existing feature, select it, and use it to determine what controls are visible
549 if(format != null) {
550 ///ystem.err.println("There is an existing format!");
551 format_list.setSelectedValue(format, true);
552 // Now use type to determine what controls are visible, and what have initial values.
553 if(format.isParamType()) {
554 ///ystem.err.println("Flag type");
555 // Flags first.
556 ///election_pane.remove(part_pane);
557 card_layout.show(control_pane, FLAG);
558 view_type = FLAG;
559 // Initial value
560 enabled_checkbox.setSelected(format.getState());
561 }
562 else {
563 ///ystem.err.println("Value type");
564 ///election_pane.add(part_pane);
565 card_layout.show(control_pane, VALUE);
566 view_type = VALUE;
567 // Initial value
568 editor_textarea.setText(format.getValue());
569 }
570 control_pane.updateUI();
571 remove_button.setEnabled(true);
572 }
573 // Otherwise there is no existing format, so we proceed by checking against the feature name
574 else {
575 ///ystem.err.println("No existing format");
576 format_list.clearSelection();
577 if(Format.isParamType(name)) {
578 ///ystem.err.println("Flag type");
579 // Flags first.
580 ///election_pane.remove(part_pane);
581 card_layout.show(control_pane, FLAG);
582 view_type = FLAG;
583 // Initial value
584 enabled_checkbox.setSelected(false);
585 }
586 else {
587 ///ystem.err.println("Value type");
588 ///election_pane.add(part_pane);
589 card_layout.show(control_pane, VALUE);
590 view_type = VALUE;
591 // Initial value
592 editor_textarea.setText(part.getDefaultFormat());
593 }
594 add_button.setEnabled(true);
595 }
596 format = null;
597 name = null;
598 }
599 part = null;
600 pname = null;
601 f = null;
602 replace_button.setEnabled(false);
603 name = null;
604 entry = null;
605 ignore_event = false;
606 }
607 }
608 }
609
610 private class FormatListListener
611 implements ListSelectionListener {
612 public void valueChanged(ListSelectionEvent event) {
613 if(!ignore_event && !event.getValueIsAdjusting()) {
614 if(!format_list.isSelectionEmpty()) {
615 ignore_event = true;
616 Format format = (Format)format_list.getSelectedValue();
617 // Try to match the target, remembering the entries within are Entry's
618 Entry an_entry = new Entry(format.getFeature());
619 feature_combobox.setSelectedItem(an_entry);
620 // If we didn't match anything, add it and select it again
621 Entry result_entry = (Entry) feature_combobox.getSelectedItem();
622 if(!an_entry.equals(result_entry)) {
623 feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount());
624 feature_combobox.setSelectedItem(an_entry);
625 }
626
627 // Now use type to determine what controls are visible, and what have initial values.
628 ///ystem.err.println("Determine the correct type.");
629 if(format.isParamType()) {
630 ///ystem.err.println("Flag type - remove part");
631 // Flags first.
632 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, false));
633 card_layout.show(control_pane, FLAG);
634 view_type = FLAG;
635 // Initial value
636 enabled_checkbox.setSelected(format.getState());
637 }
638 else {
639 ///ystem.err.println("Value type - show part");
640 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, true));
641 card_layout.show(control_pane, VALUE);
642 view_type = VALUE;
643 // Initial values
644
645 // Try to match the part.
646 String part_entry = format.getPart();
647 // Set Selected Item doesn't work so I'll do this manually
648 boolean found = false;
649 for(int i=0; i < part_combobox.getItemCount(); i++) {
650 Part a_part = (Part) part_combobox.getItemAt(i);
651 if(a_part.equals(part_entry)) {
652 part_combobox.setSelectedItem(a_part);
653 found = true;
654 }
655 a_part = null;
656 }
657 // If we didn't match anything, add it and select it again
658 if(!found) {
659 Part a_part = new Part(part_entry, "");
660 part_combobox.insertItemAt(a_part, part_combobox.getItemCount());
661 part_combobox.setSelectedItem(a_part);
662 }
663
664 editor_textarea.setText(format.getValue());
665 }
666 //control_pane.updateUI();
667 remove_button.setEnabled(true);
668 ignore_event = false;
669 }
670 else {
671 remove_button.setEnabled(false);
672 }
673 add_button.setEnabled(false);
674 replace_button.setEnabled(false);
675 }
676 }
677 }
678
679 private class InsertListener
680 implements ActionListener {
681 public void actionPerformed(ActionEvent event) {
682 editor_textarea.insert((String)variable_combobox.getSelectedItem(), editor_textarea.getCaretPosition());
683 }
684 }
685
686 private class PartListener
687 implements ActionListener {
688 public void actionPerformed(ActionEvent event) {
689 if(!ignore_event) {
690 // Add is only enabled if there isn't already a format for the choosen feature and part. Create a dummy format and test if its already in the model
691 Entry entry = (Entry) feature_combobox.getSelectedItem();
692 Object f = entry.getFeature();
693 Part part = (Part) part_combobox.getSelectedItem();
694 String pname = part.getName();
695 // You can never add anything to blank-blank
696 if(f.toString().length() == 0 && pname.length() == 0) {
697 add_button.setEnabled(false);
698 replace_button.setEnabled(false);
699 remove_button.setEnabled(false);
700 }
701 else {
702 String name = Format.generateName(f, pname);
703 Format format = getFormat(name);
704 // If there is an existing feature, select it.
705 if(format != null) {
706 format_list.setSelectedValue(format, true);
707 // Now use type to determine what controls are visible, and what have initial values.
708 if(format.isParamType()) {
709 // Flags first.
710 ///election_pane.remove(part_pane);
711 card_layout.show(control_pane, FLAG);
712 view_type = FLAG;
713 // Initial value
714 enabled_checkbox.setSelected(format.getState());
715 }
716 else {
717 ///election_pane.add(part_pane);
718 card_layout.show(control_pane, VALUE);
719 view_type = VALUE;
720 // Initial value
721 editor_textarea.setText(format.getValue());
722 }
723 control_pane.updateUI();
724 remove_button.setEnabled(true);
725 }
726 else {
727 format_list.clearSelection();
728 if(Format.isParamType(name)) {
729 // Flags first.
730 ///election_pane.remove(part_pane);
731 card_layout.show(control_pane, FLAG);
732 view_type = FLAG;
733 // Initial value
734 enabled_checkbox.setSelected(false);
735 }
736 else {
737 ///election_pane.add(part_pane);
738 card_layout.show(control_pane, VALUE);
739 view_type = VALUE;
740 // Initial value
741 editor_textarea.setText(part.getDefaultFormat());
742 }
743 add_button.setEnabled(true);
744 }
745 format = null;
746 name = null;
747 }
748
749 pname = null;
750 part = null;
751 f = null;
752 entry = null;
753 replace_button.setEnabled(false);
754 }
755 }
756 }
757
758 private class RemoveListener
759 implements ActionListener {
760 public void actionPerformed(ActionEvent event) {
761 if(!format_list.isSelectionEmpty()) {
762 removeFormat((Format)format_list.getSelectedValue());
763 // Change buttons
764 add_button.setEnabled(true);
765 replace_button.setEnabled(false);
766 }
767 remove_button.setEnabled(false);
768 }
769 }
770
771 private class ReplaceListener
772 implements ActionListener {
773
774 public void actionPerformed(ActionEvent event) {
775 ignore_event = true; // Prevent format_list excetera propagating events
776
777 if(!format_list.isSelectionEmpty()) {
778
779 // Remove the current format
780 removeFormat((Format)format_list.getSelectedValue());
781
782 Entry entry = (Entry)feature_combobox.getSelectedItem();
783 Object f = entry.getFeature();
784 String p = part_combobox.getSelectedItem().toString();
785 Format format = null;
786 if(view_type.equals(FLAG)) {
787 format = new Format(f, p, enabled_checkbox.isSelected());
788 }
789 else {
790 format = new Format(f, p, editor_textarea.getText());
791 }
792 addFormat(format);
793 add_button.setEnabled(false);
794 remove_button.setEnabled(true);
795 // Update list selection
796 format_list.setSelectedValue(format, true);
797 format = null;
798 p = null;
799 f = null;
800 entry = null;
801 }
802 replace_button.setEnabled(false);
803 ignore_event = false;
804 }
805 }
806 }
807
808 /** 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. */
809 private class Entry
810 implements Comparable {
811 private Classifier classifier = null;
812 private String text = null;
813
814 public Entry(Object object) {
815 if(object instanceof Classifier) {
816 classifier = (Classifier)object;
817 }
818 else if(object instanceof String) {
819 text = (String)object;
820 }
821 else {
822 text = "";
823 }
824 }
825
826 public Entry(String text) {
827 this.text = text;
828 }
829
830 public int compareTo(Object object) {
831 if(object == null) {
832 return 1;
833 }
834 if(toString() == null) {
835 return -1;
836 }
837 else {
838 String object_str = object.toString();
839 if(object_str == null) {
840 return 1;
841 }
842 return toString().compareTo(object_str);
843 }
844 }
845
846 public boolean equals(Object object) {
847 if(compareTo(object) == 0) {
848 return true;
849 }
850 return false;
851 }
852
853 public Classifier getClassifier() {
854 return classifier;
855 }
856
857 public Object getFeature() {
858 if(classifier != null) {
859 return classifier;
860 }
861 return text;
862 }
863
864 public String toString() {
865 if(classifier != null) {
866 // Return the classifier - less the 'classify ' prefix and with its CL index shown
867 return classifier.getPositionString() + StaticStrings.COLON_CHARACTER + StaticStrings.SPACE_CHARACTER + classifier.toString().substring(9);
868 }
869 return text;
870 }
871 }
872
873 /*
874 private class GUIChangeTask
875 implements Runnable {
876 private boolean to_add;
877 private JPanel child;
878 private JPanel parent;
879 private JPanel replacement;
880
881 public GUIChangeTask(JPanel parent, JPanel child, JPanel replacement, boolean to_add) {
882 this.child = child;
883 this.parent = parent;
884 this.replacement = replacement;
885 this.to_add = to_add;
886 }
887
888 public void run() {
889 if(to_add) {
890 parent.remove(replacement);
891 parent.add(child);
892 parent.updateUI();
893 }
894 else {
895 parent.remove(child);
896 parent.add(replacement);
897 parent.updateUI();
898 }
899 }
900 }
901 */
902
903 /** This class encapsulates all of the information associated with a certain component part of a feature within a html page returned from the receptioninst. */
904 private class Part
905 implements Comparable {
906 /** The default format string for this part */
907 private String default_format = null;
908 /** The name of this part */
909 private String name = null;
910 /** Constructor - must be provided with all of the details of a part as there are no other setter methods.
911 * @param name the name of this part
912 * @param default_format the default format string for this part
913 */
914 public Part(String name, String default_format) {
915 this.default_format = default_format;
916 this.name = name;
917 }
918 /** Compare this part to another object in terms of ordering
919 * @param obj the other Object
920 * @return <0 if the object is before, 0 if equal to, and >0 if the object is after this part
921 */
922 public int compareTo(Object obj) {
923 return name.compareTo(obj.toString());
924 }
925
926 /** Determine if the part is equivelent to some other object
927 * @param obj the other Object
928 * @return true is the two objects are equal
929 */
930 public boolean equals(Object obj) {
931 return name.equals(obj.toString());
932 }
933
934 /** Retrieve the default format string for this part
935 * @return the default format String
936 */
937 public String getDefaultFormat() {
938 // Retrieve the format for the super format - either VList or HList
939 Format default_format_object = getFormat(name);
940 if(default_format_object != null) {
941 return default_format_object.getValue();
942 }
943 else {
944 return this.default_format;
945 }
946 }
947 /** Retrieve the name of this part
948 * @return the name as a String
949 */
950 public String getName() {
951 return name;
952 }
953 /** Produce a string representation of this part, which in this case is simply the name again
954 * @return the name as a String
955 */
956 public String toString() {
957 return name;
958 }
959 }
960}
Note: See TracBrowser for help on using the repository browser.