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