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

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

changed the variable list slightly - moved the label to be the first element in the list

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