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

Last change on this file since 10332 was 10237, checked in by mdewsnip, 19 years ago

New code for "incremental" building, by Matthew Whyte.

I've only had time to look at this briefly; I've fixed a few obvious problems but I imagine this will be pretty flaky for a while.

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