source: trunk/gli/src/org/greenstone/gatherer/cdm/LanguageManager.java@ 9640

Last change on this file since 9640 was 9564, checked in by kjdon, 19 years ago

added [] around Default Language in the selected langs box

  • Property svn:keywords set to Author Date Id Revision
File size: 21.3 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29/**************************************************************************************
30 * Written: 08/05/02
31 * Revised: 17/11/02 - Commented
32 * 07/07/03 - DOM support
33 **************************************************************************************/
34import java.awt.*;
35import java.awt.event.*;
36import java.io.*;
37import java.util.*;
38import javax.swing.*;
39import javax.swing.event.*;
40import org.greenstone.gatherer.Configuration;
41import org.greenstone.gatherer.DebugStream;
42import org.greenstone.gatherer.Dictionary;
43import org.greenstone.gatherer.Gatherer;
44import org.greenstone.gatherer.gui.GLIButton;
45import org.greenstone.gatherer.util.Utility;
46import org.w3c.dom.*;
47
48/** This class manages the language commands, remembering both a list of languages to build indexes in, plus the default language.
49 * @author John Thompson, Greenstone Digital Library, University of Waikato
50 * @version 2.3
51 */
52public class LanguageManager
53 extends DOMProxyListModel {
54
55 static public Document LANGUAGES_DOCUMENT = Utility.parse("xml/languages.xml", true);
56
57 static final private Dimension COMPONENT_SIZE = new Dimension(125,25);
58
59 /** The visual controls for this manager. */
60 private Control controls = null;
61 /** A reference to this class as a model, for the inner controls class. */
62 private DOMProxyListModel model = null;
63 /** A hashtable of code->name mappings of known languages. */
64 private LinkedHashMap known_languages = null;
65 /** The default language object. */
66 private Language default_language = null;
67
68 /** Constructor. */
69 public LanguageManager(Element languages_element) {
70 super(languages_element, CollectionConfiguration.LANGUAGE_ELEMENT, new Language());
71
72 DebugStream.println("LanguageManager: " + getSize() + " languages parsed.");
73
74 this.model = this;
75 // Retrieve the default language
76 NodeList default_language_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT);
77 if(default_language_elements.getLength() > 0) {
78 default_language = new Language((Element)default_language_elements.item(0));
79 }
80 // 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.
81 known_languages = new LinkedHashMap();
82 /*
83 try {
84 File in_file = new File("languages.dat");
85 FileReader in_reader = new FileReader(in_file);
86 BufferedReader in = new BufferedReader(in_reader);
87 String entry = null;
88 while((entry = in.readLine()) != null) {
89 if(!entry.startsWith("#")) {
90 StringTokenizer tokenizer = new StringTokenizer(entry);
91 if(tokenizer.countTokens() >= 2) {
92 String name = tokenizer.nextToken();
93 String code = tokenizer.nextToken().toLowerCase();
94 known_languages.put(code, name);
95 }
96 }
97 }
98 in.close();
99 in_reader.close();
100 in = null;
101 in_reader = null;
102 in_file = null;
103 }
104 catch (Exception error) {
105 error.printStackTrace();
106 }
107 */
108 NodeList language_elements = LANGUAGES_DOCUMENT.getDocumentElement().getElementsByTagName(CollectionConfiguration.LANGUAGE_ELEMENT);
109 for(int i = 0; i < language_elements.getLength(); i++) {
110 Element language_element = (Element) language_elements.item(i);
111 String code = language_element.getAttribute(CollectionConfiguration.CODE_ATTRIBUTE);
112 String name = language_element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE);
113 known_languages.put(code.toLowerCase(), name);
114 name = null;
115 code = null;
116 language_element = null;
117 }
118 }
119
120 /** Method to add a new language.
121 * @param language The <strong>Language</strong> to add.
122 * @see org.greenstone.gatherer.Gatherer
123 * @see org.greenstone.gatherer.collection.CollectionManager
124 */
125 private void addLanguage(Language language) {
126 if(!contains(language)) {
127 Element element = language.getElement();
128 append(language);
129 Gatherer.c_man.configurationChanged();
130 }
131 }
132
133 public void destroy() {
134 if(controls != null) {
135 controls.destroy();
136 controls = null;
137 }
138 known_languages.clear();
139 known_languages = null;
140 default_language = null;
141 }
142
143 /** Method to retrieve the control for this manager.
144 * @return the Control for editing the language partitions
145 */
146 public Control getControls() {
147 if(controls == null) {
148 // Build controls
149 controls = new LanguageControl();
150 }
151 return controls;
152 }
153
154 /** Method to retrieve the default language code.
155 * @return A <strong>Language</strong> containing a two letter code.
156 */
157 /* private Language getDefaultLanguage() {
158 // If no default is set...
159 if(default_language != null && default_language.isAssigned()) {
160 return default_language;
161 }
162 return null;
163 } */
164
165 /** Method to retrieve a certain language object by its code.
166 * @param code The two letter code of a language, as a <strong>String</strong>.
167 * @return The <strong>Language</strong> that matches the given code, or <i>null</i> if no such language exists.
168 */
169 public Language getLanguage(String code) {
170 int size = getSize();
171 for(int i = 0; i < size; i++) {
172 Language language = (Language) getElementAt(i);
173 if(language.getCode().equals(code)) {
174 return language;
175 }
176 }
177 return null;
178 }
179
180 public ArrayList getLanguages() {
181 return children();
182 }
183
184 /** Method to return a list of the known language codes.
185 * @return an ArrayList containing the series of known language codes as per the languages.dat file
186 */
187 public ArrayList getLanguageCodes() {
188 return new ArrayList(known_languages.keySet());
189 }
190
191 public String getLanguageName(String code) {
192 return (String) known_languages.get(code);
193 }
194
195 private int moveLanguage(Language lang, boolean move_up)
196 {
197 // Determine the current position of the language
198 int position = indexOf(lang);
199 int new_position;
200
201 // Attempt to move the language up
202 if (move_up) {
203 // Check it's not already at the top
204 if (position == 0) {
205 return position;
206 }
207
208 // This automatically removes the language first, as an Element can only exist once in a particular document
209 new_position = position - 1;
210 addBefore(lang, (Language) getElementAt(new_position));
211 }
212
213 // Attempt to move the language down
214 else {
215 // Check it's not already at the bottom
216 if (position == (getSize()) - 1) {
217 return position;
218 }
219
220 // This automatically removes the language first, as an Element can only exist once in a particular document
221 new_position = position + 1;
222 addAfter(lang, (Language) getElementAt(new_position));
223 }
224
225 // Schedule the collection for saving
226 Gatherer.c_man.configurationChanged();
227 return new_position;
228 }
229
230 /** Method to remove a certain language.
231 * @param language The <strong>Language</strong> to remove.
232 * @see org.greenstone.gatherer.Gatherer
233 * @see org.greenstone.gatherer.collection.CollectionManager
234 */
235 private void removeLanguage(Language language) {
236 remove(language);
237 if(default_language != null && default_language.equals(language)) {
238 default_language = null;
239 }
240 Gatherer.c_man.configurationChanged();
241 }
242
243 /** Method to set the default language.
244 * @param language The <strong>Language</strong> to use as a default, or <i>null</i> for no default.
245 * @see org.greenstone.gatherer.Gatherer
246 * @see org.greenstone.gatherer.collection.CollectionManager
247 */
248 public void setDefault(Language language) {
249 if(language != null) {
250 if(default_language == null) {
251 // Create the default index element, and place immediately after indexes element.
252 Element default_language_element = root.getOwnerDocument().createElement(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT);
253 default_language = new Language(default_language_element);
254 Node target_node = CollectionConfiguration.findInsertionPoint(default_language_element);
255 if(target_node != null) {
256 root.getOwnerDocument().getDocumentElement().insertBefore(default_language_element, target_node);
257 }
258 else {
259 root.getOwnerDocument().getDocumentElement().appendChild(default_language_element);
260 }
261 }
262 default_language.setAssigned(true);
263 default_language.setCode(language.getCode());
264 }
265 else {
266 if(default_language != null) {
267 default_language.setAssigned(false);
268 }
269 }
270 Gatherer.c_man.configurationChanged();
271 }
272
273
274 /** This class represents the visual component of the Language Manager. */
275 private class LanguageControl
276 extends JPanel
277 implements Control {
278 /** The button to add a new language support. */
279 private JButton add_button = null;
280 /** The button to remove a supported language. */
281 private JButton remove_button = null;
282 /** button to move a language up in the list */
283 private JButton move_down_button;
284 /** button to move a language down in the list */
285 private JButton move_up_button;
286 /** The button to set the current language as the default one. */
287 private JButton set_default_button = null;
288 /** A combobox listing the available supported languages. */
289 private JComboBox language_combobox = null;
290 /** A list of currently supported languages. */
291 private JList selected_languages_list = null;
292 /** Constructor.
293 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.AddListener
294 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.ClearDefaultListener
295 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.ListListener
296 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.RemoveListener
297 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.SelectorListener
298 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.SetDefaultListener
299 */
300 public LanguageControl() {
301 super();
302 // Creation.
303 JPanel center_panel = new JPanel();
304
305 JLabel selected_languages_list_label = new JLabel();
306 Dictionary.registerText(selected_languages_list_label, "CDM.LanguageManager.Assigned_Languages");
307 selected_languages_list = new JList(model);
308 selected_languages_list.setCellRenderer(new MyLanguageListCellRenderer());
309 selected_languages_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
310 selected_languages_list.setVisibleRowCount(5);
311 JPanel details_panel = new JPanel();
312
313 JPanel control_panel = new JPanel();
314 JLabel selector_label = new JLabel();
315 Dictionary.registerText(selector_label, "CDM.LanguageManager.Selector");
316
317 language_combobox = new JComboBox(getLanguageCodes().toArray());
318 language_combobox.setPreferredSize(COMPONENT_SIZE);
319 language_combobox.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
320 language_combobox.setRenderer(new LanguageListCellRenderer());
321 Dictionary.registerTooltip(language_combobox, "CDM.LanguageManager.Selector_Tooltip");
322
323 JPanel movement_pane = new JPanel();
324 move_up_button = new JButton("", Utility.getImage("arrow-up.gif"));
325 move_up_button.setEnabled(false);
326 move_up_button.setMnemonic(KeyEvent.VK_U);
327 Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
328
329 move_down_button = new JButton("", Utility.getImage("arrow-down.gif"));
330 move_down_button.setEnabled(false);
331 move_down_button.setMnemonic(KeyEvent.VK_D);
332 Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
333
334 set_default_button = new GLIButton();
335 set_default_button.setEnabled(false);
336 set_default_button.setMnemonic(KeyEvent.VK_S);
337 Dictionary.registerBoth(set_default_button, "CDM.LanguageManager.Set_Default", "CDM.LanguageManager.Set_Default_Tooltip");
338
339 JPanel button_panel = new JPanel();
340
341 add_button = new GLIButton();
342 add_button.setMnemonic(KeyEvent.VK_A);
343 Dictionary.registerBoth(add_button, "CDM.LanguageManager.Add", "CDM.LanguageManager.Add_Tooltip");
344 if (getLanguage((String)language_combobox.getItemAt(0))==null) {
345 add_button.setEnabled(true);
346 } else {
347 add_button.setEnabled(false);
348 }
349 remove_button = new GLIButton();
350 remove_button.setMnemonic(KeyEvent.VK_R);
351 remove_button.setEnabled(false);
352 Dictionary.registerBoth(remove_button, "CDM.LanguageManager.Remove", "CDM.LanguageManager.Remove_Tooltip");
353
354 // Set up and connect listeners.
355 add_button.addActionListener(new AddListener());
356 move_down_button.addActionListener(new MoveListener(false));
357 move_up_button.addActionListener(new MoveListener(true));
358 remove_button.addActionListener(new RemoveListener());
359 language_combobox.addActionListener(new SelectorListener());
360 set_default_button.addActionListener(new SetDefaultListener());
361 selected_languages_list.addListSelectionListener(new ListListener());
362
363 // Layout components
364 movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
365 movement_pane.setLayout(new GridLayout(3,1));
366 movement_pane.add(move_up_button);
367 movement_pane.add(move_down_button);
368 movement_pane.add(set_default_button);
369
370 control_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
371 control_panel.setLayout(new BorderLayout());
372 control_panel.add(selector_label, BorderLayout.WEST);
373 control_panel.add(language_combobox, BorderLayout.CENTER);
374
375 center_panel.setLayout(new BorderLayout());
376 center_panel.add(selected_languages_list_label, BorderLayout.NORTH);
377 center_panel.add(new JScrollPane(selected_languages_list), BorderLayout.CENTER);
378 center_panel.add(movement_pane, BorderLayout.EAST);
379 center_panel.add(control_panel, BorderLayout.SOUTH);
380
381 button_panel.setLayout(new GridLayout(1,2));
382 button_panel.add(add_button);
383 button_panel.add(remove_button);
384// button_panel.add(set_button);
385// button_panel.add(clear_button);
386
387 //when we go to a multi list, remove inner_panel and empty_panel
388 JPanel empty_panel = new JPanel();
389 JPanel inner_panel = new JPanel();
390
391 inner_panel.setLayout(new BorderLayout());
392 inner_panel.add(center_panel, BorderLayout.CENTER);
393 inner_panel.add(button_panel, BorderLayout.SOUTH);
394 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
395 setLayout(new BorderLayout());
396 //add(center_panel, BorderLayout.CENTER);
397 //add(button_panel, BorderLayout.SOUTH);
398 add(inner_panel, BorderLayout.NORTH);
399 add(empty_panel, BorderLayout.CENTER);
400 }
401
402 /** Destructor. */
403 public void destroy() {
404 }
405
406 public void gainFocus() {
407 }
408
409 public void loseFocus() {
410 }
411
412 /** 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. */
413 private class AddListener
414 implements ActionListener {
415 /** Add a new language support.
416 * @param event an ActionEvent
417 * @see org.greenstone.gatherer.cdm.Language
418 */
419 public void actionPerformed(ActionEvent event) {
420 String language_code = (String) language_combobox.getSelectedItem();
421 if(language_code != null) {
422 addLanguage(new Language(language_code));
423 }
424 // add some collectionmeta
425 String lang_name = getLanguageName(language_code);
426 CollectionMeta metadatum = new CollectionMeta("." + language_code);
427 metadatum.setValue(lang_name);
428 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
429
430 add_button.setEnabled(false);
431 }
432 }
433
434 /** 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. */
435 private class RemoveListener
436 implements ActionListener {
437 /** Remove the currently selected language, if any.
438 * @param event An <strong>ActionEvent</strong>.
439 * @see org.greenstone.gatherer.cdm.Language
440 */
441 public void actionPerformed(ActionEvent event) {
442 Language delete_me = (Language)selected_languages_list.getSelectedValue();
443 if(delete_me != null) {
444 // Remove any current metadata for this language
445 CollectionDesignManager.collectionmeta_manager.removeMetadata("." + delete_me.getCode());
446 removeLanguage(delete_me);
447 if(default_language != null && default_language.equals(delete_me)) {
448 setDefault(null);
449 //clear_button.setEnabled(false);
450 //default_language_field.setText("");
451 }
452 }
453 remove_button.setEnabled(false);
454 }
455 }
456
457 /** Listens for selections within the combobox on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
458 private class SelectorListener
459 implements ActionListener {
460 /** Enable or disable controls depeding on selection.
461 * @param event An <strong>ActionEvent</strong>.
462 */
463 public void actionPerformed(ActionEvent event) {
464 String language_code = (String) language_combobox.getSelectedItem();
465 if(language_code != null && getLanguage(language_code) == null) {
466 add_button.setEnabled(true);
467 }
468 else {
469 add_button.setEnabled(false);
470 }
471 }
472 }
473
474 /** Listens for actions apon the 'set default' button in the LanguageManager controls, and if detected calls the <i>setDefault()</i> method of the manager with the language selected for default. */
475 private class SetDefaultListener
476 implements ActionListener {
477 /** Set the default index to the one currently selected, if any.
478 * @param event An <strong>ActionEvent</strong>.
479 * @see org.greenstone.gatherer.cdm.Language
480 */
481 public void actionPerformed(ActionEvent event) {
482 Language selected_language = (Language) selected_languages_list.getSelectedValue();
483 if(selected_language != null) {
484 setDefault(selected_language);
485 //clear_button.setEnabled(true);
486 // This should cause a repaint of just the desired row
487 selected_languages_list.setSelectedValue(selected_language, true);
488 }
489 set_default_button.setEnabled(false);
490 }
491 }
492
493 private class MoveListener
494 implements ActionListener
495 {
496 private boolean move_up;
497
498 public MoveListener(boolean move_up)
499 {
500 this.move_up = move_up;
501 }
502
503 public void actionPerformed(ActionEvent event)
504 {
505 // Retrieve the selected language
506 Language language = (Language) selected_languages_list.getSelectedValue();
507 if (language != null) {
508 int new_position = moveLanguage(language, move_up);
509 // Ensure the language that moved is still selected
510 selected_languages_list.setSelectedIndex(new_position);
511 }
512 }
513 }
514
515
516 /** Listens for selections within the list on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
517 private class ListListener
518 implements ListSelectionListener {
519 /** Enable or disable controls depending on the current list selection.
520 * @param event A <strong>ListSelectionEvent</strong>.
521 */
522 public void valueChanged(ListSelectionEvent event) {
523 if (event.getValueIsAdjusting()) {
524 return;
525 }
526 if(selected_languages_list.isSelectionEmpty()) {
527 remove_button.setEnabled(false);
528 set_default_button.setEnabled(false);
529 move_down_button.setEnabled(false);
530 move_up_button.setEnabled(false);
531 return;
532 }
533
534 int i = selected_languages_list.getSelectedIndex();
535 int size = selected_languages_list.getModel().getSize();
536 Language selected_lang = (Language)selected_languages_list.getSelectedValue();
537 remove_button.setEnabled(true);
538 set_default_button.setEnabled(default_language == null || !default_language.equals(selected_lang));
539
540 if (i > 0) {
541 move_up_button.setEnabled(true);
542 }
543 else {
544 move_up_button.setEnabled(false);
545 }
546 if (i < size-1){
547 move_down_button.setEnabled(true);
548 }
549 else {
550 move_down_button.setEnabled(false);
551 }
552 }
553 }
554
555 private class MyLanguageListCellRenderer
556 extends DefaultListCellRenderer
557 {
558 /** Return a component that has been configured to display the specified value. */
559 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
560 JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
561 if (default_language != null && default_language.equals(value)) {
562 component.setText(component.getText() + " [" + Dictionary.get("CDM.LanguageManager.Default_Language")+"]");
563 }
564 return component;
565 }
566 }
567 }
568}
Note: See TracBrowser for help on using the repository browser.