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

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

changed the interface a bit to make it more like the other two tabs. still needs to allow selection of multiple indexes, but will wait till after the next cdrom so we don'tneed to change the help text

  • Property svn:keywords set to Author Date Id Revision
File size: 21.2 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.