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

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

unfixed the size of labels so that other langs fit in

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