001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.plugin; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.FlowLayout; 007import java.awt.GridBagConstraints; 008import java.awt.GridBagLayout; 009import java.awt.Insets; 010import java.util.EnumMap; 011import java.util.Locale; 012import java.util.Map; 013 014import javax.swing.ButtonGroup; 015import javax.swing.JLabel; 016import javax.swing.JPanel; 017import javax.swing.JRadioButton; 018import javax.swing.event.ChangeEvent; 019import javax.swing.event.ChangeListener; 020 021import org.openstreetmap.josm.Main; 022import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 023import org.openstreetmap.josm.gui.widgets.JosmTextField; 024import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator; 025import org.openstreetmap.josm.plugins.PluginHandler; 026 027/** 028 * A panel for configuring whether JOSM shall update plugins at startup. 029 * 030 */ 031public class PluginUpdatePolicyPanel extends JPanel { 032 033 private enum Policy { 034 ASK("ask"), 035 ALWAYS("always"), 036 NEVER("never"); 037 038 private String preferenceValue; 039 Policy(String preferenceValue) { 040 this.preferenceValue = preferenceValue; 041 } 042 043 public String getPreferencesValue() { 044 return preferenceValue; 045 } 046 047 static Policy fromPreferenceValue(String preferenceValue) { 048 if (preferenceValue == null) 049 return null; 050 String prefValue = preferenceValue.trim().toLowerCase(Locale.ENGLISH); 051 for (Policy p: Policy.values()) { 052 if (p.getPreferencesValue().equals(prefValue)) 053 return p; 054 } 055 return null; 056 } 057 } 058 059 private transient Map<Policy, JRadioButton> rbVersionBasedUpatePolicy; 060 private transient Map<Policy, JRadioButton> rbTimeBasedUpatePolicy; 061 private final JosmTextField tfUpdateInterval = new JosmTextField(5); 062 private final JLabel lblUpdateInterval = new JLabel(tr("Update interval (in days):")); 063 064 /** 065 * Constructs a new {@code PluginUpdatePolicyPanel}. 066 */ 067 public PluginUpdatePolicyPanel() { 068 build(); 069 initFromPreferences(); 070 } 071 072 protected JPanel buildVersionBasedUpdatePolicyPanel() { 073 JPanel pnl = new JPanel(new GridBagLayout()); 074 GridBagConstraints gc = new GridBagConstraints(); 075 gc.anchor = GridBagConstraints.NORTHWEST; 076 gc.fill = GridBagConstraints.HORIZONTAL; 077 gc.weightx = 1.0; 078 079 ButtonGroup bgVersionBasedUpdatePolicy = new ButtonGroup(); 080 rbVersionBasedUpatePolicy = new EnumMap<>(Policy.class); 081 JRadioButton btn = new JRadioButton(tr("Ask before updating")); 082 rbVersionBasedUpatePolicy.put(Policy.ASK, btn); 083 bgVersionBasedUpdatePolicy.add(btn); 084 085 btn = new JRadioButton(tr("Always update without asking")); 086 rbVersionBasedUpatePolicy.put(Policy.ALWAYS, btn); 087 bgVersionBasedUpdatePolicy.add(btn); 088 089 btn = new JRadioButton(tr("Never update")); 090 rbVersionBasedUpatePolicy.put(Policy.NEVER, btn); 091 bgVersionBasedUpdatePolicy.add(btn); 092 093 JMultilineLabel lbl = new JMultilineLabel( 094 tr("Please decide whether JOSM shall automatically update active plugins at startup after an update of JOSM itself.")); 095 gc.gridy = 0; 096 pnl.add(lbl, gc); 097 for (Policy p: Policy.values()) { 098 gc.gridy++; 099 pnl.add(rbVersionBasedUpatePolicy.get(p), gc); 100 } 101 return pnl; 102 } 103 104 protected JPanel buildUpdateIntervalPanel() { 105 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT)); 106 pnl.add(lblUpdateInterval); 107 pnl.add(tfUpdateInterval); 108 lblUpdateInterval.setLabelFor(tfUpdateInterval); 109 SelectAllOnFocusGainedDecorator.decorate(tfUpdateInterval); 110 return pnl; 111 } 112 113 protected JPanel buildTimeBasedUpdatePolicyPanel() { 114 JPanel pnl = new JPanel(new GridBagLayout()); 115 GridBagConstraints gc = new GridBagConstraints(); 116 gc.anchor = GridBagConstraints.NORTHWEST; 117 gc.fill = GridBagConstraints.HORIZONTAL; 118 gc.weightx = 1.0; 119 120 TimeBasedPolicyChangeListener changeListener = new TimeBasedPolicyChangeListener(); 121 122 ButtonGroup bgTimeBasedUpdatePolicy = new ButtonGroup(); 123 rbTimeBasedUpatePolicy = new EnumMap<>(Policy.class); 124 JRadioButton btn = new JRadioButton(tr("Ask before updating")); 125 btn.addChangeListener(changeListener); 126 rbTimeBasedUpatePolicy.put(Policy.ASK, btn); 127 bgTimeBasedUpdatePolicy.add(btn); 128 129 btn = new JRadioButton(tr("Always update without asking")); 130 btn.addChangeListener(changeListener); 131 rbTimeBasedUpatePolicy.put(Policy.ALWAYS, btn); 132 bgTimeBasedUpdatePolicy.add(btn); 133 134 btn = new JRadioButton(tr("Never update")); 135 btn.addChangeListener(changeListener); 136 rbTimeBasedUpatePolicy.put(Policy.NEVER, btn); 137 bgTimeBasedUpdatePolicy.add(btn); 138 139 JMultilineLabel lbl = new JMultilineLabel( 140 tr("Please decide whether JOSM shall automatically update active plugins after a certain period of time.")); 141 gc.gridy = 0; 142 pnl.add(lbl, gc); 143 for (Policy p: Policy.values()) { 144 gc.gridy++; 145 pnl.add(rbTimeBasedUpatePolicy.get(p), gc); 146 } 147 gc.gridy++; 148 pnl.add(buildUpdateIntervalPanel(), gc); 149 return pnl; 150 } 151 152 protected final void build() { 153 setLayout(new GridBagLayout()); 154 GridBagConstraints gc = new GridBagConstraints(); 155 gc.anchor = GridBagConstraints.NORTHWEST; 156 gc.fill = GridBagConstraints.HORIZONTAL; 157 gc.weightx = 1.0; 158 gc.insets = new Insets(5, 5, 10, 5); 159 160 add(buildVersionBasedUpdatePolicyPanel(), gc); 161 gc.gridy = 1; 162 add(buildTimeBasedUpdatePolicyPanel(), gc); 163 164 gc.gridy = 2; 165 gc.weighty = 1.0; 166 gc.fill = GridBagConstraints.BOTH; 167 add(new JPanel(), gc); 168 } 169 170 /** 171 * Loads the relevant preference values from the JOSM preferences 172 */ 173 public final void initFromPreferences() { 174 String pref = Main.pref.get("pluginmanager.version-based-update.policy", "ask"); 175 Policy p = Policy.fromPreferenceValue(pref); 176 if (p == null) { 177 p = Policy.ASK; 178 } 179 rbVersionBasedUpatePolicy.get(p).setSelected(true); 180 181 pref = Main.pref.get("pluginmanager.time-based-update.policy", "ask"); 182 p = Policy.fromPreferenceValue(pref); 183 if (p == null) { 184 p = Policy.ASK; 185 } 186 rbTimeBasedUpatePolicy.get(p).setSelected(true); 187 188 pref = Main.pref.get("pluginmanager.warntime", null); 189 int days = 0; 190 if (pref != null) { 191 // remove legacy preference 192 Main.pref.put("pluginmanager.warntime", null); 193 pref = pref.trim(); 194 try { 195 days = Integer.parseInt(pref); 196 } catch (NumberFormatException e) { 197 // ignore - load from preference pluginmanager.time-based-update.interval 198 if (Main.isTraceEnabled()) { 199 Main.trace(e.getMessage()); 200 } 201 } 202 if (days <= 0) { 203 days = PluginHandler.DEFAULT_TIME_BASED_UPDATE_INTERVAL; 204 } 205 } 206 if (days == 0) { 207 days = Main.pref.getInteger("pluginmanager.time-based-update.interval", PluginHandler.DEFAULT_TIME_BASED_UPDATE_INTERVAL); 208 } 209 tfUpdateInterval.setText(Integer.toString(days)); 210 } 211 212 /** 213 * Remebers the update policy preference settings on the JOSM preferences 214 */ 215 public void rememberInPreferences() { 216 217 // remember policy for version based update 218 // 219 for (Policy p: Policy.values()) { 220 if (rbVersionBasedUpatePolicy.get(p).isSelected()) { 221 Main.pref.put("pluginmanager.version-based-update.policy", p.getPreferencesValue()); 222 break; 223 } 224 } 225 226 // remember policy for time based update 227 // 228 for (Policy p: Policy.values()) { 229 if (rbTimeBasedUpatePolicy.get(p).isSelected()) { 230 Main.pref.put("pluginmanager.time-based-update.policy", p.getPreferencesValue()); 231 break; 232 } 233 } 234 235 // remember update interval 236 // 237 int days = 0; 238 try { 239 days = Integer.parseInt(tfUpdateInterval.getText().trim()); 240 if (days <= 0) { 241 days = PluginHandler.DEFAULT_TIME_BASED_UPDATE_INTERVAL; 242 } 243 } catch (NumberFormatException e) { 244 days = PluginHandler.DEFAULT_TIME_BASED_UPDATE_INTERVAL; 245 } 246 Main.pref.putInteger("pluginmanager.time-based-update.interval", days); 247 } 248 249 class TimeBasedPolicyChangeListener implements ChangeListener { 250 @Override 251 public void stateChanged(ChangeEvent e) { 252 lblUpdateInterval.setEnabled(!rbTimeBasedUpatePolicy.get(Policy.NEVER).isSelected()); 253 tfUpdateInterval.setEnabled(!rbTimeBasedUpatePolicy.get(Policy.NEVER).isSelected()); 254 } 255 } 256 257}