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