Ignore:
Timestamp:
2004-10-13T14:48:20+13:00 (20 years ago)
Author:
mdewsnip
Message:

Finally committing the (many) changes to the GLI to use the new metadata code... I hope this doesn't have too many bugs in it and committing it now doesn't stuff anyone up! (Katherine said I could commit it, so blame her if anything goes wrong).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/cdm/MetadataSetView.java

    r8243 r8313  
    2929import java.awt.*;
    3030import java.awt.event.*;
     31import java.io.File;
    3132import java.util.*;
    3233import javax.swing.*;
    3334import javax.swing.event.*;
     35import javax.swing.filechooser.*;
    3436import org.greenstone.gatherer.Configuration;
    3537import org.greenstone.gatherer.DebugStream;
     
    3739import org.greenstone.gatherer.Gatherer;
    3840import org.greenstone.gatherer.gui.GLIButton;
    39 import org.greenstone.gatherer.mem.MetadataEditorManager;
    40 import org.greenstone.gatherer.msm.MetadataSet;
    41 import org.greenstone.gatherer.msm.MSMEvent;
    42 import org.greenstone.gatherer.msm.MSMListener;
    43 import org.w3c.dom.*;
     41import org.greenstone.gatherer.gui.MetadataElementListCellRenderer;
     42import org.greenstone.gatherer.metadata.MetadataElement;
     43import org.greenstone.gatherer.metadata.MetadataSet;
     44import org.greenstone.gatherer.metadata.MetadataSetManager;
     45import org.greenstone.gatherer.metadata.MetadataTools;
     46import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
     47import org.greenstone.gatherer.util.Utility;
     48
    4449
    4550/** This class only knows how to produce a simple visual representation of the currently imported metadata sets. It is also read-only, so should be fairly straight forward.
     
    4853 */
    4954public class MetadataSetView
    50     extends DynamicListModel
    51     implements MSMListener {
     55    extends DynamicListModel {
     56
    5257    /** The visual contols used to review the metadata sets. */
    5358    private Control controls = null;
     
    5560    private DynamicListModel model = null;
    5661
    57     /** Constructor.
    58      */
    59     public MetadataSetView() {
    60     DebugStream.println("MetadataSetView: Initialized.");
     62
     63    public MetadataSetView()
     64    {
    6165    model = this;
    62     Gatherer.c_man.getCollection().msm.addMSMListener(this);
    63     loadMetadataSets();
     66
     67    // Initialise the model
     68    refreshModel();
     69
    6470    // Build the controls
    65     controls = new MetadataSetControl();
    66     }
    67 
    68     /** Destructor. Remove any references of this class from persistant objects.
    69      * @see org.greenstone.gatherer.Gatherer
    70      * @see org.greenstone.gatherer.collection.CollectionManager
    71      */
    72     public void destroy() {
     71    controls = new MetadataSetViewControls();
     72    }
     73
     74
     75    public void destroy()
     76    {
    7377    controls.destroy();
    7478    controls = null;
    75     Gatherer.c_man.msm.removeMSMListener(this);
    7679    model = null;
    7780    }
    7881
    79     /** Called when an element is changed within a set in the MSM, prompting us to refresh our list of elements being shown.
    80      * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change.
    81      * @see org.greenstone.gatherer.cdm.MetadataSetView.MetadataSetControl
    82      */
    83     public void elementChanged(MSMEvent event) {
    84     // Get the controls to refresh element list.
    85     ((MetadataSetControl)controls).refreshElementList();
    86     }
    8782
    8883    /** A method for retrieve the controls for this manager.
    89      * @see org.greenstone.gatherer.Dictionary
    90      * @see org.greenstone.gatherer.gui.Coloring
    9184     */
    9285    public Control getControls() {
     
    9487    }
    9588
    96     /** Called when a metadata value has undergone significant change.
    97      * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change.
    98      */
    99     public void metadataChanged(MSMEvent event) {
    100     // Couldn't care less.
    101     }
    102 
    103     /** Called when a set is added or removed from the MSM.
    104      * @param event A <strong>MSMEvent</strong> which encapsulates relevant data about the change.
    105      */
    106     public void setChanged(MSMEvent event) {
    107     // Reload model.
    108     clear();
    109     loadMetadataSets();
    110     }
    111 
    112 
    113     /** Prints out the contents of this manager, as they would appear in the collection configuration file.
    114      * @return A <strong>String</strong> containing a block of commands.
    115      * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    116      */
    117     public String toString() {
    118     String text = "";
    119     for(int i = 0; i < size(); i++) {
    120         SetWrapper set = (SetWrapper)get(i);
    121         text = text + set.toString() + "\n";
    122     }
    123     text = text + "\n";
    124     return text;
    125     }
    126 
    127     /** Called when a significant change has occured to a value tree for a certain element, however we take no further action.
    128      * @param event A <strong>MSMEvent</strong> containing information relevant to the event.
    129      */
    130     public void valueChanged(MSMEvent event) {
    131     }
    132 
    133     /** Retrieves the current list of loaded metadata sets, and builds a list model around them.
    134      * @see org.greenstone.gatherer.Gatherer
    135      * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    136      * @see org.greenstone.gatherer.collection.CollectionManager
    137      */
    138     private void loadMetadataSets() {
    139     // We initialize the set_model with wrapped metadata sets. Note that when we call getSets() we also end up adding ourselves as a listener to the metadata set manager.
    140     Vector sets = Gatherer.c_man.getCollection().msm.getSets();
    141     for(int i = 0; i < sets.size(); i++) {
    142         addElement(new SetWrapper((MetadataSet)sets.get(i)));
    143     }
    144     }
     89
     90    public void refreshModel()
     91    {
     92    // Remove any metadata sets from the model that are no longer loaded
     93    ArrayList loaded_metadata_sets = MetadataSetManager.getMetadataSets();
     94    for (int i = size() - 1; i >= 0; i--) {
     95        MetadataSet metadata_set = (MetadataSet) get(i);
     96        if (loaded_metadata_sets.contains(metadata_set) == false) {
     97        // System.err.println("Metadata set in list no longer loaded...removing.");
     98        remove(i);
     99        }
     100    }
     101
     102    // Add any metadata sets that are loaded but not in the model
     103    for (int i = 0; i < loaded_metadata_sets.size(); i++) {
     104        MetadataSet loaded_metadata_set = (MetadataSet) loaded_metadata_sets.get(i);
     105        boolean in_model = false;
     106        for (int j = 0; j < size(); j++) {
     107        MetadataSet metadata_set = (MetadataSet) get(j);
     108        if (metadata_set.equals(loaded_metadata_set)) {
     109            in_model = true;
     110            break;
     111        }
     112        }
     113
     114        if (in_model == false) {
     115        // System.err.println("Metadata set loaded but not in list...adding.");
     116        addElement(loaded_metadata_set);
     117        }
     118    }
     119    }
     120
    145121
    146122    /** This class creates and lays-out the various controls for reviewing the metadata sets, and their commands as they would appear in the collection configuration file. */
    147     private class MetadataSetControl
     123    private class MetadataSetViewControls
    148124    extends JPanel
    149125    implements Control {
    150     /** Listens for clicks upon the configure button, or double clicks from the metadata set list. */
    151     private ConfigureActionListener configure_action_listener;
    152126    /** Opens the MEM and systematically performs as if the add set button were clicked. */
    153127    private JButton add_button;
    154     /** Opens the MEM with the appropriate set open for editing. */
    155     private JButton configure_button;
    156128    /** Opens the MEM and systematically performs as if the remove set button were clicked. */
    157129    private JButton remove_button;
     
    179151    private JTextArea instructions = null;
    180152
    181     private ListListener list_listener;
    182 
    183     private MultilingualListCellRenderer element_list_cell_renderer;
    184 
    185     /** The element model for the currently selected set. */
    186     private Vector element_model = null;
     153    private MetadataElementListCellRenderer element_list_cell_renderer;
     154    private MetadataSetListSelectionListener list_listener;
    187155
    188156    /* Constructor.
     
    191159     * @see org.greenstone.gatherer.cdm.MetadataSetView.ListListener
    192160     */
    193     public MetadataSetControl() {
     161    public MetadataSetViewControls()
     162    {
    194163        // Create visual components
    195164        central_pane = new JPanel();
     
    198167        element_label.setOpaque(true);
    199168        Dictionary.registerText(element_label, "CDM.MetadataSetManager.Elements");
     169        element_list = new JList();
    200170        element_list_scroll_pane = new JScrollPane();
    201         element_list_cell_renderer = new MultilingualListCellRenderer(element_list_scroll_pane);
    202         element_list = new JList();
    203171        element_list_scroll_pane.setViewportView(element_list);
     172        element_list_cell_renderer = new MetadataElementListCellRenderer();
    204173        element_list.setCellRenderer(element_list_cell_renderer);
    205174        element_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     
    218187        Dictionary.registerText(set_label, "CDM.MetadataSetManager.Sets");
    219188        set_list = new JList(model);
     189        set_list.setCellRenderer(new MetadataSetListCellRenderer());
    220190        set_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    221         if(model.size() > 0) {
    222         set_list.setSelectedIndex(0);
    223         }
    224191
    225192        set_pane = new JPanel();
     
    234201        add_button.setMnemonic(KeyEvent.VK_A);
    235202        Dictionary.registerBoth(add_button, "CDM.MetadataSetManager.Add", "CDM.MetadataSetManager.Add_Tooltip");
    236         configure_button = new GLIButton();
    237         configure_button.setEnabled(false);
    238         configure_button.setMnemonic(KeyEvent.VK_C);
    239         Dictionary.registerBoth(configure_button, "CDM.MetadataSetManager.Configure", "CDM.MetadataSetManager.Configure_Tooltip");
    240203        remove_button = new GLIButton();
    241204        remove_button.setEnabled(false);
    242205        remove_button.setMnemonic(KeyEvent.VK_R);
    243206        Dictionary.registerBoth(remove_button, "CDM.MetadataSetManager.Remove", "CDM.MetadataSetManager.Remove_Tooltip");
    244         configure_action_listener = new ConfigureActionListener();
    245         list_listener = new ListListener();
     207        list_listener = new MetadataSetListSelectionListener();
    246208
    247209        // Add listeners
    248210        add_button.addActionListener(new AddButtonListener());
    249         configure_button.addActionListener(configure_action_listener);
    250211        remove_button.addActionListener(new RemoveButtonListener());
    251212        set_list.addListSelectionListener(list_listener);
    252         set_list.addMouseListener(configure_action_listener);
    253213        // Layout
    254214        instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
     
    273233        button_pane.setLayout(new GridLayout(1,3,0,0));
    274234        button_pane.add(add_button);
    275         button_pane.add(configure_button);
    276235        button_pane.add(remove_button);
    277236
     
    282241        add(button_pane, BorderLayout.SOUTH);
    283242    }
    284     /** Destructor. */
    285     public void destroy() {
    286     }
    287     /** Update the element list. */
    288     public void refreshElementList() {
    289         element_list.updateUI();
    290     }
    291 
    292     /** Overriden to ensure the instruction area is scrolled to top.
    293      */
    294     public void gainFocus() {
    295         if(instructions != null) {
     243
     244
     245    public void destroy() { }
     246
     247
     248    public void gainFocus()
     249    {
     250        // Ensure the instructions area is scrolled to the top
     251        if (instructions != null) {
    296252        instructions.setCaretPosition(0);
    297253        }
     254
    298255        // If no current selection, select first available set
    299         if(set_list.isSelectionEmpty() && set_list.getModel().getSize() > 0) {
     256        if (set_list.isSelectionEmpty() && set_list.getModel().getSize() > 0) {
    300257        set_list.setSelectedIndex(0);
    301258        list_listener.valueChanged(new ListSelectionEvent(set_list, 0, 0, true));
     
    303260    }
    304261
    305     public void loseFocus() {
    306     }
    307 
    308     /** Listens for clicks on the add button, and actions them accordingly by opening the MEM and clicking add set. */
     262
     263    public void loseFocus() { }
     264
     265
     266    /** Listens for clicks on the add button. */
    309267    private class AddButtonListener
    310268        implements ActionListener {
     269
    311270        /** Called when the add button is clicked.
    312271         * @param event an ActionEvent containing information about the mouse click
    313          * @see org.greenstone.gatherer.Gatherer
    314          * @see org.greenstone.gatherer.collection.Collection
    315          * @see org.greenstone.gatherer.collection.CollectionManager
    316          * @see org.greenstone.gatherer.mem.MetadataEditorManager
    317272         */
    318         public void actionPerformed(ActionEvent event) {
    319         Gatherer.c_man.getCollection().msm.editMDS(null, MetadataEditorManager.ADD_SET);
    320         }
    321     }
    322 
    323     /** Listens for clicks on the configure button or double clicks upon the metadata set list and chains to the MEM as appropriate. */
    324     private class ConfigureActionListener
    325         extends MouseAdapter
     273        public void actionPerformed(ActionEvent event)
     274        {
     275        JFileChooser chooser = new JFileChooser(new File(Utility.METADATA_DIR));
     276        chooser.setFileFilter(new MetadataSet.MetadataSetFileFilter());
     277        int return_val = chooser.showDialog(Gatherer.g_man, Dictionary.get("MSMPrompt.File_Import"));
     278        if (return_val == JFileChooser.APPROVE_OPTION) {
     279            Gatherer.c_man.importMetadataSet(new MetadataSet(chooser.getSelectedFile()));
     280            refreshModel();
     281
     282            // The metadata.xml files may possibly contain metadata for this newly added metadata set
     283            // Re-read all the metadata.xml files to account for this case
     284            MetadataXMLFileManager.clearMetadataXMLFiles();
     285            MetadataXMLFileManager.loadMetadataXMLFiles(new File(Gatherer.c_man.getCollectionImport()));
     286        }
     287        }
     288    }
     289
     290
     291    private class MetadataSetListCellRenderer
     292        implements ListCellRenderer
     293    {
     294        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
     295        {
     296        DefaultListCellRenderer default_list_cell_renderer = new DefaultListCellRenderer();
     297        JLabel list_cell_label = (JLabel) default_list_cell_renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     298
     299        if (value instanceof MetadataSet) {
     300            MetadataSet metadata_set = (MetadataSet) value;
     301            String metadata_set_name = MetadataTools.getMetadataSetAttribute(metadata_set, "Name", Configuration.getLanguage(), "en");
     302            list_cell_label.setText("metadataset " + metadata_set.getNamespace() + " \"" + metadata_set_name + "\"");
     303        }
     304
     305        return list_cell_label;
     306        }
     307    }
     308
     309
     310    private class MetadataSetListSelectionListener
     311        implements ListSelectionListener {
     312
     313        public void valueChanged(ListSelectionEvent event)
     314        {
     315        // Wait until we get a stable event
     316        if (event.getValueIsAdjusting()) {
     317            return;
     318        }
     319
     320        // Now we can process it
     321        if (!set_list.isSelectionEmpty()) {
     322            MetadataSet metadata_set = (MetadataSet) set_list.getSelectedValue();
     323            element_list.setListData(new Vector(metadata_set.getMetadataSetElements()));
     324            remove_button.setEnabled(true);
     325
     326            // Finally check the directionality and scroll as necessary
     327            JScrollBar scroll_bar = element_list_scroll_pane.getHorizontalScrollBar();
     328            if (element_list_cell_renderer.getDirectionality() == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
     329            scroll_bar.setValue(scroll_bar.getMaximum());
     330            }
     331            else {
     332            scroll_bar.setValue(scroll_bar.getMinimum());
     333            }
     334        }
     335        else {
     336            remove_button.setEnabled(false);
     337        }
     338        }
     339    }
     340
     341
     342    /** Listens for clicks on the remove button. */
     343    private class RemoveButtonListener
    326344        implements ActionListener {
    327         /** Called when the configure button is clicked.
     345
     346        /** Called when the remove button is clicked.
    328347         * @param event an ActionEvent containing information about the mouse click
    329348         */
    330         public void actionPerformed(ActionEvent event) {
    331         configureSet();
    332         }
    333 
    334         /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt.
    335          * @param event a MouseEvent containing information about the mouse click
    336         */
    337         public void mouseClicked(MouseEvent event) {
    338         if(event.getClickCount() == 2 ) {
    339             configureSet();
    340         }
    341         }
    342         /** If some set is selected, then open the metadata set manager with the current set selected and expanded
    343          * @see org.greenstone.gatherer.Gatherer
    344          * @see org.greenstone.gatherer.collection.Collection
    345          * @see org.greenstone.gatherer.collection.CollectionManager
    346          * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    347          * @see org.greenstone.gatherer.mem.MetadataEditorManager
    348          */
    349         private void configureSet() {
    350         if(!set_list.isSelectionEmpty()) {
    351             MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet();
    352             Gatherer.c_man.getCollection().msm.editMDS(set, MetadataEditorManager.NORMAL);
    353         }
    354         else {
    355             configure_button.setEnabled(false);
    356         }
    357         }
    358     }
    359 
    360     private class ListListener
    361         implements ListSelectionListener {
    362         public void valueChanged(ListSelectionEvent event) {
    363         // Wait until we get a stable event
    364         if(event.getValueIsAdjusting()) {
    365             return;
    366         }
    367         // Now we can process it
    368         if(!set_list.isSelectionEmpty()) {
    369             MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet();
    370             NodeList elements = set.getElements();
    371             element_model = new Vector();
    372             for(int i = 0; i < elements.getLength(); i++) {
    373             element_model.add(new ElementWrapper(elements.item(i)));
    374             }
    375             //Collections.sort(element_model);
    376             element_list.setListData(element_model);
    377             configure_button.setEnabled(true);
    378             remove_button.setEnabled(true);
    379 
    380             // Finally check the directionality and scroll as necessary
    381             JScrollBar scroll_bar = element_list_scroll_pane.getHorizontalScrollBar();
    382             if(element_list_cell_renderer.getDirectionality() == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
    383             scroll_bar.setValue(scroll_bar.getMaximum());
    384             }
    385             else {
    386             scroll_bar.setValue(scroll_bar.getMinimum());
    387             }
    388 
    389         }
    390         else {
    391             configure_button.setEnabled(false);
    392             remove_button.setEnabled(false);
    393         }
    394         }
    395     }
    396 
    397     /** Listens for clicks on the remove button, and actions them accordingly by opening the MEM and clicking remove set. */
    398     private class RemoveButtonListener
    399         implements ActionListener {
    400         /** Called when the remove button is clicked.
    401          * @param event an ActionEvent containing information about the mouse click
    402          * @see org.greenstone.gatherer.Gatherer
    403          * @see org.greenstone.gatherer.collection.Collection
    404          * @see org.greenstone.gatherer.collection.CollectionManager
    405          * @see org.greenstone.gatherer.cdm.MetadataSetView.SetWrapper
    406          * @see org.greenstone.gatherer.mem.MetadataEditorManager
    407          */
    408         public void actionPerformed(ActionEvent event) {
    409         if(!set_list.isSelectionEmpty()) {
    410             MetadataSet set = ((SetWrapper)set_list.getSelectedValue()).getSet();
    411             Gatherer.c_man.getCollection().msm.editMDS(set, MetadataEditorManager.REMOVE_SET);
    412         }
    413         else {
    414             remove_button.setEnabled(false);
    415         }
    416         }
    417     }
    418 
    419     private class MultilingualListCellRenderer
    420         extends DefaultListCellRenderer {
    421         private byte previous_directionality = Character.DIRECTIONALITY_UNDEFINED;
    422         private JScrollPane scroll_pane;
    423         public MultilingualListCellRenderer(JScrollPane scroll_pane) {
    424         super();
    425         this.scroll_pane = scroll_pane;
    426         }
    427 
    428         public byte getDirectionality() {
    429         if(previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || previous_directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE) {
    430             return Character.DIRECTIONALITY_RIGHT_TO_LEFT;
    431         }
    432         else {
    433             return Character.DIRECTIONALITY_LEFT_TO_RIGHT;
    434         }
    435         }
    436        
    437         public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    438         JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    439         // Determine if the text should be left aligned or right aligned
    440         String text = value.toString();
    441         int text_index = 0;
    442         byte directionality = Character.DIRECTIONALITY_UNDEFINED;
    443         while(directionality == Character.DIRECTIONALITY_UNDEFINED && text_index < text.length()) {
    444             directionality = Character.getDirectionality(text.charAt(text_index));
    445             text_index++;
    446         }
    447         if(directionality != previous_directionality) {
    448             previous_directionality = directionality;
    449             if(directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE) {
    450             ///ystem.err.println("R2L for: " + text);
    451             component.setHorizontalAlignment(JLabel.TRAILING);
    452             component.setHorizontalTextPosition(JLabel.TRAILING);
    453             component.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    454             //scroll_pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    455             }
    456             else {
    457             component.setHorizontalAlignment(JLabel.LEADING);
    458             component.setHorizontalTextPosition(JLabel.LEADING);
    459             ///ystem.err.println("L2R for: " + text);
    460             component.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    461             //scroll_pane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    462             }
    463         }
    464 
    465         text = null;
    466         return component;
    467         }
    468 
    469     }
    470    
    471     }
    472 
    473     /** Provides a convience wrapper around a metadata set, that allows it to appear in the <strong>JList</strong> the same way it would in the collection configuration file. */
    474     private class SetWrapper {
    475     private MetadataSet set = null;
    476     public SetWrapper(MetadataSet set) {
    477         this.set = set;
    478     }
    479     public MetadataSet getSet() {
    480         return set;
    481     }
    482     public String toString() {
    483         String namespace = set.getNamespace();
    484         // Watch out for the greenstone set, with its namespace of ""
    485         return "metadataset " + namespace + " \"" + set.getName() + "\"";
     349        public void actionPerformed(ActionEvent event)
     350        {
     351        MetadataSet metadata_set = (MetadataSet) set_list.getSelectedValue();
     352        Gatherer.c_man.removeMetadataSet(metadata_set);
     353        refreshModel();
     354        element_list.setListData(new Vector());
     355        }
    486356    }
    487357    }
Note: See TracChangeset for help on using the changeset viewer.