source: main/trunk/gli/src/org/greenstone/gatherer/cdm/Format4gs3Manager.java@ 31556

Last change on this file since 31556 was 31556, checked in by ak19, 7 years ago

Adding the ability to turn on user comments from GLI. Off by default. Need to add usage instructions on wiki.

  • Property svn:keywords set to Author Date Id Revision
File size: 28.4 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 * Copyright (C) 1999 New Zealand Digital Library Project
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *########################################################################
24 */
25package org.greenstone.gatherer.cdm;
26
27import java.awt.*;
28import java.awt.event.*;
29import java.util.*;
30import javax.swing.*;
31import javax.swing.event.*;
32import javax.swing.undo.*;
33import javax.xml.parsers.DocumentBuilderFactory;
34
35import org.fife.ui.rsyntaxtextarea.*;
36
37import org.greenstone.gatherer.Configuration;
38import org.greenstone.gatherer.DebugStream;
39import org.greenstone.gatherer.Dictionary;
40import org.greenstone.gatherer.Gatherer;
41import org.greenstone.gatherer.gui.DesignPaneHeader;
42import org.greenstone.gatherer.gui.GLIButton;
43import org.greenstone.gatherer.gui.FormatPane;
44import org.greenstone.gatherer.gui.NumberedJTextArea;
45import org.greenstone.gatherer.metadata.MetadataElement;
46import org.greenstone.gatherer.metadata.MetadataSetManager;
47import org.greenstone.gatherer.util.StaticStrings;
48import org.greenstone.gatherer.util.Utility;
49import org.greenstone.gatherer.util.XMLTools;
50import org.w3c.dom.*;
51import org.xml.sax.InputSource;
52
53import java.awt.FontMetrics;
54import java.awt.Graphics;
55import java.awt.Insets;
56import java.awt.Rectangle;
57import java.io.ByteArrayInputStream;
58
59/**
60 * This class maintains a list of format statements, and allows the addition and
61 * removal of these statements. This is the greenstone 3 equivalent class of
62 * FormatManager.java which is used by greenstone 2
63 */
64public class Format4gs3Manager implements SharedByTwoFormatManager
65{
66 // The default global format
67 static final private String GLOBAL_FORMAT;
68 static
69 {
70 // @formatter:off
71 String GLOBAL_FORMAT_TEMP = "" +
72 "<gsf:template name=\"choose-title\">" +
73 "<gsf:choose-metadata>" +
74 "<gsf:metadata name=\"dc.Title\"/>" +
75 "<gsf:metadata name=\"exp.Title\"/>" +
76 "<gsf:metadata name=\"ex.dc.Title\"/>" +
77 "<gsf:metadata name=\"Title\"/>" +
78 "<gsf:default>Untitled</gsf:default>" +
79 "</gsf:choose-metadata>" +
80 "</gsf:template>";
81 GLOBAL_FORMAT = GLOBAL_FORMAT_TEMP;
82 // @formatter:on
83 }
84 static final private String GLOBAL = "global";
85 //The default search format
86 static final private String SEARCH_FORMAT;
87 static
88 {
89 // @formatter:off
90 String SEARCH_FORMAT_TEMP = "" +
91 "<gsf:template match=\"documentNode\">" +
92 "<td valign=\"top\">" +
93 "<gsf:link type=\"document\">" +
94 "<gsf:icon type=\"document\"/>" +
95 "</gsf:link>" +
96 "</td>" +
97 "<td>" +
98 "<gsf:link type=\"document\">" +
99 "<xsl:call-template name=\"choose-title\"/>" +
100 "</gsf:link>" +
101 "</td>" +
102 "</gsf:template>";
103 SEARCH_FORMAT = SEARCH_FORMAT_TEMP;
104 // @formatter:on
105 }
106 static final private String SEARCH = "search";
107 static final private String DISPLAY_DEFAULT_FORMAT;
108 static
109 {
110 // @formatter:off
111 String DISPLAY_DEFAULT_FORMAT_TEMP = "" +
112 "<gsf:option name=\"TOC\" value=\"true\"/>" +
113 "<gsf:option name=\"UserComments\" value=\"true\"/>" +
114 "<!--" +
115 "Overwriting this template allows you to change the heading of the document." +
116 "-->" +
117 "<!--" +
118 "<gsf:template name=\"documentHeading\">" +
119 "<span style=\"font-weight:bold; font-size: 120%;\">" +
120 "<xsl:call-template name=\"choose-title\"/>" +
121 "</span>" +
122 "</gsf:template>" +
123 "-->" +
124 "<!--" +
125 "Overwriting this template can be used to redefine the content of the whole document." +
126 "This is useful for simple documents, but not recommended for more complex documents" +
127 "(e.g. hierachical and paged documents) as it can prevent any sub-sections from showing." +
128 "-->" +
129 "<!--" +
130 "<gsf:template name=\"documentContent\">" +
131 "<xsl:call-template name=\"wrappedSectionImage\"/>" +
132 "<xsl:call-template name=\"wrappedSectionText\"/>" +
133 "</gsf:template>" +
134 "-->" +
135 "<!--" +
136 "Overwriting this template can be used to change the content of section headings." +
137 "-->" +
138 "<!--" +
139 "<gsf:template name=\"sectionHeading\">" +
140 "<xsl:call-template name=\"choose-title\"/>" +
141 "</gsf:template>" +
142 "-->" +
143 "<!--" +
144 "Overwriting this template can be used to change the content of the top-level section." +
145 "-->" +
146 "<!--" +
147 "<gsf:template name=\"topLevelSectionContent\">" +
148 "<xsl:call-template name=\"wrappedSectionImage\"/>" +
149 "<xsl:call-template name=\"wrappedSectionText\"/>" +
150 "</gsf:template>" +
151 "-->" +
152 "<!--" +
153 "Overwriting this template can be used to change the content of sections." +
154 "-->" +
155 "<!--" +
156 "<gsf:template name=\"sectionContent\">" +
157 "<xsl:call-template name=\"wrappedSectionImage\"/>" +
158 "<xsl:call-template name=\"wrappedSectionText\"/>" +
159 "</gsf:template>" +
160 "-->";
161 // @formatter:on
162
163 DISPLAY_DEFAULT_FORMAT = DISPLAY_DEFAULT_FORMAT_TEMP;
164 }
165 static final private String DISPLAY = "display";
166
167 //The default browse format
168 static final private String CLASSIFIER_DEFAULT_FORMAT;
169 static
170 {
171 // @formatter:off
172 String CLASSIFIER_DEFAULT_FORMAT_TEMP = "" +
173 "<gsf:template match=\"documentNode\">" +
174 "<td valign=\"top\">" +
175 "<gsf:link type=\"document\">" +
176 "<gsf:icon type=\"document\"/>" +
177 "</gsf:link>" +
178 "</td>" +
179 "<td valign=\"top\">" +
180 "<gsf:link type=\"source\">" +
181 "<gsf:choose-metadata>" +
182 "<gsf:metadata name=\"thumbicon\"/>" +
183 "<gsf:metadata name=\"srcicon\"/>" +
184 "</gsf:choose-metadata>" +
185 "</gsf:link>" +
186 "</td>" +
187 "<td valign=\"top\">" +
188 "<gsf:link type=\"document\">" +
189 "<xsl:call-template name=\"choose-title\"/>" +
190 "</gsf:link>" +
191 "<gsf:switch>" +
192 "<gsf:metadata name=\"Source\"/>" +
193 "<gsf:when test=\"exists\"><br/><i>(<gsf:metadata name=\"Source\"/>)</i></gsf:when>" +
194 "</gsf:switch>" +
195 "</td>" +
196 "</gsf:template>" +
197 "<gsf:template match=\"classifierNode[@classifierStyle = 'VList']\">" +
198 "<td valign=\"top\">" +
199 "<gsf:link type=\"classifier\">" +
200 "<gsf:icon type=\"classifier\"/>" +
201 "</gsf:link>" +
202 "</td>" +
203 "<td valign=\"top\">" +
204 "<gsf:metadata name=\"Title\"/>" +
205 "</td>" +
206 "</gsf:template>" +
207 "<gsf:template match=\"classifierNode[@classifierStyle = 'HList']\">" +
208 "<gsf:link type=\"classifier\">" +
209 "<gsf:metadata name=\"Title\"/>" +
210 "</gsf:link>" +
211 "</gsf:template>";
212 CLASSIFIER_DEFAULT_FORMAT = CLASSIFIER_DEFAULT_FORMAT_TEMP;
213 // @formatter:on
214 }
215 static final private String CLASSIFIER_DEFAULT = "browse";
216 static final private String SEARCHTYPE_FORMAT = "plain,simpleform,advancedform";
217 static final private String SEARCHTYPE = "searchType";
218 static final private String[] FEATURE_NAME = { SEARCH, GLOBAL, DISPLAY, CLASSIFIER_DEFAULT, SEARCHTYPE };
219 static final private String[] FEATURE_FORMAT = { SEARCH_FORMAT, GLOBAL_FORMAT, DISPLAY_DEFAULT_FORMAT, CLASSIFIER_DEFAULT_FORMAT, SEARCHTYPE_FORMAT };
220
221 static private HashMap default_format_map = null;
222 static private HashMap default_format_formated_map = null;
223
224 /** The controls used to edit the format commands. */
225 private Control controls = null;// an interface
226 /** A reference */
227 private DOMProxyListModel format_list_model = null;
228
229 //private DOMProxyListModel feature_list_model = null;
230
231 /** Constructor. */
232 public Format4gs3Manager()
233 {//pass the internal structure
234 Element root = CollectionDesignManager.collect_config.getDocumentElement();
235 format_list_model = new DOMProxyListModel(root, StaticStrings.FORMAT_STR, new Format4gs3());
236 initDefault(format_list_model, FEATURE_NAME, FEATURE_FORMAT);
237 initFormatMap(FEATURE_NAME, FEATURE_FORMAT);
238
239 }
240
241 private void initFormatMap(String[] feature_name, String[] feature_format)
242 {
243 default_format_map = new HashMap();
244 default_format_formated_map = new HashMap();
245 for (int i = 0; i < feature_name.length; i++)
246 {
247 default_format_map.put(feature_name[i], feature_format[i]);
248 default_format_formated_map.put(feature_name[i], Format4gs3.toFormatedFormat(feature_format[i]));
249 }
250
251 }
252
253 public void initDefault(DOMProxyListModel model, String[] feature_name, String[] feature_format)
254 {
255 // Establish all of the format objects.
256 for (int i = 0; i < model.getSize(); i++)
257 {
258 model.getElementAt(i);//get those objects cached
259 }
260 for (int i = 0; i < feature_name.length; i++)
261 {
262 if (getFormat(model, feature_name[i]) == null)
263 {
264 model.add(new Format4gs3(feature_name[i], feature_format[i]));
265
266 }
267 }
268 }
269
270 /**
271 * Method to remove a format.
272 *
273 * @param format
274 * The <strong>Format</strong> to remove.
275 */
276 private void removeFormat(DOMProxyListModel model, Format4gs3 format)
277 {
278 model.remove(format);
279 }
280
281 private Format4gs3 getFormat(DOMProxyListModel model, String name)
282 {
283
284 for (int index = 0; index < model.getSize(); index++)
285 {
286 Format4gs3 format = (Format4gs3) model.getElementAt(index);
287 if (format.getFeatureName().equals(name))
288 {
289 return format;
290 }
291 }
292 return null;
293 }
294
295 private void addFormat(Element parent, Format4gs3 format)
296 {
297 if (!format_list_model.contains(format))
298 {
299
300 format_list_model.add(parent, format, null);
301 }
302 }
303
304 public void destroy()
305 {
306 if (controls != null)
307 {
308 controls.destroy();
309 controls = null;
310 }
311 }
312
313 /**
314 * Method to retrieve this managers controls.
315 *
316 * @return the Control for this collection.
317 */
318 public Control getControls()
319 {
320 if (controls == null)
321 {
322 controls = new FormatControl();
323 }
324 //controls.gainFocus();
325 return controls;
326 }
327
328 /**
329 * Called when the detail mode has changed which in turn may cause several
330 * design elements to be available/hidden
331 *
332 * @param mode
333 * the new mode as an int
334 */
335 public void modeChanged(int mode)
336 {
337
338 }
339
340 /** updates the format and feature model */
341 public synchronized void refresh()
342 {
343 for (int i = 0; i < format_list_model.getSize(); i++)
344 {
345 Format4gs3 format = (Format4gs3) format_list_model.getElementAt(i);
346 format.update();
347 format = null;
348 }
349 //call the gainFocus() and in turn the buildFeatureModel() method to get the feature combobox refreshed as well
350 if (controls == null)
351 {
352 controls = new FormatControl();
353 }
354 controls.gainFocus();
355
356 //format_list_model.refresh(); //this call is not necessary as it is included in gainFocus()
357 }
358
359 private ArrayList buildFeatureModel()
360 {
361 // Rebuild feature model.
362 ArrayList feature_model = new ArrayList();
363 //This will display 'choose a feature' and is used when the format feature panel is first gained focus
364 feature_model.add(new Entry(""));
365
366 for (int i = 0; i < format_list_model.getSize(); i++)
367 {
368 Format4gs3 format = (Format4gs3) format_list_model.getElementAt(i);
369 String feature_name = format.getFeatureName();
370 if (!feature_name.startsWith(Classifier.CLASSIFIER_PREFIX))
371 {
372 feature_model.add(new Entry(format.getFeatureName()));
373
374 }
375 }
376 // Now the classifiers.
377 Element root = CollectionDesignManager.collect_config.getDocumentElement();
378 NodeList classifier_list = root.getElementsByTagName(StaticStrings.CLASSIFY_ELEMENT);
379 for (int j = 0; j < classifier_list.getLength(); j++)
380 {
381 feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j)));
382
383 }
384 //Collections.sort (feature_model);
385 return feature_model;
386 }
387
388 private String addSurroundingTags(String xml)
389 {
390 return "<ROOTELEMENT>" + xml + "</ROOTELEMENT>";
391 }
392
393 private String removeSurroundingTags(String xml)
394 {
395 return xml.replace("<ROOTELEMENT>\n", "").replace("<ROOTELEMENT>", "").replace("</ROOTELEMENT>", "").replace("<ROOTELEMENT/>","");
396 }
397
398 public class FormatControl extends JPanel implements Control
399 {
400
401 private ArrayList feature_model;
402 private boolean ignore_event = false;
403 private boolean ready = false; // Are these controls available to be refreshed
404 private JButton add_button;
405 private JButton remove_button;
406 private JButton default_button;
407 private JComboBox feature_combobox;
408 private JList format_list;
409 private NumberedJTextArea editor_textarea;
410 private JTextArea editor_msgarea;
411 private JPanel validation_msg_panel;
412 private JPanel selection_pane;
413 private final Dimension FIELD_SIZE = new Dimension(200, 30);
414 private boolean newtext = true;
415 private Format4gs3 previousFormat = null;
416 private Format4gs3 currentFormat = null;
417 private boolean fresh = true;
418
419 public FormatControl()
420 {
421 feature_model = buildFeatureModel();
422
423 // Create
424 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Formats", "formatstatements");
425
426 format_list = new JList(format_list_model);
427
428 selection_pane = new JPanel();
429 JPanel feature_pane = new JPanel();
430 JLabel feature_label = new JLabel(Dictionary.get("CDM.FormatManager.Feature"));
431
432 feature_combobox = new JComboBox(feature_model.toArray());
433 feature_combobox.setOpaque(!Utility.isMac());
434 feature_combobox.setPreferredSize(FIELD_SIZE);
435 feature_combobox.setEditable(false);
436 feature_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Feature_Tooltip"));
437
438 JPanel center_pane = new JPanel();
439 JPanel editor_pane = new JPanel();
440
441 // NumberedJTextArea comes with undo and redo buttons already hooked up to listeners
442 editor_textarea = new NumberedJTextArea(Dictionary.get("CDM.FormatManager.Add_Tooltip"));
443
444 default_button = new GLIButton(Dictionary.get("CDM.FormatManager.Default"), Dictionary.get("CDM.FormatManager.Default_Tooltip"));
445 JPanel button_pane = new JPanel();
446 add_button = new GLIButton(Dictionary.get("CDM.FormatManager.Add"), Dictionary.get("CDM.FormatManager.Add_Tooltip"));
447 add_button.setEnabled(false);
448
449 remove_button = new GLIButton(Dictionary.get("CDM.FormatManager.Remove"), Dictionary.get("CDM.FormatManager.Remove_Tooltip"));
450 remove_button.setEnabled(false);
451
452 // Connect
453 add_button.addActionListener(new AddListener());
454 remove_button.addActionListener(new RemoveListener());
455 default_button.addActionListener(new DefaultListener());
456 feature_combobox.addActionListener(new FeatureListener());
457 editor_textarea.getDocument().addDocumentListener(new EditorListener());
458
459 format_list.addListSelectionListener(new FormatListListener());
460
461 // Layout
462 JPanel format_list_pane = new JPanel();
463 format_list_pane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
464 format_list_pane.setLayout(new BorderLayout());
465 format_list_pane.add(new JScrollPane(format_list), BorderLayout.CENTER);
466
467 feature_pane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
468 feature_pane.setLayout(new BorderLayout(5, 0));
469 feature_pane.add(feature_label, BorderLayout.WEST);
470 feature_pane.add(feature_combobox, BorderLayout.CENTER);
471
472 JPanel rupanel = new JPanel();
473 rupanel.setLayout(new GridLayout(1, 2));
474 rupanel.add(editor_textarea.undoButton);
475 rupanel.add(editor_textarea.redoButton);
476
477 editor_pane.setLayout(new BorderLayout());
478 editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER);
479
480 validation_msg_panel = new JPanel();
481 JLabel validation_label = new JLabel(Dictionary.get("CDM.FormatManager.MessageBox"));
482 editor_msgarea = new JTextArea();
483
484 editor_msgarea.setCaretPosition(0);
485 editor_msgarea.setLineWrap(true);
486 editor_msgarea.setRows(3);
487 editor_msgarea.setWrapStyleWord(false);
488 editor_msgarea.setEditable(false);
489 editor_msgarea.setToolTipText(Dictionary.get("CDM.FormatManager.MessageBox_Tooltip"));
490 validation_msg_panel.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
491 validation_msg_panel.setLayout(new BorderLayout(5, 0));
492 validation_msg_panel.add(validation_label, BorderLayout.WEST);
493 validation_msg_panel.add(new JScrollPane(editor_msgarea), BorderLayout.CENTER);
494
495 selection_pane.setLayout(new BorderLayout());
496 selection_pane.add(validation_msg_panel, BorderLayout.NORTH);
497 selection_pane.add(rupanel, BorderLayout.SOUTH);
498 selection_pane.add(editor_pane, BorderLayout.CENTER);
499
500 button_pane.setLayout(new GridLayout(1, 3));
501 button_pane.add(add_button);
502 button_pane.add(remove_button);
503 button_pane.add(default_button);
504
505 center_pane.setLayout(new BorderLayout());
506 center_pane.add(feature_pane, BorderLayout.NORTH);
507 center_pane.add(selection_pane, BorderLayout.CENTER);
508 center_pane.add(button_pane, BorderLayout.SOUTH);
509
510 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
511 splitPane.add(format_list_pane, JSplitPane.TOP);
512 splitPane.add(center_pane, JSplitPane.BOTTOM);
513 splitPane.setDividerLocation(150);
514
515 setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
516 setLayout(new BorderLayout());
517 add(header_pane, BorderLayout.NORTH);
518 add(splitPane, BorderLayout.CENTER);
519 ready = true;
520 }
521
522 public void destroy()
523 {
524 }
525
526 /**
527 * Overriden to ensure that the instructions pane is scrolled to the
528 * top.
529 */
530 public void gainFocus()
531 {
532 if (ready)
533 {
534
535 format_list_model.refresh();
536 // Update the feature model, trying to maintain the same selected object
537 Object selected_feature = feature_combobox.getSelectedItem();
538 feature_combobox.setSelectedItem(selected_feature);
539 feature_model = buildFeatureModel();
540 feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray()));
541 }
542 }
543
544 public void loseFocus()
545 {
546 //validate the templates. If not wellformed, pop up an alert; otherwise, do nothing.
547 String msg = XMLTools.parse(editor_textarea.getText());
548 if (msg.startsWith(XMLTools.NOTWELLFORMED))
549 {
550 JOptionPane.showMessageDialog(null, msg, XMLTools.NOTWELLFORMED, JOptionPane.ERROR_MESSAGE);
551 }
552 format_list_model.refresh();
553 }
554
555 public Format4gs3 getCurrentFormat()
556 {
557 return (Format4gs3) format_list.getSelectedValue();
558
559 }
560
561 /**
562 * Listens for clicks on the add button, and if the relevant details are
563 * provided adds a new format. Note that formats are responsible for
564 * codecing the values into something that can be a) stored in a DOM and
565 * b) written to file
566 */
567 private class AddListener implements ActionListener
568 {
569
570 public void actionPerformed(ActionEvent event)
571 {
572
573 ignore_event = true; // Prevent format_list excetera propagating events
574
575 String format_str = editor_textarea.getText();
576 Entry entry = (Entry) feature_combobox.getSelectedItem();
577 String feature_name = entry.getClassifier().getPositionString();
578
579 Format4gs3 format = new Format4gs3(feature_name, format_str);
580 Element e = format.getClassifyElement();
581 addFormat(e, format);
582 existingFormat(format.getFeatureName().startsWith(Classifier.CLASSIFIER_PREFIX)); // set the appropriate enable/disable on the interface
583
584 // Update list selection (make the new added format highlighted on the format list panel)
585 format_list.setSelectedValue(format, true);
586
587 format = null;
588
589 ignore_event = false;
590 }
591 }
592
593 private class EditorListener implements DocumentListener
594 {
595
596 public void changedUpdate(DocumentEvent e)
597 {
598 update();
599 }
600
601 public void insertUpdate(DocumentEvent e)
602 {
603 update();
604 updateUndo("insert");
605
606 }
607
608 public void removeUpdate(DocumentEvent e)
609 {
610 update();
611 updateUndo("remove");
612
613 }
614
615 private void updateUndo(String from)
616 {
617
618 if (!newtext)
619 {
620 editor_textarea.undoButton.setEnabled(true);
621 }
622
623 if (editor_textarea.getText().length() != 0 && newtext)
624 {
625 newtext = false;
626 }
627 }
628
629 public void update()
630 {
631 if (!format_list.isSelectionEmpty())
632 {
633 Format4gs3 format = (Format4gs3) format_list.getSelectedValue();
634 String format_str = editor_textarea.getText();
635 String msg = XMLTools.parse(format_str);
636 editor_msgarea.setText(msg);
637
638 if (msg.startsWith(XMLTools.WELLFORMED))
639 {
640 format.setPureFormat(format_str);
641 format.update();
642 format_list_model.refresh(format);
643 editor_msgarea.setBackground(Color.white);
644 FormatPane.setPreviewButton(true);
645 }
646 else
647 {
648 editor_msgarea.setBackground(Color.red);
649 FormatPane.setPreviewButton(false);
650 }
651 }
652 else
653 {
654 add_button.setEnabled(false);
655 }
656 }
657 }
658
659 private class FeatureListener implements ActionListener
660 {
661 public void actionPerformed(ActionEvent event)
662 {
663 editor_textarea.undoButton.setEnabled(false);
664 editor_textarea.redoButton.setEnabled(false);
665 default_button.setEnabled(true);
666 newtext = true;
667
668 if (ignore_event == true)
669 {
670 editor_textarea.discardAllEdits();
671 return;
672 }
673
674 ignore_event = true;
675 // Add is only enabled if there isn't already a format for the choosen feature and part.
676 //Create a dummy format and test if itsa already in the model
677 Entry entry = (Entry) feature_combobox.getSelectedItem();
678 String feature_name = entry.getFeatureName();
679
680 Format4gs3 format = getFormat(format_list_model, feature_name);
681
682 if (format != null)
683 {
684 ///ystem.err.println("There is an existing format!");
685 format_list.setSelectedValue(format, true);
686 Element formatElem = null;
687 try
688 {
689 InputSource is = new InputSource(new ByteArrayInputStream(addSurroundingTags(format.getPureFormat()).getBytes("utf-8")));
690 formatElem = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is).getDocumentElement();
691 }
692 catch (Exception ex)
693 {
694 ex.printStackTrace();
695 }
696
697 if (formatElem != null)
698 {
699 StringBuffer sb = new StringBuffer();
700 XMLTools.xmlNodeToString(sb, formatElem, true, " ", 0);
701 editor_textarea.setText(removeSurroundingTags(sb.toString()));
702 }
703 else
704 {
705 editor_textarea.setText(format.getPureFormat());
706 }
707 editor_textarea.setCaretPosition(0);
708
709 existingFormat(feature_name.startsWith(Classifier.CLASSIFIER_PREFIX));
710 }
711 // Otherwise there is no existing format, then this feature must be a classifier (CL1, 2, ...)
712 // we display the ClassifierDefault for this format
713 else
714 {
715 //Fist reset the format list panel
716 format_list.clearSelection();
717
718 if (feature_name.equals(""))
719 {
720 editor_textarea.setText("");
721
722 }
723 else
724 {
725 //Only for debugging purposes
726 if (entry.getClassifier() == null)
727 {
728 DebugStream.println("It should be a classifier or choose a feature. What is it? " + entry.toString());
729 }
730
731 editor_textarea.setText(Format4gs3.toFormatedFormat(CLASSIFIER_DEFAULT_FORMAT));
732 editor_textarea.setCaretPosition(0);
733 newFormat();
734 }
735 }
736 ignore_event = false;
737 editor_textarea.discardAllEdits();
738 }
739 }
740
741 private class FormatListListener implements ListSelectionListener
742 {
743 public void valueChanged(ListSelectionEvent event)
744 {
745 editor_textarea.undoButton.setEnabled(false);
746 editor_textarea.redoButton.setEnabled(false);
747 default_button.setEnabled(true);
748 newtext = true;
749
750 if (!ignore_event && !event.getValueIsAdjusting())
751 {
752
753 if (!format_list.isSelectionEmpty())
754 {
755 ignore_event = true;
756 Format4gs3 format = (Format4gs3) format_list.getSelectedValue();
757 String feature_name = format.getFeatureName();
758 Entry entry = null;
759 if (feature_name.startsWith(Classifier.CLASSIFIER_PREFIX))
760 {
761 entry = new Entry(format.getClassifier());
762 }
763 else
764 {
765 entry = new Entry(feature_name);
766 }
767 feature_combobox.setSelectedItem(entry);
768
769 existingFormat(format.getFeatureName().startsWith(Classifier.CLASSIFIER_PREFIX));
770
771 Element formatElem = null;
772 try
773 {
774 InputSource is = new InputSource(new ByteArrayInputStream(addSurroundingTags(format.getPureFormat()).getBytes("utf-8")));
775 formatElem = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is).getDocumentElement();
776 }
777 catch (Exception ex)
778 {
779 ex.printStackTrace();
780 }
781
782 if (formatElem != null)
783 {
784 StringBuffer sb = new StringBuffer();
785 XMLTools.xmlNodeToString(sb, formatElem, true, " ", 0);
786 editor_textarea.setText(removeSurroundingTags(sb.toString()));
787 }
788 else
789 {
790 editor_textarea.setText(format.getPureFormat());
791 }
792 editor_textarea.setCaretPosition(0);
793
794 ignore_event = false;
795 }
796
797 }
798 editor_textarea.discardAllEdits();
799 }
800
801 }
802
803 private class RemoveListener implements ActionListener
804 {
805 public void actionPerformed(ActionEvent event)
806 {
807 if (!format_list.isSelectionEmpty())
808 {
809 // Remove the current format
810 Format4gs3 format = (Format4gs3) format_list.getSelectedValue();
811 removeFormat(format_list_model, format);
812 // Change buttons
813 add_button.setEnabled(true);
814 feature_combobox.setSelectedItem(new Entry(""));
815 newFormat();
816 }
817 }
818 }
819
820 private class DefaultListener implements ActionListener
821 {
822 public void actionPerformed(ActionEvent event)
823 {
824 newtext = false;
825 if (!ignore_event)
826 {
827 Entry entry = (Entry) feature_combobox.getSelectedItem();
828 String feature_name = entry.getFeatureName();
829 Format4gs3 format = getFormat(format_list_model, feature_name);
830
831 if (format != null)
832 {
833 if (format.isClassifier() == true)
834 {
835 editor_textarea.setText((String) default_format_formated_map.get(CLASSIFIER_DEFAULT));
836 editor_textarea.setCaretPosition(0);
837 remove_button.setEnabled(true);
838 }
839 else
840 {
841 editor_textarea.setText((String) default_format_formated_map.get(format.getFeatureName()));
842 editor_textarea.setCaretPosition(0);
843 remove_button.setEnabled(false);
844 }
845 }
846 else
847 {
848 editor_textarea.setText((String) default_format_formated_map.get(CLASSIFIER_DEFAULT));
849 editor_textarea.setCaretPosition(0);
850 remove_button.setEnabled(false);
851 add_button.setEnabled(true);
852 }
853 }
854 }
855 }
856
857 private void newFormat()
858 {
859 editor_textarea.setEditable(false);
860 editor_textarea.setBackground(Color.lightGray);
861 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Disabled_Tooltip"));
862
863 editor_textarea.undoButton.setEnabled(false);
864 editor_textarea.redoButton.setEnabled(false);
865 add_button.setEnabled(true);
866 remove_button.setEnabled(false);
867 default_button.setEnabled(false);
868 FormatPane.setPreviewButton(true);
869 }
870
871 private void existingFormat(boolean enableRemoveButton)
872 {
873 editor_textarea.setEditable(true);
874 editor_textarea.setBackground(Color.white);
875 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Tooltip"));
876 add_button.setEnabled(false);
877 remove_button.setEnabled(enableRemoveButton);
878 default_button.setEnabled(true);
879 FormatPane.setPreviewButton(true);
880 }
881 }
882
883 /**
884 * This object provides a wrapping around an entry in Format4gs3, which is
885 * tranparent.
886 */
887 // This class is used for display in the feature combobox
888 private class Entry implements Comparable
889 {
890 private Classifier classifier = null;
891 private String feature_name = null;
892
893 public Entry(Object object)
894 {
895 if (object instanceof Classifier)
896 {
897 classifier = (Classifier) object;
898 feature_name = classifier.getPositionString();
899 }
900 else if (object instanceof String)
901 {
902 feature_name = (String) object;
903 }
904 else
905 {
906 feature_name = "";
907 }
908 }
909
910 public Entry(String text)
911 {
912 this.feature_name = text;
913 }
914
915 public int compareTo(Object object)
916 {
917 if (object == null)
918 {
919 return 1;
920 }
921 if (toString() == null)
922 {
923 return -1;
924 }
925 else
926 {
927 String object_str = object.toString();
928 if (object_str == null)
929 {
930 return 1;
931 }
932 return toString().compareTo(object_str);
933 }
934 }
935
936 public boolean equals(Object object)
937 {
938 if (compareTo(object) == 0)
939 {
940 return true;
941 }
942 return false;
943 }
944
945 public Classifier getClassifier()
946 {
947 return classifier;
948 }
949
950 public String toString()
951 {
952 if (classifier != null)
953 {
954 // Return the classifier name - with its CL index shown, and all its metadata options as well
955 return classifier.getPositionString() + StaticStrings.SPACE_CHARACTER + classifier.toString();
956 }
957 if (feature_name.equals(""))
958 {
959 return "<html><body><i>" + "Choose a feature" + "</i></body></html>";
960 }
961 return feature_name;
962 }
963
964 public String getFeatureName()
965 {
966 return feature_name;
967 }
968 }
969}
Note: See TracBrowser for help on using the repository browser.