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

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

added line breaks to VList and DateList format statements

  • Property svn:keywords set to Author Date Id Revision
File size: 34.4 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29/**************************************************************************************
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>\n<td>[highlight]{Or}{[dls.Title],[dc.Title],[Title],Untitled}[/highlight]</td>\n<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>\n<td valign=top>[srclink]{Or}{[thumbicon],[srcicon]}[/srclink]</td>\n<td valign=top>[highlight]\n{Or}{[dls.Title],[dc.Title],[Title],Untitled}\n[/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
462 public void actionPerformed(ActionEvent event)
463 {
464 ignore_event = true; // Prevent format_list excetera propagating events
465
466 Entry entry = (Entry) feature_combobox.getSelectedItem();
467 Object f = entry.getFeature();
468 String p = "";
469 if (entry.canHavePart()) {
470 p = part_combobox.getSelectedItem().toString();
471 }
472
473 // Add a new format string of the appropriate type
474 Format format = null;
475 if (view_type.equals(FLAG)) {
476 format = new Format(f, p, enabled_checkbox.isSelected());
477 }
478 else {
479 format = new Format(f, p, editor_textarea.getText());
480 }
481 addFormat(format);
482
483 // Save the collection configuration file immediately
484 Gatherer.g_man.design_pane.saveConfiguration();
485
486 add_button.setEnabled(false);
487 replace_button.setEnabled(false);
488 remove_button.setEnabled(true);
489
490 // Update list selection
491 format_list.setSelectedValue(format, true);
492 format = null;
493 p = null;
494 f = null;
495 entry = null;
496 ignore_event = false;
497 }
498 }
499
500 private class EditorListener
501 implements DocumentListener {
502
503 public void changedUpdate(DocumentEvent e) {
504 update();
505 }
506
507 public void insertUpdate(DocumentEvent e) {
508 update();
509 }
510
511 public void removeUpdate(DocumentEvent e) {
512 update();
513 }
514
515 public void update() {
516 // Determine if replace should be enabled
517 if(!format_list.isSelectionEmpty()) {
518 Format format = (Format)format_list.getSelectedValue();
519 replace_button.setEnabled(!format.isParamType() && editor_textarea.getText() != format.getValue());
520 }
521 else {
522 replace_button.setEnabled(false);
523 }
524 }
525 }
526
527 private class EnabledListener
528 implements ActionListener {
529
530 public void actionPerformed(ActionEvent event) {
531 // 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.
532 if(!format_list.isSelectionEmpty()) {
533 Format format = (Format)format_list.getSelectedValue();
534 replace_button.setEnabled(format.isParamType() && enabled_checkbox.isSelected() != format.getState());
535 }
536 // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed.
537 }
538 }
539
540 private class FeatureListener
541 implements ActionListener {
542 public void actionPerformed(ActionEvent event) {
543 if(!ignore_event) {
544 ignore_event = true;
545 Entry entry = (Entry) feature_combobox.getSelectedItem();
546 // Step one: reset part
547 if (entry.canHavePart()) {
548 part_combobox.setEnabled(true);
549 part_combobox.setSelectedIndex(4);
550
551 } else {
552 part_combobox.setEnabled(false);
553 part_combobox.setSelectedIndex(0);
554 }
555 // Step two: the rest
556
557 String name = entry.toString();
558 // 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
559 Object f = entry.getFeature();
560 Part part = (Part)part_combobox.getSelectedItem();
561 String pname = part.getName();
562 // You can never add anything to blank-blank
563 if(f.toString().length() == 0 && pname.length() == 0) {
564 add_button.setEnabled(false);
565 replace_button.setEnabled(false);
566 remove_button.setEnabled(false);
567 }
568 else {
569 Format format = getFormat(Format.generateName(f, pname));
570 // If there is an existing feature, select it, and use it to determine what controls are visible
571 if(format != null) {
572 ///ystem.err.println("There is an existing format!");
573 format_list.setSelectedValue(format, true);
574 // Now use type to determine what controls are visible, and what have initial values.
575 if(format.isParamType()) {
576 ///ystem.err.println("Flag type");
577 // Flags first.
578 ///election_pane.remove(part_pane);
579 card_layout.show(control_pane, FLAG);
580 view_type = FLAG;
581 // Initial value
582 enabled_checkbox.setSelected(format.getState());
583 }
584 else {
585 ///ystem.err.println("Value type");
586 ///election_pane.add(part_pane);
587 card_layout.show(control_pane, VALUE);
588 view_type = VALUE;
589 // Initial value
590 editor_textarea.setText(format.getValue());
591 }
592 control_pane.updateUI();
593 remove_button.setEnabled(true);
594 }
595 // Otherwise there is no existing format, so we proceed by checking against the feature name
596 else {
597 ///ystem.err.println("No existing format");
598 format_list.clearSelection();
599 if(Format.isParamType(name)) {
600 ///ystem.err.println("Flag type");
601 // Flags first.
602 ///election_pane.remove(part_pane);
603 card_layout.show(control_pane, FLAG);
604 view_type = FLAG;
605 // Initial value
606 enabled_checkbox.setSelected(false);
607 }
608 else {
609 ///ystem.err.println("Value type");
610 ///election_pane.add(part_pane);
611 card_layout.show(control_pane, VALUE);
612 view_type = VALUE;
613 // Initial value
614 editor_textarea.setText(part.getDefaultFormat());
615 }
616 add_button.setEnabled(true);
617 }
618 format = null;
619 name = null;
620 }
621 part = null;
622 pname = null;
623 f = null;
624 replace_button.setEnabled(false);
625 name = null;
626 entry = null;
627 ignore_event = false;
628 }
629 }
630 }
631
632 private class FormatListListener
633 implements ListSelectionListener {
634 public void valueChanged(ListSelectionEvent event) {
635 if(!ignore_event && !event.getValueIsAdjusting()) {
636 if(!format_list.isSelectionEmpty()) {
637 ignore_event = true;
638 Format format = (Format)format_list.getSelectedValue();
639 // Try to match the target, remembering the entries within are Entry's
640 Entry an_entry = new Entry(format.getFeature());
641 feature_combobox.setSelectedItem(an_entry);
642 // If we didn't match anything, add it and select it again
643 Entry result_entry = (Entry) feature_combobox.getSelectedItem();
644 if(!an_entry.equals(result_entry)) {
645 feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount());
646 feature_combobox.setSelectedItem(an_entry);
647 }
648
649 // Now use type to determine what controls are visible, and what have initial values.
650 ///ystem.err.println("Determine the correct type.");
651 if(format.isParamType()) {
652 ///ystem.err.println("Flag type - remove part");
653 // Flags first.
654 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, false));
655 card_layout.show(control_pane, FLAG);
656 view_type = FLAG;
657 // Initial value
658 enabled_checkbox.setSelected(format.getState());
659 }
660 else {
661 ///ystem.err.println("Value type - show part");
662 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, true));
663 card_layout.show(control_pane, VALUE);
664 view_type = VALUE;
665 // Initial values
666
667 // Try to match the part.
668 String part_entry = format.getPart();
669 // Set Selected Item doesn't work so I'll do this manually
670 boolean found = false;
671 for(int i=0; i < part_combobox.getItemCount(); i++) {
672 Part a_part = (Part) part_combobox.getItemAt(i);
673 if(a_part.equals(part_entry)) {
674 part_combobox.setSelectedItem(a_part);
675 found = true;
676 }
677 a_part = null;
678 }
679 // If we didn't match anything, add it and select it again
680 if(!found) {
681 Part a_part = new Part(part_entry, "");
682 part_combobox.insertItemAt(a_part, part_combobox.getItemCount());
683 part_combobox.setSelectedItem(a_part);
684 }
685
686 editor_textarea.setText(format.getValue());
687 }
688 //control_pane.updateUI();
689 remove_button.setEnabled(true);
690 ignore_event = false;
691 }
692 else {
693 remove_button.setEnabled(false);
694 }
695 add_button.setEnabled(false);
696 replace_button.setEnabled(false);
697 }
698 }
699 }
700
701 private class InsertListener
702 implements ActionListener {
703 public void actionPerformed(ActionEvent event) {
704 editor_textarea.insert((String)variable_combobox.getSelectedItem(), editor_textarea.getCaretPosition());
705 }
706 }
707
708 private class PartListener
709 implements ActionListener {
710 public void actionPerformed(ActionEvent event) {
711 if(!ignore_event) {
712 // 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
713 Entry entry = (Entry) feature_combobox.getSelectedItem();
714 Object f = entry.getFeature();
715 Part part = (Part) part_combobox.getSelectedItem();
716 String pname = part.getName();
717 // You can never add anything to blank-blank
718 if(f.toString().length() == 0 && pname.length() == 0) {
719 add_button.setEnabled(false);
720 replace_button.setEnabled(false);
721 remove_button.setEnabled(false);
722 }
723 else {
724 String name = Format.generateName(f, pname);
725 Format format = getFormat(name);
726 // If there is an existing feature, select it.
727 if(format != null) {
728 format_list.setSelectedValue(format, true);
729 // Now use type to determine what controls are visible, and what have initial values.
730 if(format.isParamType()) {
731 // Flags first.
732 ///election_pane.remove(part_pane);
733 card_layout.show(control_pane, FLAG);
734 view_type = FLAG;
735 // Initial value
736 enabled_checkbox.setSelected(format.getState());
737 }
738 else {
739 ///election_pane.add(part_pane);
740 card_layout.show(control_pane, VALUE);
741 view_type = VALUE;
742 // Initial value
743 editor_textarea.setText(format.getValue());
744 }
745 control_pane.updateUI();
746 remove_button.setEnabled(true);
747 }
748 else {
749 format_list.clearSelection();
750 if(Format.isParamType(name)) {
751 // Flags first.
752 ///election_pane.remove(part_pane);
753 card_layout.show(control_pane, FLAG);
754 view_type = FLAG;
755 // Initial value
756 enabled_checkbox.setSelected(false);
757 }
758 else {
759 ///election_pane.add(part_pane);
760 card_layout.show(control_pane, VALUE);
761 view_type = VALUE;
762 // Initial value
763 editor_textarea.setText(part.getDefaultFormat());
764 }
765 add_button.setEnabled(true);
766 }
767 format = null;
768 name = null;
769 }
770
771 pname = null;
772 part = null;
773 f = null;
774 entry = null;
775 replace_button.setEnabled(false);
776 }
777 }
778 }
779
780 private class RemoveListener
781 implements ActionListener {
782
783 public void actionPerformed(ActionEvent event)
784 {
785 if (!format_list.isSelectionEmpty()) {
786 // Remove the current format
787 removeFormat((Format)format_list.getSelectedValue());
788
789 // Save the collection configuration file immediately
790 Gatherer.g_man.design_pane.saveConfiguration();
791
792 // Change buttons
793 add_button.setEnabled(true);
794 replace_button.setEnabled(false);
795 }
796
797 remove_button.setEnabled(false);
798 }
799 }
800
801 private class ReplaceListener
802 implements ActionListener {
803
804 public void actionPerformed(ActionEvent event)
805 {
806 ignore_event = true; // Prevent format_list excetera propagating events
807
808 if (!format_list.isSelectionEmpty()) {
809 // Remove the current format
810 removeFormat((Format) format_list.getSelectedValue());
811
812 Entry entry = (Entry) feature_combobox.getSelectedItem();
813 Object f = entry.getFeature();
814 String p = "";
815 if (entry.canHavePart()) {
816 p = part_combobox.getSelectedItem().toString();
817 }
818
819 // Add a new format string of the appropriate type
820 Format format = null;
821 if (view_type.equals(FLAG)) {
822 format = new Format(f, p, enabled_checkbox.isSelected());
823 }
824 else {
825 format = new Format(f, p, editor_textarea.getText());
826 }
827 addFormat(format);
828
829 // Save the collection configuration file immediately
830 Gatherer.g_man.design_pane.saveConfiguration();
831
832 add_button.setEnabled(false);
833 remove_button.setEnabled(true);
834 // Update list selection
835 format_list.setSelectedValue(format, true);
836 format = null;
837 p = null;
838 f = null;
839 entry = null;
840 }
841
842 replace_button.setEnabled(false);
843 ignore_event = false;
844 }
845 }
846 }
847
848 /** 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. */
849 private class Entry
850 implements Comparable {
851 private Classifier classifier = null;
852 private String text = null;
853
854 public Entry(Object object) {
855 if(object instanceof Classifier) {
856 classifier = (Classifier)object;
857 }
858 else if(object instanceof String) {
859 text = (String)object;
860 }
861 else {
862 text = "";
863 }
864 }
865
866 public Entry(String text) {
867 this.text = text;
868 }
869
870 public boolean canHavePart() {
871 if (classifier !=null) return true;
872 return Format.canHavePart(text);
873 }
874
875 public int compareTo(Object object) {
876 if(object == null) {
877 return 1;
878 }
879 if(toString() == null) {
880 return -1;
881 }
882 else {
883 String object_str = object.toString();
884 if(object_str == null) {
885 return 1;
886 }
887 return toString().compareTo(object_str);
888 }
889 }
890
891 public boolean equals(Object object) {
892 if(compareTo(object) == 0) {
893 return true;
894 }
895 return false;
896 }
897
898 public Classifier getClassifier() {
899 return classifier;
900 }
901
902 public Object getFeature() {
903 if(classifier != null) {
904 return classifier;
905 }
906 return text;
907 }
908
909 public String toString() {
910 if(classifier != null) {
911 // Return the classifier - less the 'classify ' prefix and with its CL index shown
912 return classifier.getPositionString() + StaticStrings.COLON_CHARACTER + StaticStrings.SPACE_CHARACTER + classifier.toString().substring(9);
913 }
914 return text;
915 }
916 }
917
918 /*
919 private class GUIChangeTask
920 implements Runnable {
921 private boolean to_add;
922 private JPanel child;
923 private JPanel parent;
924 private JPanel replacement;
925
926 public GUIChangeTask(JPanel parent, JPanel child, JPanel replacement, boolean to_add) {
927 this.child = child;
928 this.parent = parent;
929 this.replacement = replacement;
930 this.to_add = to_add;
931 }
932
933 public void run() {
934 if(to_add) {
935 parent.remove(replacement);
936 parent.add(child);
937 parent.updateUI();
938 }
939 else {
940 parent.remove(child);
941 parent.add(replacement);
942 parent.updateUI();
943 }
944 }
945 }
946 */
947
948 /** This class encapsulates all of the information associated with a certain component part of a feature within a html page returned from the receptioninst. */
949 private class Part
950 implements Comparable {
951 /** The default format string for this part */
952 private String default_format = null;
953 /** The name of this part */
954 private String name = null;
955 /** Constructor - must be provided with all of the details of a part as there are no other setter methods.
956 * @param name the name of this part
957 * @param default_format the default format string for this part
958 */
959 public Part(String name, String default_format) {
960 this.default_format = default_format;
961 this.name = name;
962 }
963 /** Compare this part to another object in terms of ordering
964 * @param obj the other Object
965 * @return <0 if the object is before, 0 if equal to, and >0 if the object is after this part
966 */
967 public int compareTo(Object obj) {
968 return name.compareTo(obj.toString());
969 }
970
971 /** Determine if the part is equivelent to some other object
972 * @param obj the other Object
973 * @return true is the two objects are equal
974 */
975 public boolean equals(Object obj) {
976 return name.equals(obj.toString());
977 }
978
979 /** Retrieve the default format string for this part
980 * @return the default format String
981 */
982 public String getDefaultFormat() {
983 // Retrieve the format for the super format - either VList or HList
984 Format default_format_object = getFormat(name);
985 if(default_format_object != null) {
986 return default_format_object.getValue();
987 }
988 else {
989 return this.default_format;
990 }
991 }
992 /** Retrieve the name of this part
993 * @return the name as a String
994 */
995 public String getName() {
996 return name;
997 }
998 /** Produce a string representation of this part, which in this case is simply the name again
999 * @return the name as a String
1000 */
1001 public String toString() {
1002 return name;
1003 }
1004 }
1005}
Note: See TracBrowser for help on using the repository browser.