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

Last change on this file since 12123 was 12123, checked in by kjdon, 18 years ago

Changed text handling to use Dictionary.get rather than Dictionary.setText or Dictionary.registerBoth etc. also removed mnemonics cos they suck for other languages.

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