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

Last change on this file since 26062 was 26062, checked in by ak19, 12 years ago
  1. Getting the Reset To Default button in Format features to work when it is pressed on the global format statement. 2. default browse format statement needs to call the choose-title template.
  • Property svn:keywords set to Author Date Id Revision
File size: 32.8 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;
34import javax.xml.ws.Dispatch;
35
36import org.fife.ui.rsyntaxtextarea.*;
37
38import org.greenstone.gatherer.Configuration;
39import org.greenstone.gatherer.DebugStream;
40import org.greenstone.gatherer.Dictionary;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.gui.DesignPaneHeader;
43import org.greenstone.gatherer.gui.GLIButton;
44import org.greenstone.gatherer.gui.FormatPane;
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 "<gsf:choose-metadata>" +
100 "<gsf:metadata name=\"dc.Title\"/>" +
101 "<gsf:metadata name=\"exp.Title\"/>" +
102 "<gsf:metadata name=\"ex.dc.Title\"/>" +
103 "<gsf:metadata name=\"Title\"/>" +
104 "<gsf:default>Untitled</gsf:default>" +
105 "</gsf:choose-metadata>" +
106 "</gsf:link>" +
107 "</td>" +
108 "</gsf:template>";
109 SEARCH_FORMAT = SEARCH_FORMAT_TEMP;
110 // @formatter:on
111 }
112 static final private String SEARCH = "search";
113 static final private String DISPLAY_DEFAULT_FORMAT;
114 static
115 {
116 // @formatter:off
117 String DISPLAY_DEFAULT_FORMAT_TEMP = "" +
118 "<gsf:option name=\"TOC\" value=\"true\"/>" +
119 "<!--" +
120 "Overwriting this template allows you to change the heading of the document." +
121 "-->" +
122 "<!--" +
123 "<gsf:template name=\"documentHeading\">" +
124 "<span style=\"font-weight:bold; font-size: 120%;\">" +
125 "<xsl:call-template name=\"choose-title\"/>" +
126 "</span>" +
127 "</gsf:template>" +
128 "-->" +
129 "<!--" +
130 "Overwriting this template can be used to redefine the content of the whole document." +
131 "This is useful for simple documents, but not recommended for more complex documents" +
132 "(e.g. hierachical and paged documents) as it can prevent any sub-sections from showing." +
133 "-->" +
134 "<!--" +
135 "<gsf:template name=\"documentContent\">" +
136 "<xsl:call-template name=\"wrappedSectionImage\"/>" +
137 "<xsl:call-template name=\"wrappedSectionText\"/>" +
138 "</gsf:template>" +
139 "-->" +
140 "<!--" +
141 "Overwriting this template can be used to change the content of section headings." +
142 "-->" +
143 "<!--" +
144 "<gsf:template name=\"sectionHeading\">" +
145 "<xsl:call-template name=\"choose-title\"/>" +
146 "</gsf:template>" +
147 "-->" +
148 "<!--" +
149 "Overwriting this template can be used to change the content of the top-level section." +
150 "-->" +
151 "<!--" +
152 "<gsf:template name=\"topLevelSectionContent\">" +
153 "<xsl:call-template name=\"wrappedSectionImage\"/>" +
154 "<xsl:call-template name=\"wrappedSectionText\"/>" +
155 "</gsf:template>" +
156 "-->" +
157 "<!--" +
158 "Overwriting this template can be used to change the content of sections." +
159 "-->" +
160 "<!--" +
161 "<gsf:template name=\"sectionContent\">" +
162 "<xsl:call-template name=\"wrappedSectionImage\"/>" +
163 "<xsl:call-template name=\"wrappedSectionText\"/>" +
164 "</gsf:template>" +
165 "-->";
166 // @formatter:on
167
168 DISPLAY_DEFAULT_FORMAT = DISPLAY_DEFAULT_FORMAT_TEMP;
169 }
170 static final private String DISPLAY = "display";
171
172 //The default browse format
173 static final private String CLASSIFIER_DEFAULT_FORMAT;
174 static
175 {
176 // @formatter:off
177 String CLASSIFIER_DEFAULT_FORMAT_TEMP = "" +
178 "<gsf:template match=\"documentNode\">" +
179 "<td valign=\"top\">" +
180 "<gsf:link type=\"document\">" +
181 "<gsf:icon type=\"document\"/>" +
182 "</gsf:link>" +
183 "</td>" +
184 "<td valign=\"top\">" +
185 "<gsf:link type=\"source\">" +
186 "<gsf:choose-metadata>" +
187 "<gsf:metadata name=\"thumbicon\"/>" +
188 "<gsf:metadata name=\"srcicon\"/>" +
189 "</gsf:choose-metadata>" +
190 "</gsf:link>" +
191 "</td>" +
192 "<td valign=\"top\">" +
193 "<gsf:link type=\"document\">" +
194 "<xsl:call-template name=\"choose-title\">" +
195 "</gsf:link>" +
196 "<gsf:switch>" +
197 "<gsf:metadata name=\"Source\"/>" +
198 "<gsf:when test=\"exists\"><br/><i>(<gsf:metadata name=\"Source\"/>)</i></gsf:when>" +
199 "</gsf:switch>" +
200 "</td>" +
201 "</gsf:template>" +
202 "<gsf:template match=\"classifierNode[@classifierStyle = 'VList']\">" +
203 "<td valign=\"top\">" +
204 "<gsf:link type=\"classifier\">" +
205 "<gsf:icon type=\"classifier\"/>" +
206 "</gsf:link>" +
207 "</td>" +
208 "<td valign=\"top\">" +
209 "<gsf:link type=\"source\">" +
210 "<gsf:choose-metadata>" +
211 "<gsf:metadata name=\"thumbicon\"/>" +
212 "<gsf:metadata name=\"srcicon\"/>" +
213 "</gsf:choose-metadata>" +
214 "</gsf:link>" +
215 "</td>" +
216 "<td valign=\"top\">" +
217 "<xsl:call-template name=\"choose-title\">" +
218 "<gsf:switch>" +
219 "<gsf:metadata name=\"Source\"/>" +
220 "<gsf:when test=\"exists\"><br/><i>(<gsf:metadata name=\"Source\"/>)</i></gsf:when>" +
221 "</gsf:switch>" +
222 "</td>" +
223 "</gsf:template>" +
224 "<gsf:template match=\"classifierNode[@classifierStyle = 'HList']\">" +
225 "<gsf:link type=\"classifier\">" +
226 "<gsf:metadata name=\"Title\"/>" +
227 "</gsf:link>" +
228 "</gsf:template>";
229 CLASSIFIER_DEFAULT_FORMAT = CLASSIFIER_DEFAULT_FORMAT_TEMP;
230 // @formatter:on
231 }
232 static final private String CLASSIFIER_DEFAULT = "browse";
233 static final private String SEARCHTYPE_FORMAT = "plain,simpleform,advancedform";
234 static final private String SEARCHTYPE = "searchType";
235 static final private String[] FEATURE_NAME = { SEARCH, GLOBAL, DISPLAY, CLASSIFIER_DEFAULT, SEARCHTYPE };
236 static final private String[] FEATURE_FORMAT = { SEARCH_FORMAT, GLOBAL_FORMAT, DISPLAY_DEFAULT_FORMAT, CLASSIFIER_DEFAULT_FORMAT, SEARCHTYPE_FORMAT };
237
238 static private HashMap default_format_map = null;
239 static private HashMap default_format_formated_map = null;
240
241 /** The controls used to edit the format commands. */
242 private Control controls = null;// an interface
243 /** A reference */
244 private DOMProxyListModel format_list_model = null;
245
246 //private DOMProxyListModel feature_list_model = null;
247
248 /** Constructor. */
249 public Format4gs3Manager()
250 {//pass the internal structure
251 Element root = CollectionDesignManager.collect_config.getDocumentElement();
252 format_list_model = new DOMProxyListModel(root, StaticStrings.FORMAT_STR, new Format4gs3());
253 initDefault(format_list_model, FEATURE_NAME, FEATURE_FORMAT);
254 initFormatMap(FEATURE_NAME, FEATURE_FORMAT);
255
256 }
257
258 private void initFormatMap(String[] feature_name, String[] feature_format)
259 {
260 default_format_map = new HashMap();
261 default_format_formated_map = new HashMap();
262 for (int i = 0; i < feature_name.length; i++)
263 {
264 default_format_map.put(feature_name[i], feature_format[i]);
265 default_format_formated_map.put(feature_name[i], Format4gs3.toFormatedFormat(feature_format[i]));
266 }
267
268 }
269
270 public void initDefault(DOMProxyListModel model, String[] feature_name, String[] feature_format)
271 {
272 // Establish all of the format objects.
273 for (int i = 0; i < model.getSize(); i++)
274 {
275 model.getElementAt(i);//get those objects cached
276 }
277 for (int i = 0; i < feature_name.length; i++)
278 {
279 if (getFormat(model, feature_name[i]) == null)
280 {
281 model.add(new Format4gs3(feature_name[i], feature_format[i]));
282
283 }
284 }
285 }
286
287 /**
288 * Method to remove a format.
289 *
290 * @param format
291 * The <strong>Format</strong> to remove.
292 */
293 private void removeFormat(DOMProxyListModel model, Format4gs3 format)
294 {
295 model.remove(format);
296 }
297
298 private Format4gs3 getFormat(DOMProxyListModel model, String name)
299 {
300
301 for (int index = 0; index < model.getSize(); index++)
302 {
303 Format4gs3 format = (Format4gs3) model.getElementAt(index);
304 if (format.getFeatureName().equals(name))
305 {
306 return format;
307 }
308 }
309 return null;
310 }
311
312 private void addFormat(Element parent, Format4gs3 format)
313 {
314 if (!format_list_model.contains(format))
315 {
316
317 format_list_model.add(parent, format, null);
318 }
319 }
320
321 public void destroy()
322 {
323 if (controls != null)
324 {
325 controls.destroy();
326 controls = null;
327 }
328 }
329
330 /**
331 * Method to retrieve this managers controls.
332 *
333 * @return the Control for this collection.
334 */
335 public Control getControls()
336 {
337 if (controls == null)
338 {
339 controls = new FormatControl();
340 }
341 //controls.gainFocus();
342 return controls;
343 }
344
345 /**
346 * Called when the detail mode has changed which in turn may cause several
347 * design elements to be available/hidden
348 *
349 * @param mode
350 * the new mode as an int
351 */
352 public void modeChanged(int mode)
353 {
354
355 }
356
357 /** updates the format and feature model */
358 public synchronized void refresh()
359 {
360 for (int i = 0; i < format_list_model.getSize(); i++)
361 {
362 Format4gs3 format = (Format4gs3) format_list_model.getElementAt(i);
363 format.update();
364 format = null;
365 }
366 //call the gainFocus() and in turn the buildFeatureModel() method to get the feature combobox refreshed as well
367 if (controls == null)
368 {
369 controls = new FormatControl();
370 }
371 controls.gainFocus();
372
373 //format_list_model.refresh(); //this call is not necessary as it is included in gainFocus()
374 }
375
376 private ArrayList buildFeatureModel()
377 {
378 // Rebuild feature model.
379 ArrayList feature_model = new ArrayList();
380 //This will display 'choose a feature' and is used when the format feature panel is first gained focus
381 feature_model.add(new Entry(""));
382
383 for (int i = 0; i < format_list_model.getSize(); i++)
384 {
385 Format4gs3 format = (Format4gs3) format_list_model.getElementAt(i);
386 String feature_name = format.getFeatureName();
387 if (!feature_name.startsWith(Classifier.CLASSIFIER_PREFIX))
388 {
389 feature_model.add(new Entry(format.getFeatureName()));
390
391 }
392 }
393 // Now the classifiers.
394 Element root = CollectionDesignManager.collect_config.getDocumentElement();
395 NodeList classifier_list = root.getElementsByTagName(StaticStrings.CLASSIFY_ELEMENT);
396 for (int j = 0; j < classifier_list.getLength(); j++)
397 {
398 feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j)));
399
400 }
401 //Collections.sort (feature_model);
402 return feature_model;
403 }
404
405 private String addSurroundingTags(String xml)
406 {
407 return "<ROOTELEMENT>" + xml + "</ROOTELEMENT>";
408 }
409
410 private String removeSurrondingTags(String xml)
411 {
412 return xml.replace("<ROOTELEMENT>\n", "").replace("<ROOTELEMENT>", "").replace("</ROOTELEMENT>", "").replace("<ROOTELEMENT/>","");
413 }
414
415 public class FormatControl extends JPanel implements Control
416 {
417
418 private ArrayList feature_model;
419 private boolean ignore_event = false;
420 private boolean ready = false; // Are these controls available to be refreshed
421 private JButton add_button;
422 private JButton remove_button;
423 private JButton default_button;
424 private JButton undo_button;
425 private JButton redo_button;
426 private JComboBox feature_combobox;
427 private JList format_list;
428 private NumberedJTextArea editor_textarea;
429 private JTextArea editor_msgarea;
430 private JPanel validation_msg_panel;
431 private JPanel selection_pane;
432 private final Dimension FIELD_SIZE = new Dimension(200, 30);
433 private final UndoManager undo = new UndoManager();
434 private boolean newtext = true;
435 private Format4gs3 previousFormat = null;
436 private Format4gs3 currentFormat = null;
437 private boolean fresh = true;
438
439 public FormatControl()
440 {
441 feature_model = buildFeatureModel();
442
443 // Create
444 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Formats", "formatstatements");
445
446 format_list = new JList(format_list_model);
447
448 selection_pane = new JPanel();
449 JPanel feature_pane = new JPanel();
450 JLabel feature_label = new JLabel(Dictionary.get("CDM.FormatManager.Feature"));
451
452 feature_combobox = new JComboBox(feature_model.toArray());
453 feature_combobox.setOpaque(!Utility.isMac());
454 feature_combobox.setPreferredSize(FIELD_SIZE);
455 feature_combobox.setEditable(false);
456 feature_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Feature_Tooltip"));
457
458 JPanel center_pane = new JPanel();
459 JPanel editor_pane = new JPanel();
460
461 editor_textarea = new NumberedJTextArea();
462
463 /* Fields specific to RSyntaxQuery inherited class */
464 editor_textarea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
465 editor_textarea.setBracketMatchingEnabled(true);
466 editor_textarea.setAnimateBracketMatching(true);
467 editor_textarea.setAntiAliasingEnabled(true);
468 editor_textarea.setAutoIndentEnabled(true);
469 editor_textarea.setPaintMarkOccurrencesBorder(false);
470
471 /* Standard fields to JTextArea */
472 editor_textarea.setOpaque(false);
473 editor_textarea.setBackground(Configuration.getColor("coloring.editable_background", false));
474 editor_textarea.setCaretPosition(0);
475 editor_textarea.setLineWrap(true);
476 editor_textarea.setRows(11);
477 editor_textarea.setWrapStyleWord(false);
478 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Add_Tooltip"));
479
480 default_button = new GLIButton(Dictionary.get("CDM.FormatManager.Default"), Dictionary.get("CDM.FormatManager.Default_Tooltip"));
481 JPanel button_pane = new JPanel();
482 add_button = new GLIButton(Dictionary.get("CDM.FormatManager.Add"), Dictionary.get("CDM.FormatManager.Add_Tooltip"));
483 add_button.setEnabled(false);
484
485 remove_button = new GLIButton(Dictionary.get("CDM.FormatManager.Remove"), Dictionary.get("CDM.FormatManager.Remove_Tooltip"));
486 remove_button.setEnabled(false);
487
488 undo_button = new GLIButton(Dictionary.get("General.Undo"), Dictionary.get("General.Undo_Tooltip"));
489 undo_button.setEnabled(false);
490
491 redo_button = new GLIButton(Dictionary.get("General.Redo"), Dictionary.get("General.Redo_Tooltip"));
492 redo_button.setEnabled(false);
493
494 // Connect
495 add_button.addActionListener(new AddListener());
496 remove_button.addActionListener(new RemoveListener());
497 default_button.addActionListener(new DefaultListener());
498 undo_button.addActionListener(new UndoListener());
499 redo_button.addActionListener(new RedoListener());
500 feature_combobox.addActionListener(new FeatureListener());
501 editor_textarea.getDocument().addDocumentListener(new EditorListener());
502 // Listen for undo and redo events
503 editor_textarea.getDocument().addUndoableEditListener(new UndoableEditListener()
504 {
505 public void undoableEditHappened(UndoableEditEvent evt)
506 {
507 undo.addEdit(evt.getEdit());
508 }
509 });
510
511 format_list.addListSelectionListener(new FormatListListener());
512
513 // Layout
514 JPanel format_list_pane = new JPanel();
515 format_list_pane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
516 format_list_pane.setLayout(new BorderLayout());
517 format_list_pane.add(new JScrollPane(format_list), BorderLayout.CENTER);
518
519 feature_pane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
520 feature_pane.setLayout(new BorderLayout(5, 0));
521 feature_pane.add(feature_label, BorderLayout.WEST);
522 feature_pane.add(feature_combobox, BorderLayout.CENTER);
523
524 JPanel rupanel = new JPanel();
525 rupanel.setLayout(new GridLayout(1, 2));
526 rupanel.add(undo_button);
527 rupanel.add(redo_button);
528
529 editor_pane.setLayout(new BorderLayout());
530 editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER);
531
532 validation_msg_panel = new JPanel();
533 JLabel validation_label = new JLabel(Dictionary.get("CDM.FormatManager.MessageBox"));
534 editor_msgarea = new JTextArea();
535
536 editor_msgarea.setCaretPosition(0);
537 editor_msgarea.setLineWrap(true);
538 editor_msgarea.setRows(3);
539 editor_msgarea.setWrapStyleWord(false);
540 editor_msgarea.setEditable(false);
541 editor_msgarea.setToolTipText(Dictionary.get("CDM.FormatManager.MessageBox_Tooltip"));
542 validation_msg_panel.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
543 validation_msg_panel.setLayout(new BorderLayout(5, 0));
544 validation_msg_panel.add(validation_label, BorderLayout.WEST);
545 validation_msg_panel.add(new JScrollPane(editor_msgarea), BorderLayout.CENTER);
546
547 selection_pane.setLayout(new BorderLayout());
548 selection_pane.add(validation_msg_panel, BorderLayout.NORTH);
549 selection_pane.add(rupanel, BorderLayout.SOUTH);
550 selection_pane.add(editor_pane, BorderLayout.CENTER);
551
552 button_pane.setLayout(new GridLayout(1, 3));
553 button_pane.add(add_button);
554 button_pane.add(remove_button);
555 button_pane.add(default_button);
556
557 center_pane.setLayout(new BorderLayout());
558 center_pane.add(feature_pane, BorderLayout.NORTH);
559 center_pane.add(selection_pane, BorderLayout.CENTER);
560 center_pane.add(button_pane, BorderLayout.SOUTH);
561
562 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
563 splitPane.add(format_list_pane, JSplitPane.TOP);
564 splitPane.add(center_pane, JSplitPane.BOTTOM);
565 splitPane.setDividerLocation(150);
566
567 setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
568 setLayout(new BorderLayout());
569 add(header_pane, BorderLayout.NORTH);
570 add(splitPane, BorderLayout.CENTER);
571 ready = true;
572 }
573
574 public void destroy()
575 {
576 }
577
578 /**
579 * Overriden to ensure that the instructions pane is scrolled to the
580 * top.
581 */
582 public void gainFocus()
583 {
584 if (ready)
585 {
586
587 format_list_model.refresh();
588 // Update the feature model, trying to maintain the same selected object
589 Object selected_feature = feature_combobox.getSelectedItem();
590 feature_combobox.setSelectedItem(selected_feature);
591 feature_model = buildFeatureModel();
592 feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray()));
593 }
594 }
595
596 public void loseFocus()
597 {
598 //validate the templates. If not wellformed, pop up an alert; otherwise, do nothing.
599 String msg = XMLTools.parse(editor_textarea.getText());
600 if (msg.startsWith(XMLTools.NOTWELLFORMED))
601 {
602 JOptionPane.showMessageDialog(null, msg, XMLTools.NOTWELLFORMED, JOptionPane.ERROR_MESSAGE);
603 }
604 format_list_model.refresh();
605 }
606
607 public Format4gs3 getCurrentFormat()
608 {
609 return (Format4gs3) format_list.getSelectedValue();
610
611 }
612
613 /**
614 * Listens for clicks on the add button, and if the relevant details are
615 * provided adds a new format. Note that formats are responsible for
616 * codecing the values into something that can be a) stored in a DOM and
617 * b) written to file
618 */
619 private class AddListener implements ActionListener
620 {
621
622 public void actionPerformed(ActionEvent event)
623 {
624
625 ignore_event = true; // Prevent format_list excetera propagating events
626
627 String format_str = editor_textarea.getText();
628 Entry entry = (Entry) feature_combobox.getSelectedItem();
629 String feature_name = entry.getClassifier().getPositionString();
630
631 Format4gs3 format = new Format4gs3(feature_name, format_str);
632 Element e = format.getClassifyElement();
633 addFormat(e, format);
634 existingFormat(format.getFeatureName().startsWith(Classifier.CLASSIFIER_PREFIX)); // set the appropriate enable/disable on the interface
635
636 // Update list selection (make the new added format highlighted on the format list panel)
637 format_list.setSelectedValue(format, true);
638
639 format = null;
640
641 ignore_event = false;
642 }
643 }
644
645 private class EditorListener implements DocumentListener
646 {
647
648 public void changedUpdate(DocumentEvent e)
649 {
650 update();
651 }
652
653 public void insertUpdate(DocumentEvent e)
654 {
655 update();
656 updateUndo("insert");
657
658 }
659
660 public void removeUpdate(DocumentEvent e)
661 {
662 update();
663 updateUndo("remove");
664
665 }
666
667 private void updateUndo(String from)
668 {
669
670 if (!newtext)
671 {
672 undo_button.setEnabled(true);
673 }
674
675 if (editor_textarea.getText().length() != 0 && newtext)
676 {
677 newtext = false;
678 }
679 }
680
681 public void update()
682 {
683 if (!format_list.isSelectionEmpty())
684 {
685 Format4gs3 format = (Format4gs3) format_list.getSelectedValue();
686 String format_str = editor_textarea.getText();
687 String msg = XMLTools.parse(format_str);
688 editor_msgarea.setText(msg);
689
690 if (msg.startsWith(XMLTools.WELLFORMED))
691 {
692 format.setPureFormat(format_str);
693 format.update();
694 format_list_model.refresh(format);
695 editor_msgarea.setBackground(Color.white);
696 FormatPane.setPreviewButton(true);
697 }
698 else
699 {
700 editor_msgarea.setBackground(Color.red);
701 FormatPane.setPreviewButton(false);
702 }
703 }
704 else
705 {
706 add_button.setEnabled(false);
707 }
708 }
709 }
710
711 private class FeatureListener implements ActionListener
712 {
713 public void actionPerformed(ActionEvent event)
714 {
715 undo_button.setEnabled(false);
716 redo_button.setEnabled(false);
717 default_button.setEnabled(true);
718 newtext = true;
719
720 if (ignore_event == true)
721 {
722 undo.discardAllEdits();
723 return;
724 }
725
726 ignore_event = true;
727 // Add is only enabled if there isn't already a format for the choosen feature and part.
728 //Create a dummy format and test if itsa already in the model
729 Entry entry = (Entry) feature_combobox.getSelectedItem();
730 String feature_name = entry.getFeatureName();
731
732 Format4gs3 format = getFormat(format_list_model, feature_name);
733
734 if (format != null)
735 {
736 ///ystem.err.println("There is an existing format!");
737 format_list.setSelectedValue(format, true);
738 Element formatElem = null;
739 try
740 {
741 InputSource is = new InputSource(new ByteArrayInputStream(addSurroundingTags(format.getPureFormat()).getBytes("utf-8")));
742 formatElem = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is).getDocumentElement();
743 }
744 catch (Exception ex)
745 {
746 ex.printStackTrace();
747 }
748
749 if (formatElem != null)
750 {
751 StringBuffer sb = new StringBuffer();
752 XMLTools.xmlNodeToString(sb, formatElem, true, " ", 0);
753 editor_textarea.setText(removeSurrondingTags(sb.toString()));
754 }
755 else
756 {
757 editor_textarea.setText(format.getPureFormat());
758 }
759 editor_textarea.setCaretPosition(0);
760
761 existingFormat(feature_name.startsWith(Classifier.CLASSIFIER_PREFIX));
762 }
763 // Otherwise there is no existing format, then this feature must be a classifier (CL1, 2, ...)
764 // we display the ClassifierDefault for this format
765 else
766 {
767 //Fist reset the format list panel
768 format_list.clearSelection();
769
770 if (feature_name.equals(""))
771 {
772 editor_textarea.setText("");
773
774 }
775 else
776 {
777 //Only for debugging purposes
778 if (entry.getClassifier() == null)
779 {
780 DebugStream.println("It should be a classifier or choose a feature. What is it? " + entry.toString());
781 }
782
783 editor_textarea.setText(Format4gs3.toFormatedFormat(CLASSIFIER_DEFAULT_FORMAT));
784 editor_textarea.setCaretPosition(0);
785 newFormat();
786 }
787 }
788 ignore_event = false;
789 undo.discardAllEdits();
790 }
791 }
792
793 private class FormatListListener implements ListSelectionListener
794 {
795 public void valueChanged(ListSelectionEvent event)
796 {
797 undo_button.setEnabled(false);
798 redo_button.setEnabled(false);
799 default_button.setEnabled(true);
800 newtext = true;
801
802 if (!ignore_event && !event.getValueIsAdjusting())
803 {
804
805 if (!format_list.isSelectionEmpty())
806 {
807 ignore_event = true;
808 Format4gs3 format = (Format4gs3) format_list.getSelectedValue();
809 String feature_name = format.getFeatureName();
810 Entry entry = null;
811 if (feature_name.startsWith(Classifier.CLASSIFIER_PREFIX))
812 {
813 entry = new Entry(format.getClassifier());
814 }
815 else
816 {
817 entry = new Entry(feature_name);
818 }
819 feature_combobox.setSelectedItem(entry);
820
821 existingFormat(format.getFeatureName().startsWith(Classifier.CLASSIFIER_PREFIX));
822
823 Element formatElem = null;
824 try
825 {
826 InputSource is = new InputSource(new ByteArrayInputStream(addSurroundingTags(format.getPureFormat()).getBytes("utf-8")));
827 formatElem = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is).getDocumentElement();
828 }
829 catch (Exception ex)
830 {
831 ex.printStackTrace();
832 }
833
834 if (formatElem != null)
835 {
836 StringBuffer sb = new StringBuffer();
837 XMLTools.xmlNodeToString(sb, formatElem, true, " ", 0);
838 editor_textarea.setText(removeSurrondingTags(sb.toString()));
839 }
840 else
841 {
842 editor_textarea.setText(format.getPureFormat());
843 }
844 editor_textarea.setCaretPosition(0);
845
846 ignore_event = false;
847 }
848
849 }
850 undo.discardAllEdits();
851 }
852
853 }
854
855 private class RemoveListener implements ActionListener
856 {
857 public void actionPerformed(ActionEvent event)
858 {
859 if (!format_list.isSelectionEmpty())
860 {
861 // Remove the current format
862 Format4gs3 format = (Format4gs3) format_list.getSelectedValue();
863 removeFormat(format_list_model, format);
864 // Change buttons
865 add_button.setEnabled(true);
866 feature_combobox.setSelectedItem(new Entry(""));
867 newFormat();
868 }
869 }
870 }
871
872 private class DefaultListener implements ActionListener
873 {
874 public void actionPerformed(ActionEvent event)
875 {
876 newtext = false;
877 if (!ignore_event)
878 {
879 Entry entry = (Entry) feature_combobox.getSelectedItem();
880 String feature_name = entry.getFeatureName();
881 Format4gs3 format = getFormat(format_list_model, feature_name);
882
883 if (format != null)
884 {
885 if (format.isClassifier() == true)
886 {
887 editor_textarea.setText((String) default_format_formated_map.get(CLASSIFIER_DEFAULT));
888 editor_textarea.setCaretPosition(0);
889 remove_button.setEnabled(true);
890 }
891 else
892 {
893 editor_textarea.setText((String) default_format_formated_map.get(format.getFeatureName()));
894 editor_textarea.setCaretPosition(0);
895 remove_button.setEnabled(false);
896 }
897 }
898 else
899 {
900 editor_textarea.setText((String) default_format_formated_map.get(CLASSIFIER_DEFAULT));
901 editor_textarea.setCaretPosition(0);
902 remove_button.setEnabled(false);
903 add_button.setEnabled(true);
904 }
905 }
906 }
907 }
908
909 private class UndoListener implements ActionListener
910 {
911
912 public void actionPerformed(ActionEvent event)
913 {
914 try
915 {
916 if (undo.canUndo())
917 {
918 int pos = editor_textarea.getCaretPosition();
919 redo_button.setEnabled(true);
920 undo.undo();
921 if (pos > 0)
922 editor_textarea.setCaretPosition(pos - 1);
923 else
924 editor_textarea.setCaretPosition(pos);
925 }
926 if (!undo.canUndo())
927 {
928 undo_button.setEnabled(false);
929 }
930 else
931 {
932 undo_button.setEnabled(true);
933 }
934
935 }
936 catch (Exception e)
937 {
938
939 }
940 }
941 }
942
943 private class RedoListener implements ActionListener
944 {
945 public void actionPerformed(ActionEvent evt)
946 {
947 try
948 {
949 if (undo.canRedo())
950 {
951 int pos = editor_textarea.getCaretPosition();
952 undo.redo();
953 editor_textarea.setCaretPosition(pos);
954 }
955 if (!undo.canRedo())
956 {
957 redo_button.setEnabled(false);
958 }
959 else
960 {
961 redo_button.setEnabled(true);
962 }
963
964 }
965 catch (Exception e)
966 {
967 }
968 }
969 }
970
971 private void newFormat()
972 {
973 editor_textarea.setEditable(false);
974 editor_textarea.setBackground(Color.lightGray);
975 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Disabled_Tooltip"));
976
977 undo_button.setEnabled(false);
978 redo_button.setEnabled(false);
979 add_button.setEnabled(true);
980 remove_button.setEnabled(false);
981 default_button.setEnabled(false);
982 FormatPane.setPreviewButton(true);
983 }
984
985 private void existingFormat(boolean enableRemoveButton)
986 {
987 editor_textarea.setEditable(true);
988 editor_textarea.setBackground(Color.white);
989 editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Tooltip"));
990 add_button.setEnabled(false);
991 remove_button.setEnabled(enableRemoveButton);
992 default_button.setEnabled(true);
993 FormatPane.setPreviewButton(true);
994 }
995
996 /**
997 * A textarea with the line number next to each line of the text
998 */
999 public class NumberedJTextArea extends RSyntaxTextArea /* JTextArea */
1000 {
1001 public void paintComponent(Graphics g)
1002 {
1003 Insets insets = getInsets();
1004 Rectangle rectangle = g.getClipBounds();
1005 g.setColor(Color.white);
1006 g.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
1007
1008 super.paintComponent(g);
1009
1010 if (rectangle.x < insets.left)
1011 {
1012 FontMetrics font_metrics = g.getFontMetrics();
1013 int font_height = font_metrics.getHeight();
1014 int y = font_metrics.getAscent() + insets.top;
1015 int line_number_start_point = ((rectangle.y + insets.top) / font_height) + 1;
1016 if (y < rectangle.y)
1017 {
1018 y = line_number_start_point * font_height - (font_height - font_metrics.getAscent());
1019 }
1020 int y_axis_end_point = y + rectangle.height + font_height;
1021 int x_axis_start_point = insets.left;
1022 x_axis_start_point -= getFontMetrics(getFont()).stringWidth(Math.max(getRows(), getLineCount() + 1) + " ");
1023 if (!this.getText().trim().equals(""))
1024 {
1025 g.setColor(Color.DARK_GRAY);
1026 }
1027 else
1028 {
1029 g.setColor(Color.white);
1030 }
1031 int length = ("" + Math.max(getRows(), getLineCount() + 1)).length();
1032 while (y < y_axis_end_point)
1033 {
1034 g.drawString(line_number_start_point + " ", x_axis_start_point, y);
1035 y += font_height;
1036 line_number_start_point++;
1037 }
1038 }
1039 }
1040
1041 public Insets getInsets()
1042 {
1043 Insets insets = super.getInsets(new Insets(0, 0, 0, 0));
1044 insets.left += getFontMetrics(getFont()).stringWidth(Math.max(getRows(), getLineCount() + 1) + " ");
1045 return insets;
1046 }
1047 }
1048 }
1049
1050 /**
1051 * This object provides a wrapping around an entry in Format4gs3, which is
1052 * tranparent.
1053 */
1054 // This class is used for display in the feature combobox
1055 private class Entry implements Comparable
1056 {
1057 private Classifier classifier = null;
1058 private String feature_name = null;
1059
1060 public Entry(Object object)
1061 {
1062 if (object instanceof Classifier)
1063 {
1064 classifier = (Classifier) object;
1065 feature_name = classifier.getPositionString();
1066 }
1067 else if (object instanceof String)
1068 {
1069 feature_name = (String) object;
1070 }
1071 else
1072 {
1073 feature_name = "";
1074 }
1075 }
1076
1077 public Entry(String text)
1078 {
1079 this.feature_name = text;
1080 }
1081
1082 public int compareTo(Object object)
1083 {
1084 if (object == null)
1085 {
1086 return 1;
1087 }
1088 if (toString() == null)
1089 {
1090 return -1;
1091 }
1092 else
1093 {
1094 String object_str = object.toString();
1095 if (object_str == null)
1096 {
1097 return 1;
1098 }
1099 return toString().compareTo(object_str);
1100 }
1101 }
1102
1103 public boolean equals(Object object)
1104 {
1105 if (compareTo(object) == 0)
1106 {
1107 return true;
1108 }
1109 return false;
1110 }
1111
1112 public Classifier getClassifier()
1113 {
1114 return classifier;
1115 }
1116
1117 public String toString()
1118 {
1119 if (classifier != null)
1120 {
1121 // Return the classifier name - with its CL index shown, and all its metadata options as well
1122 return classifier.getPositionString() + StaticStrings.SPACE_CHARACTER + classifier.toString();
1123 }
1124 if (feature_name.equals(""))
1125 {
1126 return "<html><body><i>" + "Choose a feature" + "</i></body></html>";
1127 }
1128 return feature_name;
1129 }
1130
1131 public String getFeatureName()
1132 {
1133 return feature_name;
1134 }
1135 }
1136}
Note: See TracBrowser for help on using the repository browser.