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

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

added DocumentText, DocumentButtons and DocumentHeading default formats. also removed Invisible from the part list

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