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

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

The editing area of the format features panel is now resizeable

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