001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.preferences.display;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Component;
007import java.util.ArrayList;
008import java.util.Arrays;
009import java.util.List;
010import java.util.Locale;
011
012import javax.swing.Box;
013import javax.swing.DefaultComboBoxModel;
014import javax.swing.DefaultListCellRenderer;
015import javax.swing.JLabel;
016import javax.swing.JList;
017import javax.swing.JPanel;
018import javax.swing.ListCellRenderer;
019
020import org.openstreetmap.josm.Main;
021import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
022import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
023import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
024import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
025import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
026import org.openstreetmap.josm.gui.widgets.JosmComboBox;
027import org.openstreetmap.josm.tools.GBC;
028import org.openstreetmap.josm.tools.I18n;
029
030public class LanguagePreference implements SubPreferenceSetting {
031    public static class Factory implements PreferenceSettingFactory {
032        @Override
033        public PreferenceSetting createPreferenceSetting() {
034            return new LanguagePreference();
035        }
036    }
037
038    /** the combo box with the available locales */
039    private JosmComboBox langCombo;
040    /** the model for the combo box */
041    private LanguageComboBoxModel model;
042
043    @Override
044    public void addGui(final PreferenceTabbedPane gui) {
045        model = new LanguageComboBoxModel();
046        // Selecting the language BEFORE the JComboBox listens to model changes speed up initialization by ~35ms (see #7386)
047        // See http://stackoverflow.com/questions/3194958/fast-replacement-for-jcombobox-basiccomboboxui
048        model.selectLanguage(Main.pref.get("language"));
049        langCombo = new JosmComboBox(model);
050        langCombo.setRenderer(new LanguageCellRenderer(langCombo.getRenderer()));
051
052        LafPreference lafPreference = gui.getSetting(LafPreference.class);
053        final JPanel panel = lafPreference.panel;
054        panel.add(new JLabel(tr("Language")), GBC.std().insets(20, 0, 0, 0));
055        panel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
056        panel.add(langCombo, GBC.eol().fill(GBC.HORIZONTAL));
057        panel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH));
058
059        TabPreferenceSetting tabPref = lafPreference.getTabPreferenceSetting(gui);
060        tabPref.registerSubTab(this, tabPref.getSubTab(lafPreference));
061    }
062
063    @Override
064    public boolean ok() {
065        if(langCombo.getSelectedItem() == null)
066            return Main.pref.put("language", null);
067        else
068            return Main.pref.put("language",
069                    ((Locale)langCombo.getSelectedItem()).toString());
070    }
071
072    private static class LanguageComboBoxModel extends DefaultComboBoxModel {
073        private final List<Locale> data = new ArrayList<Locale>();
074
075        public LanguageComboBoxModel(){
076            data.add(0,null);
077            data.addAll(Arrays.asList(I18n.getAvailableTranslations()));
078        }
079
080        public void selectLanguage(String language) {
081            setSelectedItem(null);
082            if (language != null) {
083                for (Locale locale: data) {
084                    if (locale == null) {
085                        continue;
086                    }
087                    if (locale.toString().equals(language)) {
088                        setSelectedItem(locale);
089                        return;
090                    }
091                }
092            }
093        }
094
095        @Override
096        public Object getElementAt(int index) {
097            return data.get(index);
098        }
099
100        @Override
101        public int getSize() {
102            return data.size();
103        }
104    }
105
106    static private class LanguageCellRenderer extends DefaultListCellRenderer {
107        private ListCellRenderer dispatch;
108        public LanguageCellRenderer(ListCellRenderer dispatch) {
109            this.dispatch = dispatch;
110        }
111        @Override
112        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
113                boolean cellHasFocus) {
114            Locale l = (Locale) value;
115            return dispatch.getListCellRendererComponent(list,
116                    l == null ? tr("Default (Auto determined)") : l.getDisplayName(l),
117                            index, isSelected, cellHasFocus);
118        }
119    }
120
121    @Override
122    public boolean isExpert() {
123        return false;
124    }
125
126    @Override
127    public TabPreferenceSetting getTabPreferenceSetting(final PreferenceTabbedPane gui) {
128        return gui.getSetting(LafPreference.class).getTabPreferenceSetting(gui);
129    }
130}