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

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

Finally committing the (many) changes to the GLI to use the new metadata code... I hope this doesn't have too many bugs in it and committing it now doesn't stuff anyone up! (Katherine said I could commit it, so blame her if anything goes wrong).

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