source: josm/trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java@ 6070

Last change on this file since 6070 was 6070, checked in by stoecker, 11 years ago

see #8853 remove tabs, trailing spaces, windows line ends, strange characters

  • Property svn:eol-style set to native
File size: 16.4 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.download;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.BorderLayout;
8import java.awt.Color;
9import java.awt.Component;
10import java.awt.Dimension;
11import java.awt.FlowLayout;
12import java.awt.Font;
13import java.awt.Graphics;
14import java.awt.GridBagLayout;
15import java.awt.event.ActionEvent;
16import java.awt.event.ActionListener;
17import java.awt.event.InputEvent;
18import java.awt.event.KeyEvent;
19import java.awt.event.WindowAdapter;
20import java.awt.event.WindowEvent;
21import java.util.ArrayList;
22import java.util.List;
23
24import javax.swing.AbstractAction;
25import javax.swing.JCheckBox;
26import javax.swing.JComponent;
27import javax.swing.JDialog;
28import javax.swing.JLabel;
29import javax.swing.JOptionPane;
30import javax.swing.JPanel;
31import javax.swing.JTabbedPane;
32import javax.swing.KeyStroke;
33
34import org.openstreetmap.josm.Main;
35import org.openstreetmap.josm.actions.ExpertToggleAction;
36import org.openstreetmap.josm.data.Bounds;
37import org.openstreetmap.josm.gui.MapView;
38import org.openstreetmap.josm.gui.SideButton;
39import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
40import org.openstreetmap.josm.gui.help.HelpUtil;
41import org.openstreetmap.josm.plugins.PluginHandler;
42import org.openstreetmap.josm.tools.GBC;
43import org.openstreetmap.josm.tools.ImageProvider;
44import org.openstreetmap.josm.tools.InputMapUtils;
45import org.openstreetmap.josm.tools.OsmUrlToBounds;
46import org.openstreetmap.josm.tools.Utils;
47import org.openstreetmap.josm.tools.WindowGeometry;
48
49/**
50 *
51 */
52public class DownloadDialog extends JDialog {
53 /** the unique instance of the download dialog */
54 static private DownloadDialog instance;
55
56 /**
57 * Replies the unique instance of the download dialog
58 *
59 * @return the unique instance of the download dialog
60 */
61 static public DownloadDialog getInstance() {
62 if (instance == null) {
63 instance = new DownloadDialog(Main.parent);
64 }
65 return instance;
66 }
67
68 protected final List<DownloadSelection> downloadSelections = new ArrayList<DownloadSelection>();
69 protected final JTabbedPane tpDownloadAreaSelectors = new JTabbedPane();
70 protected JCheckBox cbNewLayer;
71 protected JCheckBox cbStartup;
72 protected final JLabel sizeCheck = new JLabel();
73 protected Bounds currentBounds = null;
74 protected boolean canceled;
75
76 protected JCheckBox cbDownloadOsmData;
77 protected JCheckBox cbDownloadGpxData;
78 /** the download action and button */
79 private DownloadAction actDownload;
80 protected SideButton btnDownload;
81
82 private void makeCheckBoxRespondToEnter(JCheckBox cb) {
83 cb.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "doDownload");
84 cb.getActionMap().put("doDownload", actDownload);
85 }
86
87 protected JPanel buildMainPanel() {
88 JPanel pnl = new JPanel();
89 pnl.setLayout(new GridBagLayout());
90
91 // adding the download tasks
92 pnl.add(new JLabel(tr("Data Sources and Types:")), GBC.std().insets(5,5,1,5));
93 cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), true);
94 cbDownloadOsmData.setToolTipText(tr("Select to download OSM data in the selected download area."));
95 pnl.add(cbDownloadOsmData, GBC.std().insets(1,5,1,5));
96 cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"));
97 cbDownloadGpxData.setToolTipText(tr("Select to download GPS traces in the selected download area."));
98 pnl.add(cbDownloadGpxData, GBC.eol().insets(5,5,1,5));
99
100 // hook for subclasses
101 buildMainPanelAboveDownloadSelections(pnl);
102
103 // predefined download selections
104 downloadSelections.add(new SlippyMapChooser());
105 downloadSelections.add(new BookmarkSelection());
106 downloadSelections.add(new BoundingBoxSelection());
107 downloadSelections.add(new PlaceSelection());
108 downloadSelections.add(new TileSelection());
109
110 // add selections from plugins
111 PluginHandler.addDownloadSelection(downloadSelections);
112
113 // now everybody may add their tab to the tabbed pane
114 // (not done right away to allow plugins to remove one of
115 // the default selectors!)
116 for (DownloadSelection s : downloadSelections) {
117 s.addGui(this);
118 }
119
120 pnl.add(tpDownloadAreaSelectors, GBC.eol().fill());
121
122 try {
123 tpDownloadAreaSelectors.setSelectedIndex(Main.pref.getInteger("download.tab", 0));
124 } catch (Exception ex) {
125 Main.pref.putInteger("download.tab", 0);
126 }
127
128 Font labelFont = sizeCheck.getFont();
129 sizeCheck.setFont(labelFont.deriveFont(Font.PLAIN, labelFont.getSize()));
130
131 cbNewLayer = new JCheckBox(tr("Download as new layer"));
132 cbNewLayer.setToolTipText(tr("<html>Select to download data into a new data layer.<br>"
133 +"Unselect to download into the currently active data layer.</html>"));
134
135 cbStartup = new JCheckBox(tr("Open this dialog on startup"));
136 cbStartup.setToolTipText(tr("<html>Autostart ''Download from OSM'' dialog every time JOSM is started.<br>You can open it manually from File menu or toolbar.</html>"));
137 cbStartup.addActionListener(new ActionListener() {
138 public void actionPerformed(ActionEvent e) {
139 Main.pref.put("download.autorun", cbStartup.isSelected());
140 }});
141
142 pnl.add(cbNewLayer, GBC.std().anchor(GBC.WEST).insets(5,5,5,5));
143 pnl.add(cbStartup, GBC.std().anchor(GBC.WEST).insets(15,5,5,5));
144
145 pnl.add(sizeCheck, GBC.eol().anchor(GBC.EAST).insets(5,5,5,2));
146
147 if (!ExpertToggleAction.isExpert()) {
148 JLabel infoLabel = new JLabel(tr("Use left click&drag to select area, arrows or right mouse button to scroll map, wheel or +/- to zoom."));
149 pnl.add(infoLabel,GBC.eol().anchor(GBC.SOUTH).insets(0,0,0,0));
150 }
151 return pnl;
152 }
153
154 /* This should not be necessary, but if not here, repaint is not always correct in SlippyMap! */
155 public void paint(Graphics g) {
156 tpDownloadAreaSelectors.getSelectedComponent().paint(g);
157 super.paint(g);
158 }
159
160 protected JPanel buildButtonPanel() {
161 JPanel pnl = new JPanel();
162 pnl.setLayout(new FlowLayout());
163
164 // -- download button
165 pnl.add(btnDownload = new SideButton(actDownload = new DownloadAction()));
166 InputMapUtils.enableEnter(btnDownload);
167
168 makeCheckBoxRespondToEnter(cbDownloadGpxData);
169 makeCheckBoxRespondToEnter(cbDownloadOsmData);
170 makeCheckBoxRespondToEnter(cbNewLayer);
171
172 // -- cancel button
173 SideButton btnCancel;
174 CancelAction actCancel = new CancelAction();
175 pnl.add(btnCancel = new SideButton(actCancel));
176 InputMapUtils.enableEnter(btnCancel);
177
178 // -- cancel on ESC
179 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0), "cancel");
180 getRootPane().getActionMap().put("cancel", actCancel);
181
182 // -- help button
183 SideButton btnHelp;
184 pnl.add(btnHelp = new SideButton(new ContextSensitiveHelpAction(ht("/Action/Download"))));
185 InputMapUtils.enableEnter(btnHelp);
186
187 return pnl;
188 }
189
190 public DownloadDialog(Component parent) {
191 super(JOptionPane.getFrameForComponent(parent),tr("Download"), ModalityType.DOCUMENT_MODAL);
192 getContentPane().setLayout(new BorderLayout());
193 getContentPane().add(buildMainPanel(), BorderLayout.CENTER);
194 getContentPane().add(buildButtonPanel(), BorderLayout.SOUTH);
195
196 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
197 KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK), "checkClipboardContents");
198
199 getRootPane().getActionMap().put("checkClipboardContents", new AbstractAction() {
200 public void actionPerformed(ActionEvent e) {
201 String clip = Utils.getClipboardContent();
202 if (clip == null) {
203 return;
204 }
205 Bounds b = OsmUrlToBounds.parse(clip);
206 if (b != null) {
207 boundingBoxChanged(new Bounds(b), null);
208 }
209 }
210 });
211 HelpUtil.setHelpContext(getRootPane(), ht("/Action/Download"));
212 addWindowListener(new WindowEventHandler());
213 restoreSettings();
214 }
215
216 private void updateSizeCheck() {
217 if (currentBounds == null) {
218 sizeCheck.setText(tr("No area selected yet"));
219 sizeCheck.setForeground(Color.darkGray);
220 } else if (currentBounds.getArea() > Main.pref.getDouble("osm-server.max-request-area", 0.25)) {
221 sizeCheck.setText(tr("Download area too large; will probably be rejected by server"));
222 sizeCheck.setForeground(Color.red);
223 } else {
224 sizeCheck.setText(tr("Download area ok, size probably acceptable to server"));
225 sizeCheck.setForeground(Color.darkGray);
226 }
227 }
228
229 /**
230 * Distributes a "bounding box changed" from one DownloadSelection
231 * object to the others, so they may update or clear their input
232 * fields.
233 *
234 * @param eventSource - the DownloadSelection object that fired this notification.
235 */
236 public void boundingBoxChanged(Bounds b, DownloadSelection eventSource) {
237 this.currentBounds = b;
238 for (DownloadSelection s : downloadSelections) {
239 if (s != eventSource) {
240 s.setDownloadArea(currentBounds);
241 }
242 }
243 updateSizeCheck();
244 }
245
246 /**
247 * Invoked by
248 * @param b
249 */
250 public void startDownload(Bounds b) {
251 this.currentBounds = b;
252 actDownload.run();
253 }
254
255 /**
256 * Replies true if the user selected to download OSM data
257 *
258 * @return true if the user selected to download OSM data
259 */
260 public boolean isDownloadOsmData() {
261 return cbDownloadOsmData.isSelected();
262 }
263
264 /**
265 * Replies true if the user selected to download GPX data
266 *
267 * @return true if the user selected to download GPX data
268 */
269 public boolean isDownloadGpxData() {
270 return cbDownloadGpxData.isSelected();
271 }
272
273 /**
274 * Replies true if the user requires to download into a new layer
275 *
276 * @return true if the user requires to download into a new layer
277 */
278 public boolean isNewLayerRequired() {
279 return cbNewLayer.isSelected();
280 }
281
282 /**
283 * Adds a new download area selector to the download dialog
284 *
285 * @param selector the download are selector
286 * @param displayName the display name of the selector
287 */
288 public void addDownloadAreaSelector(JPanel selector, String displayName) {
289 tpDownloadAreaSelectors.add(displayName, selector);
290 }
291
292 /**
293 * Remembers the current settings in the download dialog
294 *
295 */
296 public void rememberSettings() {
297 Main.pref.put("download.tab", Integer.toString(tpDownloadAreaSelectors.getSelectedIndex()));
298 Main.pref.put("download.osm", cbDownloadOsmData.isSelected());
299 Main.pref.put("download.gps", cbDownloadGpxData.isSelected());
300 Main.pref.put("download.newlayer", cbNewLayer.isSelected());
301 if (currentBounds != null) {
302 Main.pref.put("osm-download.bounds", currentBounds.encodeAsString(";"));
303 }
304 }
305
306 public void restoreSettings() {
307 cbDownloadOsmData.setSelected(Main.pref.getBoolean("download.osm", true));
308 cbDownloadGpxData.setSelected(Main.pref.getBoolean("download.gps", false));
309 cbNewLayer.setSelected(Main.pref.getBoolean("download.newlayer", false));
310 cbStartup.setSelected( isAutorunEnabled() );
311 int idx = Main.pref.getInteger("download.tab", 0);
312 if (idx < 0 || idx > tpDownloadAreaSelectors.getTabCount()) {
313 idx = 0;
314 }
315 tpDownloadAreaSelectors.setSelectedIndex(idx);
316
317 if (Main.isDisplayingMapView()) {
318 MapView mv = Main.map.mapView;
319 currentBounds = new Bounds(
320 mv.getLatLon(0, mv.getHeight()),
321 mv.getLatLon(mv.getWidth(), 0)
322 );
323 boundingBoxChanged(currentBounds,null);
324 }
325 else if (!Main.pref.get("osm-download.bounds").isEmpty()) {
326 // read the bounding box from the preferences
327 try {
328 currentBounds = new Bounds(Main.pref.get("osm-download.bounds"), ";");
329 boundingBoxChanged(currentBounds,null);
330 }
331 catch (Exception e) {
332 e.printStackTrace();
333 }
334 }
335 }
336
337 public static boolean isAutorunEnabled() {
338 //String autorun=Main.pref.get("download.autorun",null);
339 //boolean expert=ExpertToggleAction.isExpert();
340 //return (autorun==null && !expert) || "true".equals(autorun) ;
341 return Main.pref.getBoolean("download.autorun",false);
342 }
343
344 public static void autostartIfNeeded() {
345 if (isAutorunEnabled()) {
346 Main.main.menu.download.actionPerformed(null);
347 }
348 }
349
350 /**
351 * Replies the currently selected download area. May be null, if no download area is selected
352 * yet.
353 */
354 public Bounds getSelectedDownloadArea() {
355 return currentBounds;
356 }
357
358 @Override
359 public void setVisible(boolean visible) {
360 if (visible) {
361 new WindowGeometry(
362 getClass().getName() + ".geometry",
363 WindowGeometry.centerInWindow(
364 getParent(),
365 new Dimension(1000,600)
366 )
367 ).applySafe(this);
368 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
369 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
370 }
371 super.setVisible(visible);
372 }
373
374 /**
375 * Replies true if the dialog was canceled
376 *
377 * @return true if the dialog was canceled
378 */
379 public boolean isCanceled() {
380 return canceled;
381 }
382
383 protected void setCanceled(boolean canceled) {
384 this.canceled = canceled;
385 }
386
387 protected void buildMainPanelAboveDownloadSelections(JPanel pnl) {
388 }
389
390 class CancelAction extends AbstractAction {
391 public CancelAction() {
392 putValue(NAME, tr("Cancel"));
393 putValue(SMALL_ICON, ImageProvider.get("cancel"));
394 putValue(SHORT_DESCRIPTION, tr("Click to close the dialog and to abort downloading"));
395 }
396
397 public void run() {
398 setCanceled(true);
399 setVisible(false);
400 }
401
402 public void actionPerformed(ActionEvent e) {
403 run();
404 }
405 }
406
407 class DownloadAction extends AbstractAction {
408 public DownloadAction() {
409 putValue(NAME, tr("Download"));
410 putValue(SMALL_ICON, ImageProvider.get("download"));
411 putValue(SHORT_DESCRIPTION, tr("Click to download the currently selected area"));
412 }
413
414 public void run() {
415 if (currentBounds == null) {
416 JOptionPane.showMessageDialog(
417 DownloadDialog.this,
418 tr("Please select a download area first."),
419 tr("Error"),
420 JOptionPane.ERROR_MESSAGE
421 );
422 return;
423 }
424 if (!isDownloadOsmData() && !isDownloadGpxData()) {
425 JOptionPane.showMessageDialog(
426 DownloadDialog.this,
427 tr("<html>Neither <strong>{0}</strong> nor <strong>{1}</strong> is enabled.<br>"
428 + "Please choose to either download OSM data, or GPX data, or both.</html>",
429 cbDownloadOsmData.getText(),
430 cbDownloadGpxData.getText()
431 ),
432 tr("Error"),
433 JOptionPane.ERROR_MESSAGE
434 );
435 return;
436 }
437 setCanceled(false);
438 setVisible(false);
439 }
440
441 public void actionPerformed(ActionEvent e) {
442 run();
443 }
444 }
445
446 class WindowEventHandler extends WindowAdapter {
447 @Override
448 public void windowClosing(WindowEvent e) {
449 new CancelAction().run();
450 }
451
452 @Override
453 public void windowActivated(WindowEvent e) {
454 btnDownload.requestFocusInWindow();
455 }
456 }
457}
Note: See TracBrowser for help on using the repository browser.