001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.layer.gpx;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Dimension;
007import java.awt.GridBagLayout;
008
009import javax.swing.JCheckBox;
010import javax.swing.JLabel;
011import javax.swing.JList;
012import javax.swing.JOptionPane;
013import javax.swing.JPanel;
014import javax.swing.JSpinner;
015import javax.swing.SpinnerNumberModel;
016import javax.swing.event.ChangeListener;
017
018import org.openstreetmap.josm.Main;
019import org.openstreetmap.josm.gui.HelpAwareOptionPane;
020import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
021import org.openstreetmap.josm.tools.GBC;
022import org.openstreetmap.josm.tools.ImageProvider;
023
024/**
025 * Panel displayed in "Download along..." dialogs
026 * @since 6054
027 */
028public class DownloadAlongPanel extends JPanel {
029
030    // Preferences keys
031    private final String prefOsm;
032    private final String prefGps;
033    private final String prefDist;
034    private final String prefArea;
035    private final String prefNear;
036
037    // Data types to download
038    private final JCheckBox cbDownloadOsmData;
039    private final JCheckBox cbDownloadGpxData;
040
041    private final JSpinner buffer;
042    private final JSpinner maxRect;
043    private final JList<String> downloadNear;
044
045    /**
046     * Constructs a new {@code DownloadPanel}.
047     * @param prefOsm Preference key determining if OSM data should be downloaded
048     * @param prefGps Preference key determining if GPS data should be downloaded
049     * @param prefDist Preference key determining maximum distance
050     * @param prefArea Preference key determining maximum area
051     * @param prefNear Preference key determining "near" parameter. Can be {@code null}
052     */
053    public DownloadAlongPanel(String prefOsm, String prefGps, String prefDist, String prefArea, String prefNear) {
054        super(new GridBagLayout());
055
056        this.prefOsm = prefOsm;
057        this.prefGps = prefGps;
058        this.prefDist = prefDist;
059        this.prefArea = prefArea;
060        this.prefNear = prefNear;
061
062        cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), Main.pref.getBoolean(prefOsm, true));
063        cbDownloadOsmData.setToolTipText(tr("Select to download OSM data."));
064        add(cbDownloadOsmData, GBC.std().insets(1, 5, 1, 5));
065        cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"), Main.pref.getBoolean(prefGps, false));
066        cbDownloadGpxData.setToolTipText(tr("Select to download GPS traces."));
067        add(cbDownloadGpxData, GBC.eol().insets(5, 5, 1, 5));
068
069        add(new JLabel(tr("Download everything within:")), GBC.std());
070        buffer = new JSpinner(new SpinnerNumberModel(50.0, 10.0, 5000.0, 1.0));
071        add(buffer, GBC.std().insets(5, 5, 5, 5));
072        add(new JLabel(tr("meters")), GBC.eol());
073
074        add(new JLabel(tr("Maximum area per request:")), GBC.std());
075        maxRect = new JSpinner(new SpinnerNumberModel(20.0, 0.01, 25.0, 1.0)) {
076            @Override
077            public Dimension getPreferredSize() {
078                return buffer.getPreferredSize();
079            }
080        };
081        add(maxRect, GBC.std().insets(5, 5, 5, 5));
082        add(new JLabel("km\u00b2"), GBC.eol());
083
084        if (prefNear != null) {
085            add(new JLabel(tr("Download near:")), GBC.eol());
086            downloadNear = new JList<>(new String[]{tr("track only"), tr("waypoints only"), tr("track and waypoints")});
087            downloadNear.setSelectedIndex(Main.pref.getInteger(prefNear, 0));
088            add(downloadNear, GBC.eol());
089        } else {
090            downloadNear = null;
091        }
092    }
093
094    /**
095     * Gets the maximum distance in meters
096     * @return The maximum distance, in meters
097     */
098    public final double getDistance() {
099        return (double) buffer.getValue();
100    }
101
102    /**
103     * Gets the maximum area in squared kilometers
104     * @return The maximum distance, in squared kilometers
105     */
106    public final double getArea() {
107        return (double) maxRect.getValue();
108    }
109
110    /**
111     * Gets the "download near" choosen value
112     * @return the "download near" choosen value (0: track only, 1: waypoints only, 2: both)
113     */
114    public final int getNear() {
115        return downloadNear.getSelectedIndex();
116    }
117
118    /**
119     * Replies true if the user selected to download OSM data
120     *
121     * @return true if the user selected to download OSM data
122     */
123    public boolean isDownloadOsmData() {
124        return cbDownloadOsmData.isSelected();
125    }
126
127    /**
128     * Replies true if the user selected to download GPX data
129     *
130     * @return true if the user selected to download GPX data
131     */
132    public boolean isDownloadGpxData() {
133        return cbDownloadGpxData.isSelected();
134    }
135
136    /**
137     * Remembers the current settings in the download panel
138     */
139    protected final void rememberSettings() {
140        Main.pref.put(prefOsm, isDownloadOsmData());
141        Main.pref.put(prefGps, isDownloadGpxData());
142        Main.pref.putDouble(prefDist, getDistance());
143        Main.pref.putDouble(prefArea, getArea());
144        if (prefNear != null) {
145            Main.pref.putInteger(prefNear, getNear());
146        }
147    }
148
149    /**
150     * Adds a change listener to comboboxes
151     * @param listener The listener that will be notified of each combobox change
152     */
153    protected final void addChangeListener(ChangeListener listener) {
154        cbDownloadGpxData.addChangeListener(listener);
155        cbDownloadOsmData.addChangeListener(listener);
156    }
157
158    /**
159     * Show this panel in a new "Download along" help-aware dialog
160     * @param title The dialog title
161     * @param helpTopic The dialog help topic
162     * @return The selected button index (0 for download, 1 for cancel, 2 for dialog closure)
163     */
164    public int showInDownloadDialog(String title, String helpTopic) {
165        final ButtonSpec[] options = new ButtonSpec[] {
166                new ButtonSpec(
167                        tr("Download"),
168                        ImageProvider.get("download"),
169                        tr("Click to download"),
170                        null // no specific help text
171                ),
172                new ButtonSpec(
173                        tr("Cancel"),
174                        ImageProvider.get("cancel"),
175                        tr("Click to cancel"),
176                        null // no specific help text
177                )
178        };
179
180        addChangeListener(e -> options[0].setEnabled(isDownloadOsmData() || isDownloadGpxData()));
181
182        int ret = HelpAwareOptionPane.showOptionDialog(Main.parent, this, title,
183                    JOptionPane.QUESTION_MESSAGE, null, options, options[0], helpTopic);
184        if (0 == ret) {
185            rememberSettings();
186        }
187
188        return ret;
189    }
190}