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

Last change on this file since 10342 was 10341, checked in by kjdon, 19 years ago

when change the order of the classifiers, now it calls refresh in the format manager to update the CLx format statements

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