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.awt.GridBagLayout;
008import java.text.DateFormat;
009import java.util.Date;
010
011import javax.swing.BorderFactory;
012import javax.swing.Box;
013import javax.swing.DefaultListCellRenderer;
014import javax.swing.JCheckBox;
015import javax.swing.JLabel;
016import javax.swing.JList;
017import javax.swing.JPanel;
018import javax.swing.JScrollPane;
019import javax.swing.ListCellRenderer;
020import javax.swing.LookAndFeel;
021import javax.swing.UIManager;
022import javax.swing.UIManager.LookAndFeelInfo;
023
024import org.openstreetmap.josm.Main;
025import org.openstreetmap.josm.actions.ExpertToggleAction;
026import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
027import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
028import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
029import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
030import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
031import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
032import org.openstreetmap.josm.gui.widgets.JosmComboBox;
033import org.openstreetmap.josm.tools.GBC;
034import org.openstreetmap.josm.tools.date.DateUtils;
035
036/**
037 * Look-and-feel preferences.
038 */
039public class LafPreference implements SubPreferenceSetting {
040
041    /**
042     * Factory used to create a new {@code LafPreference}.
043     */
044    public static class Factory implements PreferenceSettingFactory {
045        @Override
046        public PreferenceSetting createPreferenceSetting() {
047            return new LafPreference();
048        }
049    }
050
051    /**
052     * ComboBox with all look and feels.
053     */
054    private JosmComboBox<LookAndFeelInfo> lafCombo;
055    JPanel panel;
056    private JCheckBox showSplashScreen = new JCheckBox(tr("Show splash screen at startup"));
057    private JCheckBox showID = new JCheckBox(tr("Show object ID in selection lists"));
058    private JCheckBox showLocalizedName = new JCheckBox(tr("Show localized name in selection lists"));
059    private JCheckBox modeless = new JCheckBox(tr("Modeless working (Potlatch style)"));
060    private JCheckBox dynamicButtons = new JCheckBox(tr("Dynamic buttons in side menus"));
061    private JCheckBox isoDates = new JCheckBox(tr("Display ISO dates"));
062
063    @Override
064    public void addGui(PreferenceTabbedPane gui) {
065        lafCombo = new JosmComboBox<>(UIManager.getInstalledLookAndFeels());
066
067        // let's try to load additional LookAndFeels and put them into the list
068        if (Main.isPlatformOsx()) {
069            try {
070                Class<?> Cquaqua = Class.forName("ch.randelshofer.quaqua.QuaquaLookAndFeel");
071                Object Oquaqua = Cquaqua.getConstructor((Class[])null).newInstance((Object[])null);
072                // no exception? Then Go!
073                lafCombo.addItem(
074                        new UIManager.LookAndFeelInfo(((LookAndFeel)Oquaqua).getName(), "ch.randelshofer.quaqua.QuaquaLookAndFeel")
075                );
076            } catch (Exception ex) {
077                // just debug, Quaqua may not even be installed...
078                Main.debug(ex.getMessage());
079            }
080        }
081
082        String laf = Main.pref.get("laf", Main.platform.getDefaultStyle());
083        for (int i = 0; i < lafCombo.getItemCount(); ++i) {
084            if (lafCombo.getItemAt(i).getClassName().equals(laf)) {
085                lafCombo.setSelectedIndex(i);
086                break;
087            }
088        }
089
090        lafCombo.setRenderer(new ListCellRenderer<LookAndFeelInfo>(){
091            final DefaultListCellRenderer def = new DefaultListCellRenderer();
092            @Override
093            public Component getListCellRendererComponent(JList<? extends LookAndFeelInfo> list, LookAndFeelInfo value,
094                    int index, boolean isSelected, boolean cellHasFocus) {
095                return def.getListCellRendererComponent(list, value.getName(), index, isSelected, cellHasFocus);
096            }
097        });
098
099        panel = new JPanel(new GridBagLayout());
100        panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
101
102        // Show splash screen on startup
103        showSplashScreen.setToolTipText(tr("Show splash screen at startup"));
104        showSplashScreen.setSelected(Main.pref.getBoolean("draw.splashscreen", true));
105        panel.add(showSplashScreen, GBC.eop().insets(20, 0, 0, 0));
106
107        // Show ID in selection
108        showID.setToolTipText(tr("Show object ID in selection lists"));
109        showID.setSelected(Main.pref.getBoolean("osm-primitives.showid", false));
110
111        // Show localized names
112        showLocalizedName.setToolTipText(tr("Show localized name in selection lists, if available"));
113        showLocalizedName.setSelected(Main.pref.getBoolean("osm-primitives.localize-name", true));
114        ExpertToggleAction.addVisibilitySwitcher(showLocalizedName);
115
116        modeless.setToolTipText(tr("Do not require to switch modes (potlatch style workflow)"));
117        modeless.setSelected(Main.pref.getBoolean("modeless", false));
118        ExpertToggleAction.addVisibilitySwitcher(modeless);
119
120        panel.add(showID, GBC.eop().insets(20, 0, 0, 0));
121        panel.add(showLocalizedName, GBC.eop().insets(20, 0, 0, 0));
122        panel.add(modeless, GBC.eop().insets(20, 0, 0, 0));
123
124        dynamicButtons.setToolTipText(tr("Display buttons in right side menus only when mouse is inside the element"));
125        dynamicButtons.setSelected(ToggleDialog.PROP_DYNAMIC_BUTTONS.get());
126        panel.add(dynamicButtons, GBC.eop().insets(20, 0, 0, 0));
127
128        Date today = new Date();
129        isoDates.setToolTipText(tr("Format dates according to {0}. Today''s date will be displayed as {1} instead of {2}",
130                tr("ISO 8601"),
131                DateUtils.newIsoDateFormat().format(today),
132                DateFormat.getDateInstance(DateFormat.SHORT).format(today)));
133        isoDates.setSelected(DateUtils.PROP_ISO_DATES.get());
134        panel.add(isoDates, GBC.eop().insets(20, 0, 0, 0));
135
136        panel.add(Box.createVerticalGlue(), GBC.eol().insets(0, 20, 0, 0));
137
138        panel.add(new JLabel(tr("Look and Feel")), GBC.std().insets(20, 0, 0, 0));
139        panel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
140        panel.add(lafCombo, GBC.eol().fill(GBC.HORIZONTAL));
141
142        JScrollPane scrollpane = new JScrollPane(panel);
143        scrollpane.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
144        gui.getDisplayPreference().addSubTab(this, tr("Look and Feel"), scrollpane);
145    }
146
147    @Override
148    public boolean ok() {
149        boolean mod = false;
150        Main.pref.put("draw.splashscreen", showSplashScreen.isSelected());
151        Main.pref.put("osm-primitives.showid", showID.isSelected());
152        Main.pref.put("osm-primitives.localize-name", showLocalizedName.isSelected());
153        Main.pref.put("modeless", modeless.isSelected());
154        Main.pref.put(ToggleDialog.PROP_DYNAMIC_BUTTONS.getKey(), dynamicButtons.isSelected());
155        Main.pref.put(DateUtils.PROP_ISO_DATES.getKey(), isoDates.isSelected());
156        mod |= Main.pref.put("laf", ((LookAndFeelInfo)lafCombo.getSelectedItem()).getClassName());
157        return mod;
158    }
159
160    @Override
161    public boolean isExpert() {
162        return false;
163    }
164
165    @Override
166    public TabPreferenceSetting getTabPreferenceSetting(final PreferenceTabbedPane gui) {
167        return gui.getDisplayPreference();
168    }
169}