/** *######################################################################### * * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * Author: John Thompson, Greenstone Digital Library, University of Waikato * * Copyright (C) 1999 New Zealand Digital Library Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer.cdm; import java.awt.*; import java.awt.event.*; import java.lang.reflect.Field; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.undo.*; import org.greenstone.gatherer.Configuration; import org.greenstone.gatherer.DebugStream; import org.greenstone.gatherer.Dictionary; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.gui.DesignPaneHeader; import org.greenstone.gatherer.gui.GLIButton; import org.greenstone.gatherer.gui.WarningDialog; import org.greenstone.gatherer.metadata.MetadataElement; import org.greenstone.gatherer.metadata.MetadataSetManager; import org.greenstone.gatherer.util.StaticStrings; import org.greenstone.gatherer.util.Utility; import org.w3c.dom.*; import org.fife.ui.rsyntaxtextarea.*; /** This class maintains a list of format statements, and allows the addition and removal of these statements. * @author John Thompson, Greenstone Digital Library, University of Waikato * @version 2.3 */ public class FormatManager extends DOMProxyListModel implements SharedByTwoFormatManager { static final private String BLANK = "blank"; static final private String FLAG = "flag"; static final private String VALUE = "value"; static final private String DATELIST = "DateList"; static final private String DATELIST_DEFAULT_FORMAT = "[link][icon][/link]\n[highlight]{Or}{[dc.Title],[exp.Title],[ex.Title],Untitled}[/highlight]\n{Or}{[format:dc.Date],[format:exp.Date],[format:ex.Date]}"; static final private String HLIST = "HList"; static final private String HLIST_DEFAULT_FORMAT = "[link][highlight][ex.Title][/highlight][/link]"; static final private String VLIST = "VList"; static final private String VLIST_DEFAULT_FORMAT = "[link][icon][/link]\n[ex.srclink]{Or}{[ex.thumbicon],[ex.srcicon]}[ex./srclink]\n[highlight]\n{Or}{[dc.Title],[exp.Title],[ex.Title],Untitled}\n[/highlight]{If}{[ex.Source],
([ex.Source])}"; // static final private String INVISIBLE = "Invisible"; //static final private String INVISIBLE_DEFAULT_FORMAT = ""; static final private String DOCUMENTHEADING = "DocumentHeading"; static final private String DOCUMENTHEADING_DEFAULT_FORMAT = "{Or}{[parent(Top):Title],[Title],untitled}
"; static final private String DOCUMENTTEXT = "DocumentText"; static final private String DOCUMENTTEXT_DEFAULT_FORMAT = "[Text]"; static final private String DOCUMENTBUTTONS = "DocumentButtons"; static final private String DOCUMENTBUTTONS_DEFAULT_FORMAT = "Detach|Highlight"; static final private String SEARCHTYPES = "SearchTypes"; static final private String SEARCHTYPES_DEFAULT_FORMAT = "plain,form"; static final private String NAVBAR = "NavigationBar"; static final private String NAVBAR_OPTION = "pulldown"; static private HashMap default_format_map = null; /** The controls used to edit the format commands. */ private Control controls = null; /** A reference to ourselves so inner classes can get at the model. */ private DOMProxyListModel model = null; /** Constructor. */ public FormatManager() { super(CollectionDesignManager.collect_config.getDocumentElement(), StaticStrings.FORMAT_ELEMENT, new Format()); this.model = this; default_format_map = new HashMap(); default_format_map.put(DATELIST, DATELIST_DEFAULT_FORMAT); default_format_map.put(HLIST, HLIST_DEFAULT_FORMAT); default_format_map.put(VLIST, VLIST_DEFAULT_FORMAT); default_format_map.put(DOCUMENTHEADING, DOCUMENTHEADING_DEFAULT_FORMAT); default_format_map.put(DOCUMENTTEXT, DOCUMENTTEXT_DEFAULT_FORMAT); default_format_map.put(DOCUMENTBUTTONS, DOCUMENTBUTTONS_DEFAULT_FORMAT); default_format_map.put(SEARCHTYPES, SEARCHTYPES_DEFAULT_FORMAT); default_format_map.put(NAVBAR, NAVBAR_OPTION); default_format_map.put("", ""); DebugStream.println("FormatManager: parsed " + getSize() + " format statements."); // Establish all of the format objects, so that classifier indexes are initially correct (subsequent refreshes of the model will be sufficient to keep these up to date, as long as we start with a live reference to a classifier. int size = getSize(); for(int i = 0; i < size; i++) { getElementAt(i); } // Ensure the default formats for important format statements are assigned if (getFormat(VLIST) == null) { addFormat(new Format("",VLIST,VLIST_DEFAULT_FORMAT)); } if (getFormat(HLIST) == null) { addFormat(new Format("",HLIST,HLIST_DEFAULT_FORMAT)); } // only if DateList is used if (getFormat(DATELIST) == null && CollectionDesignManager.classifier_manager.isDateListClassifierAssigned()) { addFormat(new Format("",DATELIST,DATELIST_DEFAULT_FORMAT)); } if (getFormat(DOCUMENTHEADING) == null) { addFormat(new Format(DOCUMENTHEADING, "", DOCUMENTHEADING_DEFAULT_FORMAT)); } if (getFormat(DOCUMENTTEXT)== null) { addFormat(new Format(DOCUMENTTEXT,"",DOCUMENTTEXT_DEFAULT_FORMAT)); } if (getFormat(DOCUMENTBUTTONS) == null) { addFormat(new Format(DOCUMENTBUTTONS,"",DOCUMENTBUTTONS_DEFAULT_FORMAT)); } // only for mgpp and lucene colls if (getFormat(SEARCHTYPES)==null && (CollectionDesignManager.index_manager.isMGPP()) || CollectionDesignManager.index_manager.isLucene()) { addFormat(new Format(SEARCHTYPES, "", SEARCHTYPES_DEFAULT_FORMAT)); } } /** Method to add a new format to this manager. * @param format The Format to add. */ private void addFormat(Format format) { if(!contains(format)) { Element element = format.getElement(); // Locate where we should insert this new classifier. Node target_node = CollectionConfiguration.findInsertionPoint(element); add(root, format, target_node); } } public void destroy() { if(controls != null) { controls.destroy(); controls = null; } } private Format getFormat(String name) { int model_size = getSize(); for(int index = 0; index < model_size; index++) { Format format = (Format) getElementAt(index); if(format.getName().equals(name)) { return format; } } return null; } public String getDefaultFormatString(String name){ String default_str = ""; try{ String field_name = name.toUpperCase()+"_DEFAULT_FORMAT"; Field field = this.getClass().getDeclaredField(field_name); Class fieldType = field.getType(); default_str = (String) field.get(fieldType); } catch (SecurityException e) { //System.err.println("Debug: "+e.getMessage()); default_str = VLIST_DEFAULT_FORMAT; } catch (NoSuchFieldException e) { //System.err.println("Debug: "+e.getMessage()); default_str = VLIST_DEFAULT_FORMAT; } catch (IllegalArgumentException e) { //System.err.println("Debug: "+e.getMessage()); default_str = VLIST_DEFAULT_FORMAT; } catch (IllegalAccessException e) { //System.err.println("Debug: "+e.getMessage()); default_str = VLIST_DEFAULT_FORMAT; } return default_str; } /** Method to retrieve this managers controls. * @return the Control for this collection. */ public Control getControls() { if(controls == null) { controls = new FormatControl(); } return controls; } /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden * @param mode the new mode as an int */ public void modeChanged(int mode) { } /** updates the format model */ public synchronized void refresh() { for(int i = 0; i < getSize(); i++) { Format format = (Format) getElementAt(i); format.update(); format = null; } super.refresh(); } /** Method to remove a format. * @param format The Format to remove. */ private void removeFormat(Format format) { remove(format); } private ArrayList buildFeatureModel() { // Rebuild feature model. ArrayList feature_model = new ArrayList(); // Add the set options for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) { feature_model.add(new Entry(Format.DEFAULT_FEATURES[i])); } // Now the classifiers. for(int j = 0; j < CollectionDesignManager.classifier_manager.getSize(); j++) { feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j))); } Collections.sort(feature_model); return feature_model; } private ArrayList buildPartModel() { DebugStream.println("buildPartModel(): replace me with something that reads in a data xml file."); ArrayList part_model = new ArrayList(); part_model.add(new Part("", "")); part_model.add(new Part(DATELIST, DATELIST_DEFAULT_FORMAT)); part_model.add(new Part(HLIST, HLIST_DEFAULT_FORMAT)); //part_model.add(new Part(INVISIBLE, INVISIBLE_DEFAULT_FORMAT)); part_model.add(new Part(VLIST, VLIST_DEFAULT_FORMAT)); return part_model; } private ArrayList buildVariableModel() { ArrayList variable_model = new ArrayList(); variable_model.add(Dictionary.get("CDM.FormatManager.Insert_Variable")); variable_model.add("[Text]"); ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement(); for (int i = 0; i < every_metadata_set_element.size(); i++) { variable_model.add("[" + ((MetadataElement) every_metadata_set_element.get(i)).getFullName() + "]"); } variable_model.add("[link]"); variable_model.add("[/link]"); variable_model.add("[icon]"); variable_model.add("[numleafdocs]"); variable_model.add("[num]"); variable_model.add("[parent():_]"); variable_model.add("[parent(Top):_]"); variable_model.add("[parent(All'_'):_]"); variable_model.add("[child():_]"); variable_model.add("[child(All'_'):_]"); variable_model.add("[sibling():_]"); variable_model.add("[sibling(All'_'):_]"); return variable_model; } public class FormatControl extends JPanel implements Control{ private ArrayList feature_model; private ArrayList part_model; private ArrayList variable_model; private boolean ignore_event = false; private boolean ready = false; // Are these controls available to be refreshed private CardLayout card_layout; private JButton add_button; private JButton insert_button; private JButton remove_button; private JButton default_button; private JButton undo_button; private JButton redo_button; private JCheckBox enabled_checkbox; private JComboBox feature_combobox; private JComboBox part_combobox; private JComboBox variable_combobox; private JList format_list; private RSyntaxTextArea editor_textarea; private JPanel blank_pane; private JPanel control_pane; private JPanel part_pane; private JPanel selection_pane; private String view_type; private final Dimension FIELD_SIZE = new Dimension(200, 30); private final UndoManager undo = new UndoManager(); private boolean newtext = true; private Format previousFormat = null; private Format currentFormat = null; private boolean fresh = true; public FormatControl() { this.setComponentOrientation(Dictionary.getOrientation()); feature_model = buildFeatureModel(); part_model = buildPartModel(); variable_model = buildVariableModel(); // Create JPanel header_pane = new DesignPaneHeader("CDM.GUI.Formats", "formatstatements"); format_list = new JList(model); selection_pane = new JPanel(); JPanel feature_pane = new JPanel(); feature_pane.setComponentOrientation(Dictionary.getOrientation()); JLabel feature_label = new JLabel(Dictionary.get("CDM.FormatManager.Feature")); feature_label.setComponentOrientation(Dictionary.getOrientation()); feature_combobox = new JComboBox(feature_model.toArray()); feature_combobox.setComponentOrientation(Dictionary.getOrientation()); feature_combobox.setOpaque(!Utility.isMac()); feature_combobox.setPreferredSize(FIELD_SIZE); feature_combobox.setEditable(false); feature_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Feature_Tooltip")); part_pane = new JPanel(); part_pane.setComponentOrientation(Dictionary.getOrientation()); JLabel part_label = new JLabel(Dictionary.get("CDM.FormatManager.Part")); part_label.setComponentOrientation(Dictionary.getOrientation()); part_combobox = new JComboBox(part_model.toArray()); part_combobox.setComponentOrientation(Dictionary.getOrientation()); part_combobox.setOpaque(!Utility.isMac()); part_combobox.setPreferredSize(FIELD_SIZE); part_combobox.setEditable(false); part_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Part_Tooltip")); blank_pane = new JPanel(); JPanel center_pane = new JPanel(); card_layout = new CardLayout(); control_pane = new JPanel(); JPanel blank_pane = new JPanel(); JPanel editor_pane = new JPanel(); JPanel editor_header_pane = new JPanel(); JLabel editor_label = new JLabel(Dictionary.get("CDM.FormatManager.Editor")); editor_label.setComponentOrientation(Dictionary.getOrientation()); editor_textarea = new RSyntaxTextArea(); /* Fields specific to RSyntaxQuery inherited class */ editor_textarea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_HTML); editor_textarea.setBracketMatchingEnabled(true); editor_textarea.setAnimateBracketMatching(true); editor_textarea.setAntiAliasingEnabled(true); editor_textarea.setAutoIndentEnabled(true); editor_textarea.setPaintMarkOccurrencesBorder(false); /* Standard fields to JTextArea */ editor_textarea.setBackground(Configuration.getColor("coloring.editable_background", false)); editor_textarea.setCaretPosition(0); editor_textarea.setLineWrap(true); editor_textarea.setRows(6); editor_textarea.setWrapStyleWord(false); editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Add_Tooltip")); variable_combobox = new JComboBox(variable_model.toArray()); variable_combobox.setComponentOrientation(Dictionary.getOrientation()); variable_combobox.setOpaque(!Utility.isMac()); variable_combobox.setToolTipText(Dictionary.get("CDM.FormatManager.Variable_Tooltip")); insert_button = new GLIButton(Dictionary.get("CDM.FormatManager.Insert"), Dictionary.get("CDM.FormatManager.Insert_Tooltip")); default_button = new GLIButton(Dictionary.get("CDM.FormatManager.Default"), Dictionary.get("CDM.FormatManager.Default_Tooltip")); JPanel flag_pane = new JPanel(); enabled_checkbox = new JCheckBox(Dictionary.get("CDM.FormatManager.Enabled")); enabled_checkbox.setComponentOrientation(Dictionary.getOrientation()); JPanel button_pane = new JPanel(); button_pane.setComponentOrientation(Dictionary.getOrientation()); add_button = new GLIButton(Dictionary.get("CDM.FormatManager.Add"), Dictionary.get("CDM.FormatManager.Add_Tooltip")); add_button.setEnabled(false); remove_button = new GLIButton(Dictionary.get("CDM.FormatManager.Remove"), Dictionary.get("CDM.FormatManager.Remove_Tooltip")); remove_button.setEnabled(false); undo_button = new GLIButton(Dictionary.get("General.Undo"), Dictionary.get("General.Undo_Tooltip")); undo_button.setEnabled(false); redo_button = new GLIButton(Dictionary.get("General.Redo"), Dictionary.get("General.Redo_Tooltip")); redo_button.setEnabled(false); // Connect add_button.addActionListener(new AddListener()); remove_button.addActionListener(new RemoveListener()); default_button.addActionListener(new DefaultListener()); undo_button.addActionListener(new UndoListener()); redo_button.addActionListener(new RedoListener()); enabled_checkbox.addActionListener(new EnabledListener()); feature_combobox.addActionListener(new FeatureListener()); part_combobox.addActionListener(new PartListener()); editor_textarea.getDocument().addDocumentListener(new EditorListener()); // Listen for undo and redo events editor_textarea.getDocument().addUndoableEditListener(new UndoableEditListener() { public void undoableEditHappened(UndoableEditEvent evt) { undo.addEdit(evt.getEdit()); } }); format_list.addListSelectionListener(new FormatListListener()); variable_combobox.addActionListener(new VariableListener()); // Layout JPanel format_list_pane = new JPanel(); format_list_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); format_list_pane.setLayout(new BorderLayout()); format_list_pane.add(new JScrollPane(format_list), BorderLayout.CENTER); feature_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); feature_pane.setLayout(new BorderLayout(5,0)); feature_pane.add(feature_label, BorderLayout.LINE_START); feature_pane.add(feature_combobox, BorderLayout.CENTER); part_pane.setBorder(BorderFactory.createEmptyBorder(2,0,0,0)); part_pane.setLayout(new BorderLayout(5, 0)); part_pane.add(part_label, BorderLayout.LINE_START); part_pane.add(part_combobox, BorderLayout.CENTER); flag_pane.add(enabled_checkbox); editor_header_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0)); editor_header_pane.setLayout(new GridLayout(1,3)); editor_header_pane.add(editor_label); JPanel rupanel = new JPanel(); rupanel.setComponentOrientation(Dictionary.getOrientation()); rupanel.setLayout(new GridLayout(1,2)); rupanel.add(undo_button); rupanel.add(redo_button); JPanel variable_pane = new JPanel(); variable_pane.setComponentOrientation(Dictionary.getOrientation()); variable_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0)); variable_pane.setLayout(new GridLayout(1,3)); variable_pane.add(new JPanel()); variable_pane.add(variable_combobox); variable_pane.add(rupanel); editor_pane.setLayout(new BorderLayout()); editor_pane.add(editor_header_pane, BorderLayout.NORTH); editor_pane.add(new JScrollPane(editor_textarea), BorderLayout.CENTER); selection_pane.setLayout(new BorderLayout()); selection_pane.add(part_pane, BorderLayout.NORTH); selection_pane.add(editor_pane, BorderLayout.CENTER); selection_pane.add(variable_pane, BorderLayout.SOUTH); control_pane.setLayout(card_layout); control_pane.add(flag_pane, FLAG); control_pane.add(selection_pane, VALUE); control_pane.add(blank_pane, BLANK); button_pane.setLayout(new GridLayout(1,3)); button_pane.add(add_button); button_pane.add(remove_button); button_pane.add(default_button); center_pane.setLayout(new BorderLayout()); center_pane.add(feature_pane, BorderLayout.NORTH); center_pane.add(control_pane, BorderLayout.CENTER); center_pane.add(button_pane, BorderLayout.SOUTH); setBorder(BorderFactory.createEmptyBorder(0,5,0,0)); setLayout(new BorderLayout()); add(header_pane, BorderLayout.NORTH); add(format_list_pane, BorderLayout.CENTER); add(center_pane, BorderLayout.SOUTH); ready = true; } public void destroy() { } /** Overriden to ensure that the instructions pane is scrolled to the top. */ public void gainFocus() { // This is only necessary if the components have been realized if(ready) { model.refresh(); // Update the feature model, trying to maintain the same selected object Object selected_feature = feature_combobox.getSelectedItem(); feature_model = buildFeatureModel(); feature_combobox.setModel(new DefaultComboBoxModel(feature_model.toArray())); feature_combobox.setSelectedItem(selected_feature); // Update the variable model, variable_model = buildVariableModel(); variable_combobox.setModel(new DefaultComboBoxModel(variable_model.toArray())); } } public void loseFocus() { // Force all of the Formats to update their names with the correct values. // do we need to do this on loseFocus??? model.refresh(); } public Format getCurrentFormat() { return (Format)format_list.getSelectedValue(); } /** Listens for clicks on the add button, and if the relevant details are provided adds a new format. Note that formats are responsible for codecing the values into something that can be a) stored in a DOM and b) written to file */ private class AddListener implements ActionListener { public void actionPerformed(ActionEvent event) { ignore_event = true; // Prevent format_list excetera propagating events Entry entry = (Entry) feature_combobox.getSelectedItem(); Object f = entry.getFeature(); String p = ""; if (entry.canHavePart()) { p = ((Part)part_combobox.getSelectedItem()).getName(); } // Add a new format string of the appropriate type Format format = null; if (view_type.equals(FLAG)) { format = new Format(f, p, enabled_checkbox.isSelected()); } else { format = new Format(f, p, editor_textarea.getText()); } addFormat(format); existingFormat(); // Update list selection format_list.setSelectedValue(format, true); format = null; p = null; f = null; entry = null; ignore_event = false; } } private class EditorListener implements DocumentListener { public void changedUpdate(DocumentEvent e) { update(); } public void insertUpdate(DocumentEvent e) { update(); updateUndo("insert"); } public void removeUpdate(DocumentEvent e) { update(); updateUndo("remove"); } private void updateUndo(String from){ if (!newtext){ undo_button.setEnabled(true); } if (editor_textarea.getText().length()!=0 && newtext){ newtext = false; } } public void update() { // Determine if replace should be enabled if(!format_list.isSelectionEmpty()) { Format format = (Format)format_list.getSelectedValue(); boolean shouldSave = !format.isParamType(); if (shouldSave){ // Changed so DocumentButtons statement can be set to empty // to get rid of the Detach and NOHIGHLIGHT buttons //String format_str = editor_textarea.getText().trim(); //format_str = (format_str.equals(""))? getDefaultFormatString(format.getName()) : format_str; format.setValue(editor_textarea.getText().trim()); model.refresh((DOMProxyListEntry)format); } } else { add_button.setEnabled(false); } } } private class EnabledListener implements ActionListener { public void actionPerformed(ActionEvent event) { // If there is a current format selected, and the value of enable_checkbox is now different than to value in it, then enable to replace button. if(!format_list.isSelectionEmpty()) { Format format = (Format)format_list.getSelectedValue(); boolean shouldSave = format.isParamType(); if (shouldSave){ format.setState(enabled_checkbox.isSelected()); model.refresh((DOMProxyListEntry)format); } } // Thats it. Add would have been enabled upon feature/part selection depending if no existing format, um, existed. } } private class FeatureListener implements ActionListener { public void actionPerformed(ActionEvent event) { undo_button.setEnabled(false); redo_button.setEnabled(false); default_button.setEnabled(true); newtext = true; if(!ignore_event) { ignore_event = true; Entry entry = (Entry) feature_combobox.getSelectedItem(); // Step one: reset part if (entry.canHavePart()) { // update AffectedComponents according to current entry part_model = entry.getPartModel(); part_combobox.setModel(new DefaultComboBoxModel(part_model.toArray())); part_combobox.updateUI(); part_combobox.setEnabled(true); part_combobox.setSelectedIndex(part_combobox.getModel().getSize()-1); } else { part_combobox.setEnabled(false); part_combobox.setSelectedIndex(0); } // Step two: the rest String name = entry.toString(); // Add is only enabled if there isn't already a format for the choosen feature and part. Create a dummy format and test if itsa already in the model Object f = entry.getFeature(); Part part = (Part)part_combobox.getSelectedItem(); String pname = part.getName(); // You can never add anything to blank-blank if(f.toString().length() == 0 && pname.length() == 0) { add_button.setEnabled(false); remove_button.setEnabled(false); } else { Format format = getFormat(Format.generateName(f, pname)); // If there is an existing feature, select it, and use it to determine what controls are visible if(format != null) { ///ystem.err.println("There is an existing format!"); format_list.setSelectedValue(format, true); // Now use type to determine what controls are visible, and what have initial values. if(format.isParamType()) { ///ystem.err.println("Flag type"); // Flags first. ///election_pane.remove(part_pane); card_layout.show(control_pane, FLAG); view_type = FLAG; // Initial value enabled_checkbox.setSelected(format.getState()); } else { ///ystem.err.println("Value type"); ///election_pane.add(part_pane); card_layout.show(control_pane, VALUE); view_type = VALUE; // Initial value editor_textarea.setText(format.getValue()); editor_textarea.setCaretPosition(0); } existingFormat(); control_pane.updateUI(); } // Otherwise there is no existing format, so we proceed by checking against the feature name else { ///ystem.err.println("No existing format"); format_list.clearSelection(); if(Format.isParamType(name)) { ///ystem.err.println("Flag type"); // Flags first. ///election_pane.remove(part_pane); card_layout.show(control_pane, FLAG); view_type = FLAG; // Initial value enabled_checkbox.setSelected(false); enabled_checkbox.setEnabled(false); } else { ///ystem.err.println("Value type"); ///election_pane.add(part_pane); card_layout.show(control_pane, VALUE); view_type = VALUE; // Initial value String feature_default_format = (String) default_format_map.get(f.toString()); if (feature_default_format != null) { editor_textarea.setText(feature_default_format); } else { editor_textarea.setText(part.getDefaultFormat()); } editor_textarea.setCaretPosition(0); } newFormat(); } format = null; name = null; } part = null; pname = null; f = null; name = null; entry = null; ignore_event = false; } undo.discardAllEdits(); } } private class FormatListListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent event) { undo_button.setEnabled(false); redo_button.setEnabled(false); default_button.setEnabled(true); newtext = true; if(!ignore_event && !event.getValueIsAdjusting()) { if(!format_list.isSelectionEmpty()) { existingFormat(); ignore_event = true; Format format = (Format)format_list.getSelectedValue(); // Try to match the target, remembering the entries within are Entry's Entry an_entry = new Entry(format.getFeature()); feature_combobox.setSelectedItem(an_entry); // If we didn't match anything, add it and select it again Entry result_entry = (Entry) feature_combobox.getSelectedItem(); if(!an_entry.equals(result_entry)) { feature_combobox.insertItemAt(an_entry, feature_combobox.getItemCount()); feature_combobox.setSelectedItem(an_entry); } // Now use type to determine what controls are visible, and what have initial values. ///ystem.err.println("Determine the correct type."); if(format.isParamType()) { ///ystem.err.println("Flag type - remove part"); // Flags first. ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, false)); card_layout.show(control_pane, FLAG); view_type = FLAG; // Initial value enabled_checkbox.setSelected(format.getState()); } else { ///ystem.err.println("Value type - show part"); ///SwingUtilities.invokeLater(new GUIChangeTask(/election_pane, part_pane, blank_pane, true)); card_layout.show(control_pane, VALUE); view_type = VALUE; // Initial values // do we have a part? if (format.canHavePart()) { part_combobox.setEnabled(true); // Should update the part list and re-render the part ComboBox here part_model = result_entry.getPartModel(); part_combobox.setModel(new DefaultComboBoxModel(part_model.toArray())); part_combobox.updateUI(); // Try to match the part. String part_entry = format.getPart(); // Set Selected Item doesn't work so I'll do this manually boolean found = false; for(int i=0; i < part_combobox.getItemCount(); i++) { Part a_part = (Part) part_combobox.getItemAt(i); if(a_part.equals(part_entry)) { part_combobox.setSelectedItem(a_part); found = true; } a_part = null; } // If we didn't match anything, add it and select it again if(!found) { Part a_part = new Part(part_entry, ""); part_combobox.insertItemAt(a_part, part_combobox.getItemCount()); part_combobox.setSelectedItem(a_part); } } else { part_combobox.setEnabled(false); part_combobox.setSelectedIndex(0); } editor_textarea.setText(format.getValue()); editor_textarea.setCaretPosition(0); } //control_pane.updateUI(); ignore_event = false; } } undo.discardAllEdits(); } } private void newFormat(){ editor_textarea.setEditable(false); editor_textarea.setBackground(Color.lightGray); editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Disabled_Tooltip")); enabled_checkbox.setEnabled(false); undo_button.setEnabled(false); redo_button.setEnabled(false); variable_combobox.setEnabled(false); add_button.setEnabled(true); remove_button.setEnabled(false); default_button.setEnabled(false); } private void existingFormat(){ editor_textarea.setEditable(true); editor_textarea.setBackground(Color.white); editor_textarea.setToolTipText(Dictionary.get("CDM.FormatManager.Editor_Tooltip")); enabled_checkbox.setEnabled(true); variable_combobox.setEnabled(true); add_button.setEnabled(false); remove_button.setEnabled(true); default_button.setEnabled(true); } private class VariableListener implements ActionListener { public void actionPerformed(ActionEvent event) { int selected_index = variable_combobox.getSelectedIndex(); if (selected_index == 0) return; String selected_value = (String)variable_combobox.getSelectedItem(); editor_textarea.insert(selected_value, editor_textarea.getCaretPosition()); undo_button.setEnabled(true); variable_combobox.setSelectedIndex(0); } } private class PartListener implements ActionListener { public void actionPerformed(ActionEvent event) { undo_button.setEnabled(false); redo_button.setEnabled(false); default_button.setEnabled(true); newtext = true; if(!ignore_event) { // Add is only enabled if there isn't already a format for the choosen feature and part. Create a dummy format and test if its already in the model Entry entry = (Entry) feature_combobox.getSelectedItem(); Object f = entry.getFeature(); Part part = (Part) part_combobox.getSelectedItem(); String pname = part.getName(); // You can never add anything to blank-blank if(f.toString().length() == 0 && pname.length() == 0) { add_button.setEnabled(false); remove_button.setEnabled(false); } else { String name = Format.generateName(f, pname); Format format = getFormat(name); // If there is an existing feature, select it. if(format != null) { format_list.setSelectedValue(format, true); // Now use type to determine what controls are visible, and what have initial values. if(format.isParamType()) { // Flags first. ///election_pane.remove(part_pane); card_layout.show(control_pane, FLAG); view_type = FLAG; // Initial value enabled_checkbox.setSelected(format.getState()); } else { ///election_pane.add(part_pane); card_layout.show(control_pane, VALUE); view_type = VALUE; // Initial value editor_textarea.setText(format.getValue()); editor_textarea.setCaretPosition(0); } control_pane.updateUI(); existingFormat(); } else { format_list.clearSelection(); if(Format.isParamType(name)) { // Flags first. ///election_pane.remove(part_pane); card_layout.show(control_pane, FLAG); view_type = FLAG; // Initial value enabled_checkbox.setSelected(false); enabled_checkbox.setEnabled(false); } else { ///election_pane.add(part_pane); card_layout.show(control_pane, VALUE); view_type = VALUE; // Initial value editor_textarea.setText(part.getDefaultFormat()); editor_textarea.setCaretPosition(0); } newFormat(); } format = null; name = null; } pname = null; part = null; f = null; entry = null; } undo.discardAllEdits(); } } private class RemoveListener implements ActionListener { public void actionPerformed(ActionEvent event) { if (!format_list.isSelectionEmpty()) { // Remove the current format removeFormat((Format)format_list.getSelectedValue()); // Change buttons add_button.setEnabled(true); newFormat(); } } } private class DefaultListener implements ActionListener { public void actionPerformed(ActionEvent event) { // ensure that the user didn't accidentally press the Reset to Default button int user_choice = JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("CDM.FormatManager.Default_Warning"), Dictionary.get("General.Warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); if(user_choice == JOptionPane.CANCEL_OPTION) { return; } newtext = false; if(!ignore_event) { Entry entry = (Entry) feature_combobox.getSelectedItem(); Object f = entry.getFeature(); String name =""; String pname=""; Part part = null; if (entry.canHavePart()){ part = (Part) part_combobox.getSelectedItem(); pname = part.getName(); name = Format.generateName(f, pname); } else{ name = entry.toString(); } Format format = getFormat(name); // If there is an existing feature, select it. if(format != null) { remove_button.setEnabled(true); } else { add_button.setEnabled(true); }//endif (format !=null) if(Format.isParamType(name)) { // Flags first. card_layout.show(control_pane, FLAG); view_type = FLAG; // Initial value enabled_checkbox.setSelected(false); } else { card_layout.show(control_pane, VALUE); view_type = VALUE; // Initial value if (pname !=null && pname.length()!=0 ){ editor_textarea.setText((String) default_format_map.get(pname)); editor_textarea.setCaretPosition(0); } else{ editor_textarea.setText((String) default_format_map.get(name)); editor_textarea.setCaretPosition(0); } } } } } private class UndoListener implements ActionListener { public void actionPerformed(ActionEvent event) { try { if (undo.canUndo()) { int pos = editor_textarea.getCaretPosition(); redo_button.setEnabled(true); undo.undo(); if (pos > 0) editor_textarea.setCaretPosition(pos-1); else editor_textarea.setCaretPosition(pos); } if (!undo.canUndo()){ undo_button.setEnabled(false); } else{ undo_button.setEnabled(true); } } catch (Exception e) { } } } private class RedoListener implements ActionListener { public void actionPerformed(ActionEvent evt) { try { if (undo.canRedo()) { int pos = editor_textarea.getCaretPosition(); undo.redo(); editor_textarea.setCaretPosition(pos); } if (!undo.canRedo()){ redo_button.setEnabled(false); } else{ redo_button.setEnabled(true); } } catch (Exception e) {} } } } /** This object provides a wrapping around an entry in the format target control, which is tranparent as to whether it is backed by a String or a Classifier. */ private class Entry implements Comparable { private Classifier classifier = null; private String text = null; public Entry(Object object) { if(object instanceof Classifier) { classifier = (Classifier)object; } else if(object instanceof String) { text = (String)object; } else { text = ""; } } public Entry(String text) { this.text = text; } public boolean canHavePart() { if (classifier !=null) return true; return Format.canHavePart(text); } public int compareTo(Object object) { if(object == null) { return 1; } if(toString() == null) { return -1; } else { String object_str = object.toString(); if(object_str == null) { return 1; } return toString().compareTo(object_str); } } public boolean equals(Object object) { if(compareTo(object) == 0) { return true; } return false; } public Classifier getClassifier() { return classifier; } public Object getFeature() { if(classifier != null) { return classifier; } if (text.startsWith("")){ return ""; } return text; } public ArrayList getPartModel(){ DebugStream.println("getPartModel(): get appopriate affected components of this classifier"); String classifier_name = classifier == null ? "" : classifier.toString(); if(!classifier_name.equals("")){ classifier_name = classifier_name.substring(0, classifier_name.indexOf("-")).trim(); } ArrayList part_model = new ArrayList(); // DateList only has DateList component if(classifier_name.equals("DateList")){ part_model.add(new Part(DATELIST, DATELIST_DEFAULT_FORMAT)); } // Other Format Entries, display the default Affected Components else if(classifier_name.equals("")){ part_model = buildPartModel(); } // Other Classifiers have HList and VList as Affected Component else { part_model.add(new Part(HLIST, HLIST_DEFAULT_FORMAT)); part_model.add(new Part(VLIST, VLIST_DEFAULT_FORMAT)); } return part_model; } public String toString() { if(classifier != null) { // Return the classifier - with its CL index shown return classifier.getPositionString() + StaticStrings.COLON_CHARACTER + StaticStrings.SPACE_CHARACTER + classifier.toString(); } if (text.equals("")) { return ""+Dictionary.get("CDM.FormatManager.AllFeatures")+""; } return text; } } /* private class GUIChangeTask implements Runnable { private boolean to_add; private JPanel child; private JPanel parent; private JPanel replacement; public GUIChangeTask(JPanel parent, JPanel child, JPanel replacement, boolean to_add) { this.child = child; this.parent = parent; this.replacement = replacement; this.to_add = to_add; } public void run() { if(to_add) { parent.remove(replacement); parent.add(child); parent.updateUI(); } else { parent.remove(child); parent.add(replacement); parent.updateUI(); } } } */ /** This class encapsulates all of the information associated with a certain component part of a feature within a html page returned from the receptioninst. */ private class Part implements Comparable { /** The default format string for this part */ private String default_format = null; /** The name of this part */ private String name = null; /** Constructor - must be provided with all of the details of a part as there are no other setter methods. * @param name the name of this part * @param default_format the default format string for this part */ public Part(String name, String default_format) { this.default_format = default_format; this.name = name; } /** Compare this part to another object in terms of ordering * @param obj the other Object * @return <0 if the object is before, 0 if equal to, and >0 if the object is after this part */ public int compareTo(Object obj) { if (obj instanceof Part) { return name.compareTo(((Part)obj).getName()); } return name.compareTo(obj.toString()); } /** Determine if the part is equivelent to some other object * @param obj the other Object * @return true is the two objects are equal */ public boolean equals(Object obj) { if (obj instanceof Part) { return name.equals(((Part)obj).getName()); } return name.equals(obj.toString()); } /** Retrieve the default format string for this part * @return the default format String */ public String getDefaultFormat() { // Retrieve the format for the super format - either VList or HList Format default_format_object = getFormat(name); if(default_format_object != null) { return default_format_object.getValue(); } else { return this.default_format; } } /** Retrieve the name of this part * @return the name as a String */ public String getName() { return name; } /** Produce a string representation of this part, which in this case is simply the name again * @return the name as a String */ public String toString() { if (name.equals("")) { return ""+Dictionary.get("CDM.FormatManager.AllParts")+""; } return name; } } }