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

Last change on this file since 18583 was 18583, checked in by kjdon, 15 years ago

added format: to the Date metadata in DateList default format

  • Property svn:keywords set to Author Date Id Revision
File size: 46.2 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 String format_str = editor_textarea.getText().trim();
607 format_str = (format_str.equals(""))? getDefaultFormatString(format.getName()) : format_str;
608 format.setValue(format_str);
609 model.refresh((DOMProxyListEntry)format);
610 }
611
612 } else {
613 add_button.setEnabled(false);
614
615 }
616
617 }
618 }
619
620 private class EnabledListener
621 implements ActionListener {
622
623 public void actionPerformed(ActionEvent event) {
624 // 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.
625 if(!format_list.isSelectionEmpty()) {
626 Format format = (Format)format_list.getSelectedValue();
627 boolean shouldSave = format.isParamType();
628 if (shouldSave){
629 format.setState(enabled_checkbox.isSelected());
630 model.refresh((DOMProxyListEntry)format);
631 }
632 }
633
634 // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed.
635 }
636 }
637
638 private class FeatureListener
639 implements ActionListener {
640 public void actionPerformed(ActionEvent event) {
641 undo_button.setEnabled(false);
642 redo_button.setEnabled(false);
643 default_button.setEnabled(true);
644 newtext = true;
645
646 if(!ignore_event) {
647 ignore_event = true;
648 Entry entry = (Entry) feature_combobox.getSelectedItem();
649
650 // Step one: reset part
651 if (entry.canHavePart()) {
652 // update AffectedComponents according to current entry
653 part_model = entry.getPartModel();
654 part_combobox.setModel(new DefaultComboBoxModel(part_model.toArray()));
655 part_combobox.updateUI();
656
657 part_combobox.setEnabled(true);
658 part_combobox.setSelectedIndex(part_combobox.getModel().getSize()-1);
659
660 } else {
661 part_combobox.setEnabled(false);
662 part_combobox.setSelectedIndex(0);
663 }
664 // Step two: the rest
665
666 String name = entry.toString();
667 // 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
668 Object f = entry.getFeature();
669 Part part = (Part)part_combobox.getSelectedItem();
670 String pname = part.getName();
671 // You can never add anything to blank-blank
672 if(f.toString().length() == 0 && pname.length() == 0) {
673 add_button.setEnabled(false);
674 remove_button.setEnabled(false);
675 } else {
676
677 Format format = getFormat(Format.generateName(f, pname));
678 // If there is an existing feature, select it, and use it to determine what controls are visible
679
680 if(format != null) {
681 ///ystem.err.println("There is an existing format!");
682 format_list.setSelectedValue(format, true);
683 // Now use type to determine what controls are visible, and what have initial values.
684 if(format.isParamType()) {
685 ///ystem.err.println("Flag type");
686 // Flags first.
687 ///election_pane.remove(part_pane);
688 card_layout.show(control_pane, FLAG);
689 view_type = FLAG;
690 // Initial value
691 enabled_checkbox.setSelected(format.getState());
692 } else {
693 ///ystem.err.println("Value type");
694 ///election_pane.add(part_pane);
695 card_layout.show(control_pane, VALUE);
696 view_type = VALUE;
697 // Initial value
698
699 editor_textarea.setText(format.getValue());
700 editor_textarea.setCaretPosition(0);
701
702 }
703 existingFormat();
704 control_pane.updateUI();
705 }
706 // Otherwise there is no existing format, so we proceed by checking against the feature name
707 else {
708 ///ystem.err.println("No existing format");
709 format_list.clearSelection();
710 if(Format.isParamType(name)) {
711 ///ystem.err.println("Flag type");
712 // Flags first.
713 ///election_pane.remove(part_pane);
714 card_layout.show(control_pane, FLAG);
715 view_type = FLAG;
716 // Initial value
717 enabled_checkbox.setSelected(false);
718 enabled_checkbox.setEnabled(false);
719 } else {
720 ///ystem.err.println("Value type");
721 ///election_pane.add(part_pane);
722 card_layout.show(control_pane, VALUE);
723 view_type = VALUE;
724 // Initial value
725
726 String feature_default_format = (String) default_format_map.get(f.toString());
727 if (feature_default_format != null) {
728
729 editor_textarea.setText(feature_default_format);
730 } else {
731 editor_textarea.setText(part.getDefaultFormat());
732 }
733 editor_textarea.setCaretPosition(0);
734
735 }
736 newFormat();
737 }
738 format = null;
739 name = null;
740 }
741 part = null;
742 pname = null;
743 f = null;
744 name = null;
745 entry = null;
746 ignore_event = false;
747 }
748 undo.discardAllEdits();
749 }
750 }
751
752 private class FormatListListener
753 implements ListSelectionListener {
754 public void valueChanged(ListSelectionEvent event) {
755 undo_button.setEnabled(false);
756 redo_button.setEnabled(false);
757 default_button.setEnabled(true);
758 newtext = true;
759
760 if(!ignore_event && !event.getValueIsAdjusting()) {
761
762 if(!format_list.isSelectionEmpty()) {
763 existingFormat();
764 ignore_event = true;
765 Format format = (Format)format_list.getSelectedValue();
766 // Try to match the target, remembering the entries within are Entry's
767 Entry an_entry = new Entry(format.getFeature());
768 feature_combobox.setSelectedItem(an_entry);
769 // If we didn't match anything, add it and select it again
770 Entry result_entry = (Entry) feature_combobox.getSelectedItem();
771 if(!an_entry.equals(result_entry)) {
772 feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount());
773 feature_combobox.setSelectedItem(an_entry);
774 }
775
776 // Now use type to determine what controls are visible, and what have initial values.
777 ///ystem.err.println("Determine the correct type.");
778 if(format.isParamType()) {
779 ///ystem.err.println("Flag type - remove part");
780 // Flags first.
781 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, false));
782 card_layout.show(control_pane, FLAG);
783 view_type = FLAG;
784 // Initial value
785 enabled_checkbox.setSelected(format.getState());
786 } else {
787 ///ystem.err.println("Value type - show part");
788 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, true));
789 card_layout.show(control_pane, VALUE);
790 view_type = VALUE;
791 // Initial values
792 // do we have a part?
793 if (format.canHavePart()) {
794 part_combobox.setEnabled(true);
795
796 // Should update the part list and re-render the part ComboBox here
797 part_model = result_entry.getPartModel();
798 part_combobox.setModel(new DefaultComboBoxModel(part_model.toArray()));
799 part_combobox.updateUI();
800
801 // Try to match the part.
802 String part_entry = format.getPart();
803 // Set Selected Item doesn't work so I'll do this manually
804 boolean found = false;
805 for(int i=0; i < part_combobox.getItemCount(); i++) {
806 Part a_part = (Part) part_combobox.getItemAt(i);
807 if(a_part.equals(part_entry)) {
808 part_combobox.setSelectedItem(a_part);
809 found = true;
810 }
811 a_part = null;
812 }
813 // If we didn't match anything, add it and select it again
814 if(!found) {
815 Part a_part = new Part(part_entry, "");
816 part_combobox.insertItemAt(a_part, part_combobox.getItemCount());
817 part_combobox.setSelectedItem(a_part);
818
819 }
820 } else {
821 part_combobox.setEnabled(false);
822 part_combobox.setSelectedIndex(0);
823 }
824 editor_textarea.setText(format.getValue());
825 editor_textarea.setCaretPosition(0);
826
827 }
828
829 //control_pane.updateUI();
830 ignore_event = false;
831 }
832
833 }
834 undo.discardAllEdits();
835 }
836
837 }
838
839 private void newFormat(){
840 editor_textarea.setEditable(false);
841 editor_textarea.setBackground(Color.lightGray);
842 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Disabled_Tooltip"));
843
844 enabled_checkbox.setEnabled(false);
845 undo_button.setEnabled(false);
846 redo_button.setEnabled(false);
847 variable_combobox.setEnabled(false);
848 add_button.setEnabled(true);
849 remove_button.setEnabled(false);
850 default_button.setEnabled(false);
851
852 }
853
854 private void existingFormat(){
855 editor_textarea.setEditable(true);
856 editor_textarea.setBackground(Color.white);
857 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Tooltip"));
858 enabled_checkbox.setEnabled(true);
859 variable_combobox.setEnabled(true);
860 add_button.setEnabled(false);
861 remove_button.setEnabled(true);
862 default_button.setEnabled(true);
863
864 }
865
866 private class VariableListener
867 implements ActionListener {
868 public void actionPerformed(ActionEvent event) {
869 int selected_index = variable_combobox.getSelectedIndex();
870 if (selected_index == 0) return;
871 String selected_value = (String)variable_combobox.getSelectedItem();
872 editor_textarea.insert(selected_value, editor_textarea.getCaretPosition());
873 undo_button.setEnabled(true);
874 variable_combobox.setSelectedIndex(0);
875 }
876
877 }
878
879 private class PartListener
880 implements ActionListener {
881 public void actionPerformed(ActionEvent event) {
882 undo_button.setEnabled(false);
883 redo_button.setEnabled(false);
884 default_button.setEnabled(true);
885 newtext = true;
886 if(!ignore_event) {
887 // 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
888 Entry entry = (Entry) feature_combobox.getSelectedItem();
889 Object f = entry.getFeature();
890 Part part = (Part) part_combobox.getSelectedItem();
891 String pname = part.getName();
892 // You can never add anything to blank-blank
893 if(f.toString().length() == 0 && pname.length() == 0) {
894 add_button.setEnabled(false);
895 remove_button.setEnabled(false);
896 } else {
897 String name = Format.generateName(f, pname);
898 Format format = getFormat(name);
899 // If there is an existing feature, select it.
900 if(format != null) {
901 format_list.setSelectedValue(format, true);
902 // Now use type to determine what controls are visible, and what have initial values.
903 if(format.isParamType()) {
904 // Flags first.
905 ///election_pane.remove(part_pane);
906 card_layout.show(control_pane, FLAG);
907 view_type = FLAG;
908 // Initial value
909 enabled_checkbox.setSelected(format.getState());
910 } else {
911 ///election_pane.add(part_pane);
912 card_layout.show(control_pane, VALUE);
913 view_type = VALUE;
914 // Initial value
915
916 editor_textarea.setText(format.getValue());
917 editor_textarea.setCaretPosition(0);
918
919 }
920 control_pane.updateUI();
921 existingFormat();
922 } else {
923 format_list.clearSelection();
924 if(Format.isParamType(name)) {
925 // Flags first.
926 ///election_pane.remove(part_pane);
927 card_layout.show(control_pane, FLAG);
928 view_type = FLAG;
929 // Initial value
930 enabled_checkbox.setSelected(false);
931 enabled_checkbox.setEnabled(false);
932 } else {
933 ///election_pane.add(part_pane);
934 card_layout.show(control_pane, VALUE);
935 view_type = VALUE;
936 // Initial value
937
938 editor_textarea.setText(part.getDefaultFormat());
939 editor_textarea.setCaretPosition(0);
940
941 }
942 newFormat();
943 }
944 format = null;
945 name = null;
946 }
947
948 pname = null;
949 part = null;
950 f = null;
951 entry = null;
952 }
953 undo.discardAllEdits();
954 }
955 }
956
957 private class RemoveListener
958 implements ActionListener {
959
960 public void actionPerformed(ActionEvent event) {
961 if (!format_list.isSelectionEmpty()) {
962 // Remove the current format
963 removeFormat((Format)format_list.getSelectedValue());
964
965 // Change buttons
966 add_button.setEnabled(true);
967 newFormat();
968 }
969 }
970 }
971
972
973
974 private class DefaultListener
975 implements ActionListener {
976
977 public void actionPerformed(ActionEvent event) {
978 newtext = false;
979 if(!ignore_event) {
980 Entry entry = (Entry) feature_combobox.getSelectedItem();
981 Object f = entry.getFeature();
982 String name ="";
983 String pname="";
984 Part part = null;
985
986 if (entry.canHavePart()){
987 part = (Part) part_combobox.getSelectedItem();
988 pname = part.getName();
989 name = Format.generateName(f, pname);
990 } else{
991 name = entry.toString();
992 }
993
994 Format format = getFormat(name);
995 // If there is an existing feature, select it.
996 if(format != null) {
997 remove_button.setEnabled(true);
998 } else {
999
1000 add_button.setEnabled(true);
1001 }//endif (format !=null)
1002
1003 if(Format.isParamType(name)) {
1004 // Flags first.
1005 card_layout.show(control_pane, FLAG);
1006 view_type = FLAG;
1007 // Initial value
1008 enabled_checkbox.setSelected(false);
1009 } else {
1010 card_layout.show(control_pane, VALUE);
1011 view_type = VALUE;
1012 // Initial value
1013 if (pname !=null && pname.length()!=0 ){
1014 editor_textarea.setText((String) default_format_map.get(pname));
1015 editor_textarea.setCaretPosition(0);
1016 } else{
1017 editor_textarea.setText((String) default_format_map.get(name));
1018 editor_textarea.setCaretPosition(0);
1019 }
1020 }
1021
1022 }
1023 }
1024
1025 }
1026
1027 private class UndoListener
1028 implements ActionListener {
1029
1030 public void actionPerformed(ActionEvent event) {
1031 try {
1032 if (undo.canUndo()) {
1033 int pos = editor_textarea.getCaretPosition();
1034 redo_button.setEnabled(true);
1035 undo.undo();
1036 if (pos > 0)
1037 editor_textarea.setCaretPosition(pos-1);
1038 else
1039 editor_textarea.setCaretPosition(pos);
1040 }
1041 if (!undo.canUndo()){
1042 undo_button.setEnabled(false);
1043 } else{
1044 undo_button.setEnabled(true);
1045 }
1046
1047 } catch (Exception e) {
1048
1049 }
1050 }
1051 }
1052
1053 private class RedoListener
1054 implements ActionListener {
1055 public void actionPerformed(ActionEvent evt) {
1056 try {
1057 if (undo.canRedo()) {
1058 int pos = editor_textarea.getCaretPosition();
1059 undo.redo();
1060 editor_textarea.setCaretPosition(pos);
1061 }
1062 if (!undo.canRedo()){
1063 redo_button.setEnabled(false);
1064 } else{
1065 redo_button.setEnabled(true);
1066 }
1067
1068 } catch (Exception e) {}
1069 }
1070 }
1071
1072 }
1073
1074 /** 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. */
1075 private class Entry
1076 implements Comparable {
1077 private Classifier classifier = null;
1078 private String text = null;
1079
1080 public Entry(Object object) {
1081 if(object instanceof Classifier) {
1082 classifier = (Classifier)object;
1083 } else if(object instanceof String) {
1084 text = (String)object;
1085 } else {
1086 text = "";
1087 }
1088 }
1089
1090 public Entry(String text) {
1091 this.text = text;
1092 }
1093
1094 public boolean canHavePart() {
1095 if (classifier !=null) return true;
1096 return Format.canHavePart(text);
1097 }
1098
1099 public int compareTo(Object object) {
1100 if(object == null) {
1101 return 1;
1102 }
1103 if(toString() == null) {
1104 return -1;
1105 } else {
1106 String object_str = object.toString();
1107 if(object_str == null) {
1108 return 1;
1109 }
1110 return toString().compareTo(object_str);
1111 }
1112 }
1113
1114 public boolean equals(Object object) {
1115 if(compareTo(object) == 0) {
1116 return true;
1117 }
1118 return false;
1119 }
1120
1121 public Classifier getClassifier() {
1122 return classifier;
1123 }
1124
1125 public Object getFeature() {
1126 if(classifier != null) {
1127 return classifier;
1128 }
1129
1130 if (text.startsWith("<html>")){
1131 return "";
1132 }
1133 return text;
1134 }
1135
1136 public ArrayList getPartModel(){
1137 DebugStream.println("getPartModel(): get appopriate affected components of this classifier");
1138 String classifier_name = classifier == null ? "" : classifier.toString();
1139 if(!classifier_name.equals("")){
1140 classifier_name = classifier_name.substring(0, classifier_name.indexOf("-")).trim();
1141 }
1142 ArrayList part_model = new ArrayList();
1143 // DateList only has DateList component
1144 if(classifier_name.equals("DateList")){
1145 part_model.add(new Part(DATELIST, DATELIST_DEFAULT_FORMAT));
1146 }
1147 // Other Format Entries, display the default Affected Components
1148 else if(classifier_name.equals("")){
1149 part_model = buildPartModel();
1150 }
1151 // Other Classifiers have HList and VList as Affected Component
1152 else {
1153 part_model.add(new Part(HLIST, HLIST_DEFAULT_FORMAT));
1154 part_model.add(new Part(VLIST, VLIST_DEFAULT_FORMAT));
1155 }
1156 return part_model;
1157 }
1158
1159 public String toString() {
1160 if(classifier != null) {
1161 // Return the classifier - with its CL index shown
1162 return classifier.getPositionString() + StaticStrings.COLON_CHARACTER + StaticStrings.SPACE_CHARACTER + classifier.toString();
1163 }
1164 if (text.equals("")) {
1165 return "<html><body><i>"+Dictionary.get("CDM.FormatManager.AllFeatures")+"</i></body></html>";
1166 }
1167 return text;
1168 }
1169 }
1170
1171 /*
1172 private class GUIChangeTask
1173 implements Runnable {
1174 private boolean to_add;
1175 private JPanel child;
1176 private JPanel parent;
1177 private JPanel replacement;
1178
1179 public GUIChangeTask(JPanel parent, JPanel child, JPanel replacement, boolean to_add) {
1180 this.child = child;
1181 this.parent = parent;
1182 this.replacement = replacement;
1183 this.to_add = to_add;
1184 }
1185
1186 public void run() {
1187 if(to_add) {
1188 parent.remove(replacement);
1189 parent.add(child);
1190 parent.updateUI();
1191 }
1192 else {
1193 parent.remove(child);
1194 parent.add(replacement);
1195 parent.updateUI();
1196 }
1197 }
1198 }
1199 */
1200
1201 /** This class encapsulates all of the information associated with a certain component part of a feature within a html page returned from the receptioninst. */
1202 private class Part
1203 implements Comparable {
1204 /** The default format string for this part */
1205 private String default_format = null;
1206 /** The name of this part */
1207 private String name = null;
1208 /** Constructor - must be provided with all of the details of a part as there are no other setter methods.
1209 * @param name the name of this part
1210 * @param default_format the default format string for this part
1211 */
1212 public Part(String name, String default_format) {
1213 this.default_format = default_format;
1214 this.name = name;
1215 }
1216 /** Compare this part to another object in terms of ordering
1217 * @param obj the other Object
1218 * @return <0 if the object is before, 0 if equal to, and >0 if the object is after this part
1219 */
1220 public int compareTo(Object obj) {
1221 if (obj instanceof Part) {
1222 return name.compareTo(((Part)obj).getName());
1223 }
1224 return name.compareTo(obj.toString());
1225 }
1226
1227 /** Determine if the part is equivelent to some other object
1228 * @param obj the other Object
1229 * @return true is the two objects are equal
1230 */
1231 public boolean equals(Object obj) {
1232 if (obj instanceof Part) {
1233 return name.equals(((Part)obj).getName());
1234 }
1235 return name.equals(obj.toString());
1236 }
1237
1238 /** Retrieve the default format string for this part
1239 * @return the default format String
1240 */
1241 public String getDefaultFormat() {
1242 // Retrieve the format for the super format - either VList or HList
1243 Format default_format_object = getFormat(name);
1244 if(default_format_object != null) {
1245 return default_format_object.getValue();
1246 } else {
1247 return this.default_format;
1248 }
1249 }
1250 /** Retrieve the name of this part
1251 * @return the name as a String
1252 */
1253 public String getName() {
1254 return name;
1255 }
1256 /** Produce a string representation of this part, which in this case is simply the name again
1257 * @return the name as a String
1258 */
1259 public String toString() {
1260 if (name.equals("")) {
1261 return "<html><body><i>"+Dictionary.get("CDM.FormatManager.AllParts")+"</i></body></html>";
1262 }
1263 return name;
1264 }
1265 }
1266}
Note: See TracBrowser for help on using the repository browser.