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

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

Replaced all Gatherer.print* with DebugStream.print*.

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