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

Last change on this file since 7151 was 7151, checked in by kjdon, 20 years ago

fixed some more static label sizes and deleted a lot of commented out stuff

  • Property svn:keywords set to Author Date Id Revision
File size: 33.9 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 private final Dimension FIELD_SIZE = new Dimension(200, 30);
252 public FormatControl() {
253 feature_model = buildFeatureModel();
254 part_model = buildPartModel();
255 variable_model = buildVariableModel();
256 default_mappings = buildDefaultMappings(feature_model, part_model);
257
258 // Create
259 JPanel instructions_pane = new JPanel();
260 JLabel title_label = new JLabel();
261 title_label.setHorizontalAlignment(JLabel.CENTER);
262 title_label.setOpaque(true);
263 Dictionary.registerText(title_label, "CDM.FormatManager.Title");
264
265 instructions_textarea = new JTextArea();
266 instructions_textarea.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
267 instructions_textarea.setEditable(false);
268 instructions_textarea.setLineWrap(true);
269 instructions_textarea.setRows(6);
270 instructions_textarea.setWrapStyleWord(true);
271 Dictionary.registerText(instructions_textarea, "CDM.FormatManager.Instructions");
272
273 JLabel format_label = new JLabel();
274 Dictionary.registerText(format_label, "CDM.FormatManager.Assigned_Formats");
275 format_list = new JList(model);
276
277 selection_pane = new JPanel();
278 JPanel feature_pane = new JPanel();
279 JLabel feature_label = new JLabel();
280 Dictionary.registerText(feature_label, "CDM.FormatManager.Feature");
281 feature_combobox = new JComboBox(feature_model.toArray());
282 feature_combobox.setPreferredSize(FIELD_SIZE);
283 feature_combobox.setEditable(false);
284 Dictionary.registerTooltip(feature_combobox, "CDM.FormatManager.Feature_Tooltip");
285
286 part_pane = new JPanel();
287 JLabel part_label = new JLabel();
288 Dictionary.registerText(part_label, "CDM.FormatManager.Part");
289
290 part_combobox = new JComboBox(part_model.toArray());
291 part_combobox.setPreferredSize(FIELD_SIZE);
292 part_combobox.setEditable(false);
293 Dictionary.registerTooltip(part_combobox, "CDM.FormatManager.Part_Tooltip");
294
295 blank_pane = new JPanel();
296
297 JPanel center_pane = new JPanel();
298
299 card_layout = new CardLayout();
300 control_pane = new JPanel();
301
302 JPanel blank_pane = new JPanel();
303
304 JPanel editor_pane = new JPanel();
305 JPanel editor_header_pane = new JPanel();
306 JLabel editor_label = new JLabel();
307 Dictionary.registerText(editor_label, "CDM.FormatManager.Editor");
308
309 //default_button = new GLIButton();
310 //default_button.setEnabled(false);
311 //default_button.setMnemonic(KeyEvent.VK_D);
312 //Dictionary.registerBoth(default_button, "CDM.FormatManager.Default_Format", "CDM.FormatManager.Default_Format_Tooltip");
313
314 editor_textarea = new JTextArea();
315 editor_textarea.setBackground(Gatherer.config.getColor("coloring.editable_background", false));
316 editor_textarea.setCaretPosition(0);
317 editor_textarea.setLineWrap(true);
318 editor_textarea.setRows(6);
319 editor_textarea.setWrapStyleWord(false);
320 Dictionary.registerTooltip(editor_textarea, "CDM.FormatManager.Editor_Tooltip");
321
322 JPanel variable_pane = new JPanel();
323 JLabel variable_label = new JLabel();
324 Dictionary.registerText(variable_label, "CDM.FormatManager.Variable");
325 variable_combobox = new JComboBox(variable_model.toArray());
326 Dictionary.registerTooltip(variable_combobox, "CDM.FormatManager.Variable_Tooltip");
327
328 insert_button = new GLIButton();
329 insert_button.setMnemonic(KeyEvent.VK_I);
330 Dictionary.registerBoth(insert_button, "CDM.FormatManager.Insert", "CDM.FormatManager.Insert_Tooltip");
331
332 JPanel flag_pane = new JPanel();
333 enabled_checkbox = new JCheckBox();
334 Dictionary.registerText(enabled_checkbox, "CDM.FormatManager.Enabled");
335
336 JPanel button_pane = new JPanel();
337 add_button = new GLIButton();
338 add_button.setEnabled(false);
339 add_button.setMnemonic(KeyEvent.VK_A);
340 Dictionary.registerBoth(add_button, "CDM.FormatManager.Add", "CDM.FormatManager.Add_Tooltip");
341 replace_button = new GLIButton();
342 replace_button.setEnabled(false);
343 replace_button.setMnemonic(KeyEvent.VK_C);
344 Dictionary.registerBoth(replace_button, "CDM.FormatManager.Replace", "CDM.FormatManager.Replace_Tooltip");
345 remove_button = new GLIButton();
346 remove_button.setEnabled(false);
347 remove_button.setMnemonic(KeyEvent.VK_R);
348 Dictionary.registerBoth(remove_button, "CDM.FormatManager.Remove", "CDM.FormatManager.Remove_Tooltip");
349
350 // Connect
351 add_button.addActionListener(new AddListener());
352 insert_button.addActionListener(new InsertListener());
353 remove_button.addActionListener(new RemoveListener());
354 replace_button.addActionListener(new ReplaceListener());
355 enabled_checkbox.addActionListener(new EnabledListener());
356 feature_combobox.addActionListener(new FeatureListener());
357 part_combobox.addActionListener(new PartListener());
358 editor_textarea.getDocument().addDocumentListener(new EditorListener());
359 format_list.addListSelectionListener(new FormatListListener());
360
361 // Layout
362 instructions_pane.setLayout(new BorderLayout());
363 instructions_pane.add(title_label, BorderLayout.NORTH);
364 instructions_pane.add(new JScrollPane(instructions_textarea), BorderLayout.CENTER);
365 instructions_pane.add(format_label, BorderLayout.SOUTH);
366
367 feature_pane.setLayout(new BorderLayout(5,0));
368 feature_pane.add(feature_label, BorderLayout.WEST);
369 feature_pane.add(feature_combobox, BorderLayout.CENTER);
370
371 part_pane.setLayout(new BorderLayout(5, 0));
372 part_pane.add(part_label, BorderLayout.WEST);
373 part_pane.add(part_combobox, BorderLayout.CENTER);
374
375 //selection_pane.setLayout(new GridLayout(2,1,0,2));
376 //selection_pane.add(feature_pane);
377 //selection_pane.add(part_pane);
378
379 flag_pane.add(enabled_checkbox);
380
381 editor_header_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
382 editor_header_pane.setLayout(new GridLayout(1,3));
383 editor_header_pane.add(editor_label);
384
385 variable_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
386 variable_pane.setLayout(new GridLayout(1,3));
387 variable_pane.add(variable_label);
388 variable_pane.add(variable_combobox);
389 variable_pane.add(insert_button);
390
391 editor_pane.setLayout(new BorderLayout());
392 editor_pane.add(editor_header_pane, BorderLayout.NORTH);
393 editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER);
394 //editor_pane.add(variable_pane, BorderLayout.SOUTH);
395
396 selection_pane.setLayout(new BorderLayout());
397 selection_pane.add(part_pane, BorderLayout.NORTH);
398 selection_pane.add(editor_pane, BorderLayout.CENTER);
399 selection_pane.add(variable_pane, BorderLayout.SOUTH);
400
401 control_pane.setLayout(card_layout);
402 control_pane.add(flag_pane, FLAG);
403 control_pane.add(selection_pane, VALUE);
404 control_pane.add(blank_pane, BLANK);
405
406 button_pane.setLayout(new GridLayout(1,3));
407 button_pane.add(add_button);
408 button_pane.add(replace_button);
409 button_pane.add(remove_button);
410
411 center_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("CDM.FormatManager.Editing_Controls")), BorderFactory.createEmptyBorder(2,2,2,2)));
412 center_pane.setLayout(new BorderLayout());
413 center_pane.add(feature_pane, BorderLayout.NORTH);
414 center_pane.add(control_pane, BorderLayout.CENTER);
415 center_pane.add(button_pane, BorderLayout.SOUTH);
416
417 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
418 setLayout(new BorderLayout());
419 add(instructions_pane, BorderLayout.NORTH);
420 add(new JScrollPane(format_list), BorderLayout.CENTER);
421 add(center_pane, BorderLayout.SOUTH);
422 ready = true;
423 }
424
425 public void destroy() {
426 }
427
428 /** Overriden to ensure that the instructions pane is scrolled to the top.
429 */
430 public void gainFocus() {
431 // This is only necessary if the components have been realized
432 if(ready) {
433 formats_changed = false;
434 model.refresh();
435 feature_model = buildFeatureModel();
436 // Remember the current selection
437 Object selected_object = feature_combobox.getSelectedItem();
438 feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray()));
439 // Now restore the selected object as best as possible
440 feature_combobox.setSelectedItem(selected_object);
441 selected_object = null;
442 if(instructions_textarea != null) {
443 instructions_textarea.setCaretPosition(0);
444 }
445 }
446 }
447
448 public void loseFocus() {
449 // Force all of the Formats to update their names with the correct values.
450 int size = model.getSize();
451 for(int i = 0; i < size; i++) {
452 Format format = (Format) model.getElementAt(i);
453 format.update();
454 format = null;
455 }
456 }
457
458 /** 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 */
459 private class AddListener
460 implements ActionListener {
461 public void actionPerformed(ActionEvent event) {
462 ignore_event = true; // Prevent format_list excetera propagating events
463 Entry entry = (Entry)feature_combobox.getSelectedItem();
464 Object f = entry.getFeature();
465 String p = "";
466 if (entry.canHavePart()) {
467 p = part_combobox.getSelectedItem().toString();
468 }
469 Format format = null;
470 if(view_type.equals(FLAG)) {
471 format = new Format(f, p, enabled_checkbox.isSelected());
472 }
473 else {
474 format = new Format(f, p, editor_textarea.getText());
475 }
476 addFormat(format);
477 add_button.setEnabled(false);
478 replace_button.setEnabled(false);
479 remove_button.setEnabled(true);
480 // Update list selection
481 format_list.setSelectedValue(format, true);
482 format = null;
483 p = null;
484 f = null;
485 entry = null;
486 ignore_event = false;
487 }
488 }
489
490 private class EditorListener
491 implements DocumentListener {
492
493 public void changedUpdate(DocumentEvent e) {
494 update();
495 }
496
497 public void insertUpdate(DocumentEvent e) {
498 update();
499 }
500
501 public void removeUpdate(DocumentEvent e) {
502 update();
503 }
504
505 public void update() {
506 // Determine if replace should be enabled
507 if(!format_list.isSelectionEmpty()) {
508 Format format = (Format)format_list.getSelectedValue();
509 replace_button.setEnabled(!format.isParamType() && editor_textarea.getText() != format.getValue());
510 }
511 else {
512 replace_button.setEnabled(false);
513 }
514 }
515 }
516
517 private class EnabledListener
518 implements ActionListener {
519
520 public void actionPerformed(ActionEvent event) {
521 // 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.
522 if(!format_list.isSelectionEmpty()) {
523 Format format = (Format)format_list.getSelectedValue();
524 replace_button.setEnabled(format.isParamType() && enabled_checkbox.isSelected() != format.getState());
525 }
526 // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed.
527 }
528 }
529
530 private class FeatureListener
531 implements ActionListener {
532 public void actionPerformed(ActionEvent event) {
533 if(!ignore_event) {
534 ignore_event = true;
535 Entry entry = (Entry) feature_combobox.getSelectedItem();
536 // Step one: reset part
537 if (entry.canHavePart()) {
538 part_combobox.setEnabled(true);
539 part_combobox.setSelectedIndex(4);
540
541 } else {
542 part_combobox.setEnabled(false);
543 part_combobox.setSelectedIndex(0);
544 }
545 // Step two: the rest
546
547 String name = entry.toString();
548 // 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
549 Object f = entry.getFeature();
550 Part part = (Part)part_combobox.getSelectedItem();
551 String pname = part.getName();
552 // You can never add anything to blank-blank
553 if(f.toString().length() == 0 && pname.length() == 0) {
554 add_button.setEnabled(false);
555 replace_button.setEnabled(false);
556 remove_button.setEnabled(false);
557 }
558 else {
559 Format format = getFormat(Format.generateName(f, pname));
560 // If there is an existing feature, select it, and use it to determine what controls are visible
561 if(format != null) {
562 ///ystem.err.println("There is an existing format!");
563 format_list.setSelectedValue(format, true);
564 // Now use type to determine what controls are visible, and what have initial values.
565 if(format.isParamType()) {
566 ///ystem.err.println("Flag type");
567 // Flags first.
568 ///election_pane.remove(part_pane);
569 card_layout.show(control_pane, FLAG);
570 view_type = FLAG;
571 // Initial value
572 enabled_checkbox.setSelected(format.getState());
573 }
574 else {
575 ///ystem.err.println("Value type");
576 ///election_pane.add(part_pane);
577 card_layout.show(control_pane, VALUE);
578 view_type = VALUE;
579 // Initial value
580 editor_textarea.setText(format.getValue());
581 }
582 control_pane.updateUI();
583 remove_button.setEnabled(true);
584 }
585 // Otherwise there is no existing format, so we proceed by checking against the feature name
586 else {
587 ///ystem.err.println("No existing format");
588 format_list.clearSelection();
589 if(Format.isParamType(name)) {
590 ///ystem.err.println("Flag type");
591 // Flags first.
592 ///election_pane.remove(part_pane);
593 card_layout.show(control_pane, FLAG);
594 view_type = FLAG;
595 // Initial value
596 enabled_checkbox.setSelected(false);
597 }
598 else {
599 ///ystem.err.println("Value type");
600 ///election_pane.add(part_pane);
601 card_layout.show(control_pane, VALUE);
602 view_type = VALUE;
603 // Initial value
604 editor_textarea.setText(part.getDefaultFormat());
605 }
606 add_button.setEnabled(true);
607 }
608 format = null;
609 name = null;
610 }
611 part = null;
612 pname = null;
613 f = null;
614 replace_button.setEnabled(false);
615 name = null;
616 entry = null;
617 ignore_event = false;
618 }
619 }
620 }
621
622 private class FormatListListener
623 implements ListSelectionListener {
624 public void valueChanged(ListSelectionEvent event) {
625 if(!ignore_event && !event.getValueIsAdjusting()) {
626 if(!format_list.isSelectionEmpty()) {
627 ignore_event = true;
628 Format format = (Format)format_list.getSelectedValue();
629 // Try to match the target, remembering the entries within are Entry's
630 Entry an_entry = new Entry(format.getFeature());
631 feature_combobox.setSelectedItem(an_entry);
632 // If we didn't match anything, add it and select it again
633 Entry result_entry = (Entry) feature_combobox.getSelectedItem();
634 if(!an_entry.equals(result_entry)) {
635 feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount());
636 feature_combobox.setSelectedItem(an_entry);
637 }
638
639 // Now use type to determine what controls are visible, and what have initial values.
640 ///ystem.err.println("Determine the correct type.");
641 if(format.isParamType()) {
642 ///ystem.err.println("Flag type - remove part");
643 // Flags first.
644 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, false));
645 card_layout.show(control_pane, FLAG);
646 view_type = FLAG;
647 // Initial value
648 enabled_checkbox.setSelected(format.getState());
649 }
650 else {
651 ///ystem.err.println("Value type - show part");
652 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, true));
653 card_layout.show(control_pane, VALUE);
654 view_type = VALUE;
655 // Initial values
656
657 // Try to match the part.
658 String part_entry = format.getPart();
659 // Set Selected Item doesn't work so I'll do this manually
660 boolean found = false;
661 for(int i=0; i < part_combobox.getItemCount(); i++) {
662 Part a_part = (Part) part_combobox.getItemAt(i);
663 if(a_part.equals(part_entry)) {
664 part_combobox.setSelectedItem(a_part);
665 found = true;
666 }
667 a_part = null;
668 }
669 // If we didn't match anything, add it and select it again
670 if(!found) {
671 Part a_part = new Part(part_entry, "");
672 part_combobox.insertItemAt(a_part, part_combobox.getItemCount());
673 part_combobox.setSelectedItem(a_part);
674 }
675
676 editor_textarea.setText(format.getValue());
677 }
678 //control_pane.updateUI();
679 remove_button.setEnabled(true);
680 ignore_event = false;
681 }
682 else {
683 remove_button.setEnabled(false);
684 }
685 add_button.setEnabled(false);
686 replace_button.setEnabled(false);
687 }
688 }
689 }
690
691 private class InsertListener
692 implements ActionListener {
693 public void actionPerformed(ActionEvent event) {
694 editor_textarea.insert((String)variable_combobox.getSelectedItem(), editor_textarea.getCaretPosition());
695 }
696 }
697
698 private class PartListener
699 implements ActionListener {
700 public void actionPerformed(ActionEvent event) {
701 if(!ignore_event) {
702 // 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
703 Entry entry = (Entry) feature_combobox.getSelectedItem();
704 Object f = entry.getFeature();
705 Part part = (Part) part_combobox.getSelectedItem();
706 String pname = part.getName();
707 // You can never add anything to blank-blank
708 if(f.toString().length() == 0 && pname.length() == 0) {
709 add_button.setEnabled(false);
710 replace_button.setEnabled(false);
711 remove_button.setEnabled(false);
712 }
713 else {
714 String name = Format.generateName(f, pname);
715 Format format = getFormat(name);
716 // If there is an existing feature, select it.
717 if(format != null) {
718 format_list.setSelectedValue(format, true);
719 // Now use type to determine what controls are visible, and what have initial values.
720 if(format.isParamType()) {
721 // Flags first.
722 ///election_pane.remove(part_pane);
723 card_layout.show(control_pane, FLAG);
724 view_type = FLAG;
725 // Initial value
726 enabled_checkbox.setSelected(format.getState());
727 }
728 else {
729 ///election_pane.add(part_pane);
730 card_layout.show(control_pane, VALUE);
731 view_type = VALUE;
732 // Initial value
733 editor_textarea.setText(format.getValue());
734 }
735 control_pane.updateUI();
736 remove_button.setEnabled(true);
737 }
738 else {
739 format_list.clearSelection();
740 if(Format.isParamType(name)) {
741 // Flags first.
742 ///election_pane.remove(part_pane);
743 card_layout.show(control_pane, FLAG);
744 view_type = FLAG;
745 // Initial value
746 enabled_checkbox.setSelected(false);
747 }
748 else {
749 ///election_pane.add(part_pane);
750 card_layout.show(control_pane, VALUE);
751 view_type = VALUE;
752 // Initial value
753 editor_textarea.setText(part.getDefaultFormat());
754 }
755 add_button.setEnabled(true);
756 }
757 format = null;
758 name = null;
759 }
760
761 pname = null;
762 part = null;
763 f = null;
764 entry = null;
765 replace_button.setEnabled(false);
766 }
767 }
768 }
769
770 private class RemoveListener
771 implements ActionListener {
772 public void actionPerformed(ActionEvent event) {
773 if(!format_list.isSelectionEmpty()) {
774 removeFormat((Format)format_list.getSelectedValue());
775 // Change buttons
776 add_button.setEnabled(true);
777 replace_button.setEnabled(false);
778 }
779 remove_button.setEnabled(false);
780 }
781 }
782
783 private class ReplaceListener
784 implements ActionListener {
785
786 public void actionPerformed(ActionEvent event) {
787 ignore_event = true; // Prevent format_list excetera propagating events
788
789 if(!format_list.isSelectionEmpty()) {
790
791 // Remove the current format
792 removeFormat((Format)format_list.getSelectedValue());
793
794 Entry entry = (Entry)feature_combobox.getSelectedItem();
795 Object f = entry.getFeature();
796 String p = "";
797 if (entry.canHavePart()) {
798 p = part_combobox.getSelectedItem().toString();
799 }
800 Format format = null;
801 if(view_type.equals(FLAG)) {
802 format = new Format(f, p, enabled_checkbox.isSelected());
803 }
804 else {
805 format = new Format(f, p, editor_textarea.getText());
806 }
807 addFormat(format);
808 add_button.setEnabled(false);
809 remove_button.setEnabled(true);
810 // Update list selection
811 format_list.setSelectedValue(format, true);
812 format = null;
813 p = null;
814 f = null;
815 entry = null;
816 }
817 replace_button.setEnabled(false);
818 ignore_event = false;
819 }
820 }
821 }
822
823 /** 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. */
824 private class Entry
825 implements Comparable {
826 private Classifier classifier = null;
827 private String text = null;
828
829 public Entry(Object object) {
830 if(object instanceof Classifier) {
831 classifier = (Classifier)object;
832 }
833 else if(object instanceof String) {
834 text = (String)object;
835 }
836 else {
837 text = "";
838 }
839 }
840
841 public Entry(String text) {
842 this.text = text;
843 }
844
845 public boolean canHavePart() {
846 if (classifier !=null) return true;
847 return Format.canHavePart(text);
848 }
849
850 public int compareTo(Object object) {
851 if(object == null) {
852 return 1;
853 }
854 if(toString() == null) {
855 return -1;
856 }
857 else {
858 String object_str = object.toString();
859 if(object_str == null) {
860 return 1;
861 }
862 return toString().compareTo(object_str);
863 }
864 }
865
866 public boolean equals(Object object) {
867 if(compareTo(object) == 0) {
868 return true;
869 }
870 return false;
871 }
872
873 public Classifier getClassifier() {
874 return classifier;
875 }
876
877 public Object getFeature() {
878 if(classifier != null) {
879 return classifier;
880 }
881 return text;
882 }
883
884 public String toString() {
885 if(classifier != null) {
886 // Return the classifier - less the 'classify ' prefix and with its CL index shown
887 return classifier.getPositionString() + StaticStrings.COLON_CHARACTER + StaticStrings.SPACE_CHARACTER + classifier.toString().substring(9);
888 }
889 return text;
890 }
891 }
892
893 /*
894 private class GUIChangeTask
895 implements Runnable {
896 private boolean to_add;
897 private JPanel child;
898 private JPanel parent;
899 private JPanel replacement;
900
901 public GUIChangeTask(JPanel parent, JPanel child, JPanel replacement, boolean to_add) {
902 this.child = child;
903 this.parent = parent;
904 this.replacement = replacement;
905 this.to_add = to_add;
906 }
907
908 public void run() {
909 if(to_add) {
910 parent.remove(replacement);
911 parent.add(child);
912 parent.updateUI();
913 }
914 else {
915 parent.remove(child);
916 parent.add(replacement);
917 parent.updateUI();
918 }
919 }
920 }
921 */
922
923 /** This class encapsulates all of the information associated with a certain component part of a feature within a html page returned from the receptioninst. */
924 private class Part
925 implements Comparable {
926 /** The default format string for this part */
927 private String default_format = null;
928 /** The name of this part */
929 private String name = null;
930 /** Constructor - must be provided with all of the details of a part as there are no other setter methods.
931 * @param name the name of this part
932 * @param default_format the default format string for this part
933 */
934 public Part(String name, String default_format) {
935 this.default_format = default_format;
936 this.name = name;
937 }
938 /** Compare this part to another object in terms of ordering
939 * @param obj the other Object
940 * @return <0 if the object is before, 0 if equal to, and >0 if the object is after this part
941 */
942 public int compareTo(Object obj) {
943 return name.compareTo(obj.toString());
944 }
945
946 /** Determine if the part is equivelent to some other object
947 * @param obj the other Object
948 * @return true is the two objects are equal
949 */
950 public boolean equals(Object obj) {
951 return name.equals(obj.toString());
952 }
953
954 /** Retrieve the default format string for this part
955 * @return the default format String
956 */
957 public String getDefaultFormat() {
958 // Retrieve the format for the super format - either VList or HList
959 Format default_format_object = getFormat(name);
960 if(default_format_object != null) {
961 return default_format_object.getValue();
962 }
963 else {
964 return this.default_format;
965 }
966 }
967 /** Retrieve the name of this part
968 * @return the name as a String
969 */
970 public String getName() {
971 return name;
972 }
973 /** Produce a string representation of this part, which in this case is simply the name again
974 * @return the name as a String
975 */
976 public String toString() {
977 return name;
978 }
979 }
980}
Note: See TracBrowser for help on using the repository browser.