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

Last change on this file since 15137 was 15137, checked in by kjdon, 16 years ago

added NavigationBar into the list of format options. I added pulldown as the default value - this is the only value that currently makes sense to add. Any other value you get the default nav bar

  • Property svn:keywords set to Author Date Id Revision
File size: 45.3 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}{[dc.Date],[exp.Date],[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 feature_model = buildFeatureModel();
316 part_model = buildPartModel();
317 variable_model = buildVariableModel();
318
319 // Create
320 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Formats", "formatstatements");
321
322 format_list = new JList(model);
323
324 selection_pane = new JPanel();
325 JPanel feature_pane = new JPanel();
326 JLabel feature_label = new JLabel(Dictionary.get("CDM.FormatManager.Feature"));
327
328 feature_combobox = new JComboBox(feature_model.toArray());
329 feature_combobox.setOpaque(!Utility.isMac());
330 feature_combobox.setPreferredSize(FIELD_SIZE);
331 feature_combobox.setEditable(false);
332 feature_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Feature_Tooltip"));
333
334 part_pane = new JPanel();
335 JLabel part_label = new JLabel(Dictionary.get("CDM.FormatManager.Part"));
336 part_combobox = new JComboBox(part_model.toArray());
337 part_combobox.setOpaque(!Utility.isMac());
338 part_combobox.setPreferredSize(FIELD_SIZE);
339 part_combobox.setEditable(false);
340 part_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Part_Tooltip"));
341
342 blank_pane = new JPanel();
343
344 JPanel center_pane = new JPanel();
345
346 card_layout = new CardLayout();
347 control_pane = new JPanel();
348
349 JPanel blank_pane = new JPanel();
350
351 JPanel editor_pane = new JPanel();
352 JPanel editor_header_pane = new JPanel();
353 JLabel editor_label = new JLabel(Dictionary.get("CDM.FormatManager.Editor"));
354
355 editor_textarea = new JTextArea();
356 editor_textarea.setBackground(Configuration.getColor("coloring.editable_background", false));
357 editor_textarea.setCaretPosition(0);
358 editor_textarea.setLineWrap(true);
359 editor_textarea.setRows(6);
360 editor_textarea.setWrapStyleWord(false);
361 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Add_Tooltip"));
362
363 JPanel variable_pane = new JPanel();
364
365 variable_combobox = new JComboBox(variable_model.toArray());
366 variable_combobox.setOpaque(!Utility.isMac());
367 variable_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Variable_Tooltip"));
368
369 insert_button = new GLIButton(Dictionary.get("CDM.FormatManager.Insert"), Dictionary.get("CDM.FormatManager.Insert_Tooltip"));
370
371 default_button = new GLIButton(Dictionary.get("CDM.FormatManager.Default"), Dictionary.get("CDM.FormatManager.Default_Tooltip"));
372
373 JPanel flag_pane = new JPanel();
374 enabled_checkbox = new JCheckBox(Dictionary.get("CDM.FormatManager.Enabled"));
375
376 JPanel button_pane = new JPanel();
377 add_button = new GLIButton(Dictionary.get("CDM.FormatManager.Add"), Dictionary.get("CDM.FormatManager.Add_Tooltip"));
378 add_button.setEnabled(false);
379
380 remove_button = new GLIButton(Dictionary.get("CDM.FormatManager.Remove"), Dictionary.get("CDM.FormatManager.Remove_Tooltip"));
381 remove_button.setEnabled(false);
382
383 undo_button = new GLIButton(Dictionary.get("General.Undo"), Dictionary.get("General.Undo_Tooltip"));
384 undo_button.setEnabled(false);
385
386 redo_button = new GLIButton(Dictionary.get("General.Redo"), Dictionary.get("General.Redo_Tooltip"));
387 redo_button.setEnabled(false);
388
389 // Connect
390 add_button.addActionListener(new AddListener());
391 remove_button.addActionListener(new RemoveListener());
392 default_button.addActionListener(new DefaultListener());
393 undo_button.addActionListener(new UndoListener());
394 redo_button.addActionListener(new RedoListener());
395 enabled_checkbox.addActionListener(new EnabledListener());
396 feature_combobox.addActionListener(new FeatureListener());
397 part_combobox.addActionListener(new PartListener());
398
399 editor_textarea.getDocument().addDocumentListener(new EditorListener());
400 // Listen for undo and redo events
401 editor_textarea.getDocument().addUndoableEditListener(new UndoableEditListener() {
402 public void undoableEditHappened(UndoableEditEvent evt) {
403 undo.addEdit(evt.getEdit());
404 }
405 });
406
407
408 format_list.addListSelectionListener(new FormatListListener());
409 variable_combobox.addActionListener(new VariableListener());
410
411 // Layout
412 JPanel format_list_pane = new JPanel();
413 format_list_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
414 format_list_pane.setLayout(new BorderLayout());
415 format_list_pane.add(new JScrollPane(format_list), BorderLayout.CENTER);
416
417
418 feature_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
419 feature_pane.setLayout(new BorderLayout(5,0));
420 feature_pane.add(feature_label, BorderLayout.WEST);
421 feature_pane.add(feature_combobox, BorderLayout.CENTER);
422
423 part_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
424 part_pane.setLayout(new BorderLayout(5, 0));
425 part_pane.add(part_label, BorderLayout.WEST);
426 part_pane.add(part_combobox, BorderLayout.CENTER);
427
428
429 flag_pane.add(enabled_checkbox);
430
431 editor_header_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
432 editor_header_pane.setLayout(new GridLayout(1,3));
433 editor_header_pane.add(editor_label);
434
435 JPanel rupanel = new JPanel();
436 rupanel.setLayout(new GridLayout(1,2));
437 rupanel.add(undo_button);
438 rupanel.add(redo_button);
439
440 variable_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
441 variable_pane.setLayout(new GridLayout(1,3));
442 variable_pane.add(new JPanel());
443 variable_pane.add(variable_combobox);
444 variable_pane.add(rupanel);
445
446 editor_pane.setLayout(new BorderLayout());
447 editor_pane.add(editor_header_pane, BorderLayout.NORTH);
448 editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER);
449
450 selection_pane.setLayout(new BorderLayout());
451 selection_pane.add(part_pane, BorderLayout.NORTH);
452 selection_pane.add(editor_pane, BorderLayout.CENTER);
453 selection_pane.add(variable_pane, BorderLayout.SOUTH);
454
455 control_pane.setLayout(card_layout);
456 control_pane.add(flag_pane, FLAG);
457 control_pane.add(selection_pane, VALUE);
458 control_pane.add(blank_pane, BLANK);
459
460
461 button_pane.setLayout(new GridLayout(1,3));
462 button_pane.add(add_button);
463 button_pane.add(remove_button);
464 button_pane.add(default_button);
465
466
467 center_pane.setLayout(new BorderLayout());
468 center_pane.add(feature_pane, BorderLayout.NORTH);
469 center_pane.add(control_pane, BorderLayout.CENTER);
470 center_pane.add(button_pane, BorderLayout.SOUTH);
471
472 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
473 setLayout(new BorderLayout());
474 add(header_pane, BorderLayout.NORTH);
475 add(format_list_pane, BorderLayout.CENTER);
476 add(center_pane, BorderLayout.SOUTH);
477 ready = true;
478 }
479
480 public void destroy() {
481 }
482
483
484
485 /** Overriden to ensure that the instructions pane is scrolled to the top.
486 */
487 public void gainFocus() {
488 // This is only necessary if the components have been realized
489 if(ready) {
490 model.refresh();
491
492 // Update the feature model, trying to maintain the same selected object
493 Object selected_feature = feature_combobox.getSelectedItem();
494 feature_model = buildFeatureModel();
495 feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray()));
496 feature_combobox.setSelectedItem(selected_feature);
497
498 // Update the variable model,
499 variable_model = buildVariableModel();
500 variable_combobox.setModel(new DefaultComboBoxModel(variable_model.toArray()));
501 }
502 }
503
504 public void loseFocus() {
505 // Force all of the Formats to update their names with the correct values.
506 // do we need to do this on loseFocus???
507 model.refresh();
508 }
509
510 public Format getCurrentFormat() {
511 return (Format)format_list.getSelectedValue();
512
513 }
514
515 /** 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 */
516 private class AddListener
517 implements ActionListener {
518
519 public void actionPerformed(ActionEvent event) {
520
521 ignore_event = true; // Prevent format_list excetera propagating events
522
523 Entry entry = (Entry) feature_combobox.getSelectedItem();
524 Object f = entry.getFeature();
525 String p = "";
526 if (entry.canHavePart()) {
527 p = ((Part)part_combobox.getSelectedItem()).getName();
528 }
529
530 // Add a new format string of the appropriate type
531 Format format = null;
532 if (view_type.equals(FLAG)) {
533 format = new Format(f, p, enabled_checkbox.isSelected());
534 } else {
535 format = new Format(f, p, editor_textarea.getText());
536
537 }
538
539
540 addFormat(format);
541 existingFormat();
542
543 // Update list selection
544 format_list.setSelectedValue(format, true);
545 format = null;
546 p = null;
547 f = null;
548 entry = null;
549 ignore_event = false;
550 }
551 }
552
553 private class EditorListener
554 implements DocumentListener {
555
556 public void changedUpdate(DocumentEvent e) {
557
558 update();
559 }
560
561 public void insertUpdate(DocumentEvent e) {
562 update();
563 updateUndo("insert");
564
565 }
566
567 public void removeUpdate(DocumentEvent e) {
568 update();
569 updateUndo("remove");
570
571 }
572
573 private void updateUndo(String from){
574
575 if (!newtext){
576 undo_button.setEnabled(true);
577 }
578
579 if (editor_textarea.getText().length()!=0 && newtext){
580 newtext = false;
581 }
582 }
583
584 public void update() {
585
586 // Determine if replace should be enabled
587 if(!format_list.isSelectionEmpty()) {
588 Format format = (Format)format_list.getSelectedValue();
589 boolean shouldSave = !format.isParamType();
590
591 if (shouldSave){
592 String format_str = editor_textarea.getText().trim();
593 format_str = (format_str.equals(""))? getDefaultFormatString(format.getName()) : format_str;
594 format.setValue(format_str);
595 model.refresh((DOMProxyListEntry)format);
596 }
597
598 } else {
599 add_button.setEnabled(false);
600
601 }
602
603 }
604 }
605
606 private class EnabledListener
607 implements ActionListener {
608
609 public void actionPerformed(ActionEvent event) {
610 // 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.
611 if(!format_list.isSelectionEmpty()) {
612 Format format = (Format)format_list.getSelectedValue();
613 boolean shouldSave = format.isParamType();
614 if (shouldSave){
615 format.setState(enabled_checkbox.isSelected());
616 model.refresh((DOMProxyListEntry)format);
617 }
618 }
619
620 // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed.
621 }
622 }
623
624 private class FeatureListener
625 implements ActionListener {
626 public void actionPerformed(ActionEvent event) {
627 undo_button.setEnabled(false);
628 redo_button.setEnabled(false);
629 default_button.setEnabled(true);
630 newtext = true;
631
632 if(!ignore_event) {
633 ignore_event = true;
634 Entry entry = (Entry) feature_combobox.getSelectedItem();
635
636 // Step one: reset part
637 if (entry.canHavePart()) {
638 // update AffectedComponents according to current entry
639 part_model = entry.getPartModel();
640 part_combobox.setModel(new DefaultComboBoxModel(part_model.toArray()));
641 part_combobox.updateUI();
642
643 part_combobox.setEnabled(true);
644 part_combobox.setSelectedIndex(part_combobox.getModel().getSize()-1);
645
646 } else {
647 part_combobox.setEnabled(false);
648 part_combobox.setSelectedIndex(0);
649 }
650 // Step two: the rest
651
652 String name = entry.toString();
653 // 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
654 Object f = entry.getFeature();
655 Part part = (Part)part_combobox.getSelectedItem();
656 String pname = part.getName();
657 // You can never add anything to blank-blank
658 if(f.toString().length() == 0 && pname.length() == 0) {
659 add_button.setEnabled(false);
660 remove_button.setEnabled(false);
661 } else {
662
663 Format format = getFormat(Format.generateName(f, pname));
664 // If there is an existing feature, select it, and use it to determine what controls are visible
665
666 if(format != null) {
667 ///ystem.err.println("There is an existing format!");
668 format_list.setSelectedValue(format, true);
669 // Now use type to determine what controls are visible, and what have initial values.
670 if(format.isParamType()) {
671 ///ystem.err.println("Flag type");
672 // Flags first.
673 ///election_pane.remove(part_pane);
674 card_layout.show(control_pane, FLAG);
675 view_type = FLAG;
676 // Initial value
677 enabled_checkbox.setSelected(format.getState());
678 } else {
679 ///ystem.err.println("Value type");
680 ///election_pane.add(part_pane);
681 card_layout.show(control_pane, VALUE);
682 view_type = VALUE;
683 // Initial value
684
685 editor_textarea.setText(format.getValue());
686 editor_textarea.setCaretPosition(0);
687
688 }
689 existingFormat();
690 control_pane.updateUI();
691 }
692 // Otherwise there is no existing format, so we proceed by checking against the feature name
693 else {
694 ///ystem.err.println("No existing format");
695 format_list.clearSelection();
696 if(Format.isParamType(name)) {
697 ///ystem.err.println("Flag type");
698 // Flags first.
699 ///election_pane.remove(part_pane);
700 card_layout.show(control_pane, FLAG);
701 view_type = FLAG;
702 // Initial value
703 enabled_checkbox.setSelected(false);
704 enabled_checkbox.setEnabled(false);
705 } else {
706 ///ystem.err.println("Value type");
707 ///election_pane.add(part_pane);
708 card_layout.show(control_pane, VALUE);
709 view_type = VALUE;
710 // Initial value
711
712 String feature_default_format = (String) default_format_map.get(f.toString());
713 if (feature_default_format != null) {
714
715 editor_textarea.setText(feature_default_format);
716 } else {
717 editor_textarea.setText(part.getDefaultFormat());
718 }
719 editor_textarea.setCaretPosition(0);
720
721 }
722 newFormat();
723 }
724 format = null;
725 name = null;
726 }
727 part = null;
728 pname = null;
729 f = null;
730 name = null;
731 entry = null;
732 ignore_event = false;
733 }
734 undo.discardAllEdits();
735 }
736 }
737
738 private class FormatListListener
739 implements ListSelectionListener {
740 public void valueChanged(ListSelectionEvent event) {
741 undo_button.setEnabled(false);
742 redo_button.setEnabled(false);
743 default_button.setEnabled(true);
744 newtext = true;
745
746 if(!ignore_event && !event.getValueIsAdjusting()) {
747
748 if(!format_list.isSelectionEmpty()) {
749 existingFormat();
750 ignore_event = true;
751 Format format = (Format)format_list.getSelectedValue();
752 // Try to match the target, remembering the entries within are Entry's
753 Entry an_entry = new Entry(format.getFeature());
754 feature_combobox.setSelectedItem(an_entry);
755 // If we didn't match anything, add it and select it again
756 Entry result_entry = (Entry) feature_combobox.getSelectedItem();
757 if(!an_entry.equals(result_entry)) {
758 feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount());
759 feature_combobox.setSelectedItem(an_entry);
760 }
761
762 // Now use type to determine what controls are visible, and what have initial values.
763 ///ystem.err.println("Determine the correct type.");
764 if(format.isParamType()) {
765 ///ystem.err.println("Flag type - remove part");
766 // Flags first.
767 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, false));
768 card_layout.show(control_pane, FLAG);
769 view_type = FLAG;
770 // Initial value
771 enabled_checkbox.setSelected(format.getState());
772 } else {
773 ///ystem.err.println("Value type - show part");
774 ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, true));
775 card_layout.show(control_pane, VALUE);
776 view_type = VALUE;
777 // Initial values
778 // do we have a part?
779 if (format.canHavePart()) {
780 part_combobox.setEnabled(true);
781
782 // Should update the part list and re-render the part ComboBox here
783 part_model = result_entry.getPartModel();
784 part_combobox.setModel(new DefaultComboBoxModel(part_model.toArray()));
785 part_combobox.updateUI();
786
787 // Try to match the part.
788 String part_entry = format.getPart();
789 // Set Selected Item doesn't work so I'll do this manually
790 boolean found = false;
791 for(int i=0; i < part_combobox.getItemCount(); i++) {
792 Part a_part = (Part) part_combobox.getItemAt(i);
793 if(a_part.equals(part_entry)) {
794 part_combobox.setSelectedItem(a_part);
795 found = true;
796 }
797 a_part = null;
798 }
799 // If we didn't match anything, add it and select it again
800 if(!found) {
801 Part a_part = new Part(part_entry, "");
802 part_combobox.insertItemAt(a_part, part_combobox.getItemCount());
803 part_combobox.setSelectedItem(a_part);
804
805 }
806 } else {
807 part_combobox.setEnabled(false);
808 part_combobox.setSelectedIndex(0);
809 }
810 editor_textarea.setText(format.getValue());
811 editor_textarea.setCaretPosition(0);
812
813 }
814
815 //control_pane.updateUI();
816 ignore_event = false;
817 }
818
819 }
820 undo.discardAllEdits();
821 }
822
823 }
824
825 private void newFormat(){
826 editor_textarea.setEditable(false);
827 editor_textarea.setBackground(Color.lightGray);
828 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Disabled_Tooltip"));
829
830 enabled_checkbox.setEnabled(false);
831 undo_button.setEnabled(false);
832 redo_button.setEnabled(false);
833 variable_combobox.setEnabled(false);
834 add_button.setEnabled(true);
835 remove_button.setEnabled(false);
836 default_button.setEnabled(false);
837
838 }
839
840 private void existingFormat(){
841 editor_textarea.setEditable(true);
842 editor_textarea.setBackground(Color.white);
843 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Tooltip"));
844 enabled_checkbox.setEnabled(true);
845 variable_combobox.setEnabled(true);
846 add_button.setEnabled(false);
847 remove_button.setEnabled(true);
848 default_button.setEnabled(true);
849
850 }
851
852 private class VariableListener
853 implements ActionListener {
854 public void actionPerformed(ActionEvent event) {
855 int selected_index = variable_combobox.getSelectedIndex();
856 if (selected_index == 0) return;
857 String selected_value = (String)variable_combobox.getSelectedItem();
858 editor_textarea.insert(selected_value, editor_textarea.getCaretPosition());
859 undo_button.setEnabled(true);
860 variable_combobox.setSelectedIndex(0);
861 }
862
863 }
864
865 private class PartListener
866 implements ActionListener {
867 public void actionPerformed(ActionEvent event) {
868 undo_button.setEnabled(false);
869 redo_button.setEnabled(false);
870 default_button.setEnabled(true);
871 newtext = true;
872 if(!ignore_event) {
873 // 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
874 Entry entry = (Entry) feature_combobox.getSelectedItem();
875 Object f = entry.getFeature();
876 Part part = (Part) part_combobox.getSelectedItem();
877 String pname = part.getName();
878 // You can never add anything to blank-blank
879 if(f.toString().length() == 0 && pname.length() == 0) {
880 add_button.setEnabled(false);
881 remove_button.setEnabled(false);
882 } else {
883 String name = Format.generateName(f, pname);
884 Format format = getFormat(name);
885 // If there is an existing feature, select it.
886 if(format != null) {
887 format_list.setSelectedValue(format, true);
888 // Now use type to determine what controls are visible, and what have initial values.
889 if(format.isParamType()) {
890 // Flags first.
891 ///election_pane.remove(part_pane);
892 card_layout.show(control_pane, FLAG);
893 view_type = FLAG;
894 // Initial value
895 enabled_checkbox.setSelected(format.getState());
896 } else {
897 ///election_pane.add(part_pane);
898 card_layout.show(control_pane, VALUE);
899 view_type = VALUE;
900 // Initial value
901
902 editor_textarea.setText(format.getValue());
903 editor_textarea.setCaretPosition(0);
904
905 }
906 control_pane.updateUI();
907 existingFormat();
908 } else {
909 format_list.clearSelection();
910 if(Format.isParamType(name)) {
911 // Flags first.
912 ///election_pane.remove(part_pane);
913 card_layout.show(control_pane, FLAG);
914 view_type = FLAG;
915 // Initial value
916 enabled_checkbox.setSelected(false);
917 enabled_checkbox.setEnabled(false);
918 } else {
919 ///election_pane.add(part_pane);
920 card_layout.show(control_pane, VALUE);
921 view_type = VALUE;
922 // Initial value
923
924 editor_textarea.setText(part.getDefaultFormat());
925 editor_textarea.setCaretPosition(0);
926
927 }
928 newFormat();
929 }
930 format = null;
931 name = null;
932 }
933
934 pname = null;
935 part = null;
936 f = null;
937 entry = null;
938 }
939 undo.discardAllEdits();
940 }
941 }
942
943 private class RemoveListener
944 implements ActionListener {
945
946 public void actionPerformed(ActionEvent event) {
947 if (!format_list.isSelectionEmpty()) {
948 // Remove the current format
949 removeFormat((Format)format_list.getSelectedValue());
950
951 // Change buttons
952 add_button.setEnabled(true);
953 newFormat();
954 }
955 }
956 }
957
958
959
960 private class DefaultListener
961 implements ActionListener {
962
963 public void actionPerformed(ActionEvent event) {
964 newtext = false;
965 if(!ignore_event) {
966 Entry entry = (Entry) feature_combobox.getSelectedItem();
967 Object f = entry.getFeature();
968 String name ="";
969 String pname="";
970 Part part = null;
971
972 if (entry.canHavePart()){
973 part = (Part) part_combobox.getSelectedItem();
974 pname = part.getName();
975 name = Format.generateName(f, pname);
976 } else{
977 name = entry.toString();
978 }
979
980 Format format = getFormat(name);
981 // If there is an existing feature, select it.
982 if(format != null) {
983 remove_button.setEnabled(true);
984 } else {
985
986 add_button.setEnabled(true);
987 }//endif (format !=null)
988
989 if(Format.isParamType(name)) {
990 // Flags first.
991 card_layout.show(control_pane, FLAG);
992 view_type = FLAG;
993 // Initial value
994 enabled_checkbox.setSelected(false);
995 } else {
996 card_layout.show(control_pane, VALUE);
997 view_type = VALUE;
998 // Initial value
999 if (pname !=null && pname.length()!=0 ){
1000 editor_textarea.setText((String) default_format_map.get(pname));
1001 editor_textarea.setCaretPosition(0);
1002 } else{
1003 editor_textarea.setText((String) default_format_map.get(name));
1004 editor_textarea.setCaretPosition(0);
1005 }
1006 }
1007
1008 }
1009 }
1010
1011 }
1012
1013 private class UndoListener
1014 implements ActionListener {
1015
1016 public void actionPerformed(ActionEvent event) {
1017 try {
1018 if (undo.canUndo()) {
1019 int pos = editor_textarea.getCaretPosition();
1020 redo_button.setEnabled(true);
1021 undo.undo();
1022 if (pos > 0)
1023 editor_textarea.setCaretPosition(pos-1);
1024 else
1025 editor_textarea.setCaretPosition(pos);
1026 }
1027 if (!undo.canUndo()){
1028 undo_button.setEnabled(false);
1029 } else{
1030 undo_button.setEnabled(true);
1031 }
1032
1033 } catch (Exception e) {
1034
1035 }
1036 }
1037 }
1038
1039 private class RedoListener
1040 implements ActionListener {
1041 public void actionPerformed(ActionEvent evt) {
1042 try {
1043 if (undo.canRedo()) {
1044 int pos = editor_textarea.getCaretPosition();
1045 undo.redo();
1046 editor_textarea.setCaretPosition(pos);
1047 }
1048 if (!undo.canRedo()){
1049 redo_button.setEnabled(false);
1050 } else{
1051 redo_button.setEnabled(true);
1052 }
1053
1054 } catch (Exception e) {}
1055 }
1056 }
1057
1058 }
1059
1060 /** 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. */
1061 private class Entry
1062 implements Comparable {
1063 private Classifier classifier = null;
1064 private String text = null;
1065
1066 public Entry(Object object) {
1067 if(object instanceof Classifier) {
1068 classifier = (Classifier)object;
1069 } else if(object instanceof String) {
1070 text = (String)object;
1071 } else {
1072 text = "";
1073 }
1074 }
1075
1076 public Entry(String text) {
1077 this.text = text;
1078 }
1079
1080 public boolean canHavePart() {
1081 if (classifier !=null) return true;
1082 return Format.canHavePart(text);
1083 }
1084
1085 public int compareTo(Object object) {
1086 if(object == null) {
1087 return 1;
1088 }
1089 if(toString() == null) {
1090 return -1;
1091 } else {
1092 String object_str = object.toString();
1093 if(object_str == null) {
1094 return 1;
1095 }
1096 return toString().compareTo(object_str);
1097 }
1098 }
1099
1100 public boolean equals(Object object) {
1101 if(compareTo(object) == 0) {
1102 return true;
1103 }
1104 return false;
1105 }
1106
1107 public Classifier getClassifier() {
1108 return classifier;
1109 }
1110
1111 public Object getFeature() {
1112 if(classifier != null) {
1113 return classifier;
1114 }
1115
1116 if (text.startsWith("<html>")){
1117 return "";
1118 }
1119 return text;
1120 }
1121
1122 public ArrayList getPartModel(){
1123 DebugStream.println("getPartModel(): get appopriate affected components of this classifier");
1124 String classifier_name = classifier == null ? "" : classifier.toString();
1125 if(!classifier_name.equals("")){
1126 classifier_name = classifier_name.substring(0, classifier_name.indexOf("-")).trim();
1127 }
1128 ArrayList part_model = new ArrayList();
1129 // DateList only has DateList component
1130 if(classifier_name.equals("DateList")){
1131 part_model.add(new Part(DATELIST, DATELIST_DEFAULT_FORMAT));
1132 }
1133 // Other Format Entries, display the default Affected Components
1134 else if(classifier_name.equals("")){
1135 part_model = buildPartModel();
1136 }
1137 // Other Classifiers have HList and VList as Affected Component
1138 else {
1139 part_model.add(new Part(HLIST, HLIST_DEFAULT_FORMAT));
1140 part_model.add(new Part(VLIST, VLIST_DEFAULT_FORMAT));
1141 }
1142 return part_model;
1143 }
1144
1145 public String toString() {
1146 if(classifier != null) {
1147 // Return the classifier - with its CL index shown
1148 return classifier.getPositionString() + StaticStrings.COLON_CHARACTER + StaticStrings.SPACE_CHARACTER + classifier.toString();
1149 }
1150 if (text.equals("")) {
1151 return "<html><body><i>"+Dictionary.get("CDM.FormatManager.AllFeatures")+"</i></body></html>";
1152 }
1153 return text;
1154 }
1155 }
1156
1157 /*
1158 private class GUIChangeTask
1159 implements Runnable {
1160 private boolean to_add;
1161 private JPanel child;
1162 private JPanel parent;
1163 private JPanel replacement;
1164
1165 public GUIChangeTask(JPanel parent, JPanel child, JPanel replacement, boolean to_add) {
1166 this.child = child;
1167 this.parent = parent;
1168 this.replacement = replacement;
1169 this.to_add = to_add;
1170 }
1171
1172 public void run() {
1173 if(to_add) {
1174 parent.remove(replacement);
1175 parent.add(child);
1176 parent.updateUI();
1177 }
1178 else {
1179 parent.remove(child);
1180 parent.add(replacement);
1181 parent.updateUI();
1182 }
1183 }
1184 }
1185 */
1186
1187 /** This class encapsulates all of the information associated with a certain component part of a feature within a html page returned from the receptioninst. */
1188 private class Part
1189 implements Comparable {
1190 /** The default format string for this part */
1191 private String default_format = null;
1192 /** The name of this part */
1193 private String name = null;
1194 /** Constructor - must be provided with all of the details of a part as there are no other setter methods.
1195 * @param name the name of this part
1196 * @param default_format the default format string for this part
1197 */
1198 public Part(String name, String default_format) {
1199 this.default_format = default_format;
1200 this.name = name;
1201 }
1202 /** Compare this part to another object in terms of ordering
1203 * @param obj the other Object
1204 * @return <0 if the object is before, 0 if equal to, and >0 if the object is after this part
1205 */
1206 public int compareTo(Object obj) {
1207 if (obj instanceof Part) {
1208 return name.compareTo(((Part)obj).getName());
1209 }
1210 return name.compareTo(obj.toString());
1211 }
1212
1213 /** Determine if the part is equivelent to some other object
1214 * @param obj the other Object
1215 * @return true is the two objects are equal
1216 */
1217 public boolean equals(Object obj) {
1218 if (obj instanceof Part) {
1219 return name.equals(((Part)obj).getName());
1220 }
1221 return name.equals(obj.toString());
1222 }
1223
1224 /** Retrieve the default format string for this part
1225 * @return the default format String
1226 */
1227 public String getDefaultFormat() {
1228 // Retrieve the format for the super format - either VList or HList
1229 Format default_format_object = getFormat(name);
1230 if(default_format_object != null) {
1231 return default_format_object.getValue();
1232 } else {
1233 return this.default_format;
1234 }
1235 }
1236 /** Retrieve the name of this part
1237 * @return the name as a String
1238 */
1239 public String getName() {
1240 return name;
1241 }
1242 /** Produce a string representation of this part, which in this case is simply the name again
1243 * @return the name as a String
1244 */
1245 public String toString() {
1246 if (name.equals("")) {
1247 return "<html><body><i>"+Dictionary.get("CDM.FormatManager.AllParts")+"</i></body></html>";
1248 }
1249 return name;
1250 }
1251 }
1252}
Note: See TracBrowser for help on using the repository browser.