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

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

Changed format_map to default_format_map to be a bit more obvious, and fixed a bug where DocumentHeading, DocumentText and DocumentButtons defaults weren't available.

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