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

Last change on this file since 18835 was 18835, checked in by anna, 15 years ago

Fixed the problem that can't set a format statement to empty.

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