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

Last change on this file since 3976 was 3976, checked in by bastiK, 13 years ago

fixed #6091 - spelling

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