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