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

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

these managers now implement buildTypeChanged()

  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 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();
310 Dictionary.registerText(selected_languages_list_label, "CDM.LanguageManager.Assigned_Languages");
311 selected_languages_list = new JList(model);
312 selected_languages_list.setCellRenderer(new MyLanguageListCellRenderer());
313 selected_languages_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
314 selected_languages_list.setVisibleRowCount(5);
315 JPanel details_panel = new JPanel();
316
317 JPanel control_panel = new JPanel();
318 JLabel selector_label = new JLabel();
319 Dictionary.registerText(selector_label, "CDM.LanguageManager.Selector");
320
321 language_combobox = new JComboBox(getLanguageCodes().toArray());
322 language_combobox.setPreferredSize(COMPONENT_SIZE);
323 language_combobox.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
324 language_combobox.setRenderer(new LanguageListCellRenderer());
325 Dictionary.registerTooltip(language_combobox, "CDM.LanguageManager.Selector_Tooltip");
326
327 JPanel movement_pane = new JPanel();
328 move_up_button = new GLIButton("", JarTools.getImage("arrow-up.gif"));
329 move_up_button.setEnabled(false);
330 move_up_button.setMnemonic(KeyEvent.VK_U);
331 Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
332
333 move_down_button = new GLIButton("", JarTools.getImage("arrow-down.gif"));
334 move_down_button.setEnabled(false);
335 move_down_button.setMnemonic(KeyEvent.VK_D);
336 Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
337
338 set_default_button = new GLIButton();
339 set_default_button.setEnabled(false);
340 set_default_button.setMnemonic(KeyEvent.VK_S);
341 Dictionary.registerBoth(set_default_button, "CDM.LanguageManager.Set_Default", "CDM.LanguageManager.Set_Default_Tooltip");
342
343 JPanel button_panel = new JPanel();
344
345 add_button = new GLIButton();
346 add_button.setMnemonic(KeyEvent.VK_A);
347 Dictionary.registerBoth(add_button, "CDM.LanguageManager.Add", "CDM.LanguageManager.Add_Tooltip");
348 if (getLanguage((String)language_combobox.getItemAt(0))==null) {
349 add_button.setEnabled(true);
350 } else {
351 add_button.setEnabled(false);
352 }
353 remove_button = new GLIButton();
354 remove_button.setMnemonic(KeyEvent.VK_R);
355 remove_button.setEnabled(false);
356 Dictionary.registerBoth(remove_button, "CDM.LanguageManager.Remove", "CDM.LanguageManager.Remove_Tooltip");
357
358 // Set up and connect listeners.
359 add_button.addActionListener(new AddListener());
360 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
361 move_down_button.addActionListener(new MoveListener(false));
362 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
363 move_up_button.addActionListener(new MoveListener(true));
364 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
365 remove_button.addActionListener(new RemoveListener());
366 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
367 language_combobox.addActionListener(new SelectorListener());
368 set_default_button.addActionListener(new SetDefaultListener());
369 set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
370 selected_languages_list.addListSelectionListener(new ListListener());
371
372 // Layout components
373 movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
374 movement_pane.setLayout(new GridLayout(3,1));
375 movement_pane.add(move_up_button);
376 movement_pane.add(move_down_button);
377 movement_pane.add(set_default_button);
378
379 control_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
380 control_panel.setLayout(new BorderLayout());
381 control_panel.add(selector_label, BorderLayout.WEST);
382 control_panel.add(language_combobox, BorderLayout.CENTER);
383
384 center_panel.setLayout(new BorderLayout());
385 center_panel.add(selected_languages_list_label, BorderLayout.NORTH);
386 center_panel.add(new JScrollPane(selected_languages_list), BorderLayout.CENTER);
387 center_panel.add(movement_pane, BorderLayout.EAST);
388 center_panel.add(control_panel, BorderLayout.SOUTH);
389
390 button_panel.setLayout(new GridLayout(1,2));
391 button_panel.add(add_button);
392 button_panel.add(remove_button);
393// button_panel.add(set_button);
394// button_panel.add(clear_button);
395
396 //when we go to a multi list, remove inner_panel and empty_panel
397 JPanel empty_panel = new JPanel();
398 JPanel inner_panel = new JPanel();
399
400 inner_panel.setLayout(new BorderLayout());
401 inner_panel.add(center_panel, BorderLayout.CENTER);
402 inner_panel.add(button_panel, BorderLayout.SOUTH);
403 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
404 setLayout(new BorderLayout());
405 //add(center_panel, BorderLayout.CENTER);
406 //add(button_panel, BorderLayout.SOUTH);
407 add(inner_panel, BorderLayout.NORTH);
408 add(empty_panel, BorderLayout.CENTER);
409 }
410
411 /** Destructor. */
412 public void destroy() {
413 }
414
415 public void gainFocus() {
416 }
417
418 public void loseFocus() {
419 }
420
421 /** 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. */
422 private class AddListener
423 implements ActionListener {
424 /** Add a new language support.
425 * @param event an ActionEvent
426 * @see org.greenstone.gatherer.cdm.Language
427 */
428 public void actionPerformed(ActionEvent event) {
429 String language_code = (String) language_combobox.getSelectedItem();
430 if(language_code != null) {
431 addLanguage(new Language(language_code));
432 }
433 // add some collectionmeta
434 String lang_name = getLanguageName(language_code);
435 CollectionMeta metadatum = new CollectionMeta("." + language_code);
436 metadatum.setValue(lang_name);
437 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
438
439 add_button.setEnabled(false);
440 }
441 }
442
443 /** 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. */
444 private class RemoveListener
445 implements ActionListener {
446 /** Remove the currently selected language, if any.
447 * @param event An <strong>ActionEvent</strong>.
448 * @see org.greenstone.gatherer.cdm.Language
449 */
450 public void actionPerformed(ActionEvent event) {
451 Language delete_me = (Language)selected_languages_list.getSelectedValue();
452 if(delete_me != null) {
453 // Remove any current metadata for this language
454 CollectionDesignManager.collectionmeta_manager.removeMetadata("." + delete_me.getCode());
455 removeLanguage(delete_me);
456 if(default_language != null && default_language.equals(delete_me)) {
457 setDefault(null);
458 //clear_button.setEnabled(false);
459 //default_language_field.setText("");
460 }
461 }
462 remove_button.setEnabled(false);
463 }
464 }
465
466 /** Listens for selections within the combobox on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
467 private class SelectorListener
468 implements ActionListener {
469 /** Enable or disable controls depeding on selection.
470 * @param event An <strong>ActionEvent</strong>.
471 */
472 public void actionPerformed(ActionEvent event) {
473 String language_code = (String) language_combobox.getSelectedItem();
474 if(language_code != null && getLanguage(language_code) == null) {
475 add_button.setEnabled(true);
476 }
477 else {
478 add_button.setEnabled(false);
479 }
480 }
481 }
482
483 /** 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. */
484 private class SetDefaultListener
485 implements ActionListener {
486 /** Set the default index to the one currently selected, if any.
487 * @param event An <strong>ActionEvent</strong>.
488 * @see org.greenstone.gatherer.cdm.Language
489 */
490 public void actionPerformed(ActionEvent event) {
491 Language selected_language = (Language) selected_languages_list.getSelectedValue();
492 if(selected_language != null) {
493 setDefault(selected_language);
494 //clear_button.setEnabled(true);
495 // This should cause a repaint of just the desired row
496 selected_languages_list.setSelectedValue(selected_language, true);
497 }
498 set_default_button.setEnabled(false);
499 }
500 }
501
502 private class MoveListener
503 implements ActionListener
504 {
505 private boolean move_up;
506
507 public MoveListener(boolean move_up)
508 {
509 this.move_up = move_up;
510 }
511
512 public void actionPerformed(ActionEvent event)
513 {
514 // Retrieve the selected language
515 Language language = (Language) selected_languages_list.getSelectedValue();
516 if (language != null) {
517 int new_position = moveLanguage(language, move_up);
518 // Ensure the language that moved is still selected
519 selected_languages_list.setSelectedIndex(new_position);
520 }
521 }
522 }
523
524
525 /** Listens for selections within the list on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */
526 private class ListListener
527 implements ListSelectionListener {
528 /** Enable or disable controls depending on the current list selection.
529 * @param event A <strong>ListSelectionEvent</strong>.
530 */
531 public void valueChanged(ListSelectionEvent event) {
532 if (event.getValueIsAdjusting()) {
533 return;
534 }
535 if(selected_languages_list.isSelectionEmpty()) {
536 remove_button.setEnabled(false);
537 set_default_button.setEnabled(false);
538 move_down_button.setEnabled(false);
539 move_up_button.setEnabled(false);
540 return;
541 }
542
543 int i = selected_languages_list.getSelectedIndex();
544 int size = selected_languages_list.getModel().getSize();
545 Language selected_lang = (Language)selected_languages_list.getSelectedValue();
546 remove_button.setEnabled(true);
547 set_default_button.setEnabled(default_language == null || !default_language.equals(selected_lang));
548
549 if (i > 0) {
550 move_up_button.setEnabled(true);
551 }
552 else {
553 move_up_button.setEnabled(false);
554 }
555 if (i < size-1){
556 move_down_button.setEnabled(true);
557 }
558 else {
559 move_down_button.setEnabled(false);
560 }
561 }
562 }
563
564 private class MyLanguageListCellRenderer
565 extends DefaultListCellRenderer
566 {
567 /** Return a component that has been configured to display the specified value. */
568 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
569 JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
570 if (default_language != null && default_language.equals(value)) {
571 component.setText(component.getText() + " [" + Dictionary.get("CDM.LanguageManager.Default_Language")+"]");
572 }
573 return component;
574 }
575 }
576 }
577}
Note: See TracBrowser for help on using the repository browser.