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

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

some dictionary key changes, some other stuff

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