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

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

Removed all occurrences of classes explicitly importing other classes in the same package.

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