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

Last change on this file since 2347 was 2347, checked in by Gubaer, 14 years ago

fixed #3802: Buttons dont't react to enter in download dialog

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