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

Last change on this file since 8056 was 8002, checked in by mdewsnip, 20 years ago

Tightened up many public functions to private.

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