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

Last change on this file since 11130 was 10237, checked in by mdewsnip, 19 years ago

New code for "incremental" building, by Matthew Whyte.

I've only had time to look at this briefly; I've fixed a few obvious problems but I imagine this will be pretty flaky for a while.

  • Property svn:keywords set to Author Date Id Revision
File size: 21.5 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 private int moveLanguage(Language lang, boolean move_up)
193 {
194 // Determine the current position of the language
195 int position = indexOf(lang);
196 int new_position;
197
198 // Attempt to move the language up
199 if (move_up) {
200 // Check it's not already at the top
201 if (position == 0) {
202 return position;
203 }
204
205 // This automatically removes the language first, as an Element can only exist once in a particular document
206 new_position = position - 1;
207 addBefore(lang, (Language) getElementAt(new_position));
208 }
209
210 // Attempt to move the language down
211 else {
212 // Check it's not already at the bottom
213 if (position == (getSize()) - 1) {
214 return position;
215 }
216
217 // This automatically removes the language first, as an Element can only exist once in a particular document
218 new_position = position + 1;
219 addAfter(lang, (Language) getElementAt(new_position));
220 }
221
222 // Schedule the collection for saving
223 Gatherer.c_man.configurationChanged();
224 return new_position;
225 }
226
227 /** Method to remove a certain language.
228 * @param language The <strong>Language</strong> to remove.
229 * @see org.greenstone.gatherer.Gatherer
230 * @see org.greenstone.gatherer.collection.CollectionManager
231 */
232 private void removeLanguage(Language language) {
233 remove(language);
234 if(default_language != null && default_language.equals(language)) {
235 default_language = null;
236 }
237 Gatherer.c_man.configurationChanged();
238 }
239
240 /** Method to set the default language.
241 * @param language The <strong>Language</strong> to use as a default, or <i>null</i> for no default.
242 * @see org.greenstone.gatherer.Gatherer
243 * @see org.greenstone.gatherer.collection.CollectionManager
244 */
245 public void setDefault(Language language) {
246 if(language != null) {
247 if(default_language == null) {
248 // Create the default index element, and place immediately after indexes element.
249 Element default_language_element = root.getOwnerDocument().createElement(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT);
250 default_language = new Language(default_language_element);
251 Node target_node = CollectionConfiguration.findInsertionPoint(default_language_element);
252 if(target_node != null) {
253 root.getOwnerDocument().getDocumentElement().insertBefore(default_language_element, target_node);
254 }
255 else {
256 root.getOwnerDocument().getDocumentElement().appendChild(default_language_element);
257 }
258 }
259 default_language.setAssigned(true);
260 default_language.setCode(language.getCode());
261 }
262 else {
263 if(default_language != null) {
264 default_language.setAssigned(false);
265 }
266 }
267 Gatherer.c_man.configurationChanged();
268 }
269
270
271 /** This class represents the visual component of the Language Manager. */
272 private class LanguageControl
273 extends JPanel
274 implements Control {
275 /** The button to add a new language support. */
276 private JButton add_button = null;
277 /** The button to remove a supported language. */
278 private JButton remove_button = null;
279 /** button to move a language up in the list */
280 private JButton move_down_button;
281 /** button to move a language down in the list */
282 private JButton move_up_button;
283 /** The button to set the current language as the default one. */
284 private JButton set_default_button = null;
285 /** A combobox listing the available supported languages. */
286 private JComboBox language_combobox = null;
287 /** A list of currently supported languages. */
288 private JList selected_languages_list = null;
289 /** Constructor.
290 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.AddListener
291 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.ClearDefaultListener
292 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.ListListener
293 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.RemoveListener
294 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.SelectorListener
295 * @see org.greenstone.gatherer.cdm.LanguageManager.LanguageControl.SetDefaultListener
296 */
297 public LanguageControl() {
298 super();
299 // Creation.
300 JPanel center_panel = new JPanel();
301
302 JLabel selected_languages_list_label = new JLabel();
303 Dictionary.registerText(selected_languages_list_label, "CDM.LanguageManager.Assigned_Languages");
304 selected_languages_list = new JList(model);
305 selected_languages_list.setCellRenderer(new MyLanguageListCellRenderer());
306 selected_languages_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
307 selected_languages_list.setVisibleRowCount(5);
308 JPanel details_panel = new JPanel();
309
310 JPanel control_panel = new JPanel();
311 JLabel selector_label = new JLabel();
312 Dictionary.registerText(selector_label, "CDM.LanguageManager.Selector");
313
314 language_combobox = new JComboBox(getLanguageCodes().toArray());
315 language_combobox.setPreferredSize(COMPONENT_SIZE);
316 language_combobox.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
317 language_combobox.setRenderer(new LanguageListCellRenderer());
318 Dictionary.registerTooltip(language_combobox, "CDM.LanguageManager.Selector_Tooltip");
319
320 JPanel movement_pane = new JPanel();
321 move_up_button = new JButton("", JarTools.getImage("arrow-up.gif"));
322 move_up_button.setEnabled(false);
323 move_up_button.setMnemonic(KeyEvent.VK_U);
324 Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
325
326 move_down_button = new JButton("", JarTools.getImage("arrow-down.gif"));
327 move_down_button.setEnabled(false);
328 move_down_button.setMnemonic(KeyEvent.VK_D);
329 Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
330
331 set_default_button = new GLIButton();
332 set_default_button.setEnabled(false);
333 set_default_button.setMnemonic(KeyEvent.VK_S);
334 Dictionary.registerBoth(set_default_button, "CDM.LanguageManager.Set_Default", "CDM.LanguageManager.Set_Default_Tooltip");
335
336 JPanel button_panel = new JPanel();
337
338 add_button = new GLIButton();
339 add_button.setMnemonic(KeyEvent.VK_A);
340 Dictionary.registerBoth(add_button, "CDM.LanguageManager.Add", "CDM.LanguageManager.Add_Tooltip");
341 if (getLanguage((String)language_combobox.getItemAt(0))==null) {
342 add_button.setEnabled(true);
343 } else {
344 add_button.setEnabled(false);
345 }
346 remove_button = new GLIButton();
347 remove_button.setMnemonic(KeyEvent.VK_R);
348 remove_button.setEnabled(false);
349 Dictionary.registerBoth(remove_button, "CDM.LanguageManager.Remove", "CDM.LanguageManager.Remove_Tooltip");
350
351 // Set up and connect listeners.
352 add_button.addActionListener(new AddListener());
353 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
354 move_down_button.addActionListener(new MoveListener(false));
355 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
356 move_up_button.addActionListener(new MoveListener(true));
357 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
358 remove_button.addActionListener(new RemoveListener());
359 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
360 language_combobox.addActionListener(new SelectorListener());
361 set_default_button.addActionListener(new SetDefaultListener());
362 set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
363 selected_languages_list.addListSelectionListener(new ListListener());
364
365 // Layout components
366 movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
367 movement_pane.setLayout(new GridLayout(3,1));
368 movement_pane.add(move_up_button);
369 movement_pane.add(move_down_button);
370 movement_pane.add(set_default_button);
371
372 control_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
373 control_panel.setLayout(new BorderLayout());
374 control_panel.add(selector_label, BorderLayout.WEST);
375 control_panel.add(language_combobox, BorderLayout.CENTER);
376
377 center_panel.setLayout(new BorderLayout());
378 center_panel.add(selected_languages_list_label, BorderLayout.NORTH);
379 center_panel.add(new JScrollPane(selected_languages_list), BorderLayout.CENTER);
380 center_panel.add(movement_pane, BorderLayout.EAST);
381 center_panel.add(control_panel, BorderLayout.SOUTH);
382
383 button_panel.setLayout(new GridLayout(1,2));
384 button_panel.add(add_button);
385 button_panel.add(remove_button);
386// button_panel.add(set_button);
387// button_panel.add(clear_button);
388
389 //when we go to a multi list, remove inner_panel and empty_panel
390 JPanel empty_panel = new JPanel();
391 JPanel inner_panel = new JPanel();
392
393 inner_panel.setLayout(new BorderLayout());
394 inner_panel.add(center_panel, BorderLayout.CENTER);
395 inner_panel.add(button_panel, BorderLayout.SOUTH);
396 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
397 setLayout(new BorderLayout());
398 //add(center_panel, BorderLayout.CENTER);
399 //add(button_panel, BorderLayout.SOUTH);
400 add(inner_panel, BorderLayout.NORTH);
401 add(empty_panel, BorderLayout.CENTER);
402 }
403
404 /** Destructor. */
405 public void destroy() {
406 }
407
408 public void gainFocus() {
409 }
410
411 public void loseFocus() {
412 }
413
414 /** 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. */
415 private class AddListener
416 implements ActionListener {
417 /** Add a new language support.
418 * @param event an ActionEvent
419 * @see org.greenstone.gatherer.cdm.Language
420 */
421 public void actionPerformed(ActionEvent event) {
422 String language_code = (String) language_combobox.getSelectedItem();
423 if(language_code != null) {
424 addLanguage(new Language(language_code));
425 }
426 // add some collectionmeta
427 String lang_name = getLanguageName(language_code);
428 CollectionMeta metadatum = new CollectionMeta("." + language_code);
429 metadatum.setValue(lang_name);
430 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
431
432 add_button.setEnabled(false);
433 }
434 }
435
436 /** 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. */
437 private class RemoveListener
438 implements ActionListener {
439 /** Remove the currently selected language, if any.
440 * @param event An <strong>ActionEvent</strong>.
441 * @see org.greenstone.gatherer.cdm.Language
442 */
443 public void actionPerformed(ActionEvent event) {
444 Language delete_me = (Language)selected_languages_list.getSelectedValue();
445 if(delete_me != null) {
446 // Remove any current metadata for this language
447 CollectionDesignManager.collectionmeta_manager.removeMetadata("." + delete_me.getCode());
448 removeLanguage(delete_me);
449 if(default_language != null && default_language.equals(delete_me)) {
450 setDefault(null);
451 //clear_button.setEnabled(false);
452 //default_language_field.setText("");
453 }
454 }
455 remove_button.setEnabled(false);
456 }
457 }
458
459 /** Listens for selections within the combobox on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
460 private class SelectorListener
461 implements ActionListener {
462 /** Enable or disable controls depeding on selection.
463 * @param event An <strong>ActionEvent</strong>.
464 */
465 public void actionPerformed(ActionEvent event) {
466 String language_code = (String) language_combobox.getSelectedItem();
467 if(language_code != null && getLanguage(language_code) == null) {
468 add_button.setEnabled(true);
469 }
470 else {
471 add_button.setEnabled(false);
472 }
473 }
474 }
475
476 /** 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. */
477 private class SetDefaultListener
478 implements ActionListener {
479 /** Set the default index to the one currently selected, if any.
480 * @param event An <strong>ActionEvent</strong>.
481 * @see org.greenstone.gatherer.cdm.Language
482 */
483 public void actionPerformed(ActionEvent event) {
484 Language selected_language = (Language) selected_languages_list.getSelectedValue();
485 if(selected_language != null) {
486 setDefault(selected_language);
487 //clear_button.setEnabled(true);
488 // This should cause a repaint of just the desired row
489 selected_languages_list.setSelectedValue(selected_language, true);
490 }
491 set_default_button.setEnabled(false);
492 }
493 }
494
495 private class MoveListener
496 implements ActionListener
497 {
498 private boolean move_up;
499
500 public MoveListener(boolean move_up)
501 {
502 this.move_up = move_up;
503 }
504
505 public void actionPerformed(ActionEvent event)
506 {
507 // Retrieve the selected language
508 Language language = (Language) selected_languages_list.getSelectedValue();
509 if (language != null) {
510 int new_position = moveLanguage(language, move_up);
511 // Ensure the language that moved is still selected
512 selected_languages_list.setSelectedIndex(new_position);
513 }
514 }
515 }
516
517
518 /** Listens for selections within the list on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
519 private class ListListener
520 implements ListSelectionListener {
521 /** Enable or disable controls depending on the current list selection.
522 * @param event A <strong>ListSelectionEvent</strong>.
523 */
524 public void valueChanged(ListSelectionEvent event) {
525 if (event.getValueIsAdjusting()) {
526 return;
527 }
528 if(selected_languages_list.isSelectionEmpty()) {
529 remove_button.setEnabled(false);
530 set_default_button.setEnabled(false);
531 move_down_button.setEnabled(false);
532 move_up_button.setEnabled(false);
533 return;
534 }
535
536 int i = selected_languages_list.getSelectedIndex();
537 int size = selected_languages_list.getModel().getSize();
538 Language selected_lang = (Language)selected_languages_list.getSelectedValue();
539 remove_button.setEnabled(true);
540 set_default_button.setEnabled(default_language == null || !default_language.equals(selected_lang));
541
542 if (i > 0) {
543 move_up_button.setEnabled(true);
544 }
545 else {
546 move_up_button.setEnabled(false);
547 }
548 if (i < size-1){
549 move_down_button.setEnabled(true);
550 }
551 else {
552 move_down_button.setEnabled(false);
553 }
554 }
555 }
556
557 private class MyLanguageListCellRenderer
558 extends DefaultListCellRenderer
559 {
560 /** Return a component that has been configured to display the specified value. */
561 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
562 JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
563 if (default_language != null && default_language.equals(value)) {
564 component.setText(component.getText() + " [" + Dictionary.get("CDM.LanguageManager.Default_Language")+"]");
565 }
566 return component;
567 }
568 }
569 }
570}
Note: See TracBrowser for help on using the repository browser.