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 | */
|
---|
27 | package org.greenstone.gatherer.cdm;
|
---|
28 | /**************************************************************************************
|
---|
29 | * Written: 08/05/02
|
---|
30 | * Revised: 17/11/02 - Commented
|
---|
31 | * 07/07/03 - DOM support
|
---|
32 | **************************************************************************************/
|
---|
33 | import java.awt.*;
|
---|
34 | import java.awt.event.*;
|
---|
35 | import java.io.*;
|
---|
36 | import java.util.*;
|
---|
37 | import javax.swing.*;
|
---|
38 | import javax.swing.event.*;
|
---|
39 | import org.greenstone.gatherer.Gatherer;
|
---|
40 | import org.greenstone.gatherer.cdm.CollectionConfiguration;
|
---|
41 | import org.greenstone.gatherer.cdm.CollectionDesignManager;
|
---|
42 | import org.greenstone.gatherer.cdm.Control;
|
---|
43 | import org.greenstone.gatherer.cdm.DOMProxyListModel;
|
---|
44 | import org.greenstone.gatherer.cdm.Language;
|
---|
45 | import org.greenstone.gatherer.cdm.LanguageListCellRenderer;
|
---|
46 | import org.w3c.dom.*;
|
---|
47 | /** This class manages the language commands, remembering both a list of languages to build indexes in, plus the default language.
|
---|
48 | * @author John Thompson, Greenstone Digital Library, University of Waikato
|
---|
49 | * @version 2.3
|
---|
50 | */
|
---|
51 | public class LanguageManager
|
---|
52 | extends DOMProxyListModel {
|
---|
53 |
|
---|
54 | static final private Dimension LABEL_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 | Gatherer.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.dat' file, which is essentially a subset of the ISO 639 Standard.
|
---|
78 | known_languages = new LinkedHashMap();
|
---|
79 | try {
|
---|
80 | File in_file = new File("languages.dat");
|
---|
81 | FileReader in_reader = new FileReader(in_file);
|
---|
82 | BufferedReader in = new BufferedReader(in_reader);
|
---|
83 | String entry = null;
|
---|
84 | while((entry = in.readLine()) != null) {
|
---|
85 | if(!entry.startsWith("#")) {
|
---|
86 | StringTokenizer tokenizer = new StringTokenizer(entry);
|
---|
87 | if(tokenizer.countTokens() >= 2) {
|
---|
88 | String name = tokenizer.nextToken();
|
---|
89 | String code = tokenizer.nextToken().toLowerCase();
|
---|
90 | known_languages.put(code, name);
|
---|
91 | }
|
---|
92 | }
|
---|
93 | }
|
---|
94 | in.close();
|
---|
95 | in_reader.close();
|
---|
96 | in = null;
|
---|
97 | in_reader = null;
|
---|
98 | in_file = null;
|
---|
99 | }
|
---|
100 | catch (Exception error) {
|
---|
101 | error.printStackTrace();
|
---|
102 | }
|
---|
103 | }
|
---|
104 |
|
---|
105 | /** Method to add a new language.
|
---|
106 | * @param language The <strong>Language</strong> to add.
|
---|
107 | * @see org.greenstone.gatherer.Gatherer
|
---|
108 | * @see org.greenstone.gatherer.collection.CollectionManager
|
---|
109 | */
|
---|
110 | public void addLanguage(Language language) {
|
---|
111 | if(!contains(language)) {
|
---|
112 | Element element = language.getElement();
|
---|
113 | // Locate where we should insert this new subcollection.
|
---|
114 | Node target_node = CollectionConfiguration.findInsertionPoint(element);
|
---|
115 | // Failing that we insert immediately after a language string
|
---|
116 | add(root, language, target_node);
|
---|
117 | Gatherer.c_man.configurationChanged();
|
---|
118 | }
|
---|
119 | }
|
---|
120 |
|
---|
121 | public void destroy() {
|
---|
122 | if(controls != null) {
|
---|
123 | controls.destroy();
|
---|
124 | controls = null;
|
---|
125 | }
|
---|
126 | known_languages.clear();
|
---|
127 | known_languages = null;
|
---|
128 | }
|
---|
129 |
|
---|
130 | /** Method to retrieve the control for this manager.
|
---|
131 | * @return the Control for editing the language partitions
|
---|
132 | */
|
---|
133 | public Control getControls() {
|
---|
134 | if(controls == null) {
|
---|
135 | // Build controls
|
---|
136 | controls = new LanguageControl();
|
---|
137 | }
|
---|
138 | return controls;
|
---|
139 | }
|
---|
140 |
|
---|
141 | /** Method to retrieve the default language code.
|
---|
142 | * @return A <strong>Language</strong> containing a two letter code.
|
---|
143 | */
|
---|
144 | public Language getDefaultLanguage() {
|
---|
145 | // If no default is set...
|
---|
146 | if(default_language != null && default_language.isAssigned()) {
|
---|
147 | return default_language;
|
---|
148 | }
|
---|
149 | return null;
|
---|
150 | }
|
---|
151 |
|
---|
152 | /** Method to retrieve a certain language object by its code.
|
---|
153 | * @param code The two letter code of a language, as a <strong>String</strong>.
|
---|
154 | * @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.
|
---|
155 | * @return The <strong>Language</strong> that matches the given code, or <i>null</i> if no such language exists.
|
---|
156 | */
|
---|
157 | public Language getLanguage(String code) {
|
---|
158 | int size = getSize();
|
---|
159 | for(int i = 0; i < size; i++) {
|
---|
160 | Language language = (Language) getElementAt(i);
|
---|
161 | if(language.getCode().equals(code)) {
|
---|
162 | return language;
|
---|
163 | }
|
---|
164 | }
|
---|
165 | return null;
|
---|
166 | }
|
---|
167 |
|
---|
168 | public ArrayList getLanguages() {
|
---|
169 | return children();
|
---|
170 | }
|
---|
171 |
|
---|
172 | /** Method to return a list of the known language codes.
|
---|
173 | * @return an ArrayList containing the series of known language codes as per the languages.dat file
|
---|
174 | */
|
---|
175 | public ArrayList getLanguageCodes() {
|
---|
176 | return new ArrayList(known_languages.keySet());
|
---|
177 | }
|
---|
178 |
|
---|
179 | public String getLanguageName(String code) {
|
---|
180 | return (String) known_languages.get(code);
|
---|
181 | }
|
---|
182 |
|
---|
183 | /** Method to remove a certain language.
|
---|
184 | * @param language The <strong>Language</strong> to remove.
|
---|
185 | * @see org.greenstone.gatherer.Gatherer
|
---|
186 | * @see org.greenstone.gatherer.collection.CollectionManager
|
---|
187 | */
|
---|
188 | public void removeLanguage(Language language) {
|
---|
189 | remove(language);
|
---|
190 | if(default_language != null && default_language.equals(language)) {
|
---|
191 | default_language = null;
|
---|
192 | }
|
---|
193 | Gatherer.c_man.configurationChanged();
|
---|
194 | }
|
---|
195 |
|
---|
196 | /** Method to set the default language.
|
---|
197 | * @param language The <strong>Language</strong> to use as a default, or <i>null</i> for no default.
|
---|
198 | * @see org.greenstone.gatherer.Gatherer
|
---|
199 | * @see org.greenstone.gatherer.collection.CollectionManager
|
---|
200 | */
|
---|
201 | public void setDefault(Language language) {
|
---|
202 | if(language != null) {
|
---|
203 | if(default_language == null) {
|
---|
204 | // Create the default index element, and place immediately after indexes element.
|
---|
205 | Element default_language_element = root.getOwnerDocument().createElement(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT);
|
---|
206 | default_language = new Language(default_language_element);
|
---|
207 | Node target_node = CollectionConfiguration.findInsertionPoint(default_language_element);
|
---|
208 | if(target_node != null) {
|
---|
209 | root.getOwnerDocument().getDocumentElement().insertBefore(default_language_element, target_node);
|
---|
210 | }
|
---|
211 | else {
|
---|
212 | root.getOwnerDocument().getDocumentElement().appendChild(default_language_element);
|
---|
213 | }
|
---|
214 | }
|
---|
215 | default_language.setAssigned(true);
|
---|
216 | default_language.setCode(language.getCode());
|
---|
217 | }
|
---|
218 | else {
|
---|
219 | if(default_language != null) {
|
---|
220 | default_language.setAssigned(false);
|
---|
221 | }
|
---|
222 | }
|
---|
223 | Gatherer.c_man.configurationChanged();
|
---|
224 | }
|
---|
225 |
|
---|
226 | /** Overloaded to call get with both a key and an empty argument array.
|
---|
227 | * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle.
|
---|
228 | * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call.
|
---|
229 | */
|
---|
230 | private String get(String key) {
|
---|
231 | if(key.indexOf('.') == -1) {
|
---|
232 | key = "CDM.LanguageManager." + key;
|
---|
233 | }
|
---|
234 | return Gatherer.dictionary.get(key, (String[])null);
|
---|
235 | }
|
---|
236 |
|
---|
237 | /** This class represents the visual component of the Language Manager. */
|
---|
238 | private class LanguageControl
|
---|
239 | extends JPanel
|
---|
240 | implements Control {
|
---|
241 | /** The button to add a new language support. */
|
---|
242 | private JButton add_button = null;
|
---|
243 | /** The button to clear the current default language. */
|
---|
244 | private JButton clear_button = null;
|
---|
245 | /** The button to remove a supported language. */
|
---|
246 | private JButton remove_button = null;
|
---|
247 | /** The button to set the current language as the default one. */
|
---|
248 | private JButton set_button = null;
|
---|
249 | /** A combobox listing the available supported languages. */
|
---|
250 | private JComboBox selector_combobox = null;
|
---|
251 | /** A list of currently supported languages. */
|
---|
252 | private JList language_list = null;
|
---|
253 | /** A description of the language currently selected. */
|
---|
254 | private JTextArea description_textarea = null;
|
---|
255 | /** The text field showing the currently name of the default language. Non-editable. */
|
---|
256 | private JTextField default_language_field = null;
|
---|
257 | /** Constructor.
|
---|
258 | * @see org.greenstone.gatherer.cdm.LanguageManager.Control.AddListener
|
---|
259 | * @see org.greenstone.gatherer.cdm.LanguageManager.Control.ClearDefaultListener
|
---|
260 | * @see org.greenstone.gatherer.cdm.LanguageManager.Control.ListListener
|
---|
261 | * @see org.greenstone.gatherer.cdm.LanguageManager.Control.RemoveListener
|
---|
262 | * @see org.greenstone.gatherer.cdm.LanguageManager.Control.SelectorListener
|
---|
263 | * @see org.greenstone.gatherer.cdm.LanguageManager.Control.SetDefaultListener
|
---|
264 | * @see org.greenstone.gatherer.cdm.LanguageManager.Control.TranslateListener
|
---|
265 | */
|
---|
266 | public LanguageControl() {
|
---|
267 | super();
|
---|
268 | // Creation.
|
---|
269 | JPanel center_panel = new JPanel();
|
---|
270 |
|
---|
271 | JLabel title_label = new JLabel(get("Title"));
|
---|
272 | title_label.setHorizontalAlignment(JLabel.CENTER);
|
---|
273 | title_label.setOpaque(true);
|
---|
274 |
|
---|
275 | language_list = new JList(model);
|
---|
276 |
|
---|
277 | JPanel details_panel = new JPanel();
|
---|
278 |
|
---|
279 | JPanel default_panel = new JPanel();
|
---|
280 |
|
---|
281 | JLabel default_label = new JLabel(get("Default_Language"));
|
---|
282 | default_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
|
---|
283 | default_label.setPreferredSize(LABEL_SIZE);
|
---|
284 |
|
---|
285 | if(default_language == null) {
|
---|
286 | default_language_field = new JTextField();
|
---|
287 | }
|
---|
288 | else {
|
---|
289 | default_language_field = new JTextField(default_language.toString());
|
---|
290 | }
|
---|
291 | default_language_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
|
---|
292 | default_language_field.setEditable(false);
|
---|
293 |
|
---|
294 | JPanel control_panel = new JPanel();
|
---|
295 |
|
---|
296 | JLabel selector_label = new JLabel(get("Selector"));
|
---|
297 | selector_label.setPreferredSize(LABEL_SIZE);
|
---|
298 |
|
---|
299 | selector_combobox = new JComboBox(getLanguageCodes().toArray());
|
---|
300 | selector_combobox.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
|
---|
301 | selector_combobox.setRenderer(new LanguageListCellRenderer());
|
---|
302 |
|
---|
303 | JPanel button_panel = new JPanel();
|
---|
304 |
|
---|
305 | add_button = new JButton(get("Add"));
|
---|
306 | add_button.setMnemonic(KeyEvent.VK_A);
|
---|
307 |
|
---|
308 | remove_button = new JButton(get("Remove"));
|
---|
309 | remove_button.setMnemonic(KeyEvent.VK_R);
|
---|
310 | remove_button.setEnabled(false);
|
---|
311 |
|
---|
312 | clear_button = new JButton(get("Clear_Default"));
|
---|
313 | clear_button.setMnemonic(KeyEvent.VK_C);
|
---|
314 | clear_button.setEnabled(false);
|
---|
315 |
|
---|
316 | set_button = new JButton(get("Set_Default"));
|
---|
317 | set_button.setMnemonic(KeyEvent.VK_S);
|
---|
318 | set_button.setEnabled(false);
|
---|
319 |
|
---|
320 | // Set up and connect listeners.
|
---|
321 | add_button.addActionListener(new AddListener());
|
---|
322 | clear_button.addActionListener(new ClearDefaultListener());
|
---|
323 | remove_button.addActionListener(new RemoveListener());
|
---|
324 | selector_combobox.addActionListener(new SelectorListener());
|
---|
325 | set_button.addActionListener(new SetDefaultListener());
|
---|
326 | language_list.addListSelectionListener(new ListListener());
|
---|
327 | // Layout components.
|
---|
328 | default_panel.setBorder(BorderFactory.createRaisedBevelBorder());
|
---|
329 | default_panel.setLayout(new BorderLayout());
|
---|
330 | default_panel.add(default_label, BorderLayout.WEST);
|
---|
331 | default_panel.add(default_language_field, BorderLayout.CENTER);
|
---|
332 |
|
---|
333 | control_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
|
---|
334 | control_panel.setLayout(new BorderLayout());
|
---|
335 | control_panel.add(selector_label, BorderLayout.WEST);
|
---|
336 | control_panel.add(selector_combobox, BorderLayout.CENTER);
|
---|
337 |
|
---|
338 | details_panel.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
|
---|
339 | details_panel.setLayout(new BorderLayout());
|
---|
340 | details_panel.add(default_panel, BorderLayout.CENTER);
|
---|
341 | details_panel.add(control_panel, BorderLayout.SOUTH);
|
---|
342 |
|
---|
343 | center_panel.setLayout(new BorderLayout());
|
---|
344 | center_panel.add(title_label, BorderLayout.NORTH);
|
---|
345 | center_panel.add(new JScrollPane(language_list), BorderLayout.CENTER);
|
---|
346 | center_panel.add(details_panel, BorderLayout.SOUTH);
|
---|
347 |
|
---|
348 | button_panel.setLayout(new GridLayout(2,2,5,5));
|
---|
349 | button_panel.add(add_button);
|
---|
350 | button_panel.add(remove_button);
|
---|
351 | button_panel.add(clear_button);
|
---|
352 | button_panel.add(set_button);
|
---|
353 |
|
---|
354 | setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
---|
355 | setLayout(new BorderLayout());
|
---|
356 | add(center_panel, BorderLayout.CENTER);
|
---|
357 | add(button_panel, BorderLayout.SOUTH);
|
---|
358 | }
|
---|
359 | /** Destructor. */
|
---|
360 | public void destroy() {
|
---|
361 | }
|
---|
362 |
|
---|
363 | public void gainFocus() {
|
---|
364 | }
|
---|
365 |
|
---|
366 | public void loseFocus() {
|
---|
367 | }
|
---|
368 |
|
---|
369 | /** 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. */
|
---|
370 | private class AddListener
|
---|
371 | implements ActionListener {
|
---|
372 | /** Add a new language support.
|
---|
373 | * @param event an ActionEvent
|
---|
374 | * @see org.greenstone.gatherer.cdm.Language
|
---|
375 | */
|
---|
376 | public void actionPerformed(ActionEvent event) {
|
---|
377 | String language_code = (String) selector_combobox.getSelectedItem();
|
---|
378 | if(language_code != null) {
|
---|
379 | addLanguage(new Language(language_code));
|
---|
380 | }
|
---|
381 | add_button.setEnabled(false);
|
---|
382 | }
|
---|
383 | }
|
---|
384 |
|
---|
385 | /** Listens for actions apon the 'clear default' button in the LanguageManager controls, and if detected calls the setDefault method of the manager with <i>null</i>. */
|
---|
386 | private class ClearDefaultListener
|
---|
387 | implements ActionListener {
|
---|
388 | /** Clear the default index.
|
---|
389 | * @param event An <strong>ActionEvent</strong>.
|
---|
390 | */
|
---|
391 | public void actionPerformed(ActionEvent event) {
|
---|
392 | setDefault(null);
|
---|
393 | clear_button.setEnabled(false);
|
---|
394 | default_language_field.setText("");
|
---|
395 | }
|
---|
396 | }
|
---|
397 |
|
---|
398 | /** 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. */
|
---|
399 | private class RemoveListener
|
---|
400 | implements ActionListener {
|
---|
401 | /** Remove the currently selected language, if any.
|
---|
402 | * @param event An <strong>ActionEvent</strong>.
|
---|
403 | * @see org.greenstone.gatherer.cdm.Language
|
---|
404 | */
|
---|
405 | public void actionPerformed(ActionEvent event) {
|
---|
406 | Language delete_me = (Language)language_list.getSelectedValue();
|
---|
407 | if(delete_me != null) {
|
---|
408 | removeLanguage(delete_me);
|
---|
409 | if(default_language != null && default_language.equals(delete_me)) {
|
---|
410 | setDefault(null);
|
---|
411 | clear_button.setEnabled(false);
|
---|
412 | default_language_field.setText("");
|
---|
413 | }
|
---|
414 | }
|
---|
415 | remove_button.setEnabled(false);
|
---|
416 | }
|
---|
417 | }
|
---|
418 |
|
---|
419 | /** Listens for selections within the combobox on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
|
---|
420 | private class SelectorListener
|
---|
421 | implements ActionListener {
|
---|
422 | /** Enable or disable controls depeding on selection.
|
---|
423 | * @param event An <strong>ActionEvent</strong>.
|
---|
424 | */
|
---|
425 | public void actionPerformed(ActionEvent event) {
|
---|
426 | if(selector_combobox.getSelectedItem() != null) {
|
---|
427 | add_button.setEnabled(true);
|
---|
428 | }
|
---|
429 | else {
|
---|
430 | add_button.setEnabled(false);
|
---|
431 | }
|
---|
432 | }
|
---|
433 | }
|
---|
434 |
|
---|
435 | /** 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. */
|
---|
436 | private class SetDefaultListener
|
---|
437 | implements ActionListener {
|
---|
438 | /** Set the default index to the one currently selected, if any.
|
---|
439 | * @param event An <strong>ActionEvent</strong>.
|
---|
440 | * @see org.greenstone.gatherer.cdm.Language
|
---|
441 | */
|
---|
442 | public void actionPerformed(ActionEvent event) {
|
---|
443 | if(!language_list.isSelectionEmpty()) {
|
---|
444 | setDefault((Language)language_list.getSelectedValue());
|
---|
445 | clear_button.setEnabled(true);
|
---|
446 | default_language_field.setText(default_language.toString());
|
---|
447 | }
|
---|
448 | }
|
---|
449 | }
|
---|
450 |
|
---|
451 | /** Listens for selections within the list on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
|
---|
452 | private class ListListener
|
---|
453 | implements ListSelectionListener {
|
---|
454 | /** Enable or disable controls depending on the current list selection.
|
---|
455 | * @param event A <strong>ListSelectionEvent</strong>.
|
---|
456 | */
|
---|
457 | public void valueChanged(ListSelectionEvent event) {
|
---|
458 | if(language_list.isSelectionEmpty()) {
|
---|
459 | remove_button.setEnabled(false);
|
---|
460 | set_button.setEnabled(false);
|
---|
461 | }
|
---|
462 | else {
|
---|
463 | remove_button.setEnabled(true);
|
---|
464 | set_button.setEnabled(true);
|
---|
465 | }
|
---|
466 | }
|
---|
467 | }
|
---|
468 | }
|
---|
469 | }
|
---|
470 |
|
---|
471 |
|
---|
472 |
|
---|
473 |
|
---|
474 |
|
---|
475 |
|
---|
476 |
|
---|