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