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