/**
*#########################################################################
*
* A component of the Gatherer application, part of the Greenstone digital
* library suite from the New Zealand Digital Library Project at the
* University of Waikato, New Zealand.
*
* Author: John Thompson, Greenstone Digital Library, University of Waikato
*
* Copyright (C) 1999 New Zealand Digital Library Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*########################################################################
*/
package org.greenstone.gatherer.cdm;
/**************************************************************************************
* Written: 08/05/02
* Revised: 17/11/02 - Commented
* 07/07/03 - DOM support
**************************************************************************************/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.DebugStream;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.gui.GLIButton;
import org.greenstone.gatherer.util.Utility;
import org.w3c.dom.*;
/** This class manages the language commands, remembering both a list of languages to build indexes in, plus the default language.
* @author John Thompson, Greenstone Digital Library, University of Waikato
* @version 2.3
*/
public class LanguageManager
extends DOMProxyListModel {
static public Document LANGUAGES_DOCUMENT = Utility.parse("xml/languages.xml", true);
static final private Dimension COMPONENT_SIZE = new Dimension(125,25);
/** The visual controls for this manager. */
private Control controls = null;
/** A reference to this class as a model, for the inner controls class. */
private DOMProxyListModel model = null;
/** A hashtable of code->name mappings of known languages. */
private LinkedHashMap known_languages = null;
/** The default language object. */
private Language default_language = null;
/** Constructor. */
public LanguageManager(Element languages_element) {
super(languages_element, CollectionConfiguration.LANGUAGE_ELEMENT, new Language());
DebugStream.println("LanguageManager: " + getSize() + " languages parsed.");
this.model = this;
// Retrieve the default language
NodeList default_language_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT);
if(default_language_elements.getLength() > 0) {
default_language = new Language((Element)default_language_elements.item(0));
}
// Load a series of code->language mappings into known_languages, by reading from the 'languages.xml' file, which is essentially a subset of the ISO 639 Standard.
known_languages = new LinkedHashMap();
/*
try {
File in_file = new File("languages.dat");
FileReader in_reader = new FileReader(in_file);
BufferedReader in = new BufferedReader(in_reader);
String entry = null;
while((entry = in.readLine()) != null) {
if(!entry.startsWith("#")) {
StringTokenizer tokenizer = new StringTokenizer(entry);
if(tokenizer.countTokens() >= 2) {
String name = tokenizer.nextToken();
String code = tokenizer.nextToken().toLowerCase();
known_languages.put(code, name);
}
}
}
in.close();
in_reader.close();
in = null;
in_reader = null;
in_file = null;
}
catch (Exception error) {
error.printStackTrace();
}
*/
NodeList language_elements = LANGUAGES_DOCUMENT.getDocumentElement().getElementsByTagName(CollectionConfiguration.LANGUAGE_ELEMENT);
for(int i = 0; i < language_elements.getLength(); i++) {
Element language_element = (Element) language_elements.item(i);
String code = language_element.getAttribute(CollectionConfiguration.CODE_ATTRIBUTE);
String name = language_element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE);
known_languages.put(code.toLowerCase(), name);
name = null;
code = null;
language_element = null;
}
}
/** Method to add a new language.
* @param language The Language to add.
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.collection.CollectionManager
*/
private void addLanguage(Language language) {
if(!contains(language)) {
Element element = language.getElement();
append(language);
Gatherer.c_man.configurationChanged();
}
}
public void destroy() {
if(controls != null) {
controls.destroy();
controls = null;
}
known_languages.clear();
known_languages = null;
}
/** Method to retrieve the control for this manager.
* @return the Control for editing the language partitions
*/
public Control getControls() {
if(controls == null) {
// Build controls
controls = new LanguageControl();
}
return controls;
}
/** Method to retrieve the default language code.
* @return A Language containing a two letter code.
*/
/* private Language getDefaultLanguage() {
// If no default is set...
if(default_language != null && default_language.isAssigned()) {
return default_language;
}
return null;
} */
/** Method to retrieve a certain language object by its code.
* @param code The two letter code of a language, as a String.
* @return The Language that matches the given code, or null if no such language exists.
*/
public Language getLanguage(String code) {
int size = getSize();
for(int i = 0; i < size; i++) {
Language language = (Language) getElementAt(i);
if(language.getCode().equals(code)) {
return language;
}
}
return null;
}
public ArrayList getLanguages() {
return children();
}
/** Method to return a list of the known language codes.
* @return an ArrayList containing the series of known language codes as per the languages.dat file
*/
public ArrayList getLanguageCodes() {
return new ArrayList(known_languages.keySet());
}
public String getLanguageName(String code) {
return (String) known_languages.get(code);
}
/** Method to remove a certain language.
* @param language The Language to remove.
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.collection.CollectionManager
*/
private void removeLanguage(Language language) {
remove(language);
if(default_language != null && default_language.equals(language)) {
default_language = null;
((LanguageControl)controls).clearDefaultLanguage();
}
Gatherer.c_man.configurationChanged();
}
/** Method to set the default language.
* @param language The Language to use as a default, or null for no default.
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.collection.CollectionManager
*/
public void setDefault(Language language) {
if(language != null) {
if(default_language == null) {
// Create the default index element, and place immediately after indexes element.
Element default_language_element = root.getOwnerDocument().createElement(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT);
default_language = new Language(default_language_element);
Node target_node = CollectionConfiguration.findInsertionPoint(default_language_element);
if(target_node != null) {
root.getOwnerDocument().getDocumentElement().insertBefore(default_language_element, target_node);
}
else {
root.getOwnerDocument().getDocumentElement().appendChild(default_language_element);
}
}
default_language.setAssigned(true);
default_language.setCode(language.getCode());
}
else {
if(default_language != null) {
default_language.setAssigned(false);
}
}
Gatherer.c_man.configurationChanged();
}
/** This class represents the visual component of the Language Manager. */
private class LanguageControl
extends JPanel
implements Control {
/** The button to add a new language support. */
private JButton add_button = null;
/** The button to clear the current default language. */
private JButton clear_button = null;
/** The button to remove a supported language. */
private JButton remove_button = null;
/** The button to set the current language as the default one. */
private JButton set_button = null;
/** A combobox listing the available supported languages. */
private JComboBox selector_combobox = null;
/** A list of currently supported languages. */
private JList language_list = null;
/** A description of the language currently selected. */
private JTextArea description_textarea = null;
/** The text field showing the currently name of the default language. Non-editable. */
private JTextField default_language_field = null;
/** Constructor.
* @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.AddListener
* @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.ClearDefaultListener
* @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.ListListener
* @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.RemoveListener
* @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.SelectorListener
* @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.SetDefaultListener
*/
public LanguageControl() {
super();
// Creation.
JPanel center_panel = new JPanel();
JLabel language_list_label = new JLabel();
Dictionary.registerText(language_list_label, "CDM.LanguageManager.Assigned_Languages");
language_list = new JList(model);
JPanel details_panel = new JPanel();
JPanel default_panel = new JPanel();
JLabel default_label = new JLabel();
default_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
Dictionary.registerText(default_label, "CDM.LanguageManager.Default_Language");
if(default_language == null) {
default_language_field = new JTextField();
}
else {
default_language_field = new JTextField(default_language.toString());
}
default_language_field.setPreferredSize(COMPONENT_SIZE);
default_language_field.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
default_language_field.setEditable(false);
JPanel control_panel = new JPanel();
JLabel selector_label = new JLabel();
Dictionary.registerText(selector_label, "CDM.LanguageManager.Selector");
selector_combobox = new JComboBox(getLanguageCodes().toArray());
selector_combobox.setPreferredSize(COMPONENT_SIZE);
selector_combobox.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
selector_combobox.setRenderer(new LanguageListCellRenderer());
Dictionary.registerTooltip(selector_combobox, "CDM.LanguageManager.Selector_Tooltip");
JPanel button_panel = new JPanel();
add_button = new GLIButton();
add_button.setMnemonic(KeyEvent.VK_A);
Dictionary.registerBoth(add_button, "CDM.LanguageManager.Add", "CDM.LanguageManager.Add_Tooltip");
remove_button = new GLIButton();
remove_button.setMnemonic(KeyEvent.VK_R);
remove_button.setEnabled(false);
Dictionary.registerBoth(remove_button, "CDM.LanguageManager.Remove", "CDM.LanguageManager.Remove_Tooltip");
clear_button = new GLIButton();
clear_button.setMnemonic(KeyEvent.VK_C);
// If there is a default language, then this is enabled
clear_button.setEnabled(default_language != null && default_language.isAssigned());
Dictionary.registerBoth(clear_button, "CDM.LanguageManager.Clear_Default", "CDM.LanguageManager.Clear_Default_Tooltip");
set_button = new GLIButton();
set_button.setMnemonic(KeyEvent.VK_S);
set_button.setEnabled(false);
Dictionary.registerBoth(set_button, "CDM.LanguageManager.Set_Default", "CDM.LanguageManager.Set_Default_Tooltip");
// Set up and connect listeners.
add_button.addActionListener(new AddListener());
clear_button.addActionListener(new ClearDefaultListener());
remove_button.addActionListener(new RemoveListener());
selector_combobox.addActionListener(new SelectorListener());
set_button.addActionListener(new SetDefaultListener());
language_list.addListSelectionListener(new ListListener());
// Layout components
default_panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createEmptyBorder(2,0,2,2)));
default_panel.setLayout(new BorderLayout());
default_panel.add(default_label, BorderLayout.WEST);
default_panel.add(default_language_field, BorderLayout.CENTER);
control_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
control_panel.setLayout(new BorderLayout());
control_panel.add(selector_label, BorderLayout.WEST);
control_panel.add(selector_combobox, BorderLayout.CENTER);
details_panel.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
details_panel.setLayout(new BorderLayout());
details_panel.add(default_panel, BorderLayout.CENTER);
details_panel.add(control_panel, BorderLayout.SOUTH);
center_panel.setLayout(new BorderLayout());
center_panel.add(language_list_label, BorderLayout.NORTH);
center_panel.add(new JScrollPane(language_list), BorderLayout.CENTER);
center_panel.add(details_panel, BorderLayout.SOUTH);
button_panel.setLayout(new GridLayout(2,2));
button_panel.add(add_button);
button_panel.add(remove_button);
button_panel.add(set_button);
button_panel.add(clear_button);
setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
setLayout(new BorderLayout());
add(center_panel, BorderLayout.CENTER);
add(button_panel, BorderLayout.SOUTH);
}
public void clearDefaultLanguage() {
clear_button.doClick();
}
/** Destructor. */
public void destroy() {
}
public void gainFocus() {
}
public void loseFocus() {
}
/** 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. */
private class AddListener
implements ActionListener {
/** Add a new language support.
* @param event an ActionEvent
* @see org.greenstone.gatherer.cdm.Language
*/
public void actionPerformed(ActionEvent event) {
String language_code = (String) selector_combobox.getSelectedItem();
if(language_code != null) {
addLanguage(new Language(language_code));
}
add_button.setEnabled(false);
}
}
/** Listens for actions apon the 'clear default' button in the LanguageManager controls, and if detected calls the setDefault method of the manager with null. */
private class ClearDefaultListener
implements ActionListener {
/** Clear the default index.
* @param event An ActionEvent.
*/
public void actionPerformed(ActionEvent event) {
setDefault(null);
clear_button.setEnabled(false);
default_language_field.setText("");
}
}
/** Listens for actions apon the 'remove' button in the LanguageManager controls, and if detected calls the remove method of the manager with the language selected for removal. */
private class RemoveListener
implements ActionListener {
/** Remove the currently selected language, if any.
* @param event An ActionEvent.
* @see org.greenstone.gatherer.cdm.Language
*/
public void actionPerformed(ActionEvent event) {
Language delete_me = (Language)language_list.getSelectedValue();
if(delete_me != null) {
removeLanguage(delete_me);
if(default_language != null && default_language.equals(delete_me)) {
setDefault(null);
clear_button.setEnabled(false);
default_language_field.setText("");
}
}
remove_button.setEnabled(false);
}
}
/** Listens for selections within the combobox on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
private class SelectorListener
implements ActionListener {
/** Enable or disable controls depeding on selection.
* @param event An ActionEvent.
*/
public void actionPerformed(ActionEvent event) {
if(selector_combobox.getSelectedItem() != null) {
add_button.setEnabled(true);
}
else {
add_button.setEnabled(false);
}
}
}
/** Listens for actions apon the 'set default' button in the LanguageManager controls, and if detected calls the setDefault() method of the manager with the language selected for default. */
private class SetDefaultListener
implements ActionListener {
/** Set the default index to the one currently selected, if any.
* @param event An ActionEvent.
* @see org.greenstone.gatherer.cdm.Language
*/
public void actionPerformed(ActionEvent event) {
if(!language_list.isSelectionEmpty()) {
setDefault((Language)language_list.getSelectedValue());
clear_button.setEnabled(true);
default_language_field.setText(default_language.toString());
}
}
}
/** Listens for selections within the list on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
private class ListListener
implements ListSelectionListener {
/** Enable or disable controls depending on the current list selection.
* @param event A ListSelectionEvent.
*/
public void valueChanged(ListSelectionEvent event) {
if(language_list.isSelectionEmpty()) {
remove_button.setEnabled(false);
set_button.setEnabled(false);
}
else {
remove_button.setEnabled(true);
set_button.setEnabled(true);
}
}
}
}
}