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