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 JCheckBox showSplashScreen = new JCheckBox(tr("Show splash screen at startup")); 058 private JCheckBox showID = new JCheckBox(tr("Show object ID in selection lists")); 059 private JCheckBox showLocalizedName = new JCheckBox(tr("Show localized name in selection lists")); 060 private JCheckBox modeless = new JCheckBox(tr("Modeless working (Potlatch style)")); 061 private JCheckBox dynamicButtons = new JCheckBox(tr("Dynamic buttons in side menus")); 062 private JCheckBox isoDates = new JCheckBox(tr("Display ISO dates")); 063 private 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}