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

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

added [numleafdocs] to the format list

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