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

Last change on this file since 11038 was 11038, checked in by mdewsnip, 18 years ago

Tidied up the look of the Design pane. Each Design pane screen now has consistent borders, and vertical spacing between elements has been improved.

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