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