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

Last change on this file since 11502 was 11502, checked in by kjdon, 18 years ago

chnaged the default format statements for VList and DocumentText to match changes in receptionist

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