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

Last change on this file since 26064 was 26064, checked in by ak19, 12 years ago

Correction to previous commit: needed to close the elements calling 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.