Changeset 4494


Ignore:
Timestamp:
2003-06-06T09:52:49+12:00 (21 years ago)
Author:
jmt12
Message:

2030098: Fixed translation manager and separated the Languages from the possible text fragment Translations.

Location:
trunk/gli/src/org/greenstone/gatherer/cdm
Files:
9 edited

Legend:

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

    r4366 r4494  
    112112    /** Contains: A list of subcollections, (defined on metadatadata), a list of which subcollection indexes to build and the default subcollection index. */
    113113    public SubcollectionManager subcollections = null;
     114    /** A supercollection command allows a single search to be conducted across several collections. It is a very basic command and so avoids all the crazy model stuff that exists in most of the design managers. */
     115    public SuperCollectionManager superman; // Just cause I could ;p
     116    /** The text translation manager. */
     117    public TranslationManager transman;
    114118    /** A list of whatever commands could not be parsed at all. */
    115119    private ArrayList rest = null;
     
    137141    this.plugins = new PlugInManager(gatherer, this);
    138142    this.rest = new ArrayList();
    139     this.subcollections = new SubcollectionManager(gatherer);
     143    this.subcollections = new SubcollectionManager(gatherer, this);
     144    this.superman = new SuperCollectionManager();
     145    this.transman = new TranslationManager(this);
    140146    }
    141147    /** In order to prevent Components that have registered themselves wasting memory, this method invalidates each of the sub-managers controls, causing them to unregister listeners.
     
    164170        plugins.invalidateControls();
    165171        subcollections.invalidateControls();
     172        superman.invalidateControls();
    166173    }
    167174    // Null globals.
     
    178185    plugins = null;
    179186    subcollections = null;
     187    superman = null;
    180188    rest = null;
    181189    gatherer = null;
     
    293301            found = collectionmetadatum.parse(command, false);
    294302            }
     303            if(!found) {
     304            found = superman.parse(command);
     305            }
    295306            // Metadataset commands
    296307            if(command_lc.startsWith("metadataset")) {
     
    369380        text.append("\n");
    370381        }
     382        if(plugins.size() > 0) {
     383        text.append(plugins.toString());
     384        }
    371385        if(indexes.size() > 0) {
    372386        text.append(indexes.toString());
    373387        }
     388        if(languages.size() > 0) {
     389        text.append(languages.toString());
     390        }
    374391        if(subcollections.size() > 0) {
    375392        text.append(subcollections.toString());
    376393        }
    377         if(languages.size() > 0) {
    378         text.append(languages.toString());
    379         }
    380         if(plugins.size() > 0) {
    381         text.append(plugins.toString());
     394        String super_collections_command = superman.toString();
     395        if(super_collections_command != null) {
     396        text.append(super_collections_command);
    382397        }
    383398        if(classifiers.size() > 0) {
  • trunk/gli/src/org/greenstone/gatherer/cdm/CollectionMeta.java

    r4366 r4494  
    6464    /** The language of this metadata. Should be a two letter code. */
    6565    private Language language = null;
    66     /** The name of the thing this metadata is assigned to, which may index an Index. */
     66    /** The name of the thing this metadata is assigned to, which may also refer to an Index or a Partition. */
    6767    private Object name = null;
    6868    /** The value of this metadata. */
     
    118118    }
    119119    /** Method to retrieve the value of language.
    120       * @return The value of language as a <strong>Language</strong>.
    121       */
     120     * @return The value of language as a <strong>Language</strong>.
     121     */
    122122    public Language getLanguage() {
    123123    return language;
    124124    }
    125125    /** Method to retrieve the value of name.
    126       * @return The value of name as an <strong>Object</strong>.
    127       */
     126     * @return The value of name as an <strong>Object</strong>.
     127     */
    128128    public Object getName() {
    129129    return name;
     
    144144        Index index = (Index)name;
    145145        text = text + index.toString(false) + " ";
     146    }
     147    else if(name instanceof SubIndex) {
     148        text = text + ".";
     149        SubIndex index = (SubIndex)name;
     150        text = text + index.toString() + " ";
    146151    }
    147152    else {
     
    164169    this.value = value;
    165170    }
     171
     172    /** Change the value of value.
     173     * @param value the new value as a String.
     174     */
     175    public void setValue(String value) {
     176    this.value = value;
     177    }
     178
    166179    /** Ensure this is a valid metadata entry by checking that the value is non-null and non-zero length (after having removed whitespace).
    167       * @return <i>true</i> if this metadata has a valid value and should be added to the config, <i>false</i> otherwise.
    168       */
     180     * @return <i>true</i> if this metadata has a valid value and should be added to the config, <i>false</i> otherwise.
     181     */
    169182    public boolean valid() {
    170183    return(value != null && value.trim().length() > 0);
  • trunk/gli/src/org/greenstone/gatherer/cdm/CollectionMetaManager.java

    r4366 r4494  
    5151 * Revised:      22/08/02 Revamped, Optimized and Commented.
    5252 **************************************************************************************/
    53 import java.awt.BorderLayout;
    54 import java.awt.Dimension;
    55 import java.awt.GridLayout;
    56 import java.awt.Toolkit;
    57 import java.awt.event.ActionEvent;
    58 import java.awt.event.ActionListener;
    59 import java.awt.event.FocusAdapter;
    60 import java.awt.event.FocusEvent;
    61 import java.awt.event.KeyAdapter;
    62 import java.awt.event.KeyEvent;
    63 import java.util.ArrayList;
    64 import java.util.Collections;
    65 import javax.swing.BorderFactory;
    66 import javax.swing.ButtonGroup;
    67 import javax.swing.DefaultListModel;
    68 import javax.swing.JButton;
    69 import javax.swing.JComboBox;
    70 import javax.swing.JDialog;
    71 import javax.swing.JLabel;
    72 import javax.swing.JList;
    73 import javax.swing.JPanel;
    74 import javax.swing.JScrollPane;
    75 import javax.swing.JTextArea;
    76 import javax.swing.JTextField;
    77 import javax.swing.ListSelectionModel;
    78 import javax.swing.event.ListSelectionEvent;
    79 import javax.swing.event.ListSelectionListener;
     53import java.awt.*;
     54import java.awt.event.*;
     55import java.util.*;
     56import javax.swing.*;
     57import javax.swing.event.*;
    8058import org.greenstone.gatherer.Gatherer;
    8159import org.greenstone.gatherer.cdm.CollectionDesignManager;
     
    172150     
    173151    /** Retrieve all of the metadata for the given feature, regardless of language. */
    174     public ArrayList getMetadata(String name) {
     152    public ArrayList getMetadata(Object name) {
    175153    ArrayList result = new ArrayList();
    176154    for(int i = 0; i < size(); i++) {
     
    183161    }
    184162    /** Method to retrieve a certain piece of metadata based on its name and language.
    185       * @param name The name of the metadata as a <strong>String</strong>.
     163      * @param name the name of the metadata as an Object (as it may actually be a refernce to an Index or SubIndex)
    186164      * @param language The <strong>Language</strong> of the metadata.
    187165      * @param partial <i>true</i> to return the first partial match (ie matches name but not language).
    188166      * @return The <strong>CollectionMeta</strong> requested, or <i>null</i> if no such metadata.
    189167      */
    190     public CollectionMeta getMetadata(String name, Language language, boolean partial) {
     168    public CollectionMeta getMetadata(Object name, Language language, boolean partial) {
    191169    CollectionMeta partial_match = null;
    192170    for(int i = 0; i < size(); i++) {
    193171        CollectionMeta metadata = (CollectionMeta) get(i);
    194         if(metadata.getName().equals(name)) {
     172        Object metadata_name = metadata.getName();
     173        // We test the case of an object match (ie Index to Index)...
     174        if(metadata_name.equals(name)) {
     175        if (metadata.getLanguage().equals(language)) {
     176            return metadata;
     177        }
     178        partial_match = metadata;
     179        }
     180        // But if that fails we also try a string match such that "section:dls.Title" == Index
     181        if(metadata_name.toString().equals(name.toString())) {
    195182        if (metadata.getLanguage().equals(language)) {
    196183            return metadata;
     
    303290      */
    304291    public String toString() {
     292    // We sort the metadata first.
     293    ArrayList metadatum = new ArrayList();
     294    for(int i = 0; i < size(); i++) {
     295        metadatum.add(get(i));
     296    }
     297    Collections.sort(metadatum, new CollectionMetaComparator());
     298    // Now we print them
    305299    StringBuffer text = new StringBuffer("");
    306     for(int i = 0; i < size(); i++) {
    307         CollectionMeta data = (CollectionMeta) get(i);
     300    for(int i = 0; i < metadatum.size(); i++) {
     301        CollectionMeta data = (CollectionMeta) metadatum.get(i);
    308302        if(data.valid()) {
    309303        text.append(data.toString());
    310304        }
    311305    }
     306    metadatum = null;
    312307    text.append("\n");
    313308    return text.toString();
     
    334329    return gatherer.dictionary.get(key, args);
    335330    }
     331
     332    private class CollectionMetaComparator
     333    implements Comparator {
     334    public int compare(Object o1, Object o2) {
     335        String s1 = o1.toString();
     336        String s2 = o2.toString();
     337        if(s1.startsWith(".")) {
     338        return 1;
     339        }
     340        else if(s2.startsWith(".")) {
     341        return -1;
     342        }
     343        return o1.toString().compareTo(o2.toString());
     344    }
     345    public boolean equals(Object o2) {
     346        return (compare(this, o2) == 0);
     347    }
     348    }
    336349}
  • trunk/gli/src/org/greenstone/gatherer/cdm/GUI.java

    r4366 r4494  
    66 * University of Waikato, New Zealand.
    77 *
    8  * <BR><BR>
    9  *
    108 * Author: John Thompson, Greenstone Digital Library, University of Waikato
    119 *
    12  * <BR><BR>
    13  *
    1410 * Copyright (C) 1999 New Zealand Digital Library Project
    15  *
    16  * <BR><BR>
    1711 *
    1812 * This program is free software; you can redistribute it and/or modify
     
    2115 * (at your option) any later version.
    2216 *
    23  * <BR><BR>
    24  *
    2517 * This program is distributed in the hope that it will be useful,
    2618 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2719 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2820 * GNU General Public License for more details.
    29  *
    30  * <BR><BR>
    3121 *
    3222 * You should have received a copy of the GNU General Public License
     
    3525 *########################################################################
    3626 */
    37 
    38  
    39 
    40 
    41 
    42 
    4327package org.greenstone.gatherer.cdm;
    44 /**************************************************************************************
    45  * Title:        Gatherer
    46  * Description:  The Gatherer: a tool for gathering and enriching a digital collection.
    47  * Copyright:    Copyright (c) 2001
    48  * Company:      The University of Waikato
    49  * Written:      03/05/02
    50  * Revised:      28/05/02
    51  **************************************************************************************/
    52 import java.awt.AWTEvent;
    53 import java.awt.BorderLayout;
    54 import java.awt.Color;
    55 import java.awt.Dimension;
    56 import java.awt.FlowLayout;
    57 import java.awt.GridLayout;
    58 import java.awt.event.ActionEvent;
    59 import java.awt.event.ActionListener;
    60 import java.awt.event.KeyAdapter;
    61 import java.awt.event.KeyEvent;
    62 import java.awt.event.WindowEvent;
    63 import javax.swing.BorderFactory;
    64 import javax.swing.JCheckBox;
    65 import javax.swing.JFrame;
    66 import javax.swing.JLabel;
    67 import javax.swing.JPanel;
    68 import javax.swing.JScrollPane;
    69 import javax.swing.JTextArea;
    70 import javax.swing.JTextField;
    71 import javax.swing.JTree;
    72 import javax.swing.event.TreeSelectionEvent;
    73 import javax.swing.event.TreeSelectionListener;
     28
     29import java.awt.*;
     30import java.awt.event.*;
     31import javax.swing.*;
     32import javax.swing.event.*;
    7433import javax.swing.text.JTextComponent;
    75 import javax.swing.tree.DefaultMutableTreeNode;
    76 import javax.swing.tree.DefaultTreeModel;
    77 import javax.swing.tree.TreePath;
     34import javax.swing.tree.*;
    7835import org.greenstone.gatherer.Gatherer;
    7936import org.greenstone.gatherer.cdm.CollectionDesignManager;
     
    8744public class GUI
    8845    extends JPanel {
     46    /** A flag used to tell whether we should initialize the divider location. */
     47    private boolean init = true;
    8948    /** A reference to the collection manager, as it is here that all of the other data members and managers reside. */
    9049    private CollectionDesignManager manager = null;
     
    10160    /** The panel apon which is rendered the currently selected section screen. */
    10261    private JPanel view = null;
     62    /** A split pane in which the contents menu and context controls sit. */
     63    //private JSplitPane center_pane;
    10364    /** The available subscreens. */
    104     static final public String CONTENTS[] = {"General", "Indexes", "Subcollections", "Languages", "Plugins", "Classifiers", "Formats", "MetadataSets"};
     65    static final public String CONTENTS[] = {"General", "Plugins", "Indexes", "Subcollections", "Classifiers", "Formats", "SuperCollection", "Translation", "MetadataSets"};
    10566    /** The preferred size of the collection design module screen real-estate. */
    10667    static final private Dimension SIZE = new Dimension(760, 500);
     68    static final private Dimension TREE_SIZE = new Dimension(200, 500);
    10769    /** Constructor.
    10870     * @see DesignTree
     
    11577    this.manager = manager;
    11678    // Creation
     79    //center_pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
    11780    this.title = new JLabel(get("Design_Topics"));
    11881    this.tree = new DesignTree();
     
    12285    tree.addTreeSelectionListener(new TreeListener());
    12386    tree_pane.setLayout(new BorderLayout());
     87    tree_pane.setPreferredSize(TREE_SIZE);
    12488    tree_pane.add(title, BorderLayout.NORTH);
    12589    tree_pane.add(new JScrollPane(tree), BorderLayout.CENTER);
    12690    // Layout
     91    //center_pane.setLeftComponent(tree_pane);
     92    //center_pane.setRightComponent(view);
     93
    12794    setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
    12895    setLayout(new BorderLayout());
     96    //add(center_pane, BorderLayout.CENTER);
    12997    add(tree_pane, BorderLayout.WEST);
    13098    add(view, BorderLayout.CENTER);
     
    153121    super.updateUI();
    154122    }
     123
    155124    /**Overridden so we can exit when window is closed
    156       * @param event A <strong>WindowsEvent</strong> that encapsulates all the information gathered about the event that called this method.
    157       * @see org.greenstone.gatherer.cdm.CollectionDesignManager
    158       */
     125     * @param event A <strong>WindowsEvent</strong> that encapsulates all the information gathered about the event that called this method.
     126     * @see org.greenstone.gatherer.cdm.CollectionDesignManager
     127     */
    159128    protected void processWindowEvent(WindowEvent event) {
    160129    if(event.getID() == WindowEvent.WINDOW_CLOSING) {
     
    455424        }
    456425        }
    457                 /** Any extension of a KeyAdapter may override this method so we can be informed when a key has been released (ie after the character etc has been added). In this case we want to update the appropriate metadata, however there are three distinct cases to consider:<br>&nbsp;1. A simple update of the value field is all that is necessary,<br>&nbsp;2. The metadata exists but it currently has no language, so we must set the language to default and update the value, or<br>&nbsp;3. The metadata doesn't exist so we'll create a new one with the specified name, default language and new value.<br>This final case is highly unlikely but still possible.
    458                 * @param event An <strong>Event</strong> containing information about the key release.
    459                 * @see org.greenstone.gatherer.Gatherer
    460                 * @see org.greenstone.gatherer.cdm.CollectionDesignManager
    461                 * @see org.greenstone.gatherer.cdm.CollectionMeta
    462                 * @see org.greenstone.gatherer.cdm.CollectionMetaManager
    463                 * @see org.greenstone.gatherer.cdm.Language
    464                 * @see org.greenstone.gatherer.cdm.LanguageManager
    465                 * @see org.greenstone.gatherer.collection.CollectionManager
    466                 */
     426        /** Any extension of a KeyAdapter may override this method so we can be informed when a key has been released (ie after the character etc has been added). In this case we want to update the appropriate metadata, however there are three distinct cases to consider:<br>&nbsp;1. A simple update of the value field is all that is necessary,<br>&nbsp;2. The metadata exists but it currently has no language, so we must set the language to default and update the value, or<br>&nbsp;3. The metadata doesn't exist so we'll create a new one with the specified name, default language and new value.<br>This final case is highly unlikely but still possible.
     427         * @param event An <strong>Event</strong> containing information about the key release.
     428         * @see org.greenstone.gatherer.Gatherer
     429         * @see org.greenstone.gatherer.cdm.CollectionDesignManager
     430         * @see org.greenstone.gatherer.cdm.CollectionMeta
     431         * @see org.greenstone.gatherer.cdm.CollectionMetaManager
     432         * @see org.greenstone.gatherer.cdm.Language
     433         * @see org.greenstone.gatherer.cdm.LanguageManager
     434         * @see org.greenstone.gatherer.collection.CollectionManager
     435         */
    467436        public void keyReleased(KeyEvent event) {
    468437        if(metadata != null) {
     
    572541        if(type.equals("General")) {
    573542            view = getControls();
     543        }       
     544        else if(type.equals("Plugins")) {
     545            view = manager.plugins.getControls();
    574546        }
    575547        else if(type.equals("Indexes")) {
     
    579551            view = manager.subcollections.getControls();
    580552        }
    581         else if(type.equals("Languages")) {
    582             view = manager.languages.getControls();
    583         }
    584         else if(type.equals("Plugins")) {
    585             view = manager.plugins.getControls();
     553        else if(type.equals("SuperCollection")) {
     554            view = manager.superman.getControls();
    586555        }
    587556        else if(type.equals("Classifiers")) {
     
    591560            view = manager.formats.getControls();
    592561        }
     562        else if(type.equals("Translation")) {
     563            view = manager.transman.getControls();
     564        }
    593565        else if(type.equals("MetadataSets")) {
    594566            view = manager.metadatasets.getControls();
    595567        }
    596568        add(view, BorderLayout.CENTER);
     569        //center_pane.setRightComponent(view);
    597570        view.updateUI();
    598571        // Ready
  • trunk/gli/src/org/greenstone/gatherer/cdm/Index.java

    r4366 r4494  
    9595      */
    9696    public int compareTo(Object object) {
    97     if(object instanceof Index) {
    98         Index index = (Index) object;
    99         return toString(false).compareTo(index.toString(false));
    100     }
    10197    return toString(false).compareTo(object.toString());
    10298    }
     
    155151      */
    156152    public String toString() {
    157     return LEVEL[level] + ":" + getData() + "  \"" + getName() + "\"";
     153    return LEVEL[level] + ":" + getData();
    158154    }
    159155    /** Retrieve a textual representation of this index.
  • trunk/gli/src/org/greenstone/gatherer/cdm/LanguageManager.java

    r4366 r4494  
    102102    /** The default language object. */
    103103    private Language default_language = null;
     104
     105    static final private Dimension LABEL_SIZE = new Dimension(125,25);
    104106    /** Constructor.
    105107     * @param gatherer A reference to the <strong>Gatherer</strong>.
     
    170172    }
    171173    /** Method to retrieve a certain language object by its code.
    172       * @param code The two letter code of a language, as a <strong>String</strong>.
    173       * @param assigned_only If <i>true</i> only those languages currently having indexes built for them are checked, otherwise the known languages buffer is checked.
    174       * @return The <strong>Language</strong> that matches the given code, or <i>null</i> if no such language exists.
    175       */
     174     * @param code The two letter code of a language, as a <strong>String</strong>.
     175     * @param assigned_only If <i>true</i> only those languages currently having indexes built for them are checked, otherwise the known languages buffer is checked.
     176     * @return The <strong>Language</strong> that matches the given code, or <i>null</i> if no such language exists.
     177     */
    176178    public Language getLanguage(String code, boolean assigned_only) {
    177179    if(assigned_only) {
     
    192194    }
    193195    /** Method to return a list of the known language codes.
    194       * @return An <strong>ArrayList</strong> containing a series of alphabetically sorted two letter codes.
    195       */
     196     * @return An <strong>ArrayList</strong> containing a series of alphabetically sorted two letter codes.
     197     */
    196198    public ArrayList getLanguageCodes() {
    197199    ArrayList result = new ArrayList();
     
    323325    }
    324326    /** Method to translate this object into a block of commands as you you expect to find in the collection configuration file.
    325       * @return A <strong>String</string> containing a series of commands.
    326       */
     327     * @return A <strong>String</string> containing a series of commands.
     328     */
    327329    public String toString() {
    328330    StringBuffer text = new StringBuffer();
     
    406408    /** The button to set the current language as the default one. */
    407409    private JButton set_default = null;
    408     /** A button to active the translation manager prompt. */
    409     private JButton translate = null;
    410410    /** A combobox listing the available supported languages. */
    411411    private JComboBox selector = null;
    412     /** The label denoting the default language. */
    413     private JLabel default_language_label = null;
    414     /** The label denoting the language selector. */
    415     private JLabel selector_label = null;
    416     /** The title label of this control view. */
    417     private JLabel title = null;
    418412    /** A list of currently supported languages. */
    419413    private JList list = null;
    420     /** The pane in which the control buttons are placed. */
    421     private JPanel button_pane = null;
    422     /** The pane onto which all other panes are placed. */
    423     private JPanel central_pane = null;
    424     /** The pane to the left containing editing controls. */
    425     private JPanel control_pane = null;
    426     /** A panel used to correctly layout the default language box. */
    427     private JPanel default_language_pane = null;
    428     /** The display pane contains the title and instruction controls. */
    429     private JPanel display_pane = null;
    430     /** The pane which holds everything the display pane doesn't! */
    431     private JPanel lower_pane = null;
    432     /** The pane containing the selector combobox. */
    433     private JPanel selector_pane = null;
    434     /** A text area displaying inline instructions. */
    435     private JTextArea instructions = null;
    436414    /** A description of the language currently selected. */
    437415    private JTextArea description = null;
     
    449427    public Control() {
    450428        super();
    451                 // Creation.
    452         title = new JLabel(get("Title"));
    453         title.setHorizontalAlignment(JLabel.CENTER);
    454         title.setOpaque(true);
    455 
    456         central_pane = new JPanel();
    457 
    458         control_pane = new JPanel();
    459 
    460         instructions = new JTextArea(get("Instructions"));
    461         instructions.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    462         instructions.setEditable(false);
    463         instructions.setLineWrap(true);
    464         instructions.setWrapStyleWord(true);
    465 
    466         selector_pane = new JPanel();
    467 
    468         selector_label = new JLabel(get("Selector"));
    469         selector = new JComboBox(getLanguageCodes().toArray());
    470 
    471         display_pane = new JPanel();
     429        // Creation.
     430        JPanel center_panel = new JPanel();
     431
     432        JLabel title_label = new JLabel(get("Title"));
     433        title_label.setHorizontalAlignment(JLabel.CENTER);
     434        title_label.setOpaque(true);
    472435
    473436        list = new JList(model);
     437        list.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    474438        list.setCellRenderer(new ListRenderer());
    475439
    476         default_language_pane = new JPanel();
    477 
    478         default_language_label = new JLabel(get("Default_Language"));
    479         default_language_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
     440        JPanel details_panel = new JPanel();
     441
     442        JPanel default_panel = new JPanel();
     443
     444        JLabel default_label = new JLabel(get("Default_Language"));
     445        default_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
     446        default_label.setPreferredSize(LABEL_SIZE);
     447
    480448        if(default_language == null) {
    481449        default_language_value = new JTextField();
     
    484452        default_language_value = new JTextField(default_language.toString());
    485453        }
    486         default_language_value.setBackground(Color.white);
     454        default_language_value.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    487455        default_language_value.setEditable(false);
    488456
    489         button_pane = new JPanel();
     457        JPanel control_panel = new JPanel();
     458
     459        JLabel selector_label = new JLabel(get("Selector"));
     460        selector_label.setPreferredSize(LABEL_SIZE);
     461
     462        selector = new JComboBox(getLanguageCodes().toArray());
     463        selector.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     464
     465        JPanel button_panel = new JPanel();
    490466
    491467        add = new JButton(get("Add"));
     
    510486        set_default.setEnabled(false);
    511487
    512         lower_pane = new JPanel();
    513         translate = new JButton(get("Translate"));
    514         translate.setMnemonic(KeyEvent.VK_T);
    515 
    516                 // Set up and connect listeners.
     488        // Set up and connect listeners.
    517489        add.addActionListener(new AddListener());
    518490        clear_default.addActionListener(new ClearDefaultListener());
     
    520492        selector.addActionListener(new SelectorListener());
    521493        set_default.addActionListener(new SetDefaultListener());
    522         translate.addActionListener(new TranslateListener());
    523494        list.addListSelectionListener(new ListListener());
    524                 // Layout components.
    525         selector_pane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
    526         selector_pane.setLayout(new BorderLayout());
    527         selector_pane.add(selector_label, BorderLayout.WEST);
    528         selector_pane.add(selector, BorderLayout.CENTER);
    529 
    530         instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
    531 
    532         control_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    533         control_pane.setLayout(new BorderLayout());
    534         control_pane.add(new JScrollPane(instructions), BorderLayout.CENTER);
    535         control_pane.add(selector_pane, BorderLayout.SOUTH);
    536 
    537         default_language_pane.setBorder
    538         (BorderFactory.createCompoundBorder
    539          (BorderFactory.createCompoundBorder
    540           (BorderFactory.createEmptyBorder(5,5,5,5),
    541            BorderFactory.createRaisedBevelBorder()),
    542           BorderFactory.createEmptyBorder(2,2,2,2)));
    543         default_language_pane.setLayout(new BorderLayout());
    544         default_language_pane.add(default_language_label, BorderLayout.WEST);
    545         default_language_pane.add(default_language_value, BorderLayout.CENTER);
    546 
    547         display_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,5));
    548         display_pane.setLayout(new BorderLayout());
    549         display_pane.add(new JScrollPane(list), BorderLayout.CENTER);
    550         display_pane.add(default_language_pane, BorderLayout.SOUTH);
    551 
    552         central_pane.setLayout(new GridLayout(1,2));
    553         central_pane.add(control_pane);
    554         central_pane.add(display_pane);
    555 
    556         button_pane.setLayout(new GridLayout(2,2));
    557         button_pane.add(add);
    558         button_pane.add(remove);
    559         button_pane.add(clear_default);
    560         button_pane.add(set_default);
    561 
    562         lower_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
    563         lower_pane = new JPanel(new BorderLayout());
    564         lower_pane.add(button_pane, BorderLayout.NORTH);
    565         lower_pane.add(translate, BorderLayout.CENTER);
     495        // Layout components.
     496        default_panel.setBorder(BorderFactory.createRaisedBevelBorder());
     497        default_panel.setLayout(new BorderLayout());
     498        default_panel.add(default_label, BorderLayout.WEST);
     499        default_panel.add(default_language_value, BorderLayout.CENTER);
     500
     501        control_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
     502        control_panel.setLayout(new BorderLayout());
     503        control_panel.add(selector_label, BorderLayout.WEST);
     504        control_panel.add(selector, BorderLayout.CENTER);
     505
     506        details_panel.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
     507        details_panel.setLayout(new BorderLayout());
     508        details_panel.add(default_panel, BorderLayout.CENTER);
     509        details_panel.add(control_panel, BorderLayout.SOUTH);
     510
     511        center_panel.setLayout(new BorderLayout());
     512        center_panel.add(title_label, BorderLayout.NORTH);
     513        center_panel.add(new JScrollPane(list), BorderLayout.CENTER);
     514        center_panel.add(details_panel, BorderLayout.SOUTH);
     515
     516        button_panel.setLayout(new GridLayout(2,2,5,5));
     517        button_panel.add(add);
     518        button_panel.add(remove);
     519        button_panel.add(clear_default);
     520        button_panel.add(set_default);
    566521
    567522        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    568523        setLayout(new BorderLayout());
    569         add(title, BorderLayout.NORTH);
    570         add(central_pane, BorderLayout.CENTER);
    571         add(lower_pane, BorderLayout.SOUTH);
     524        add(center_panel, BorderLayout.CENTER);
     525        add(button_panel, BorderLayout.SOUTH);
    572526    }
    573527    /** Destructor.
     
    575529    public void destroy() {
    576530    }
    577     /** We override the updateUI method so that we can ensure we are scrolled to the top of the instructions box first.
    578             */
    579     public void updateUI() {
    580         if(instructions != null) {
    581         instructions.setCaretPosition(0);
    582         }
    583         super.updateUI();
    584     }
    585531    /** Listens for actions apon the 'add' button in the LanguageManager controls, and if detected calls the add method of the manager with a newly created language. */
    586532    private class AddListener
    587533        implements ActionListener {
    588                 /** Add a new language support.
    589                  * @param event An <strong>ActionEvent</strong>.
    590                 * @see org.greenstone.gatherer.cdm.Language
    591                 */
     534        /** Add a new language support.
     535         * @param event an ActionEvent
     536        * @see org.greenstone.gatherer.cdm.Language
     537        */
    592538        public void actionPerformed(ActionEvent event) {
    593539        Language language = (Language)selector.getSelectedItem();
     
    600546    private class ClearDefaultListener
    601547        implements ActionListener {
    602                 /** Clear the default index.
    603                 * @param event An <strong>ActionEvent</strong>.
    604                 */
     548        /** Clear the default index.
     549        * @param event An <strong>ActionEvent</strong>.
     550         */
    605551        public void actionPerformed(ActionEvent event) {
    606552        setDefault(null);
     
    612558    private class RemoveListener
    613559        implements ActionListener {
    614                 /** Remove the currently selected language, if any.
    615                 * @param event An <strong>ActionEvent</strong>.
    616                 * @see org.greenstone.gatherer.cdm.Language
    617                 */
     560        /** Remove the currently selected language, if any.
     561        * @param event An <strong>ActionEvent</strong>.
     562        * @see org.greenstone.gatherer.cdm.Language
     563        */
    618564        public void actionPerformed(ActionEvent event) {
    619565        if(!list.isSelectionEmpty()) {
     
    629575    private class SelectorListener
    630576        implements ActionListener {
    631                 /** Enable or disable controls depeding on selection.
    632                 * @param event An <strong>ActionEvent</strong>.
    633                 */
     577        /** Enable or disable controls depeding on selection.
     578        * @param event An <strong>ActionEvent</strong>.
     579         */
    634580        public void actionPerformed(ActionEvent event) {
    635581        if(selector.getSelectedItem() != null) {
     
    658604        }
    659605    }
    660     /** Listens for actions apon the 'translate' button in the LanguageManager controls, and if detected creates a new <strong>TranslationManager</strong> to allow the user to tranlate. */
    661     private class TranslateListener
    662         implements ActionListener {
    663                 /** Create a new translation manager, but remember to clean up after it disposes.
    664                  * @param event An <strong>ActionEvent</strong>.
    665                  * @see org.greenstone.gatherer.cdm.TranslationManager
    666                  */
    667         public void actionPerformed(ActionEvent event) {
    668         TranslationManager tm = new TranslationManager(gatherer, manager);
    669         tm.destroy();
    670         }
    671     }
    672606    /** Listens for selections within the list on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
    673607    private class ListListener
    674608        implements ListSelectionListener {
    675                 /** Enable or disable controls depending on the current list selection.
    676                 * @param event A <strong>ListSelectionEvent</strong>.
    677                 */
     609        /** Enable or disable controls depending on the current list selection.
     610        * @param event A <strong>ListSelectionEvent</strong>.
     611         */
    678612        public void valueChanged(ListSelectionEvent event) {
    679613        if(list.isSelectionEmpty()) {
     
    691625    private class ListRenderer
    692626        extends DefaultListCellRenderer {
    693                 /** Method to produce the component used to display an entry in the list.
    694                 * @param list The <strong>JList</strong> the component will be placed in.
    695                 * @param value A value to be displayed for this component, as a <strong>Object</strong>.
    696                 * @param index The position in the list it will occupy as an <i>int</i>.
    697                 * @param isSelected Whether the user has currently selected this component, as a <i>boolean</i>.
    698                 * @param cellHasFocus Whether the component currently has focus, again as a <i>boolean</i>.
    699                 * @return A <strong>Component</strong> to be used as the entry in the list.
    700                 * @see org.greenstone.gatherer.cdm.Language
    701                 */
     627        /** Method to produce the component used to display an entry in the list.
     628        * @param list The <strong>JList</strong> the component will be placed in.
     629        * @param value A value to be displayed for this component, as a <strong>Object</strong>.
     630        * @param index The position in the list it will occupy as an <i>int</i>.
     631        * @param isSelected Whether the user has currently selected this component, as a <i>boolean</i>.
     632        * @param cellHasFocus Whether the component currently has focus, again as a <i>boolean</i>.
     633        * @return A <strong>Component</strong> to be used as the entry in the list.
     634        * @see org.greenstone.gatherer.cdm.Language
     635        */
    702636        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    703637        Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  • trunk/gli/src/org/greenstone/gatherer/cdm/SubIndex.java

    r4366 r4494  
    9393      */
    9494    public int compareTo(Object object) {
    95     SubIndex index = (SubIndex) object;
    96     return toString().compareTo(index.toString());
     95    return toString().compareTo(object.toString());
    9796    }
    9897    /** Method to determine if this subindex contains a certain subcollection.
     
    114113      */
    115114    public boolean equals(Object object) {
    116     if(compareTo(object) == 0) {
    117         return true;
    118     }
    119     return false;
     115    return (compareTo(object) == 0);
    120116    }
    121117    /** Method to generate a comma separated list from a subindex vector.
     
    123119      */
    124120    public String toString() {
    125     String text = "";
     121    StringBuffer text = new StringBuffer("");
    126122    for(int i = 0; i < size(); i++) {
    127123        Object object = get(i);
    128124        Subcollection sub = (Subcollection) get(i);
    129         text = text + sub.getName();
     125        text.append(sub.getName());
    130126        if(i < size() - 1) {
    131         text = text + ",";
     127        text.append(",");
    132128        }
    133129    }
    134     return text;
     130    return text.toString();
    135131    }
    136132}
  • trunk/gli/src/org/greenstone/gatherer/cdm/SubcollectionManager.java

    r4366 r4494  
    5050 * Revised:      17/11/02 - Commented
    5151 **************************************************************************************/
    52 import java.awt.BorderLayout;
    53 import java.awt.GridLayout;
    54 import java.awt.event.ActionEvent;
    55 import java.awt.event.ActionListener;
    56 import java.awt.event.KeyAdapter;
    57 import java.awt.event.KeyEvent;
    58 import java.io.Serializable;
    59 import java.util.ArrayList;
    60 import java.util.Collections;
    61 import java.util.Enumeration;
    62 import java.util.Hashtable;
    63 import java.util.Vector;
    64 import javax.swing.BorderFactory;
    65 import javax.swing.ButtonGroup;
    66 import javax.swing.DefaultListModel;
    67 import javax.swing.JButton;
    68 import javax.swing.JCheckBox;
    69 import javax.swing.JComboBox;
    70 import javax.swing.JLabel;
    71 import javax.swing.JList;
    72 import javax.swing.JPanel;
    73 import javax.swing.JScrollPane;
    74 import javax.swing.JTabbedPane;
    75 import javax.swing.JTextArea;
    76 import javax.swing.JTextField;
    77 import javax.swing.JToggleButton;
    78 import javax.swing.ListSelectionModel;
    79 import javax.swing.event.ListSelectionEvent;
    80 import javax.swing.event.ListSelectionListener;
     52import java.awt.*;
     53import java.awt.event.*;
     54import java.util.*;
     55import javax.swing.*;
     56import javax.swing.event.*;
    8157import org.greenstone.gatherer.Gatherer;
    8258import org.greenstone.gatherer.cdm.Subcollection;
     
    9268public class SubcollectionManager
    9369    extends DefaultListModel {
     70    /** A reference to the manager so we can get access to languages. */
     71    private CollectionDesignManager manager;
    9472    /** The controls used to edit the settings of this manager. */
    9573    private Control controls = null;
     
    11088     * @see org.greenstone.gatherer.cdm.SubIndexes
    11189     */
    112     public SubcollectionManager(Gatherer gatherer) {
     90    public SubcollectionManager(Gatherer gatherer, CollectionDesignManager manager) {
    11391    super();
    11492    this.gatherer = gatherer;
     93    this.manager = manager;
    11594    this.model = this;
    11695    this.subcollections = new Hashtable();
     
    11998    }
    12099    /** Method to add a subindex.
    121       * @param subindex A <strong>SubIndex</strong>.
    122         * @see org.greenstone.gatherer.Gatherer
    123         * @see org.greenstone.gatherer.collection.CollectionManager
    124       */
     100     * @param subindex A <strong>SubIndex</strong>.
     101     * @see org.greenstone.gatherer.Gatherer
     102     * @see org.greenstone.gatherer.collection.CollectionManager
     103     */
    125104    public void addSubIndex(SubIndex subindex) {
    126105    if(!subindexes.contains(subindex)) {
     
    412391    /** The name of this subcollection. */
    413392    private JTextField name = null;
     393    /** The name of this subindex. */
     394    private JTextField subindex_name;
    414395    /** When this button is selected the filter matching files are excluded. */
    415396    private JToggleButton exclude = null;
     
    435416        createSubcollection();
    436417        createSubindex();
    437                 // Add listeners
    438                 // Layout
     418        // Add listeners
     419        // Layout
    439420        instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
    440421        header_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     
    444425        tabbed_pane.addTab(get("Subcollection_Controls"), subcollection_pane);
    445426        tabbed_pane.addTab(get("Subindex_Controls"), subindex_pane);
     427        tabbed_pane.addTab(get("Language_Controls"), manager.languages.getControls());
    446428        border_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
    447429        border_pane.setLayout(new BorderLayout());
     
    460442            */
    461443    public void createSubcollection() {
    462                 // Create
     444        // Create
    463445        add = new JButton(get("Add"));
    464446        add.setMnemonic(KeyEvent.VK_A);
     
    494476        JLabel subcollection_list_label = new JLabel(get("Assigned"));
    495477
    496                 // Add listeners
     478        // Add listeners
    497479        add.addActionListener(new AddListener());
    498480        remove.addActionListener(new RemoveListener());
    499481        subcollection_list.addListSelectionListener(new ListListener());
    500482
    501                 // Layout
     483        // Layout
    502484        inclusive_pane.setLayout(new GridLayout());
    503485        inclusive_pane.add(include);
     
    531513    }
    532514    /** Create the subindex controls.
    533             * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.AddSubIndexListener
    534             * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.ClearDefaultListener
    535             * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.ChangeListener
    536             * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.RemoveSubIndexListener
    537             * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.SetDefaultListener
    538             * @see org.greenstone.gatherer.util.ExclusiveListListener
    539             */
     515    * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.AddSubIndexListener
     516    * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.ClearDefaultListener
     517    * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.ChangeListener
     518    * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.RemoveSubIndexListener
     519    * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.SetDefaultListener
     520    * @see org.greenstone.gatherer.util.ExclusiveListListener
     521    */
    540522    public void createSubindex() {
    541                 // Creation
     523        // Creation
     524        JPanel subindex_name_panel = new JPanel();
     525        JLabel subindex_name_label = new JLabel(get("Name"));
     526        subindex_name = new JTextField();
     527
    542528        add_index = new JButton(get("Add_Subindex"));
    543529        add_index.setMnemonic(KeyEvent.VK_A);
     530        add_index.setEnabled(false);
    544531        JPanel button_pane_2 = new JPanel();
    545532        clear_default = new JButton(get("Clear_Default_Subindex"));
     
    568555        JLabel subindexes_label = new JLabel(get("Subindexes"));
    569556        subindexes_list = new JList(subindexes);
     557        subindexes_list.setCellRenderer(new SubIndexListCellRenderer());
    570558        subindexes_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    571559        JPanel subindexes_pane = new JPanel();
    572560
    573                 // Add listeners
     561        // Add listeners
    574562        ChangeListener cl = new ChangeListener();
    575563        ExclusiveListSelectionListener ell = new ExclusiveListSelectionListener();
     
    587575        name.addKeyListener(cl);
    588576
    589                 // Layout
     577        subindex_name.getDocument().addDocumentListener(new SubIndexNameDocumentListener());
     578        subcollection_list_2.addListSelectionListener(new SubcollectionListSelectionListener());
     579
     580        // Layout
     581        subindex_name_panel.setLayout(new BorderLayout());
     582        subindex_name_panel.add(subindex_name_label, BorderLayout.WEST);
     583        subindex_name_panel.add(subindex_name, BorderLayout.CENTER);
     584
    590585        list_2_pane.setLayout(new BorderLayout());
    591586        list_2_pane.add(subcollection_label, BorderLayout.NORTH);
    592587        list_2_pane.add(new JScrollPane(subcollection_list_2), BorderLayout.CENTER);
     588       
    593589        subindexes_pane.setLayout(new BorderLayout());
    594590        subindexes_pane.add(subindexes_label, BorderLayout.NORTH);
    595591        subindexes_pane.add(new JScrollPane(subindexes_list), BorderLayout.CENTER);
    596         subindex_inner_pane_2.setLayout(new GridLayout(2,1));
     592       
     593        subindex_inner_pane_2.setLayout(new GridLayout(1,2,0,5));
    597594        subindex_inner_pane_2.add(list_2_pane);
    598595        subindex_inner_pane_2.add(subindexes_pane);
     596       
    599597        default_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
    600598        default_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createRaisedBevelBorder()), BorderFactory.createEmptyBorder(2,2,2,2)));
     
    602600        default_pane.add(default_label, BorderLayout.WEST);
    603601        default_pane.add(default_value, BorderLayout.CENTER);
     602       
    604603        subindex_inner_pane_1.setLayout(new BorderLayout());
     604        subindex_inner_pane_1.add(subindex_name_panel, BorderLayout.NORTH);
    605605        subindex_inner_pane_1.add(subindex_inner_pane_2, BorderLayout.CENTER);
    606606        subindex_inner_pane_1.add(default_pane, BorderLayout.SOUTH);
     607       
    607608        button_pane_2.setLayout(new GridLayout(2,2));
    608609        button_pane_2.add(add_index);
     
    610611        button_pane_2.add(clear_default);
    611612        button_pane_2.add(set_default);
     613       
    612614        subindex_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    613615        subindex_pane.setLayout(new BorderLayout());
     
    615617        subindex_pane.add(button_pane_2, BorderLayout.SOUTH);
    616618    }
     619
     620    private class SubIndexListCellRenderer
     621        extends DefaultListCellRenderer {
     622       
     623        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
     624        StringBuffer text = new StringBuffer(value.toString());
     625        // Retrieve the indexes name if any.
     626        CollectionMeta metadata = manager.collectionmetadatum.getMetadata(value, manager.languages.getDefaultLanguage(), true);
     627        if(metadata != null) {
     628            text.append(" \"");
     629            text.append(metadata.getValue());
     630            text.append("\"");
     631        }
     632        return super.getListCellRendererComponent(list, text.toString(), index, isSelected, cellHasFocus);
     633        }
     634
     635    }
     636
     637    private class SubcollectionListSelectionListener
     638        implements ListSelectionListener {
     639
     640        public void valueChanged(ListSelectionEvent event) {
     641        if(!event.getValueIsAdjusting()) {
     642            add_index.setEnabled(!subcollection_list_2.isSelectionEmpty() && subindex_name.getText().length() > 0);
     643        }
     644        }
     645    }
     646   
     647    private class SubIndexNameDocumentListener
     648        implements DocumentListener {
     649        /** Gives notification that an attribute or set of attributes changed. */
     650        public void changedUpdate(DocumentEvent e) {
     651        update();
     652        }
     653        /** Gives notification that there was an insert into the document. */
     654        public void insertUpdate(DocumentEvent e) {
     655        update();
     656        }
     657        /** Gives notification that a portion of the document has been removed. */
     658        public void removeUpdate(DocumentEvent e) {
     659        update();
     660        }
     661        /** The text area has changed in some way. Given that this can only happed when we are editing or adding a text fragment we better respond appropriately. */
     662        private void update() {
     663        add_index.setEnabled(!subcollection_list_2.isSelectionEmpty() && subindex_name.getText().length() > 0);
     664        }
     665    }
     666
    617667    /** Method to unregister any listeners to avoid memory leaks.
    618668            */
     
    684734    private class AddSubIndexListener
    685735        implements ActionListener {
    686                 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to check if they have a series of subcollections selected, and if so build an new subindex based apon them.
    687                 * @param event An <strong>ActionEvent</strong> containing information about the event.
    688                 * @see org.greenstone.gatherer.cdm.SubIndex
    689                 */
     736        /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to check if they have a series of subcollections selected, and if so build an new subindex based apon them.
     737        * @param event An <strong>ActionEvent</strong> containing information about the event.
     738        * @see org.greenstone.gatherer.cdm.SubIndex
     739        */
    690740        public void actionPerformed(ActionEvent event) {
    691         if(!subcollection_list_2.isSelectionEmpty()) {
     741        if(!subcollection_list_2.isSelectionEmpty() && subindex_name.getText().length() > 0) {
    692742            Vector selected = new Vector();
    693743            Object raw[] = subcollection_list_2.getSelectedValues();
     
    695745            selected.add(raw[i]);
    696746            }
    697             addSubIndex(new SubIndex(selected));
     747            SubIndex subindex = new SubIndex(selected);
     748            addSubIndex(subindex);
     749            // Add the subindexes name.
     750            CollectionMeta metadata = new CollectionMeta(manager, subindex, manager.languages.getDefaultLanguage(), subindex_name.getText());
     751            manager.collectionmetadatum.addMetadata(metadata);
    698752        }
    699753        }
  • trunk/gli/src/org/greenstone/gatherer/cdm/TranslationManager.java

    r4415 r4494  
    66 * University of Waikato, New Zealand.
    77 *
    8  * <BR><BR>
    9  *
    108 * Author: John Thompson, Greenstone Digital Library, University of Waikato
    119 *
    12  * <BR><BR>
    13  *
    1410 * Copyright (C) 1999 New Zealand Digital Library Project
    15  *
    16  * <BR><BR>
    1711 *
    1812 * This program is free software; you can redistribute it and/or modify
     
    2115 * (at your option) any later version.
    2216 *
    23  * <BR><BR>
    24  *
    2517 * This program is distributed in the hope that it will be useful,
    2618 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2719 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2820 * GNU General Public License for more details.
    29  *
    30  * <BR><BR>
    3121 *
    3222 * You should have received a copy of the GNU General Public License
     
    3525 *########################################################################
    3626 */
    37 
    38  
    39 
    40 
    41 
    42 
    4327package org.greenstone.gatherer.cdm;
    44 /**************************************************************************************
    45  * Title:        Gatherer
    46  * Description:  The Gatherer: a tool for gathering and enriching a digital collection.
    47  * Copyright:    Copyright (c) 2001
    48  * Company:      The University of Waikato
    49  * Written:      22/05/02
    50  * Revised:      17/11/02 - Commented
    51  **************************************************************************************/
    52 import java.awt.BorderLayout;
    53 import java.awt.Color;
    54 import java.awt.Component;
    55 import java.awt.Dimension;
    56 import java.awt.Font;
    57 import java.awt.GridLayout;
    58 import java.awt.Toolkit;
    59 import java.awt.event.ActionEvent;
    60 import java.awt.event.ActionListener;
    61 import java.awt.event.KeyAdapter;
    62 import java.awt.event.KeyEvent;
    63 import java.util.ArrayList;
    64 import java.util.Collections;
    65 import javax.swing.BorderFactory;
    66 import javax.swing.DefaultListModel;
    67 import javax.swing.ListSelectionModel;
    68 import javax.swing.JButton;
    69 import javax.swing.JCheckBox;
    70 import javax.swing.JDialog;
    71 import javax.swing.JLabel;
    72 import javax.swing.JList;
    73 import javax.swing.JPanel;
    74 import javax.swing.JScrollPane;
    75 import javax.swing.JTable;
    76 import javax.swing.JTextArea;
    77 import javax.swing.event.ListSelectionEvent;
    78 import javax.swing.event.ListSelectionListener;
    79 import javax.swing.table.AbstractTableModel;
    80 import javax.swing.table.DefaultTableCellRenderer;
    81 import javax.swing.table.TableColumn;
     28
     29import java.awt.*;
     30import java.awt.event.*;
     31import java.util.*;
     32import javax.swing.*;
     33import javax.swing.event.*;
     34import javax.swing.table.*;
     35import org.greenstone.gatherer.Dictionary;
    8236import org.greenstone.gatherer.Gatherer;
    8337import org.greenstone.gatherer.cdm.CollectionDesignManager;
     
    8640import org.greenstone.gatherer.cdm.Language;
    8741import org.greenstone.gatherer.cdm.LanguageManager;
    88 import org.greenstone.gatherer.gui.SimpleMenuBar;
    89 import org.greenstone.gatherer.gui.ModalDialog;
    9042
    9143/** This class provides a graphical interface to allow a user to quickly and conviently (ie all in one place) translate the text fragments associated with general metadata and indexes into each of the assigned languages in the collection. It should provide clear controls for the editing of these text fragments, plus clear indicate what languages still need further translation, which it will do through a combination of coloring and other visual indicators.
     
    9345 * @version 2.3
    9446 */
    95 public class TranslationManager
    96     extends ModalDialog {
    97     /** A reference to our creator, the CollectionDesignManager. */
    98     private CollectionDesignManager manager = null;
    99     /** The currently selected collection metadata. */
    100     private CollectionMeta current = null;
    101     /** A listener for selection changes in the feature list. */
    102     private FeatureListener features_listener = null;
    103     /** A reference to the Gatherer, for access to the Dictionary and messaging purposes. */
    104     private Gatherer gatherer = null;
    105     /** The button used to close the translation dialog. */
    106     private JButton close_button = null;
    107     /** A reference to the dialog so that our inner classes can interact with it. */
    108     private JDialog dialog = null;
    109     /** The label denoting the features list. */
    110     private JLabel features_label = null;
    111     /** The label denoting the language table. */
    112     private JLabel languages_label = null;
    113     /** The label denoting the original text area. */
    114     private JLabel original_label = null;
    115     /** The label denoting the original language field */
    116     private JLabel original_language_label = null;
    117     /** The label denoting the translated text area. */
    118     private JLabel translation_label = null;
    119     /** The label denoting the translated language field. */
    120     private JLabel translation_language_label = null;
    121     /** A list of the various features that have collection metadata associated with them. */
    122     private JList features_list = null;
    123     /** The base panel. */
    124     private JPanel content_pane = null;
    125     /** The right panel. */
    126     private JPanel control_pane = null;
    127     /** The panel the features list is shown in. */
    128     private JPanel features_pane = null;
    129     /** The panel the languages table is shown in. */
    130     private JPanel languages_pane = null;
    131     /** The panel the original text is shown in. */
    132     private JPanel original_pane = null;
    133     /** The panel the original language field is shown in. */
    134     private JPanel original_header_pane = null;
    135     /** The panel the translation text is shown in. */
    136     private JPanel translation_pane = null;
    137     /** The panel the translation language field is shown in. */
    138     private JPanel translation_header_pane = null;
    139     /** The table used to show the languages supported by the collection. */
    140     private JTable languages_table = null;
    141     /** The text area displaying the original text (in the default language). */
    142     private JTextArea original = null;
    143     /** The text area displaying the translated text (in the selected language). */
    144     private JTextArea translation = null;
    145     /** The language currently selected. */
    146     private Language current_language = null;
    147     /** The proxy model to the language manager which serves as the basis for the table. */
    148     private TableProxy languages_model = null;
    149     /** The default size of the features list. */
    150     static final private Dimension FEATURE_SIZE = new Dimension(200, 400);
    151     /** The default size of the translation dialog. */
    152     static final private Dimension SIZE = new Dimension(800, 475);
    153     /** Constructor.
    154      * @param gatherer A reference to the <strong>Gatherer</strong>.
    155      * @param manager A reference to the <strong>CollectionDesignManager</strong>.
    156      * @see org.greenstone.gatherer.Configuration
    157      * @see org.greenstone.gatherer.cdm.CollectionMeta
    158      * @see org.greenstone.gatherer.cdm.TranslationManager.TableProxy
    159      */
    160     public TranslationManager(Gatherer gatherer, CollectionDesignManager manager) {
    161     super(gatherer.g_man);
    162     this.dialog = this;
    163     this.gatherer = gatherer;
     47public class TranslationManager {
     48
     49    private CollectionDesignManager manager;
     50    private Control controls;
     51
     52    static final private Dimension LABEL_SIZE = new Dimension(225,25);
     53    static final private int LANGUAGE_WIDTH = 75;
     54    static final private String GENERAL_STR = "General:";
     55    static final private String INDEX_STR = "Index:";
     56    static final private String PARTITION_STR = "Partitions:";
     57
     58    TranslationManager(CollectionDesignManager manager) {
    16459    this.manager = manager;
    165     this.languages_model = new TableProxy();
    166     // Create the features model. Basically we want one string entry for each unique name in the metadata.
     60    }
     61
     62    public JPanel getControls() {
     63    if(controls == null) {
     64        controls = new Control();
     65    }
     66    return controls;
     67    }
     68
     69    private String get(String key) {
     70    if(key.indexOf(".") == -1) {
     71        key = "CDM.TranslationManager." + key;
     72    }
     73    return Gatherer.dictionary.get(key);
     74    }
     75
     76    private Object[] getFeaturesList() {
    16777    ArrayList features_model = new ArrayList();
    16878    for(int i = 0; i < manager.collectionmetadatum.size(); i++) {
    16979        CollectionMeta metadata = (CollectionMeta) manager.collectionmetadatum.get(i);
    170         Object object = metadata.getName();
    171         String name = null;
    172         if(object instanceof Index) {
    173         name = ((Index)object).toString(false);
    174         }
    175         else {
    176         name = object.toString();
    177         }
    178         if(!features_model.contains(name)) {
    179         features_model.add(name);
    180         }
     80        Object bob = new BobTheMagicalComparableWrapper(metadata.getName());
     81        if(!features_model.contains(bob)) {
     82        features_model.add(bob);
     83        }
     84    }
     85    // We also add subindexes.
     86    SubIndexes subindexes = manager.subcollections.getSubIndexes();
     87    for(int j = 0; j < subindexes.size(); j++) {
     88        Object bob = new BobTheMagicalComparableWrapper(subindexes.get(j));
     89        if(!features_model.contains(bob)) {
     90        features_model.add(bob);
     91        }
    18192    }
    18293    Collections.sort(features_model);
    183     // Create components...
    184     setModal(true);
    185     setSize(SIZE);
    186     setJMenuBar(new SimpleMenuBar("7.5")); 
    187     close_button = new JButton(get("General.Close"));
    188     content_pane = (JPanel) getContentPane();
    189     control_pane = new JPanel();
    190     features_label = new JLabel(get("Affected_Features"));
    191     features_label.setHorizontalAlignment(JLabel.CENTER);
    192     features_list = new JList(features_model.toArray());
    193     features_listener = new FeatureListener();
    194     features_pane = new JPanel();
    195     features_pane.setPreferredSize(FEATURE_SIZE);
    196     languages_table = new JTable(languages_model);
    197     languages_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    198     languages_label = new JLabel(get("Assigned_Languages"));
    199     languages_label.setHorizontalAlignment(JLabel.CENTER);
    200     languages_pane = new JPanel();
    201     original = new JTextArea();
    202     original.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    203     original.setEditable(false);
    204     original.setFont(new Font("Arial Unicode MS", Font.PLAIN, 10));
    205     original_header_pane = new JPanel();
    206     original_label = new JLabel(get("Default_Text"));
    207     original_label.setHorizontalAlignment(JLabel.CENTER);
    208     original_language_label = new JLabel("");
    209     original_pane = new JPanel();
    210     translation = new JTextArea();
    211     translation.setEnabled(false);
    212     translation.setFont(new Font("Arial Unicode MS", Font.PLAIN, 10));
    213     translation_header_pane = new JPanel();
    214     translation_label = new JLabel(get("Translation"));
    215     translation_label.setHorizontalAlignment(JLabel.CENTER);
    216     translation_language_label = new JLabel("");
    217     translation_pane = new JPanel();
    218     // Add listeners...
    219     close_button.addActionListener(new CloseListener());
    220     translation.addKeyListener(new TranslationListener());
    221     features_list.addListSelectionListener(features_listener);
    222     features_list.addListSelectionListener(languages_model);
    223     ListSelectionModel languages_selection_model = languages_table.getSelectionModel();
    224     languages_selection_model.addListSelectionListener(new TableListener());
    225     // Layout...
    226     features_pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
    227     features_pane.setLayout(new BorderLayout());
    228     features_pane.add(features_label, BorderLayout.NORTH);
    229     features_pane.add(new JScrollPane(features_list), BorderLayout.CENTER);
    230     languages_label.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
    231     languages_pane.setLayout(new BorderLayout());
    232     languages_pane.add(languages_label, BorderLayout.NORTH);
    233     languages_pane.add(new JScrollPane(languages_table), BorderLayout.CENTER);
    234     original_header_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
    235     original_header_pane.setLayout(new BorderLayout());
    236     original_header_pane.add(original_label, BorderLayout.WEST);
    237     original_header_pane.add(original_language_label, BorderLayout.EAST);
    238     original_pane.setLayout(new BorderLayout());
    239     original_pane.add(original_header_pane, BorderLayout.NORTH);
    240     original_pane.add(new JScrollPane(original), BorderLayout.CENTER);
    241     translation_header_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
    242     translation_header_pane.setLayout(new BorderLayout());
    243     translation_header_pane.add(translation_label, BorderLayout.WEST);
    244     translation_header_pane.add(translation_language_label, BorderLayout.EAST);
    245     translation_pane.setLayout(new BorderLayout());
    246     translation_pane.add(translation_header_pane, BorderLayout.NORTH);
    247     translation_pane.add(new JScrollPane(translation), BorderLayout.CENTER);
    248     control_pane.setLayout(new GridLayout(3,1));
    249     control_pane.add(languages_pane);
    250     control_pane.add(original_pane);
    251     control_pane.add(translation_pane);
    252     content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    253     content_pane.setLayout(new BorderLayout());
    254     content_pane.add(features_pane, BorderLayout.WEST);
    255     content_pane.add(control_pane, BorderLayout.CENTER);
    256     content_pane.add(close_button, BorderLayout.SOUTH);
    257     // Display...
    258     Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
    259     for (int i = 0; i < languages_model.getColumnCount() - 1; i++) {
    260         TableColumn column = languages_table.getColumnModel().getColumn(i);
    261         column.setMinWidth(0);
    262         column.setMaxWidth(screen_size.width);
    263         column.setPreferredWidth((SIZE.width - FEATURE_SIZE.width) / 6);
    264     }
    265     setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
    266     setVisible(true);
     94    return features_model.toArray();
    26795    }
    268     /** Destructor
    269       */
    270     public void destroy() {
    271     dialog = null;
     96   
     97
     98    private class BobTheMagicalComparableWrapper
     99    implements Comparable {
     100    private Object content;
     101    private String text;
     102    BobTheMagicalComparableWrapper(Object content) {
     103        this.content = content;
     104    }
     105    public int compareTo(Object object) {
     106        if(object == null) {
     107        object = "";
     108        }
     109        if(text == null) {
     110        toString();
     111        }
     112        return text.compareTo(object.toString());
     113    }
     114    public boolean equals(Object object) {
     115        if(object == null) {
     116        return false;
     117        }
     118        if(text == null) {
     119        toString();
     120        }
     121        return text.equals(object.toString());
     122    }
     123    public Object getContent() {
     124        return content;
     125    }
     126    public String toString() {
     127        if(text == null) {
     128        if(content instanceof Index) {
     129            text = INDEX_STR + content.toString();
     130        }
     131        else if(content instanceof SubIndex) {
     132            text = PARTITION_STR + content.toString();
     133        }
     134        else {
     135            text = GENERAL_STR + content.toString();
     136        }
     137        }
     138        return text;
     139    }
    272140    }
    273     /** Retrieve a phrase from the dictionary based on a certain key.
    274       * @param key The search <strong>String</strong>.
    275       * @return The matching phrase from the Dictionary as a <strong>String</strong>.
    276       */
    277     private String get(String key) {
    278     return get(key, null);
    279     }
    280     /** Retrieve a phrase from the dictionary based on a certain key and certain arguments.
    281       * @param key The search <strong>String</strong>.
    282       * @param args A <strong>String[]</strong> used to complete and format the returned phrase.
    283       * @return The matching phrase from the Dictionary as a <strong>String</strong>.
    284       * @see org.greenstone.gatherer.Dictionary
    285       * @see org.greenstone.gatherer.Gatherer
    286       */
    287     private String get(String key, String args[]) {
    288     if(key.indexOf(".") == -1) {
    289         key = "CDM.TranslationManager." + key;
    290     }
    291     return gatherer.dictionary.get(key, args);
    292     }
    293     /** Listens for actions apon the close button. */
    294     private class CloseListener
    295     implements ActionListener {
    296     /** Closes the dialog. Any implementation of an ActionListener must include this method so we can be informed when an action has occured.
    297      * @param event An <Strong>ActionEvent</strong> containing details about the action.
    298             */
    299     public void actionPerformed(ActionEvent event) {
    300         dialog.dispose();
    301     }
    302     }
    303     /** Listens to selections within the feature list. */
    304     private class FeatureListener
    305     implements ListSelectionListener {
    306     /** Called whenever the selection changes in the registered list, which requires us to create a new TableProxy.
    307      * @param event A <strong>ListSelectionEvent</strong> containing more information about the list selection change.
    308      * @see org.greenstone.gatherer.cdm.CollectionMeta
    309      * @see org.greenstone.gatherer.cdm.Language
    310      */
    311     public void valueChanged(ListSelectionEvent event) {
    312                 // Try to find the default language value for this feature.
    313         String name = (String) features_list.getSelectedValue();
    314         Language language = manager.languages.getDefaultLanguage();
    315         CollectionMeta metadata = manager.collectionmetadatum.getMetadata(name, language, true);
    316         if(metadata != null && metadata.getValue() != null && metadata.getValue().length() != 0) {
    317         if(!metadata.getLanguage().equals(language)) {
    318             original_label.setText(get("Existing_Text"));
    319         }
    320         else {
    321             original_label.setText(get("Default_Text"));
    322         }
    323         original.setText(metadata.getValue());
    324         original_language_label.setText(metadata.getLanguage().toString());
    325         }
    326         else {
    327         original_label.setText(get("No_Text"));
    328         original.setText("");
    329         }
    330     }
    331     }
    332     /** Listens for selections within the languages table. */
    333     private class TableListener
    334     implements ListSelectionListener {
    335     /** Called whenever the selection changes in the registered list, which requires us to update several parts of the dialog.
    336      * @param event A <strong>ListSelectionEvent</strong> containing more information about the list selection change.
    337      * @see org.greenstone.gatherer.cdm.CollectionMeta
    338      * @see org.greenstone.gatherer.cdm.Language
    339      */
    340     public void valueChanged(ListSelectionEvent event) {
    341         if (event.getValueIsAdjusting()) return;
    342         ListSelectionModel lsm = (ListSelectionModel)event.getSource();
    343         if (!lsm.isSelectionEmpty()) {
    344         int row = lsm.getMinSelectionIndex();
    345         current = languages_model.getMetadata(row);
    346         if(current != null) {
    347             if (current.getValue() != null) {
    348             translation.setText(current.getValue());
     141
     142    private class Control
     143    extends JPanel {
     144
     145    private boolean ignore_event = false;
     146    private FragmentTableModel fragment_table_model;
     147    private JComboBox language_combobox;
     148    private JList features_list;
     149    private JTable fragment_table;
     150    private JTextArea default_area;
     151    private JTextArea translation_area;
     152
     153    Control() {
     154        fragment_table_model = new FragmentTableModel(new ArrayList());
     155        // Creation
     156        JPanel header_panel = new JPanel();
     157        JLabel title_label = new JLabel(get("Title"));
     158        title_label.setHorizontalAlignment(JLabel.CENTER);
     159        JTextArea instruction_area = new JTextArea(get("Instructions"));
     160        instruction_area.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     161        instruction_area.setEditable(false);
     162        instruction_area.setLineWrap(true);
     163        instruction_area.setRows(3);
     164        instruction_area.setWrapStyleWord(true);
     165
     166        JPanel center_panel = new JPanel();
     167
     168        JPanel selection_panel = new JPanel();
     169
     170        JPanel component_selection_panel = new JPanel();
     171        JLabel component_label = new JLabel(get("Affected_Features"));
     172        features_list = new JList(getFeaturesList());
     173        features_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     174
     175        JPanel fragment_selection_panel = new JPanel();
     176        JLabel fragment_label = new JLabel(get("Assigned_Fragments"));
     177        fragment_table = new JTable(fragment_table_model);
     178        fragment_table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
     179        fragment_table.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     180        fragment_table.setColumnSelectionAllowed(false);
     181        fragment_table.setDefaultRenderer(Object.class, new FragmentTableRenderer());
     182        fragment_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     183        //TableColumnModel column_model = fragment_table.getColumnModel();
     184        //TableColumn language_column = column_model.getColumn(0);
     185        //language_column.setPreferredWidth(LANGUAGE_WIDTH);
     186        //language_column = null;
     187        //column_model = null;
     188        //fragment_table.sizeColumnsToFit(0);
     189
     190        JPanel south_panel = new JPanel();
     191
     192        JPanel text_panel = new JPanel();
     193
     194        JPanel language_panel = new JPanel();
     195        JLabel language_label = new JLabel(get("Language"));
     196        language_label.setPreferredSize(LABEL_SIZE);
     197        language_combobox = new JComboBox(manager.languages.getLanguageCodes().toArray());
     198
     199        JPanel default_text_panel = new JPanel();
     200        JLabel default_label = new JLabel(get("Default_Text"));
     201        default_area = new JTextArea();
     202        default_area.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
     203        default_area.setEditable(false);
     204        default_area.setLineWrap(true);
     205        default_area.setWrapStyleWord(true);
     206
     207        JPanel translated_text_panel = new JPanel();
     208        JLabel translation_label = new JLabel(get("Translation"));
     209        translation_area = new JTextArea();
     210        translation_area.setBackground(Gatherer.config.getColor("coloring.disabled", false));
     211        translation_area.setEnabled(false);
     212        translation_area.setLineWrap(true);
     213        translation_area.setWrapStyleWord(true);
     214   
     215        // Connection
     216        language_combobox.addActionListener(new LanguageActionListener());
     217        translation_area.getDocument().addDocumentListener(new TranslationDocumentListener());
     218        features_list.addListSelectionListener(new FeaturesListSelectionListener());
     219        fragment_table.getSelectionModel().addListSelectionListener(new FragmentListSelectionListener());
     220        // Layout
     221        header_panel.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
     222        header_panel.setLayout(new BorderLayout());
     223        header_panel.add(title_label, BorderLayout.NORTH);
     224        header_panel.add(new JScrollPane(instruction_area), BorderLayout.CENTER);
     225
     226        component_selection_panel.setLayout(new BorderLayout());
     227        component_selection_panel.add(component_label, BorderLayout.NORTH);
     228        component_selection_panel.add(new JScrollPane(features_list), BorderLayout.CENTER);
     229
     230        fragment_selection_panel.setLayout(new BorderLayout());
     231        fragment_selection_panel.add(fragment_label, BorderLayout.NORTH);
     232        fragment_selection_panel.add(new JScrollPane(fragment_table), BorderLayout.CENTER);
     233
     234        selection_panel.setLayout(new GridLayout(2,1,0,5));
     235        selection_panel.add(component_selection_panel);
     236        selection_panel.add(fragment_selection_panel);
     237
     238        default_text_panel.setLayout(new BorderLayout());
     239        default_text_panel.add(default_label, BorderLayout.NORTH);
     240        default_text_panel.add(new JScrollPane(default_area), BorderLayout.CENTER);
     241
     242        translated_text_panel.setLayout(new BorderLayout());
     243        translated_text_panel.add(translation_label, BorderLayout.NORTH);
     244        translated_text_panel.add(new JScrollPane(translation_area), BorderLayout.CENTER);
     245
     246        text_panel.setLayout(new GridLayout(1,2,5,0));
     247        text_panel.add(default_text_panel);
     248        text_panel.add(translated_text_panel);
     249
     250        language_panel.setLayout(new BorderLayout());
     251        language_panel.add(language_label, BorderLayout.WEST);
     252        language_panel.add(language_combobox, BorderLayout.CENTER);
     253
     254        south_panel.setLayout(new BorderLayout());
     255        south_panel.add(language_panel, BorderLayout.NORTH);
     256        south_panel.add(text_panel, BorderLayout.CENTER);
     257
     258        center_panel.setLayout(new GridLayout(2,1,0,5));
     259        center_panel.add(selection_panel);
     260        center_panel.add(south_panel);
     261
     262        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     263        setLayout(new BorderLayout());
     264        add(header_panel, BorderLayout.NORTH);
     265        add(center_panel, BorderLayout.CENTER);
     266    }
     267
     268    public void updateUI() {
     269        // Rebuild the features model, just incase features have been added or removed.
     270        if(features_list != null) {
     271        Object selected_feature = features_list.getSelectedValue();
     272        features_list.setListData(getFeaturesList());
     273        if(selected_feature != null) {
     274            features_list.setSelectedValue(selected_feature, true);
     275        }
     276        }
     277        // Carry on.
     278        super.updateUI();
     279    }
     280
     281    private class FeaturesListSelectionListener
     282        implements ListSelectionListener {
     283        public void valueChanged(ListSelectionEvent event) {
     284        if(!event.getValueIsAdjusting()) {
     285            if(!ignore_event) { // And it shouldn't ever be.
     286            ignore_event = true;
     287            ///ystem.err.println("FeaturesListSelectionListener");
     288            if(!features_list.isSelectionEmpty()) {
     289                // Determine the features name. Remember to remove our helpful source prefix (delimited by ':').
     290                BobTheMagicalComparableWrapper bob = (BobTheMagicalComparableWrapper)features_list.getSelectedValue();
     291                Object selected_feature = bob.getContent();
     292                bob = null;
     293                // Retrieve the default language translation, or otherwise the first match, to be default text.
     294                CollectionMeta default_metadata = manager.collectionmetadatum.getMetadata(selected_feature, manager.languages.getDefaultLanguage(), true);
     295                if(default_metadata != null) {
     296                default_area.setText(default_metadata.getValue());
     297                }
     298                // Update the text fragment table.
     299                fragment_table.clearSelection();
     300                fragment_table_model.setData(manager.collectionmetadatum.getMetadata(selected_feature));
     301                selected_feature = null;
     302                // Now we check whatever value is currently selected in the combobox to see if it is valid to add.
     303                String language_name = language_combobox.getSelectedItem().toString();
     304                int index = fragment_table_model.getMetadataIndexByLanguage(language_name);
     305                if(index != -1) {
     306                CollectionMeta metadata = fragment_table_model.getMetadata(index);
     307                fragment_table.setRowSelectionInterval(index, index);
     308                translation_area.setText(metadata.getValue());
     309                metadata = null;
     310                }
     311                else {
     312                translation_area.setText("");
     313                }
     314                // Update and enable the text area
     315                translation_area.setEnabled(true);
     316                translation_area.setBackground(Gatherer.config.getColor("coloring.editable", false));
     317            }
     318            else {
     319                default_area.setText("");
     320                fragment_table.clearSelection();
     321                fragment_table_model.setData(new ArrayList());
     322                translation_area.setText("");
     323                // Update and disable the text area
     324                translation_area.setText("");
     325                translation_area.setEnabled(false);
     326                translation_area.setBackground(Gatherer.config.getColor("coloring.disabled", false));
     327            }
     328            ignore_event = false;
     329            }
     330        }
     331        }
     332    }
     333
     334    private class FragmentListSelectionListener
     335        implements ListSelectionListener {
     336        public void valueChanged(ListSelectionEvent event) {
     337        if(!event.getValueIsAdjusting() && !ignore_event) {
     338            ignore_event = true;
     339            ///ystem.err.println("FragmentListSelectionListener");
     340            int index = -1;
     341            if((index = fragment_table.getSelectedRow()) != -1) {
     342            // A row has been selected. Retrieve the collection metadata.
     343            CollectionMeta metadata = fragment_table_model.getMetadata(index);
     344            if(metadata != null) {
     345                // Update the combobox to show the current language.
     346                Language language = metadata.getLanguage();
     347                String language_name = language.toString();
     348                ///ystem.err.println("Searching for the language: " + language_name);
     349                for(int i = 0; i < language_combobox.getItemCount(); i++) {
     350                if(language_combobox.getItemAt(i).toString().equals(language_name)) {
     351                    language_combobox.setSelectedIndex(i);
     352                }
     353                }
     354            }
     355            translation_area.setText(metadata.getValue());
    349356            }
    350357            else {
    351             translation.setText("");
    352             }
    353             current_language = current.getLanguage();
    354         }
    355         else {
    356             current_language = (Language) languages_model.getValueAt(row, 1);
    357             translation.setText("");
    358         }
    359         features_listener.valueChanged(null);
    360         translation_language_label.setText(current_language.toString());
    361         translation.setEnabled(true);
    362         }
    363     }
    364     }
    365     /** A AbstractTableModel extension based upon a vector of CollectionMeta, which can also listen to a list for selection changes. */
    366     private class TableProxy
    367     extends AbstractTableModel
    368     implements ListSelectionListener {
    369     /** Called when the contents of a cell changes.
    370      */
    371     public void cellChanged() {
    372         fireTableDataChanged();
    373     }
    374     /** Returns the most specific superclass for all the cell values in the column.
    375             * @param column An <i>int</i> specifying which columns class to be determined.
    376             * @return The columns <strong>Class</strong>.
    377             */
    378         public Class getColumnClass(int column) {
    379         return String.class;
    380     }
    381     /** Returns the number of columns in the model.
    382             * @return An <i>int</i> specifying the number of columns.
    383             */
    384     public int getColumnCount() {
    385         if(!features_list.isSelectionEmpty()) {
     358            translation_area.setText("");
     359            }
     360            ignore_event = false;
     361        }
     362        }
     363    }
     364
     365    private class FragmentTableModel
     366        extends AbstractTableModel {
     367       
     368        private ArrayList metadatum;
     369
     370        FragmentTableModel(ArrayList metadatum) {
     371        this.metadatum = metadatum;
     372        }
     373        public int getRowCount() {
     374        return metadatum.size();
     375        }
     376        public int getColumnCount() {
    386377        return 2;
    387378        }
    388         return 0;
    389     }
    390         /** Returns the name of the column at columnIndex.
    391             * @param column An <i>int</i> specifying the column whose name you are interesting in.
    392             * @return The name of the column as a <strong>String</strong>.
    393             */
    394     public String getColumnName(int column) {
    395         String name = null;
    396         switch(column) {
    397         case 0:
    398         name = get("Language");
    399         break;
    400         case 1:
    401         name = get("Text");
    402         break;
    403         }
    404         return name;
    405     }
    406     /** Retrieve the collection metadata from the specified row.
    407           * @param row An <i>int</i> indicating the row in question.
    408           * @see org.greenstone.gatherer.cdm.Language
    409           * @see org.greenstone.gatherer.cdm.LanguageManager
    410           */
    411     public CollectionMeta getMetadata(int row) {
    412         String name = (String) features_list.getSelectedValue();
    413         Language language = (Language) getValueAt(row, 0);
    414         return manager.collectionmetadatum.getMetadata(name, language, false);
    415     }
    416         /** Returns the number of rows in the model.
    417             * @return An <i>int</i> specifying the number of rows in the table, which is exactly the number of languages assigned to this collection.
    418             * @see org.greenstone.gatherer.cdm.LanguageManager
    419             */
    420     public int getRowCount() {
    421         return manager.languages.size();
    422     }
    423     /** Returns the value for the cell at column and row.
    424             * @param row The desired row as an <i>int</i>.
    425             * @param column The desired column as an <i>int</i>.
    426             * @return The value at the row, column reference.
    427             * @see org.greenstone.gatherer.cdm.CollectionMeta
    428             * @see org.greenstone.gatherer.cdm.Language
    429             * @see org.greenstone.gatherer.cdm.LanguageManager
    430             */
    431     public Object getValueAt(int row, int column) {
    432         if(!features_list.isSelectionEmpty()) {
    433         // First of all find the Language that matches the row and the current feature name, because in any case you'll need them.
    434         Language language = (Language)manager.languages.get(row);
    435         String feature_name = (String)features_list.getSelectedValue();
    436         // Also try to locate the collection level metadata that matches.
    437         CollectionMeta metadata = manager.collectionmetadatum.getMetadata(feature_name, language, false);
    438         // Now we do subtly different things depending on the column.
    439         switch(column) {
    440         case 0: // The Language. Easiest case.
    441             return language;
    442         case 1: // The value of the metadata. Needs us to retrieve the value for a certain feature and language.
    443             if(metadata != null) {
     379        public String getColumnName(int column) {
     380        return get("Column_Name_" + column);
     381        }
     382
     383        public CollectionMeta getMetadata(int row) {
     384        if(0 <= row && row < metadatum.size()) {
     385            return (CollectionMeta) metadatum.get(row);
     386        }
     387        return null;
     388        }
     389
     390        public int getMetadataIndexByLanguage(String language) {
     391        for(int i = 0; i < metadatum.size(); i++) {
     392            CollectionMeta metadata = (CollectionMeta) metadatum.get(i);
     393            if(language.equals(metadata.getLanguage().toString())) {
     394            return i;
     395            }
     396        }
     397        return -1;
     398        }
     399
     400        public Object getValueAt(int row, int column) {
     401        if(0 <= row && row < metadatum.size()) {
     402            CollectionMeta metadata = (CollectionMeta) metadatum.get(row);
     403            switch(column) {
     404            case 0:
     405            return metadata.getLanguage();
     406            default:
    444407            return metadata.getValue();
    445408            }
    446409        }
    447         // If all else fails, return an empty string and hope the class caster doesn't explode.
    448         }
    449         return "";
    450     }
    451         /** Returns true if the cell at row and column is editable.
    452             * @param row The row of the cell as an <i>int</i>.
    453             * @param column The column of the cell also as an <i>int</i>.
    454             */
    455     public boolean isCellEditable(int rowIndex, int columnIndex) {
    456         return false;
    457     }
    458         /** Sets the value in the cell at columnIndex and rowIndex to aValue.
    459             */
    460     public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    461     }
    462     /** Any implementation of <i>ListSelectionListener</i> must include this method so we can be informed when the list selection has changed.
    463             * @param event A <strong>ListSelectionEvent</strong> containing information about the selection change.
    464             */
    465     public void valueChanged(ListSelectionEvent event) {
    466         fireTableStructureChanged();
    467     }
    468     }
    469     /** This provides a custom renderer that colours the background of the default language cell green, and the foreground of currently unready metadata rows red. */
    470     private class TableRenderer
    471     extends DefaultTableCellRenderer {
    472     /** Retrieve the component used to rubberstamp the table based on the given parameters.
    473      * @param table The <strong>JTable</strong> to rendered.
    474      * @param value The <strong>Object</strong> whose representation will be shown in the table row.
    475      * @param isSelected <i>true</i> iff the column/row is selected.
    476      * @param hasFocus <i>true</i> iff the column/row is in focus.
    477      * @param row An <i>int</i> specifying the target row.
    478      * @param column An <i>int</i> specifying the target column.
    479      * @see org.greenstone.gatherer.cdm.Language
    480      */
    481     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    482         Component component = null;
    483                 // Create the component.
    484         if(value instanceof String || value instanceof Language) {
    485         JLabel label = new JLabel(value.toString());
    486         label.setOpaque(true);
    487         component = label;
    488         }
    489         else {
    490         JCheckBox check = new JCheckBox("", ((Boolean)value).booleanValue());
    491         JPanel pane = new JPanel(new BorderLayout());
    492         pane.add(check, BorderLayout.CENTER);
    493         component = pane;
    494         }
    495                 // Check for default property
    496         Language language = (Language)languages_model.getValueAt(row, 1);
    497         if(language.isDefault()) {
     410        return "#Error";
     411        }
     412       
     413        public void remove(int index) {
     414        metadatum.remove(index);
     415        fireTableRowsDeleted(index, index);
     416        }
     417
     418        public void setData(ArrayList metadatum) {
     419        this.metadatum = metadatum;
     420        fireTableDataChanged();
     421        }
     422    }
     423
     424    private class FragmentTableRenderer
     425        extends DefaultTableCellRenderer {
     426        /** Retrieve the component used to rubberstamp the table based on the given parameters.
     427         * @param table The <strong>JTable</strong> to rendered.
     428         * @param value The <strong>Object</strong> whose representation will be shown in the table row.
     429         * @param isSelected <i>true</i> iff the column/row is selected.
     430         * @param hasFocus <i>true</i> iff the column/row is in focus.
     431         * @param row An <i>int</i> specifying the target row.
     432         * @param column An <i>int</i> specifying the target column.
     433         * @see org.greenstone.gatherer.cdm.Language
     434         */
     435        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
     436        JComponent component = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    498437        if(isSelected) {
    499             component.setBackground(Gatherer.config.getColor("coloring.collection_selection_background", false));
     438            component.setBackground(Gatherer.config.getColor("coloring.workspace_heading_background", false));
    500439        }
    501440        else {
    502441            component.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
    503442        }
    504         }
    505         else {
    506         if(isSelected) {
    507             component.setBackground(table.getSelectionBackground());
    508         }
    509         else {
    510             component.setForeground(Color.white);
    511         }
    512         }
    513                 // Check for readiness
    514         Boolean ready = (Boolean)languages_model.getValueAt(row, 0);
    515         if(!ready.booleanValue()) {
    516         component.setForeground(Color.red);
    517         }
    518         else {
    519         component.setForeground(Color.black);
    520         }
    521         return component;
     443        return component;
     444        }
     445    }
     446
     447    private class LanguageActionListener
     448        implements ActionListener {
     449        public void actionPerformed(ActionEvent event) {
     450        if(!ignore_event) {
     451            ignore_event = true;
     452            ///ystem.err.println("LanguageActionListener");
     453            // If the newly selected language value already exists in the fragment table, and that row isn't the one selected, then select that row the text area.
     454            String language_name = language_combobox.getSelectedItem().toString();
     455            int index = fragment_table_model.getMetadataIndexByLanguage(language_name);
     456            if(index != -1) {
     457            CollectionMeta metadata = fragment_table_model.getMetadata(index);
     458            fragment_table.setRowSelectionInterval(index, index);
     459            translation_area.setText(metadata.getValue());
     460            }
     461            else {
     462            fragment_table.clearSelection();
     463            translation_area.setText("");
     464            }
     465            // Ready the text area
     466            translation_area.setEnabled(true); 
     467            translation_area.setBackground(Gatherer.config.getColor("coloring.editable", false));
     468            ignore_event = false;
     469        }
     470        }       
     471    }
     472
     473    private class TranslationDocumentListener
     474        implements DocumentListener {
     475        /** Gives notification that an attribute or set of attributes changed. */
     476        public void changedUpdate(DocumentEvent e) {
     477        update();
     478        }
     479        /** Gives notification that there was an insert into the document. */
     480        public void insertUpdate(DocumentEvent e) {
     481        update();
     482        }
     483        /** Gives notification that a portion of the document has been removed. */
     484        public void removeUpdate(DocumentEvent e) {
     485        update();
     486        }
     487        /** The text area has changed in some way. Given that this can only happed when we are editing or adding a text fragment we better respond appropriately. */
     488        private void update() {
     489        if(!ignore_event) {
     490            ignore_event = true;
     491            String translation_text = translation_area.getText();
     492            // If there is no current fragment table selection, but translation text is not an empty string, then this is a new fragment. Create new collection metadata, refresh the fragment table, then ensure that the new metadata is selected. Remember that it is the selected metadata to which changes will be applied.
     493            int index = -1;
     494            if((index = fragment_table.getSelectedRow()) == -1 && translation_text.length() > 0) {
     495            ///ystem.err.println("Adding new collectionmeta!");
     496            BobTheMagicalComparableWrapper bob = (BobTheMagicalComparableWrapper)features_list.getSelectedValue();
     497            Object selected_feature = bob.getContent();
     498            Language language = (Language) language_combobox.getSelectedItem();
     499            CollectionMeta metadata = new CollectionMeta(manager, selected_feature, language, translation_text);
     500            manager.collectionmetadatum.addMetadata(metadata);
     501            fragment_table.clearSelection();
     502            fragment_table_model.setData(manager.collectionmetadatum.getMetadata(selected_feature));
     503            index = fragment_table_model.getMetadataIndexByLanguage(language.toString());
     504            fragment_table.setRowSelectionInterval(index, index);
     505            metadata = null;
     506            language = null;
     507            selected_feature = null;
     508            }
     509            else {
     510            CollectionMeta metadata = fragment_table_model.getMetadata(index);
     511            // If the text is now empty, and there was previously a metadata fragment selected, then remove the fragments metadata and update the table
     512            if(translation_text.length() == 0) {
     513                ///ystem.err.println("Removing collectionmeta! fireTableRowsDeleted(" + index + "," + index + ")");
     514                manager.collectionmetadatum.removeMetadata(metadata);
     515                fragment_table_model.remove(index);
     516            }
     517            // Otherwise update the fragment metadata and ask the table to repaint the appropriate row
     518            else {
     519                ///ystem.err.println("Updating collectionmeta!");
     520                metadata.setValue(translation_text);
     521                fragment_table_model.fireTableRowsUpdated(index, index);
     522            }
     523            metadata = null;
     524            }
     525            translation_text = null;
     526            ignore_event = false;
     527        }
     528        }
    522529    }
    523530    }
    524     /** Listens for actions within the translation text field and immediately updates the collection metadata as necessary. */
    525     private class TranslationListener
    526     extends KeyAdapter {
    527     /** This method is called when a key has been released, and is perfect for us to synchronize the contents of the translation field with the collection metadata associated with the selected feature and language.
    528      * @param event A <strong>KeyEvent</strong> containing more detail about the key released.
    529      * @see org.greenstone.gatherer.cdm.CollectionMeta
    530      * @see org.greenstone.gatherer.cdm.CollectionMetaManager
    531      * @see org.greenstone.gatherer.cdm.Index
    532      */
    533     public void keyReleased(KeyEvent event) {
    534         if(current == null) {
    535         String name = (String)features_list.getSelectedValue();
    536         Index index = manager.indexes.getIndex(name);
    537         if(index == null) {
    538             current = new CollectionMeta(manager, name, current_language, translation.getText());
    539         }
    540         else {
    541             current = new CollectionMeta(manager, index, current_language, translation.getText());
    542         }
    543         manager.collectionmetadatum.addMetadata(current);
    544         }
    545         else {
    546         current.update(current.getName(), current.getLanguage(), translation.getText());
    547         }
    548         languages_model.cellChanged();
    549     }
    550     }
     531
    551532}
     533
     534
Note: See TracChangeset for help on using the changeset viewer.