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

Last change on this file since 25709 was 25709, checked in by sjm84, 12 years ago

Some very minor formatting

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