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

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

Replaced all "Gatherer.config" with "Configuration".

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