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

Last change on this file since 12828 was 12828, checked in by kjdon, 18 years ago

add search types format into default format map

  • Property svn:keywords set to Author Date Id Revision
File size: 39.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
29import java.awt.*;
30import java.awt.event.*;
31import java.util.*;
32import javax.swing.*;
33import javax.swing.event.*;
34import javax.swing.undo.*;
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 = "[Text]";
71
72 static final private String DOCUMENTBUTTONS = "DocumentButtons";
73 static final private String DOCUMENTBUTTONS_DEFAULT_FORMAT = "Detach|Highlight";
74 static final private String SEARCHTYPES = "SearchTypes";
75 static final private String SEARCHTYPES_DEFAULT_FORMAT = "plain,form";
76
77 static private HashMap default_format_map = null;
78
79 /** The controls used to edit the format commands. */
80 private Control controls = null;
81 /** A reference to ourselves so inner classes can get at the model. */
82 private DOMProxyListModel model = null;
83
84
85 /** Constructor. */
86 public FormatManager() {
87 super(CollectionDesignManager.collect_config.getDocumentElement(), StaticStrings.FORMAT_ELEMENT, new Format());
88 this.model = this;
89
90 default_format_map = new HashMap();
91 default_format_map.put(DATELIST, DATELIST_DEFAULT_FORMAT);
92 default_format_map.put(HLIST, HLIST_DEFAULT_FORMAT);
93 default_format_map.put(VLIST, VLIST_DEFAULT_FORMAT);
94 default_format_map.put(DOCUMENTHEADING, DOCUMENTHEADING_DEFAULT_FORMAT);
95 default_format_map.put(DOCUMENTTEXT, DOCUMENTTEXT_DEFAULT_FORMAT);
96 default_format_map.put(DOCUMENTBUTTONS, DOCUMENTBUTTONS_DEFAULT_FORMAT);
97 default_format_map.put(SEARCHTYPES, SEARCHTYPES_DEFAULT_FORMAT);
98 default_format_map.put("", "");
99
100 DebugStream.println("FormatManager: parsed " + getSize() + " format statements.");
101 // 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.
102 int size = getSize();
103 for(int i = 0; i < size; i++) {
104 getElementAt(i);
105 }
106
107// // Ensure the default formats for DateList, HList and VList are assigned
108// if (getFormat(DATELIST) == null) {
109// addFormat(new Format("",DATELIST,DATELIST_DEFAULT_FORMAT));
110// }
111
112
113// if (getFormat(HLIST) == null) {
114// addFormat(new Format("",HLIST,HLIST_DEFAULT_FORMAT));
115// }
116
117
118// if (getFormat(VLIST) == null) {
119// addFormat(new Format("",VLIST,VLIST_DEFAULT_FORMAT));
120// }
121
122
123// if (getFormat(DOCUMENTHEADING) == null) {
124// addFormat(new Format(DOCUMENTHEADING, "", DOCUMENTHEADING_DEFAULT_FORMAT));
125// }
126
127
128// if (getFormat(DOCUMENTTEXT)== null) {
129// addFormat(new Format(DOCUMENTTEXT,"",DOCUMENTTEXT_DEFAULT_FORMAT));
130// }
131
132
133
134// if (getFormat(DOCUMENTBUTTONS) == null) {
135// addFormat(new Format(DOCUMENTBUTTONS,"",DOCUMENTBUTTONS_DEFAULT_FORMAT));
136
137// }
138
139// // only for mgpp and lucene colls - change!
140// if (getFormat(SEARCHTYPES)==null) {
141// addFormat(new Format(SEARCHTYPES, "", SEARCHTYPES_DEFAULT_FORMAT));
142// }
143
144 }
145
146 /** Method to add a new format to this manager.
147 * @param format The <strong>Format</strong> to add.
148 */
149 private void addFormat(Format format) {
150 if(!contains(format)) {
151 Element element = format.getElement();
152 // Locate where we should insert this new classifier.
153 Node target_node = CollectionConfiguration.findInsertionPoint(element);
154 add(root, format, target_node);
155 }
156 }
157
158
159 public void destroy() {
160 if(controls != null) {
161 controls.destroy();
162 controls = null;
163 }
164 }
165
166
167 private Format getFormat(String name) {
168 int model_size = getSize();
169 for(int index = 0; index < model_size; index++) {
170 Format format = (Format) getElementAt(index);
171 if(format.getName().equals(name)) {
172 return format;
173 }
174 }
175 return null;
176 }
177
178 /** Method to retrieve this managers controls.
179 * @return the Control for this collection.
180 */
181 public Control getControls() {
182 if(controls == null) {
183 controls = new FormatControl();
184 }
185 return controls;
186 }
187
188 /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
189 * @param mode the new mode as an int
190 */
191 public void modeChanged(int mode) {
192
193 }
194
195
196 /** updates the format model */
197 public synchronized void refresh() {
198 for(int i = 0; i < getSize(); i++) {
199 Format format = (Format) getElementAt(i);
200 format.update();
201 format = null;
202 }
203 super.refresh();
204 }
205 /** Method to remove a format.
206 * @param format The <strong>Format</strong> to remove.
207 */
208 private void removeFormat(Format format) {
209 remove(format);
210 }
211
212 private ArrayList buildFeatureModel() {
213 // Rebuild feature model.
214 ArrayList feature_model = new ArrayList();
215 // Add the set options
216 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) {
217 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i]));
218 }
219 // Now the classifiers.
220 for(int j = 0; j < CollectionDesignManager.classifier_manager.getSize(); j++) {
221 feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j)));
222 }
223 Collections.sort(feature_model);
224 return feature_model;
225 }
226
227 private ArrayList buildPartModel() {
228 DebugStream.println("buildPartModel(): replace me with something that reads in a data xml file.");
229 ArrayList part_model = new ArrayList();
230 part_model.add(new Part("", ""));
231 part_model.add(new Part(DATELIST, DATELIST_DEFAULT_FORMAT));
232 part_model.add(new Part(HLIST, HLIST_DEFAULT_FORMAT));
233 //part_model.add(new Part(INVISIBLE, INVISIBLE_DEFAULT_FORMAT));
234 part_model.add(new Part(VLIST, VLIST_DEFAULT_FORMAT));
235 return part_model;
236 }
237
238 private ArrayList buildVariableModel()
239 {
240 ArrayList variable_model = new ArrayList();
241 variable_model.add(Dictionary.get("CDM.FormatManager.Insert_Variable"));
242 variable_model.add("[Text]");
243 ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
244 for (int i = 0; i < every_metadata_set_element.size(); i++) {
245 variable_model.add("[" + ((MetadataElement) every_metadata_set_element.get(i)).getFullName() + "]");
246 }
247 variable_model.add("[link]");
248 variable_model.add("[/link]");
249 variable_model.add("[icon]");
250 variable_model.add("[numleafdocs]");
251 variable_model.add("[num]");
252 variable_model.add("[parent():_]");
253 variable_model.add("[parent(Top):_]");
254 variable_model.add("[parent(All'_'):_]");
255 variable_model.add("[child():_]");
256 variable_model.add("[child(All'_'):_]");
257 variable_model.add("[sibling():_]");
258 variable_model.add("[sibling(All'_'):_]");
259
260 return variable_model;
261 }
262
263 public class FormatControl
264 extends JPanel
265 implements Control{
266
267 private ArrayList feature_model;
268 private ArrayList part_model;
269 private ArrayList variable_model;
270 private boolean ignore_event = false;
271 private boolean ready = false; // Are these controls available to be refreshed
272 private CardLayout card_layout;
273 private JButton add_button;
274 private JButton insert_button;
275 private JButton remove_button;
276 private JButton default_button;
277 private JButton undo_button;
278 private JButton redo_button;
279 private JCheckBox enabled_checkbox;
280 private JComboBox feature_combobox;
281 private JComboBox part_combobox;
282 private JComboBox variable_combobox;
283 private JList format_list;
284 private JTextArea editor_textarea;
285 private JPanel blank_pane;
286 private JPanel control_pane;
287 private JPanel part_pane;
288 private JPanel selection_pane;
289 private String view_type;
290 private final Dimension FIELD_SIZE = new Dimension(200, 30);
291 private final UndoManager undo = new UndoManager();
292 private boolean newtext = true;
293 private Format previousFormat = null;
294 private Format currentFormat = null;
295 private boolean fresh = true;
296
297 public FormatControl() {
298 feature_model = buildFeatureModel();
299 part_model = buildPartModel();
300 variable_model = buildVariableModel();
301
302 // Create
303 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Formats", "formatstatements");
304
305 format_list = new JList(model);
306
307 selection_pane = new JPanel();
308 JPanel feature_pane = new JPanel();
309 JLabel feature_label = new JLabel(Dictionary.get("CDM.FormatManager.Feature"));
310
311 feature_combobox = new JComboBox(feature_model.toArray());
312 feature_combobox.setPreferredSize(FIELD_SIZE);
313 feature_combobox.setEditable(false);
314 feature_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Feature_Tooltip"));
315
316 part_pane = new JPanel();
317 JLabel part_label = new JLabel(Dictionary.get("CDM.FormatManager.Part"));
318 part_combobox = new JComboBox(part_model.toArray());
319 part_combobox.setPreferredSize(FIELD_SIZE);
320 part_combobox.setEditable(false);
321 part_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Part_Tooltip"));
322
323 blank_pane = new JPanel();
324
325 JPanel center_pane = new JPanel();
326
327 card_layout = new CardLayout();
328 control_pane = new JPanel();
329
330 JPanel blank_pane = new JPanel();
331
332 JPanel editor_pane = new JPanel();
333 JPanel editor_header_pane = new JPanel();
334 JLabel editor_label = new JLabel(Dictionary.get("CDM.FormatManager.Editor"));
335
336 editor_textarea = new JTextArea();
337 editor_textarea.setBackground(Configuration.getColor("coloring.editable_background", false));
338 editor_textarea.setCaretPosition(0);
339 editor_textarea.setLineWrap(true);
340 editor_textarea.setRows(6);
341 editor_textarea.setWrapStyleWord(false);
342 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Add_Tooltip"));
343
344 JPanel variable_pane = new JPanel();
345
346 variable_combobox = new JComboBox(variable_model.toArray());
347 variable_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Variable_Tooltip"));
348
349 insert_button = new GLIButton(Dictionary.get("CDM.FormatManager.Insert"), Dictionary.get("CDM.FormatManager.Insert_Tooltip"));
350
351 default_button = new GLIButton(Dictionary.get("CDM.FormatManager.Default"), Dictionary.get("CDM.FormatManager.Default_Tooltip"));
352
353 JPanel flag_pane = new JPanel();
354 enabled_checkbox = new JCheckBox(Dictionary.get("CDM.FormatManager.Enabled"));
355
356 JPanel button_pane = new JPanel();
357 add_button = new GLIButton(Dictionary.get("CDM.FormatManager.Add"), Dictionary.get("CDM.FormatManager.Add_Tooltip"));
358 add_button.setEnabled(false);
359
360 remove_button = new GLIButton(Dictionary.get("CDM.FormatManager.Remove"), Dictionary.get("CDM.FormatManager.Remove_Tooltip"));
361 remove_button.setEnabled(false);
362
363 undo_button = new GLIButton(Dictionary.get("General.Undo"), Dictionary.get("General.Undo_Tooltip"));
364 undo_button.setEnabled(false);
365
366 redo_button = new GLIButton(Dictionary.get("General.Redo"), Dictionary.get("General.Redo_Tooltip"));
367 redo_button.setEnabled(false);
368
369 // Connect
370 add_button.addActionListener(new AddListener());
371 remove_button.addActionListener(new RemoveListener());
372 default_button.addActionListener(new DefaultListener());
373 undo_button.addActionListener(new UndoListener());
374 redo_button.addActionListener(new RedoListener());
375 enabled_checkbox.addActionListener(new EnabledListener());
376 feature_combobox.addActionListener(new FeatureListener());
377 part_combobox.addActionListener(new PartListener());
378
379 editor_textarea.getDocument().addDocumentListener(new EditorListener());
380 // Listen for undo and redo events
381 editor_textarea.getDocument().addUndoableEditListener(new UndoableEditListener() {
382 public void undoableEditHappened(UndoableEditEvent evt) {
383 undo.addEdit(evt.getEdit());
384 }
385 });
386
387
388 format_list.addListSelectionListener(new FormatListListener());
389 variable_combobox.addActionListener(new VariableListener());
390
391 // Layout
392 JPanel format_list_pane = new JPanel();
393 format_list_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
394 format_list_pane.setLayout(new BorderLayout());
395 format_list_pane.add(new JScrollPane(format_list), BorderLayout.CENTER);
396
397
398 feature_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
399 feature_pane.setLayout(new BorderLayout(5,0));
400 feature_pane.add(feature_label, BorderLayout.WEST);
401 feature_pane.add(feature_combobox, BorderLayout.CENTER);
402
403 part_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
404 part_pane.setLayout(new BorderLayout(5, 0));
405 part_pane.add(part_label, BorderLayout.WEST);
406 part_pane.add(part_combobox, BorderLayout.CENTER);
407
408
409 flag_pane.add(enabled_checkbox);
410
411 editor_header_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
412 editor_header_pane.setLayout(new GridLayout(1,3));
413 editor_header_pane.add(editor_label);
414
415 JPanel rupanel = new JPanel();
416 rupanel.setLayout(new GridLayout(1,2));
417 rupanel.add(undo_button);
418 rupanel.add(redo_button);
419
420 variable_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
421 variable_pane.setLayout(new GridLayout(1,3));
422 variable_pane.add(new JPanel());
423 variable_pane.add(variable_combobox);
424 variable_pane.add(rupanel);
425
426 editor_pane.setLayout(new BorderLayout());
427 editor_pane.add(editor_header_pane, BorderLayout.NORTH);
428 editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER);
429
430 selection_pane.setLayout(new BorderLayout());
431 selection_pane.add(part_pane, BorderLayout.NORTH);
432 selection_pane.add(editor_pane, BorderLayout.CENTER);
433 selection_pane.add(variable_pane, BorderLayout.SOUTH);
434
435 control_pane.setLayout(card_layout);
436 control_pane.add(flag_pane, FLAG);
437 control_pane.add(selection_pane, VALUE);
438 control_pane.add(blank_pane, BLANK);
439
440
441 button_pane.setLayout(new GridLayout(1,3));
442 button_pane.add(add_button);
443 button_pane.add(remove_button);
444 button_pane.add(default_button);
445
446
447 center_pane.setLayout(new BorderLayout());
448 center_pane.add(feature_pane, BorderLayout.NORTH);
449 center_pane.add(control_pane, BorderLayout.CENTER);
450 center_pane.add(button_pane, BorderLayout.SOUTH);
451
452 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
453 setLayout(new BorderLayout());
454 add(header_pane, BorderLayout.NORTH);
455 add(format_list_pane, BorderLayout.CENTER);
456 add(center_pane, BorderLayout.SOUTH);
457 ready = true;
458 }
459
460 public void destroy() {
461 }
462
463
464
465 /** Overriden to ensure that the instructions pane is scrolled to the top.
466 */
467 public void gainFocus() {
468 // This is only necessary if the components have been realized
469 if(ready) {
470 model.refresh();
471
472 // Update the feature model, trying to maintain the same selected object
473 Object selected_feature = feature_combobox.getSelectedItem();
474 feature_model = buildFeatureModel();
475 feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray()));
476 feature_combobox.setSelectedItem(selected_feature);
477
478 // Update the variable model,
479 variable_model = buildVariableModel();
480 variable_combobox.setModel(new DefaultComboBoxModel(variable_model.toArray()));
481 }
482 }
483
484 public void loseFocus() {
485 // Force all of the Formats to update their names with the correct values.
486 // do we need to do this on loseFocus???
487 model.refresh();
488 }
489
490 public Format getCurrentFormat() {
491 return (Format)format_list.getSelectedValue();
492
493 }
494
495 /** 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 */
496 private class AddListener
497 implements ActionListener {
498
499 public void actionPerformed(ActionEvent event)
500 {
501
502 ignore_event = true; // Prevent format_list excetera propagating events
503
504 Entry entry = (Entry) feature_combobox.getSelectedItem();
505 Object f = entry.getFeature();
506 String p = "";
507 if (entry.canHavePart()) {
508 p = ((Part)part_combobox.getSelectedItem()).getName();
509 }
510
511 // Add a new format string of the appropriate type
512 Format format = null;
513 if (view_type.equals(FLAG)) {
514 format = new Format(f, p, enabled_checkbox.isSelected());
515 }
516 else {
517 format = new Format(f, p, editor_textarea.getText());
518
519 }
520
521
522 addFormat(format);
523 existingFormat();
524
525 // Update list selection
526 format_list.setSelectedValue(format, true);
527 format = null;
528 p = null;
529 f = null;
530 entry = null;
531 ignore_event = false;
532 }
533 }
534
535 private class EditorListener
536 implements DocumentListener {
537
538 public void changedUpdate(DocumentEvent e) {
539
540 update();
541 }
542
543 public void insertUpdate(DocumentEvent e) {
544 update();
545 updateUndo("insert");
546
547 }
548
549 public void removeUpdate(DocumentEvent e) {
550 update();
551 updateUndo("remove");
552
553 }
554
555 private void updateUndo(String from){
556
557 if (!newtext){
558 undo_button.setEnabled(true);
559 }
560
561 if (editor_textarea.getText().length()!=0 && newtext){
562 newtext = false;
563 }
564 }
565
566 public void update() {
567
568 // Determine if replace should be enabled
569 if(!format_list.isSelectionEmpty()) {
570 Format format = (Format)format_list.getSelectedValue();
571 boolean shouldSave = !format.isParamType();
572
573 if (shouldSave){
574 format.setValue(editor_textarea.getText());
575 model.refresh((DOMProxyListEntry)format);
576 }
577
578 }
579 else {
580 add_button.setEnabled(false);
581
582 }
583
584 }
585 }
586
587 private class EnabledListener
588 implements ActionListener {
589
590 public void actionPerformed(ActionEvent event) {
591 // 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.
592 if(!format_list.isSelectionEmpty()) {
593 Format format = (Format)format_list.getSelectedValue();
594 boolean shouldSave = format.isParamType();
595 if (shouldSave){
596 format.setState(enabled_checkbox.isSelected());
597 model.refresh((DOMProxyListEntry)format);
598 }
599 }
600
601 // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed.
602 }
603 }
604
605 private class FeatureListener
606 implements ActionListener {
607 public void actionPerformed(ActionEvent event) {
608 undo_button.setEnabled(false);
609 redo_button.setEnabled(false);
610 default_button.setEnabled(true);
611 newtext = true;
612
613 if(!ignore_event) {
614 ignore_event = true;
615 Entry entry = (Entry) feature_combobox.getSelectedItem();
616
617 // Step one: reset part
618 if (entry.canHavePart()) {
619 part_combobox.setEnabled(true);
620 part_combobox.setSelectedIndex(part_combobox.getModel().getSize()-1);
621
622 } else {
623 part_combobox.setEnabled(false);
624 part_combobox.setSelectedIndex(0);
625 }
626 // Step two: the rest
627
628 String name = entry.toString();
629 // 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
630 Object f = entry.getFeature();
631 Part part = (Part)part_combobox.getSelectedItem();
632 String pname = part.getName();
633 // You can never add anything to blank-blank
634 if(f.toString().length() == 0 && pname.length() == 0) {
635 add_button.setEnabled(false);
636 remove_button.setEnabled(false);
637 }
638 else {
639
640 Format format = getFormat(Format.generateName(f, pname));
641 // If there is an existing feature, select it, and use it to determine what controls are visible
642
643 if(format != null) {
644 ///ystem.err.println("There is an existing format!");
645 format_list.setSelectedValue(format, true);
646 // Now use type to determine what controls are visible, and what have initial values.
647 if(format.isParamType()) {
648 ///ystem.err.println("Flag type");
649 // Flags first.
650 ///election_pane.remove(part_pane);
651 card_layout.show(control_pane, FLAG);
652 view_type = FLAG;
653 // Initial value
654 enabled_checkbox.setSelected(format.getState());
655 }
656 else {
657 ///ystem.err.println("Value type");
658 ///election_pane.add(part_pane);
659 card_layout.show(control_pane, VALUE);
660 view_type = VALUE;
661 // Initial value
662
663 editor_textarea.setText(format.getValue());
664 editor_textarea.setCaretPosition(0);
665
666 }
667 existingFormat();
668 control_pane.updateUI();
669 }
670 // Otherwise there is no existing format, so we proceed by checking against the feature name
671 else {
672 ///ystem.err.println("No existing format");
673 format_list.clearSelection();
674 if(Format.isParamType(name)) {
675 ///ystem.err.println("Flag type");
676 // Flags first.
677 ///election_pane.remove(part_pane);
678 card_layout.show(control_pane, FLAG);
679 view_type = FLAG;
680 // Initial value
681 enabled_checkbox.setSelected(false);
682 enabled_checkbox.setEnabled(false);
683 }
684 else {
685 ///ystem.err.println("Value type");
686 ///election_pane.add(part_pane);
687 card_layout.show(control_pane, VALUE);
688 view_type = VALUE;
689 // Initial value
690
691 editor_textarea.setText((String) default_format_map.get(f.toString()));
692 editor_textarea.setCaretPosition(0);
693
694 }
695 newFormat();
696 }
697 format = null;
698 name = null;
699 }
700 part = null;
701 pname = null;
702 f = null;
703 name = null;
704 entry = null;
705 ignore_event = false;
706 }
707 undo.discardAllEdits();
708 }
709 }
710
711 private class FormatListListener
712 implements ListSelectionListener {
713 public void valueChanged(ListSelectionEvent event) {
714 undo_button.setEnabled(false);
715 redo_button.setEnabled(false);
716 default_button.setEnabled(true);
717 newtext = true;
718
719 if(!ignore_event && !event.getValueIsAdjusting()) {
720
721 if(!format_list.isSelectionEmpty()) {
722 existingFormat();
723 ignore_event = true;
724 Format format = (Format)format_list.getSelectedValue();
725 // Try to match the target, remembering the entries within are Entry's
726 Entry an_entry = new Entry(format.getFeature());
727 feature_combobox.setSelectedItem(an_entry);
728 // If we didn't match anything, add it and select it again
729 Entry result_entry = (Entry) feature_combobox.getSelectedItem();
730 if(!an_entry.equals(result_entry)) {
731 feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount());
732 feature_combobox.setSelectedItem(an_entry);
733 }
734
735 // Now use type to determine what controls are visible, and what have initial values.
736 ///ystem.err.println("Determine the correct type.");
737 if(format.isParamType()) {
738 ///ystem.err.println("Flag type - remove part");
739 // Flags first.
740 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, false));
741 card_layout.show(control_pane, FLAG);
742 view_type = FLAG;
743 // Initial value
744 enabled_checkbox.setSelected(format.getState());
745 }
746 else {
747 ///ystem.err.println("Value type - show part");
748 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, true));
749 card_layout.show(control_pane, VALUE);
750 view_type = VALUE;
751 // Initial values
752 // do we have a part?
753 if (format.canHavePart()) {
754 part_combobox.setEnabled(true);
755 // Try to match the part.
756 String part_entry = format.getPart();
757 // Set Selected Item doesn't work so I'll do this manually
758 boolean found = false;
759 for(int i=0; i < part_combobox.getItemCount(); i++) {
760 Part a_part = (Part) part_combobox.getItemAt(i);
761 if(a_part.equals(part_entry)) {
762 part_combobox.setSelectedItem(a_part);
763 found = true;
764 }
765 a_part = null;
766 }
767 // If we didn't match anything, add it and select it again
768 if(!found) {
769 Part a_part = new Part(part_entry, "");
770 part_combobox.insertItemAt(a_part, part_combobox.getItemCount());
771 part_combobox.setSelectedItem(a_part);
772
773 }
774 } else {
775 part_combobox.setEnabled(false);
776 part_combobox.setSelectedIndex(0);
777 }
778 editor_textarea.setText(format.getValue());
779 editor_textarea.setCaretPosition(0);
780
781 }
782
783 //control_pane.updateUI();
784 ignore_event = false;
785 }
786
787 }
788 undo.discardAllEdits();
789 }
790
791 }
792
793 private void newFormat(){
794 editor_textarea.setEditable(false);
795 editor_textarea.setBackground(Color.lightGray);
796 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Disabled_Tooltip"));
797
798 enabled_checkbox.setEnabled(false);
799 undo_button.setEnabled(false);
800 redo_button.setEnabled(false);
801 variable_combobox.setEnabled(false);
802 add_button.setEnabled(true);
803 remove_button.setEnabled(false);
804 default_button.setEnabled(false);
805
806 }
807
808 private void existingFormat(){
809 editor_textarea.setEditable(true);
810 editor_textarea.setBackground(Color.white);
811 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Tooltip"));
812 enabled_checkbox.setEnabled(true);
813 variable_combobox.setEnabled(true);
814 add_button.setEnabled(false);
815 remove_button.setEnabled(true);
816 default_button.setEnabled(true);
817
818 }
819
820 private class VariableListener
821 implements ActionListener {
822 public void actionPerformed(ActionEvent event) {
823 int selected_index = variable_combobox.getSelectedIndex();
824 if (selected_index == 0) return;
825 String selected_value = (String)variable_combobox.getSelectedItem();
826 editor_textarea.insert(selected_value, editor_textarea.getCaretPosition());
827 undo_button.setEnabled(true);
828 variable_combobox.setSelectedIndex(0);
829 }
830
831 }
832
833 private class PartListener
834 implements ActionListener {
835 public void actionPerformed(ActionEvent event) {
836 undo_button.setEnabled(false);
837 redo_button.setEnabled(false);
838 default_button.setEnabled(true);
839 newtext = true;
840 if(!ignore_event) {
841 // 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
842 Entry entry = (Entry) feature_combobox.getSelectedItem();
843 Object f = entry.getFeature();
844 Part part = (Part) part_combobox.getSelectedItem();
845 String pname = part.getName();
846 // You can never add anything to blank-blank
847 if(f.toString().length() == 0 && pname.length() == 0) {
848 add_button.setEnabled(false);
849 remove_button.setEnabled(false);
850 }
851 else {
852 String name = Format.generateName(f, pname);
853 Format format = getFormat(name);
854 // If there is an existing feature, select it.
855 if(format != null) {
856 format_list.setSelectedValue(format, true);
857 // Now use type to determine what controls are visible, and what have initial values.
858 if(format.isParamType()) {
859 // Flags first.
860 ///election_pane.remove(part_pane);
861 card_layout.show(control_pane, FLAG);
862 view_type = FLAG;
863 // Initial value
864 enabled_checkbox.setSelected(format.getState());
865 }
866 else {
867 ///election_pane.add(part_pane);
868 card_layout.show(control_pane, VALUE);
869 view_type = VALUE;
870 // Initial value
871
872 editor_textarea.setText(format.getValue());
873 editor_textarea.setCaretPosition(0);
874
875 }
876 control_pane.updateUI();
877 existingFormat();
878 }
879 else {
880 format_list.clearSelection();
881 if(Format.isParamType(name)) {
882 // Flags first.
883 ///election_pane.remove(part_pane);
884 card_layout.show(control_pane, FLAG);
885 view_type = FLAG;
886 // Initial value
887 enabled_checkbox.setSelected(false);
888 enabled_checkbox.setEnabled(false);
889 }
890 else {
891 ///election_pane.add(part_pane);
892 card_layout.show(control_pane, VALUE);
893 view_type = VALUE;
894 // Initial value
895
896 editor_textarea.setText(part.getDefaultFormat());
897 editor_textarea.setCaretPosition(0);
898
899 }
900 newFormat();
901 }
902 format = null;
903 name = null;
904 }
905
906 pname = null;
907 part = null;
908 f = null;
909 entry = null;
910 }
911 undo.discardAllEdits();
912 }
913 }
914
915 private class RemoveListener
916 implements ActionListener {
917
918 public void actionPerformed(ActionEvent event)
919 {
920 if (!format_list.isSelectionEmpty()) {
921 // Remove the current format
922 removeFormat((Format)format_list.getSelectedValue());
923
924 // Change buttons
925 add_button.setEnabled(true);
926 newFormat();
927 }
928 }
929 }
930
931
932
933 private class DefaultListener
934 implements ActionListener {
935
936 public void actionPerformed(ActionEvent event)
937 {
938 newtext = false;
939 if(!ignore_event) {
940 Entry entry = (Entry) feature_combobox.getSelectedItem();
941 Object f = entry.getFeature();
942 String name ="";
943 String pname="";
944 Part part = null;
945
946 if (entry.canHavePart()){
947 part = (Part) part_combobox.getSelectedItem();
948 pname = part.getName();
949 name = Format.generateName(f, pname);
950 }
951 else{
952 name = entry.toString();
953 }
954
955 Format format = getFormat(name);
956 // If there is an existing feature, select it.
957 if(format != null) {
958 remove_button.setEnabled(true);
959 }
960 else {
961
962 add_button.setEnabled(true);
963 }//endif (format !=null)
964
965 if(Format.isParamType(name)) {
966 // Flags first.
967 card_layout.show(control_pane, FLAG);
968 view_type = FLAG;
969 // Initial value
970 enabled_checkbox.setSelected(false);
971 }
972 else {
973 card_layout.show(control_pane, VALUE);
974 view_type = VALUE;
975 // Initial value
976 if (pname !=null && pname.length()!=0 ){
977 editor_textarea.setText((String) default_format_map.get(pname));
978 editor_textarea.setCaretPosition(0);
979 }
980 else{
981 editor_textarea.setText((String) default_format_map.get(name));
982 editor_textarea.setCaretPosition(0);
983 }
984 }
985
986 }
987 }
988
989 }
990
991 private class UndoListener
992 implements ActionListener {
993
994 public void actionPerformed(ActionEvent event)
995 {
996 try {
997 if (undo.canUndo()) {
998 int pos = editor_textarea.getCaretPosition();
999 undo.undo();
1000 editor_textarea.setCaretPosition(pos);
1001 redo_button.setEnabled(true);
1002
1003 }
1004 if (!undo.canUndo()){
1005 undo_button.setEnabled(false);
1006 }
1007 else{
1008 undo_button.setEnabled(true);
1009 }
1010
1011 } catch (Exception e) {
1012 }
1013 }
1014 }
1015
1016 private class RedoListener
1017 implements ActionListener {
1018 public void actionPerformed(ActionEvent evt) {
1019 try {
1020 if (undo.canRedo()) {
1021 int pos = editor_textarea.getCaretPosition();
1022 undo.redo();
1023 editor_textarea.setCaretPosition(pos);
1024 }
1025 if (!undo.canRedo()){
1026 redo_button.setEnabled(false);
1027 }
1028 else{
1029 redo_button.setEnabled(true);
1030 }
1031
1032 } catch (Exception e) {}
1033 }
1034 }
1035
1036 }
1037
1038 /** 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. */
1039 private class Entry
1040 implements Comparable {
1041 private Classifier classifier = null;
1042 private String text = null;
1043
1044 public Entry(Object object) {
1045 if(object instanceof Classifier) {
1046 classifier = (Classifier)object;
1047 }
1048 else if(object instanceof String) {
1049 text = (String)object;
1050 }
1051 else {
1052 text = "";
1053 }
1054 }
1055
1056 public Entry(String text) {
1057 this.text = text;
1058 }
1059
1060 public boolean canHavePart() {
1061 if (classifier !=null) return true;
1062 return Format.canHavePart(text);
1063 }
1064
1065 public int compareTo(Object object) {
1066 if(object == null) {
1067 return 1;
1068 }
1069 if(toString() == null) {
1070 return -1;
1071 }
1072 else {
1073 String object_str = object.toString();
1074 if(object_str == null) {
1075 return 1;
1076 }
1077 return toString().compareTo(object_str);
1078 }
1079 }
1080
1081 public boolean equals(Object object) {
1082 if(compareTo(object) == 0) {
1083 return true;
1084 }
1085 return false;
1086 }
1087
1088 public Classifier getClassifier() {
1089 return classifier;
1090 }
1091
1092 public Object getFeature() {
1093 if(classifier != null) {
1094 return classifier;
1095 }
1096
1097 if (text.startsWith("<html>")){
1098 return "";
1099 }
1100 return text;
1101 }
1102
1103 public String toString() {
1104 if(classifier != null) {
1105 // Return the classifier - with its CL index shown
1106 return classifier.getPositionString() + StaticStrings.COLON_CHARACTER + StaticStrings.SPACE_CHARACTER + classifier.toString();
1107 }
1108 if (text.equals("")) {
1109 return "<html><body><i>"+Dictionary.get("CDM.FormatManager.AllFeatures")+"</i></body></html>";
1110 }
1111 return text;
1112 }
1113 }
1114
1115 /*
1116 private class GUIChangeTask
1117 implements Runnable {
1118 private boolean to_add;
1119 private JPanel child;
1120 private JPanel parent;
1121 private JPanel replacement;
1122
1123 public GUIChangeTask(JPanel parent, JPanel child, JPanel replacement, boolean to_add) {
1124 this.child = child;
1125 this.parent = parent;
1126 this.replacement = replacement;
1127 this.to_add = to_add;
1128 }
1129
1130 public void run() {
1131 if(to_add) {
1132 parent.remove(replacement);
1133 parent.add(child);
1134 parent.updateUI();
1135 }
1136 else {
1137 parent.remove(child);
1138 parent.add(replacement);
1139 parent.updateUI();
1140 }
1141 }
1142 }
1143 */
1144
1145 /** This class encapsulates all of the information associated with a certain component part of a feature within a html page returned from the receptioninst. */
1146 private class Part
1147 implements Comparable {
1148 /** The default format string for this part */
1149 private String default_format = null;
1150 /** The name of this part */
1151 private String name = null;
1152 /** Constructor - must be provided with all of the details of a part as there are no other setter methods.
1153 * @param name the name of this part
1154 * @param default_format the default format string for this part
1155 */
1156 public Part(String name, String default_format) {
1157 this.default_format = default_format;
1158 this.name = name;
1159 }
1160 /** Compare this part to another object in terms of ordering
1161 * @param obj the other Object
1162 * @return <0 if the object is before, 0 if equal to, and >0 if the object is after this part
1163 */
1164 public int compareTo(Object obj) {
1165 if (obj instanceof Part) {
1166 return name.compareTo(((Part)obj).getName());
1167 }
1168 return name.compareTo(obj.toString());
1169 }
1170
1171 /** Determine if the part is equivelent to some other object
1172 * @param obj the other Object
1173 * @return true is the two objects are equal
1174 */
1175 public boolean equals(Object obj) {
1176 if (obj instanceof Part) {
1177 return name.equals(((Part)obj).getName());
1178 }
1179 return name.equals(obj.toString());
1180 }
1181
1182 /** Retrieve the default format string for this part
1183 * @return the default format String
1184 */
1185 public String getDefaultFormat() {
1186 // Retrieve the format for the super format - either VList or HList
1187 Format default_format_object = getFormat(name);
1188 if(default_format_object != null) {
1189 return default_format_object.getValue();
1190 }
1191 else {
1192 return this.default_format;
1193 }
1194 }
1195 /** Retrieve the name of this part
1196 * @return the name as a String
1197 */
1198 public String getName() {
1199 return name;
1200 }
1201 /** Produce a string representation of this part, which in this case is simply the name again
1202 * @return the name as a String
1203 */
1204 public String toString() {
1205 if (name.equals("")) {
1206 return "<html><body><i>"+Dictionary.get("CDM.FormatManager.AllParts")+"</i></body></html>";
1207 }
1208 return name;
1209 }
1210 }
1211}
Note: See TracBrowser for help on using the repository browser.