Statistics
| Revision:

root / trunk / extensions / extI18n / src / org / gvsig / i18n / extension / preferences / I18nPreferencePage.java @ 34841

History | View | Annotate | Download (19 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Gobernment (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2008 {DiSiD Technologies}  {New extension for installation and update of text translations}
26
 */
27
package org.gvsig.i18n.extension.preferences;
28

    
29
import java.awt.Component;
30
import java.awt.Dimension;
31
import java.awt.Font;
32
import java.awt.GridBagConstraints;
33
import java.awt.GridBagLayout;
34
import java.awt.Insets;
35
import java.awt.event.ActionEvent;
36
import java.awt.event.ActionListener;
37
import java.io.File;
38
import java.util.ArrayList;
39
import java.util.HashSet;
40
import java.util.List;
41
import java.util.Locale;
42
import java.util.Set;
43

    
44
import javax.swing.Box;
45
import javax.swing.BoxLayout;
46
import javax.swing.ImageIcon;
47
import javax.swing.JFileChooser;
48
import javax.swing.JLabel;
49
import javax.swing.JOptionPane;
50
import javax.swing.JPanel;
51
import javax.swing.JScrollPane;
52
import javax.swing.JTable;
53
import javax.swing.JTextArea;
54
import javax.swing.ListSelectionModel;
55
import javax.swing.filechooser.FileFilter;
56
import javax.swing.table.TableColumn;
57

    
58
import org.gvsig.gui.beans.swing.JButton;
59
import org.gvsig.i18n.I18nException;
60
import org.gvsig.i18n.I18nManager;
61
import org.gvsig.i18n.Messages;
62
import org.gvsig.i18n.extension.preferences.table.LocaleTableModel;
63
import org.gvsig.i18n.extension.preferences.table.RadioButtonCellEditor;
64
import org.gvsig.i18n.extension.preferences.table.RadioButtonCellRenderer;
65
import org.gvsig.i18n.impl.I18nManagerImpl;
66

    
67
import com.iver.andami.preferences.AbstractPreferencePage;
68
import com.iver.andami.preferences.StoreException;
69

    
70
/**
71
 * Prefence page to manage gvSIG locales.
72
 * 
73
 * @author <a href="mailto:dcervera@disid.com">David Cervera</a>
74
 */
75
public class I18nPreferencePage extends AbstractPreferencePage implements
76
        ActionListener {
77

    
78
    private static final long serialVersionUID = 7164183052397200888L;
79

    
80
    private static final String COMMAND_UNINSTALL = "UNINSTALL";
81

    
82
    private static final String COMMAND_EXPORT = "EXPORT";
83

    
84
    private static final String COMMAND_EXPORT_NEW = "EXPORT_NEW";
85

    
86
    private static final String COMMAND_INSTALL = "INSTALL";
87

    
88
    private static final String EXPORT_JAR_FILE_EXTENSION = ".jar";
89

    
90
    private static final String EXPORT_ZIP_FILE_EXTENSION = ".zip";
91

    
92
    private ImageIcon icon;
93

    
94
    private I18nManager manager = I18nManagerImpl.getInstance();
95

    
96
    private JTable localesTable;
97

    
98
    private LocaleTableModel tableModel;
99

    
100
    private JFileChooser fileChooser;
101

    
102
    /**
103
     * Creates a new I18n preferences page.
104
     */
105
    public I18nPreferencePage() {
106
        setParentID("com.iver.core.preferences.general.GeneralPage");
107
        icon = new ImageIcon(this.getClass().getClassLoader().getResource(
108
                "images/babel.png"));
109

    
110
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
111

    
112
        add(getLocalesPanel());
113
        add(Box.createRigidArea(new Dimension(0, 5)));
114
        add(getActiveLocaleLabel());
115
        add(Box.createRigidArea(new Dimension(0, 5)));
116
        add(getButtonsPanel());
117
        add(Box.createRigidArea(new Dimension(0, 5)));
118
        add(getCollaborationLabel());
119
    }
120

    
121
    public String getID() {
122
        return getClass().getName();
123
    }
124

    
125
    public String getTitle() {
126
        return Messages.getText("idioma");
127
    }
128

    
129
    public ImageIcon getIcon() {
130
        return icon;
131
    }
132

    
133
    public JPanel getPanel() {
134
        return this;
135
    }
136

    
137
    public void setChangesApplied() {
138
        tableModel.setChangesApplied();
139
    }
140

    
141
    public boolean isValueChanged() {
142
        return tableModel.isValueChanged();
143
    }
144

    
145
    public void storeValues() throws StoreException {
146
        tableModel.saveSelectedLocale();
147
    }
148

    
149
    public void initializeDefaults() {
150
        tableModel.selectDefaultLocale();
151
    }
152

    
153
    public void initializeValues() {
154
        tableModel.selectPreviousLocale();
155
    }
156

    
157
    public void actionPerformed(ActionEvent event) {
158
        if (COMMAND_INSTALL.equals(event.getActionCommand())) {
159
            installLocale();
160
        }
161
        else if (COMMAND_EXPORT.equals(event.getActionCommand())) {
162
            exportLocaleForUpdate();
163
        }
164
        else if (COMMAND_EXPORT_NEW.equals(event.getActionCommand())) {
165
            exportLocaleForTranslation();
166
        }
167
        else if (COMMAND_UNINSTALL.equals(event.getActionCommand())) {
168
            uninstallSelectedLocale();
169
        }
170
    }
171

    
172
    /**
173
     * Installs a new Locale translation or updates an already existing one.
174
     */
175
    private void installLocale() {
176
        JFileChooser fileChooser = getJarFileChooser();
177

    
178
        int returnVal = fileChooser.showOpenDialog(this);
179

    
180
        if (returnVal == JFileChooser.APPROVE_OPTION) {
181
            File importFile = fileChooser.getSelectedFile();
182
            try {
183
                Locale[] installedLocales = manager.installLocales(importFile);
184
                if (installedLocales == null || installedLocales.length == 0) {
185
                    JOptionPane
186
                            .showMessageDialog(
187
                                    this,
188
                                    Messages
189
                                            .getText("I18nPreferencePage.idiomas_no_encontrados_para_instalar"),
190
                                    Messages
191
                                            .getText("I18nPreferencePage.error_instalar_idiomas"),
192
                                    JOptionPane.ERROR_MESSAGE);
193
                }
194
                else {
195
                    StringBuffer msg = new StringBuffer(Messages
196
                            .getText("I18nPreferencePage.idiomas_instalados"));
197

    
198
                    if (installedLocales.length>=3){
199
                            msg.append("\n");
200
                    }
201
                    for (int i = 0; i < installedLocales.length; i++) {
202
                        msg.append(manager.getDisplayName(installedLocales[i]));
203
                        if (i < installedLocales.length - 1) {
204
                                if((i+1)%3 == 0){
205
                                    msg.append(",\n");
206
                                } else {
207
                                        msg.append(", ");
208
                                }
209
                        }
210
                    }
211
                    msg.append("\n");
212
                    msg.append(Messages
213
                                    .getText("I18nPreferencePage.changes_will_be_applied_when_restarting_the_application"));
214
                    tableModel.reloadLocales();
215
                    JOptionPane
216
                            .showMessageDialog(
217
                                    this,
218
                                    msg.toString(),
219
                                    Messages
220
                                            .getText("I18nPreferencePage.instalar_idiomas"),
221
                                    JOptionPane.INFORMATION_MESSAGE);
222
                }
223
            } catch (I18nException ex) {
224
                ex.showError();
225
            }
226
        }
227
    }
228
    
229
    /**
230
     * Updates the translation of a locale
231
     */
232
    private void exportLocaleForUpdate() {
233
        Locale[] locales = getSelectedLocales();
234

    
235
        if (locales == null) {
236
            JOptionPane.showMessageDialog(this, Messages
237
                    .getText("I18nPreferencePage.seleccione_idioma"), Messages
238
                    .getText("I18nPreferencePage.error_actualizar_idioma"),
239
                    JOptionPane.ERROR_MESSAGE);
240
        }
241
        else {
242
            // Select the reference language
243
            LocaleItem[] items = getLocaleItemsForSelection(manager
244
                    .getInstalledLocales(), locales);
245
            LocaleItem selected = null;
246
            if (items != null && items.length > 0) {
247
                // Select by default the current locale, or the first one
248
                // if the current locale is one of the ones to be updated
249
                for (int i = 0; i < locales.length && selected == null; i++) {
250
                    if (locales[i].equals(manager.getCurrentLocale())) {
251
                        selected = items[0];
252
                    }
253
                }
254
                if (selected == null) {
255
                    selected = new LocaleItem(manager.getCurrentLocale(),
256
                            manager);
257
                }
258
                selected = (LocaleItem) JOptionPane
259
                        .showInputDialog(
260
                                this,
261
                                Messages
262
                                        .getText("I18nPreferencePage.seleccione_idioma_referencia"),
263
                                Messages
264
                                        .getText("I18nPreferencePage.exportar_idioma"),
265
                                JOptionPane.QUESTION_MESSAGE, null, items,
266
                                selected);
267

    
268
                if (selected == null) {
269
                    return;
270
                }
271
            }
272
            // Select the file to export to
273
            JFileChooser fileChooser = getJarFileChooser();
274
            fileChooser.setSelectedFile(new File(
275
                    getLocaleJarFileName(locales[0])));
276

    
277
            if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
278
                File saveFile = fileChooser.getSelectedFile();
279
                try {
280
                    Locale fileNameLocale = selected == null ? manager
281
                            .getCurrentLocale() : selected.getLocale();
282
                    manager.exportLocalesForUpdate(locales, fileNameLocale,
283
                            saveFile);
284
                    
285
                    JOptionPane
286
                            .showMessageDialog(
287
                                    this,
288
                                    Messages
289
                                            .getText("I18nPreferencePage.exportado_textos_idioma")
290
                                            + " "
291
                                            + saveFile,
292
                                    Messages
293
                                            .getText("I18nPreferencePage.exportar_idioma"),
294
                                    JOptionPane.INFORMATION_MESSAGE);
295
                } catch (I18nException ex) {
296
                    ex.showError();
297
                }
298
            }
299
        }
300
    }
301

    
302
    /**
303
     * Prepares a locale for translation.
304
     */
305
    private void exportLocaleForTranslation() {
306
        // Get the selected locale as the ones for reference
307
        Locale[] refLocales = getSelectedLocales();
308

    
309
        if (refLocales == null) {
310
            JOptionPane
311
                    .showMessageDialog(
312
                            this,
313
                            Messages
314
                                    .getText("I18nPreferencePage.seleccione_idioma_actualizar"),
315
                            Messages
316
                                    .getText("I18nPreferencePage.error_actualizar_idioma"),
317
                            JOptionPane.ERROR_MESSAGE);
318
        }
319
        else {
320

    
321
            // Select the locale to translate
322
            LocaleItem[] items = getLocaleItemsForSelection(Locale
323
                    .getAvailableLocales(), manager.getInstalledLocales());
324
            LocaleItem selected = (LocaleItem) JOptionPane
325
                    .showInputDialog(
326
                            this,
327
                            Messages
328
                                    .getText("I18nPreferencePage.seleccione_idioma_traducir"),
329
                            Messages
330
                                    .getText("I18nPreferencePage.exportar_idioma"),
331
                            JOptionPane.QUESTION_MESSAGE, null, items, items[0]);
332

    
333
            if (selected == null) {
334
                return;
335
            }
336

    
337
            // Select the file to export to
338
            JFileChooser fileChooser = getJarFileChooser();
339
            fileChooser.setSelectedFile(new File(getLocaleJarFileName(selected
340
                    .getLocale())));
341

    
342
            if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
343
                File saveFile = fileChooser.getSelectedFile();
344
                try {
345
                    manager.exportLocaleForTranslation(selected.getLocale(),
346
                            refLocales, saveFile);
347

    
348
                    JOptionPane
349
                            .showMessageDialog(
350
                                    this,
351
                                    Messages
352
                                            .getText("I18nPreferencePage.idioma_preparado_traducir")
353
                                            + manager.getDisplayName(selected
354
                                                    .getLocale())
355
                                            + Messages
356
                                                    .getText("I18nPreferencePage.en_archivo")
357
                                            + saveFile,
358
                                    Messages
359
                                            .getText("I18nPreferencePage.exportar_idioma"),
360
                                    JOptionPane.INFORMATION_MESSAGE);
361
                } catch (I18nException ex) {
362
                    ex.showError();
363
                }
364
            }
365
        }
366

    
367
    }
368

    
369
    private LocaleItem[] getLocaleItemsForSelection(Locale[] locales,
370
            Locale[] exceptions) {
371
        List items = new ArrayList();
372
        Set exceptionsSet = new HashSet(exceptions.length);
373
        for (int i = 0; i < exceptions.length; i++) {
374
            exceptionsSet.add(exceptions[i]);
375
        }
376

    
377
        int j = 0;
378
        for (int i = 0; i < locales.length; i++) {
379
            // Only add locales not included in the exceptions list
380
            if (!exceptionsSet.contains(locales[i])) {
381
                items.add(new LocaleItem(locales[i], manager));
382
                j++;
383
            }
384
        }
385
        return (LocaleItem[]) items.toArray(new LocaleItem[items.size()]);
386
    }
387

    
388
    /**
389
     * Returns a name for the jar file to export a locale.
390
     */
391
    private String getLocaleJarFileName(Locale locale) {
392
        return manager.getDisplayName(locale, I18nManager.ENGLISH).replace(' ',
393
                '_').concat(EXPORT_ZIP_FILE_EXTENSION);
394
    }
395

    
396
    /**
397
     * Creates a new JFileChooser to import or export a locale jar file.
398
     */
399
    private JFileChooser getJarFileChooser() {
400
        if (fileChooser == null) {
401
            fileChooser = new JFileChooser();
402
            fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
403
            fileChooser.setMultiSelectionEnabled(false);
404
            fileChooser.setFileFilter(new FileFilter() {
405

    
406
                public boolean accept(File file) {
407
                    return (file.isDirectory()
408
                            || file.getName().endsWith(
409
                                    EXPORT_JAR_FILE_EXTENSION) || file
410
                            .getName().endsWith(EXPORT_ZIP_FILE_EXTENSION));
411
                }
412

    
413
                public String getDescription() {
414
                    return Messages.getText("I18nPreferencePage.archivos_jar");
415
                }
416

    
417
            });
418
        }
419
        return fileChooser;
420
    }
421

    
422
    /**
423
     * Removes some installed locales from gvSIG.
424
     */
425
    private void uninstallSelectedLocale() {
426
        Locale[] locales = getSelectedLocales();
427

    
428
        if (locales == null) {
429
            JOptionPane
430
                    .showMessageDialog(
431
                            this,
432
                            Messages
433
                                    .getText("I18nPreferencePage.seleccione_idioma_desinstalar"),
434
                            Messages
435
                                    .getText("I18nPreferencePage.error_desinstalar_idioma"),
436
                            JOptionPane.ERROR_MESSAGE);
437
            return;
438
        }
439
        
440
        for (int i = 0; i < locales.length; i++) {
441

    
442
            if (locales[i].equals(manager.getCurrentLocale())) {
443
                JOptionPane
444
                        .showMessageDialog(
445
                                this,
446
                                Messages
447
                                        .getText("I18nPreferencePage.idioma_actual_no_puede_desinstalar"),
448
                                Messages
449
                                        .getText("I18nPreferencePage.error_desinstalar_idioma"),
450
                                JOptionPane.ERROR_MESSAGE);
451
            } else {
452
                int option = JOptionPane
453
                        .showConfirmDialog(
454
                                this,
455
                                Messages
456
                                        .getText("I18nPreferencePage.seguro_desea_desinstalar_idioma")
457
                                        + " "
458
                                        + manager.getDisplayName(locales[i])
459
                                        + "?",
460
                                Messages
461
                                        .getText("I18nPreferencePage.confirmar_desinstalar_idioma"),
462
                                JOptionPane.YES_NO_OPTION);
463
                if (option == JOptionPane.YES_OPTION) {
464
                    try {
465
                        tableModel.removeLocale(locales[i]);
466
                    } catch (I18nException ex) {
467
                        ex.showError();
468
                    }
469
                }
470
            }
471
        }
472
    }
473

    
474
    /**
475
     * Returns the Locales selected in the table of available locales.
476
     */
477
    private Locale[] getSelectedLocales() {
478
        int[] rowIndexes = localesTable.getSelectedRows();
479
        if (rowIndexes != null && rowIndexes.length > 0) {
480
            Locale[] locales = new Locale[rowIndexes.length];
481
            for (int i = 0; i < locales.length; i++) {
482
                locales[i] = tableModel.getLocale(rowIndexes[i]);
483
            }
484
            return locales;
485
        }
486
        else {
487
            return null;
488
        }
489
    }
490

    
491
    /**
492
     * Creates the Panel with the table of Locales.
493
     */
494
    private Component getLocalesPanel() {
495
        tableModel = new LocaleTableModel(manager);
496
        localesTable = new JTable(tableModel);
497

    
498
        TableColumn activeColumn = localesTable.getColumnModel().getColumn(
499
                LocaleTableModel.COLUMN_ACTIVE);
500
        activeColumn.setCellEditor(new RadioButtonCellEditor());
501
        activeColumn.setCellRenderer(new RadioButtonCellRenderer());
502

    
503
        localesTable
504
                .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
505
        localesTable.getSelectionModel().setSelectionInterval(0, 0);
506
        JScrollPane scrollPane = new JScrollPane(localesTable);
507

    
508
        // Container panel
509
        JPanel localesPanel = new JPanel();
510
        localesPanel.setLayout(new BoxLayout(localesPanel, BoxLayout.Y_AXIS));
511
        localesPanel.add(scrollPane);
512
        localesPanel.setAlignmentX(CENTER_ALIGNMENT);
513
        localesPanel.setPreferredSize(new Dimension(236, 230));
514
        localesPanel.setMaximumSize(new Dimension(500, 230));
515

    
516
        return localesPanel;
517
    }
518

    
519
    /**
520
     * Creates the panel with the buttons to perform the related actions.
521
     */
522
    private Component getButtonsPanel() {
523
        JPanel buttonPanel = new JPanel(new GridBagLayout());
524
        GridBagConstraints constraints = new GridBagConstraints();
525
        constraints.fill = GridBagConstraints.NONE;
526
        constraints.anchor = GridBagConstraints.LINE_START;
527
        Insets btInsets = new Insets(2, 0, 2, 4);
528
        Insets lbInsets = new Insets(2, 2, 2, 0);
529

    
530
        /* ROW 0 */
531
        constraints.gridy = 0;
532

    
533
        constraints.gridx = 0;
534
        constraints.insets = btInsets;
535
        JButton newLocaleButton = new JButton(Messages
536
                .getText("I18nPreferencePage.Instalar"));
537
        newLocaleButton.setActionCommand(COMMAND_INSTALL);
538
        newLocaleButton.addActionListener(this);
539
        newLocaleButton.setToolTipText(Messages
540
                .getText("I18nPreferencePage.Instalar_idioma_tooltip"));
541
        buttonPanel.add(newLocaleButton, constraints);
542

    
543
        constraints.gridx = 1;
544
        constraints.insets = lbInsets;
545
        buttonPanel.add(new JLabel(Messages
546
                .getText("I18nPreferencePage.Instalar_idioma_tooltip")),
547
                constraints);
548

    
549
        /* ROW 1 */
550
        constraints.gridy = 1;
551

    
552
        constraints.gridx = 0;
553
        constraints.insets = btInsets;
554
        JButton removeLocaleButton = new JButton(Messages
555
                .getText("I18nPreferencePage.Desinstalar"));
556
        removeLocaleButton.setActionCommand(COMMAND_UNINSTALL);
557
        removeLocaleButton.addActionListener(this);
558
        removeLocaleButton.setToolTipText(Messages
559
                .getText("I18nPreferencePage.Desinstalar_idioma_tooltip"));
560
        buttonPanel.add(removeLocaleButton, constraints);
561

    
562
        constraints.gridx = 1;
563
        constraints.insets = lbInsets;
564
        buttonPanel.add(new JLabel(Messages
565
                .getText("I18nPreferencePage.Desinstalar_idioma_tooltip")),
566
                constraints);
567

    
568
        /* ROW 2 */
569
        constraints.gridy = 2;
570

    
571
        constraints.gridx = 0;
572
        constraints.insets = btInsets;
573
        JButton exportLocaleButton = new JButton(Messages
574
                .getText("I18nPreferencePage.exportar_actualizar"));
575
        exportLocaleButton.setActionCommand(COMMAND_EXPORT);
576
        exportLocaleButton.addActionListener(this);
577
        exportLocaleButton.setToolTipText(Messages
578
                .getText("I18nPreferencePage.exportar_actualizar_tooltip"));
579
        buttonPanel.add(exportLocaleButton, constraints);
580

    
581
        constraints.gridx = 1;
582
        constraints.insets = lbInsets;
583
        buttonPanel.add(new JLabel(Messages
584
                .getText("I18nPreferencePage.exportar_actualizar_tooltip")),
585
                constraints);
586

    
587
        /* ROW 3 */
588
        constraints.gridy = 3;
589

    
590
        constraints.gridx = 0;
591
        constraints.insets = btInsets;
592
        JButton exportNewLocaleButton = new JButton(Messages
593
                .getText("I18nPreferencePage.exportar_traducir"));
594
        exportNewLocaleButton.setActionCommand(COMMAND_EXPORT_NEW);
595
        exportNewLocaleButton.addActionListener(this);
596
        exportNewLocaleButton.setToolTipText(Messages
597
                .getText("I18nPreferencePage.exportar_traducir_tooltip"));
598
        buttonPanel.add(exportNewLocaleButton, constraints);
599

    
600
        constraints.gridx = 1;
601
        constraints.insets = lbInsets;
602
        buttonPanel.add(new JLabel(Messages
603
                .getText("I18nPreferencePage.exportar_traducir_tooltip")),
604
                constraints);
605

    
606
        buttonPanel.setAlignmentX(CENTER_ALIGNMENT);
607
        return buttonPanel;
608
    }
609

    
610
    /**
611
     * Creates the JLabel to show information about the preference page.
612
     */
613
    private Component getActiveLocaleLabel() {
614
        JTextArea textArea = new JTextArea(Messages
615
                .getText("I18nPreferencePage.ayuda"));
616
        textArea.setEditable(false);
617
        textArea.setAutoscrolls(true);
618
        textArea.setLineWrap(true);
619
        textArea.setWrapStyleWord(true);
620
        textArea.setFont(textArea.getFont().deriveFont(Font.BOLD));
621
        return textArea;
622
    }
623

    
624
    /**
625
     * Creates the JLabel to show information about gvSIG translation
626
     * collaboration.
627
     */
628
    private Component getCollaborationLabel() {
629
        JTextArea textArea = new JTextArea(Messages
630
                .getText("I18nPreferencePage.colaboracion"));
631
        textArea.setEditable(false);
632
        textArea.setAutoscrolls(true);
633
        textArea.setLineWrap(true);
634
        textArea.setWrapStyleWord(true);
635
        return textArea;
636
    }
637

    
638
    private class LocaleItem {
639
        private final Locale locale;
640
        private final I18nManager manager;
641

    
642
        public LocaleItem(Locale locale, I18nManager manager) {
643
            this.locale = locale;
644
            this.manager = manager;
645
        }
646

    
647
        public Locale getLocale() {
648
            return locale;
649
        }
650

    
651
        public String toString() {
652
            return manager.getDisplayName(locale);
653
        }
654

    
655
        public boolean equals(Object obj) {
656
            if (obj == null || !(obj instanceof LocaleItem)) {
657
                return false;
658
            }
659

    
660
            LocaleItem item = (LocaleItem) obj;
661
            return locale.equals(item.getLocale());
662
        }
663
    }
664
}