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

Last change on this file since 12273 was 12273, checked in by shaoqun, 18 years ago

added all features

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