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

Last change on this file since 12684 was 12684, checked in by bastiK, 8 years ago

see #15167 - moved the info label in non expert mode (patch by bafonins)

  • Property svn:eol-style set to native
File size: 24.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
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.Component;
9import java.awt.Dimension;
10import java.awt.FlowLayout;
11import java.awt.Graphics;
12import java.awt.GridBagLayout;
13import java.awt.event.ActionEvent;
14import java.awt.event.InputEvent;
15import java.awt.event.KeyEvent;
16import java.awt.event.WindowAdapter;
17import java.awt.event.WindowEvent;
18import java.beans.PropertyChangeListener;
19import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.List;
22import java.util.Optional;
23import java.util.stream.IntStream;
24
25import javax.swing.AbstractAction;
26import javax.swing.Icon;
27import javax.swing.JButton;
28import javax.swing.JCheckBox;
29import javax.swing.JComponent;
30import javax.swing.JDialog;
31import javax.swing.JLabel;
32import javax.swing.JPanel;
33import javax.swing.JSplitPane;
34import javax.swing.JTabbedPane;
35import javax.swing.KeyStroke;
36import javax.swing.event.ChangeEvent;
37import javax.swing.event.ChangeListener;
38
39import org.openstreetmap.josm.Main;
40import org.openstreetmap.josm.actions.ExpertToggleAction;
41import org.openstreetmap.josm.data.Bounds;
42import org.openstreetmap.josm.data.preferences.BooleanProperty;
43import org.openstreetmap.josm.data.preferences.IntegerProperty;
44import org.openstreetmap.josm.gui.MainApplication;
45import org.openstreetmap.josm.gui.MapView;
46import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
47import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
48import org.openstreetmap.josm.gui.help.HelpUtil;
49import org.openstreetmap.josm.gui.util.GuiHelper;
50import org.openstreetmap.josm.gui.util.WindowGeometry;
51import org.openstreetmap.josm.io.OnlineResource;
52import org.openstreetmap.josm.plugins.PluginHandler;
53import org.openstreetmap.josm.tools.GBC;
54import org.openstreetmap.josm.tools.ImageProvider;
55import org.openstreetmap.josm.tools.InputMapUtils;
56import org.openstreetmap.josm.tools.JosmRuntimeException;
57import org.openstreetmap.josm.tools.Logging;
58import org.openstreetmap.josm.tools.OsmUrlToBounds;
59
60/**
61 * Dialog displayed to the user to download mapping data.
62 */
63public class DownloadDialog extends JDialog {
64
65 /**
66 * Preference properties
67 */
68 private static final String TAB_SPLIT_NAMESPACE = "download.tabsplit.";
69 private static final IntegerProperty DOWNLOAD_TAB = new IntegerProperty("download.tab", 0);
70 private static final IntegerProperty DOWNLOAD_SOURCE_TAB = new IntegerProperty("download-source.tab", 0);
71 private static final BooleanProperty DOWNLOAD_AUTORUN = new BooleanProperty("download.autorun", false);
72 private static final BooleanProperty DOWNLOAD_NEWLAYER = new BooleanProperty("download.newlayer", false);
73 private static final BooleanProperty DOWNLOAD_ZOOMTODATA = new BooleanProperty("download.zoomtodata", true);
74
75 /** the unique instance of the download dialog */
76 private static DownloadDialog instance;
77
78 /**
79 * Replies the unique instance of the download dialog
80 *
81 * @return the unique instance of the download dialog
82 */
83 public static synchronized DownloadDialog getInstance() {
84 if (instance == null) {
85 instance = new DownloadDialog(Main.parent);
86 }
87 return instance;
88 }
89
90 protected final transient List<DownloadSource<?>> downloadSources = new ArrayList<>();
91 protected final transient List<DownloadSelection> downloadSelections = new ArrayList<>();
92 protected final JTabbedPane tpDownloadAreaSelectors = new JTabbedPane();
93 protected final JTabbedPane downloadSourcesTab = new JTabbedPane();
94
95 protected JCheckBox cbNewLayer;
96 protected JCheckBox cbStartup;
97 protected JCheckBox cbZoomToDownloadedData;
98 protected SlippyMapChooser slippyMapChooser;
99 protected JPanel mainPanel;
100 protected JSplitPane dialogSplit;
101
102 /*
103 * Keep the reference globally to avoid having it garbage collected
104 */
105 protected final transient ExpertToggleAction.ExpertModeChangeListener expertListener =
106 getExpertModeListenerForDownloadSources();
107 protected transient Bounds currentBounds;
108 protected boolean canceled;
109
110 protected JButton btnDownload;
111 protected JButton btnCancel;
112 protected JButton btnHelp;
113
114 /**
115 * Builds the main panel of the dialog.
116 * @return The panel of the dialog.
117 */
118 protected final JPanel buildMainPanel() {
119 mainPanel = new JPanel(new GridBagLayout());
120
121 // add default download sources
122 addDownloadSource(new OSMDownloadSource());
123 addDownloadSource(new OverpassDownloadSource());
124
125 // must be created before hook
126 slippyMapChooser = new SlippyMapChooser();
127
128 // predefined download selections
129 downloadSelections.add(slippyMapChooser);
130 downloadSelections.add(new BookmarkSelection());
131 downloadSelections.add(new BoundingBoxSelection());
132 downloadSelections.add(new PlaceSelection());
133 downloadSelections.add(new TileSelection());
134
135 // add selections from plugins
136 PluginHandler.addDownloadSelection(downloadSelections);
137
138 // register all default download selections
139 for (DownloadSelection s : downloadSelections) {
140 s.addGui(this);
141 }
142
143 // allow to collapse the panes, but reserve some space for tabs
144 downloadSourcesTab.setMinimumSize(new Dimension(0, 25));
145 tpDownloadAreaSelectors.setMinimumSize(new Dimension(0, 0));
146
147 dialogSplit = new JSplitPane(
148 JSplitPane.VERTICAL_SPLIT,
149 downloadSourcesTab,
150 tpDownloadAreaSelectors);
151 dialogSplit.addPropertyChangeListener(getDividerChangedListener());
152
153 ChangeListener tabChangedListener = getDownloadSourceTabChangeListener();
154 tabChangedListener.stateChanged(new ChangeEvent(downloadSourcesTab));
155 downloadSourcesTab.addChangeListener(tabChangedListener);
156
157 mainPanel.add(dialogSplit, GBC.eol().fill());
158
159 cbNewLayer = new JCheckBox(tr("Download as new layer"));
160 cbNewLayer.setToolTipText(tr("<html>Select to download data into a new data layer.<br>"
161 +"Unselect to download into the currently active data layer.</html>"));
162
163 cbStartup = new JCheckBox(tr("Open this dialog on startup"));
164 cbStartup.setToolTipText(
165 tr("<html>Autostart ''Download from OSM'' dialog every time JOSM is started.<br>" +
166 "You can open it manually from File menu or toolbar.</html>"));
167 cbStartup.addActionListener(e -> DOWNLOAD_AUTORUN.put(cbStartup.isSelected()));
168
169 cbZoomToDownloadedData = new JCheckBox(tr("Zoom to downloaded data"));
170 cbZoomToDownloadedData.setToolTipText(tr("Select to zoom to entire newly downloaded data."));
171
172 mainPanel.add(cbNewLayer, GBC.std().anchor(GBC.WEST).insets(5, 5, 5, 5));
173 mainPanel.add(cbStartup, GBC.std().anchor(GBC.WEST).insets(15, 5, 5, 5));
174 mainPanel.add(cbZoomToDownloadedData, GBC.std().anchor(GBC.WEST).insets(15, 5, 5, 5));
175
176 ExpertToggleAction.addVisibilitySwitcher(cbZoomToDownloadedData);
177
178 mainPanel.add(new JLabel(), GBC.eol()); // place info label at a new line
179 JLabel infoLabel = new JLabel(
180 tr("Use left click&drag to select area, arrows or right mouse button to scroll map, wheel or +/- to zoom."));
181 mainPanel.add(infoLabel, GBC.eol().anchor(GBC.CENTER).insets(0, 0, 0, 0));
182
183 ExpertToggleAction.addExpertModeChangeListener(isExpert -> infoLabel.setVisible(!isExpert), true);
184
185 return mainPanel;
186 }
187
188 /* This should not be necessary, but if not here, repaint is not always correct in SlippyMap! */
189 @Override
190 public void paint(Graphics g) {
191 tpDownloadAreaSelectors.getSelectedComponent().paint(g);
192 super.paint(g);
193 }
194
195 /**
196 * Builds the button pane of the dialog.
197 * @return The button panel of the dialog.
198 */
199 protected final JPanel buildButtonPanel() {
200 btnDownload = new JButton(new DownloadAction());
201 btnCancel = new JButton(new CancelAction());
202 btnHelp = new JButton(
203 new ContextSensitiveHelpAction(getRootPane().getClientProperty("help").toString()));
204
205 JPanel pnl = new JPanel(new FlowLayout());
206
207 pnl.add(btnDownload);
208 pnl.add(btnCancel);
209 pnl.add(btnHelp);
210
211 InputMapUtils.enableEnter(btnDownload);
212 InputMapUtils.enableEnter(btnCancel);
213 InputMapUtils.addEscapeAction(getRootPane(), btnCancel.getAction());
214 InputMapUtils.enableEnter(btnHelp);
215
216 InputMapUtils.addEnterActionWhenAncestor(cbNewLayer, btnDownload.getAction());
217 InputMapUtils.addEnterActionWhenAncestor(cbStartup, btnDownload.getAction());
218 InputMapUtils.addEnterActionWhenAncestor(cbZoomToDownloadedData, btnDownload.getAction());
219
220 return pnl;
221 }
222
223 /**
224 * Constructs a new {@code DownloadDialog}.
225 * @param parent the parent component
226 */
227 public DownloadDialog(Component parent) {
228 this(parent, ht("/Action/Download"));
229 }
230
231 /**
232 * Constructs a new {@code DownloadDialog}.
233 * @param parent the parent component
234 * @param helpTopic the help topic to assign
235 */
236 public DownloadDialog(Component parent, String helpTopic) {
237 super(GuiHelper.getFrameForComponent(parent), tr("Download"), ModalityType.DOCUMENT_MODAL);
238 HelpUtil.setHelpContext(getRootPane(), helpTopic);
239 getContentPane().setLayout(new BorderLayout());
240 getContentPane().add(buildMainPanel(), BorderLayout.CENTER);
241 getContentPane().add(buildButtonPanel(), BorderLayout.SOUTH);
242
243 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
244 KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK), "checkClipboardContents");
245
246 getRootPane().getActionMap().put("checkClipboardContents", new AbstractAction() {
247 @Override
248 public void actionPerformed(ActionEvent e) {
249 String clip = ClipboardUtils.getClipboardStringContent();
250 if (clip == null) {
251 return;
252 }
253 Bounds b = OsmUrlToBounds.parse(clip);
254 if (b != null) {
255 boundingBoxChanged(new Bounds(b), null);
256 }
257 }
258 });
259 addWindowListener(new WindowEventHandler());
260 ExpertToggleAction.addExpertModeChangeListener(expertListener);
261 restoreSettings();
262
263 // if no bounding box is selected make sure it is still propagated.
264 if (currentBounds == null) {
265 boundingBoxChanged(null, null);
266 }
267 }
268
269 /**
270 * Distributes a "bounding box changed" from one DownloadSelection
271 * object to the others, so they may update or clear their input fields. Also informs
272 * download sources about the change, so they can react on it.
273 * @param b new current bounds
274 *
275 * @param eventSource - the DownloadSelection object that fired this notification.
276 */
277 public void boundingBoxChanged(Bounds b, DownloadSelection eventSource) {
278 this.currentBounds = b;
279 for (DownloadSelection s : downloadSelections) {
280 if (s != eventSource) {
281 s.setDownloadArea(currentBounds);
282 }
283 }
284
285 for (Component ds : downloadSourcesTab.getComponents()) {
286 if (ds instanceof AbstractDownloadSourcePanel) {
287 ((AbstractDownloadSourcePanel<?>) ds).boudingBoxChanged(b);
288 }
289 }
290 }
291
292 /**
293 * Starts download for the given bounding box
294 * @param b bounding box to download
295 */
296 public void startDownload(Bounds b) {
297 this.currentBounds = b;
298 startDownload();
299 }
300
301 /**
302 * Starts download.
303 */
304 public void startDownload() {
305 btnDownload.doClick();
306 }
307
308 /**
309 * Replies true if the user requires to download into a new layer
310 *
311 * @return true if the user requires to download into a new layer
312 */
313 public boolean isNewLayerRequired() {
314 return cbNewLayer.isSelected();
315 }
316
317 /**
318 * Replies true if the user requires to zoom to new downloaded data
319 *
320 * @return true if the user requires to zoom to new downloaded data
321 * @since 11658
322 */
323 public boolean isZoomToDownloadedDataRequired() {
324 return cbZoomToDownloadedData.isSelected();
325 }
326
327 /**
328 * Determines if the dialog autorun is enabled in preferences.
329 * @return {@code true} if the download dialog must be open at startup, {@code false} otherwise.
330 */
331 public static boolean isAutorunEnabled() {
332 return DOWNLOAD_AUTORUN.get();
333 }
334
335 /**
336 * Adds a new download area selector to the download dialog.
337 *
338 * @param selector the download are selector.
339 * @param displayName the display name of the selector.
340 */
341 public void addDownloadAreaSelector(JPanel selector, String displayName) {
342 tpDownloadAreaSelectors.add(displayName, selector);
343 }
344
345 /**
346 * Adds a new download source to the download dialog if it is not added.
347 *
348 * @param downloadSource The download source to be added.
349 * @param <T> The type of the download data.
350 * @throws JosmRuntimeException If the download source is already added. Note, download sources are
351 * compared by their reference.
352 */
353 public <T> void addDownloadSource(DownloadSource<T> downloadSource) {
354 if (downloadSources.contains(downloadSource)) {
355 throw new JosmRuntimeException("The download source you are trying to add already exists.");
356 }
357
358 downloadSources.add(downloadSource);
359 if ((ExpertToggleAction.isExpert() && downloadSource.onlyExpert()) || !downloadSource.onlyExpert()) {
360 addNewDownloadSourceTab(downloadSource);
361 }
362 }
363
364 /**
365 * Refreshes the tile sources.
366 * @since 6364
367 */
368 public final void refreshTileSources() {
369 if (slippyMapChooser != null) {
370 slippyMapChooser.refreshTileSources();
371 }
372 }
373
374 /**
375 * Remembers the current settings in the download dialog.
376 */
377 public void rememberSettings() {
378 DOWNLOAD_TAB.put(tpDownloadAreaSelectors.getSelectedIndex());
379 DOWNLOAD_SOURCE_TAB.put(downloadSourcesTab.getSelectedIndex());
380 DOWNLOAD_NEWLAYER.put(cbNewLayer.isSelected());
381 DOWNLOAD_ZOOMTODATA.put(cbZoomToDownloadedData.isSelected());
382 if (currentBounds != null) {
383 Main.pref.put("osm-download.bounds", currentBounds.encodeAsString(";"));
384 }
385 }
386
387 /**
388 * Restores the previous settings in the download dialog.
389 */
390 public void restoreSettings() {
391 cbNewLayer.setSelected(DOWNLOAD_NEWLAYER.get());
392 cbStartup.setSelected(isAutorunEnabled());
393 cbZoomToDownloadedData.setSelected(DOWNLOAD_ZOOMTODATA.get());
394
395 try {
396 tpDownloadAreaSelectors.setSelectedIndex(DOWNLOAD_TAB.get());
397 } catch (IndexOutOfBoundsException e) {
398 Logging.trace(e);
399 tpDownloadAreaSelectors.setSelectedIndex(0);
400 }
401
402 try {
403 downloadSourcesTab.setSelectedIndex(DOWNLOAD_SOURCE_TAB.get());
404 } catch (IndexOutOfBoundsException e) {
405 Logging.trace(e);
406 downloadSourcesTab.setSelectedIndex(0);
407 }
408
409 if (MainApplication.isDisplayingMapView()) {
410 MapView mv = MainApplication.getMap().mapView;
411 currentBounds = new Bounds(
412 mv.getLatLon(0, mv.getHeight()),
413 mv.getLatLon(mv.getWidth(), 0)
414 );
415 boundingBoxChanged(currentBounds, null);
416 } else {
417 Bounds bounds = getSavedDownloadBounds();
418 if (bounds != null) {
419 currentBounds = bounds;
420 boundingBoxChanged(currentBounds, null);
421 }
422 }
423 }
424
425 /**
426 * Returns the previously saved bounding box from preferences.
427 * @return The bounding box saved in preferences if any, {@code null} otherwise.
428 * @since 6509
429 */
430 public static Bounds getSavedDownloadBounds() {
431 String value = Main.pref.get("osm-download.bounds");
432 if (!value.isEmpty()) {
433 try {
434 return new Bounds(value, ";");
435 } catch (IllegalArgumentException e) {
436 Logging.warn(e);
437 }
438 }
439 return null;
440 }
441
442 /**
443 * Automatically opens the download dialog, if autorun is enabled.
444 * @see #isAutorunEnabled
445 */
446 public static void autostartIfNeeded() {
447 if (isAutorunEnabled()) {
448 MainApplication.getMenu().download.actionPerformed(null);
449 }
450 }
451
452 /**
453 * Returns an {@link Optional} of the currently selected download area.
454 * @return An {@link Optional} of the currently selected download area.
455 * @since 12574 Return type changed to optional
456 */
457 public Optional<Bounds> getSelectedDownloadArea() {
458 return Optional.ofNullable(currentBounds);
459 }
460
461 @Override
462 public void setVisible(boolean visible) {
463 if (visible) {
464 new WindowGeometry(
465 getClass().getName() + ".geometry",
466 WindowGeometry.centerInWindow(
467 getParent(),
468 new Dimension(1000, 600)
469 )
470 ).applySafe(this);
471 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
472 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
473 }
474 super.setVisible(visible);
475 }
476
477 /**
478 * Replies true if the dialog was canceled
479 *
480 * @return true if the dialog was canceled
481 */
482 public boolean isCanceled() {
483 return canceled;
484 }
485
486 /**
487 * Gets the global settings of the download dialog.
488 * @return The {@link DownloadSettings} object that describes the current state of
489 * the download dialog.
490 */
491 public DownloadSettings getDownloadSettings() {
492 return new DownloadSettings(currentBounds, isNewLayerRequired(), isZoomToDownloadedDataRequired());
493 }
494
495 protected void setCanceled(boolean canceled) {
496 this.canceled = canceled;
497 }
498
499 /**
500 * Returns position of the download source in the tabbed pane.
501 * @param downloadSource The download source.
502 * @return The index of the download source, or -1 if it not in the pane.
503 */
504 protected int getDownloadSourceIndex(DownloadSource<?> downloadSource) {
505 return Arrays.stream(downloadSourcesTab.getComponents())
506 .filter(it -> it instanceof AbstractDownloadSourcePanel)
507 .map(it -> (AbstractDownloadSourcePanel<?>) it)
508 .filter(it -> it.getDownloadSource().equals(downloadSource))
509 .findAny()
510 .map(downloadSourcesTab::indexOfComponent)
511 .orElse(-1);
512 }
513
514 /**
515 * Adds the download source to the download sources tab.
516 * @param downloadSource The download source to be added.
517 * @param <T> The type of the download data.
518 */
519 protected <T> void addNewDownloadSourceTab(DownloadSource<T> downloadSource) {
520 AbstractDownloadSourcePanel<T> panel = downloadSource.createPanel();
521 downloadSourcesTab.add(panel, downloadSource.getLabel());
522 Icon icon = panel.getIcon();
523 if (icon != null) {
524 int idx = getDownloadSourceIndex(downloadSource);
525 downloadSourcesTab.setIconAt(
526 idx != -1 ? idx : downloadSourcesTab.getTabCount() - 1,
527 icon);
528 }
529 }
530
531 /**
532 * Creates listener that removes/adds download sources from/to {@code downloadSourcesTab}
533 * depending on the current mode.
534 * @return The expert mode listener.
535 */
536 private ExpertToggleAction.ExpertModeChangeListener getExpertModeListenerForDownloadSources() {
537 return isExpert -> {
538 if (isExpert) {
539 downloadSources.stream()
540 .filter(DownloadSource::onlyExpert)
541 .filter(it -> getDownloadSourceIndex(it) == -1)
542 .forEach(this::addNewDownloadSourceTab);
543 } else {
544 IntStream.range(0, downloadSourcesTab.getTabCount())
545 .mapToObj(downloadSourcesTab::getComponentAt)
546 .filter(it -> it instanceof AbstractDownloadSourcePanel)
547 .map(it -> (AbstractDownloadSourcePanel<?>) it)
548 .filter(it -> it.getDownloadSource().onlyExpert())
549 .forEach(downloadSourcesTab::remove);
550 }
551 };
552 }
553
554 /**
555 * Creates a listener that reacts on tab switches for {@code downloadSourcesTab} in order
556 * to adjust proper division of the dialog according to user saved preferences or minimal size
557 * of the panel.
558 * @return A listener to adjust dialog division.
559 */
560 private ChangeListener getDownloadSourceTabChangeListener() {
561 return ec -> {
562 JTabbedPane tabbedPane = (JTabbedPane) ec.getSource();
563 Component selectedComponent = tabbedPane.getSelectedComponent();
564 if (selectedComponent instanceof AbstractDownloadSourcePanel) {
565 AbstractDownloadSourcePanel<?> panel = (AbstractDownloadSourcePanel<?>) selectedComponent;
566 dialogSplit.setDividerLocation(Main.pref.getInteger(
567 TAB_SPLIT_NAMESPACE + panel.getSimpleName(),
568 panel.getMinimumSize().height));
569 }
570 };
571 }
572
573 /**
574 * Creates a listener that react on dialog splitters movements to save users preferences.
575 * @return A listener to save user preferred split of the dialog.
576 */
577 private PropertyChangeListener getDividerChangedListener() {
578 return evt -> {
579 if (evt.getPropertyName().equalsIgnoreCase(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {
580 Component selectedComponent = downloadSourcesTab.getSelectedComponent();
581 if (selectedComponent instanceof AbstractDownloadSourcePanel) {
582 AbstractDownloadSourcePanel<?> panel = (AbstractDownloadSourcePanel<?>) selectedComponent;
583 Main.pref.put(
584 TAB_SPLIT_NAMESPACE + panel.getSimpleName(),
585 String.valueOf(dialogSplit.getDividerLocation())
586 );
587 }
588 }
589 };
590 }
591
592 /**
593 * Action that is executed when the cancel button is pressed.
594 */
595 class CancelAction extends AbstractAction {
596 CancelAction() {
597 putValue(NAME, tr("Cancel"));
598 new ImageProvider("cancel").getResource().attachImageIcon(this);
599 putValue(SHORT_DESCRIPTION, tr("Click to close the dialog and to abort downloading"));
600 }
601
602 /**
603 * Cancels the download
604 */
605 public void run() {
606 setCanceled(true);
607 setVisible(false);
608 }
609
610 @Override
611 public void actionPerformed(ActionEvent e) {
612 Component panel = downloadSourcesTab.getSelectedComponent();
613 if (panel instanceof AbstractDownloadSourcePanel) {
614 AbstractDownloadSourcePanel<?> pnl = (AbstractDownloadSourcePanel<?>) panel;
615 run();
616 pnl.checkCancel();
617 } else {
618 run();
619 }
620 }
621 }
622
623 /**
624 * Action that is executed when the download button is pressed.
625 */
626 class DownloadAction extends AbstractAction {
627 DownloadAction() {
628 putValue(NAME, tr("Download"));
629 new ImageProvider("download").getResource().attachImageIcon(this);
630 putValue(SHORT_DESCRIPTION, tr("Click to download the currently selected area"));
631 setEnabled(!Main.isOffline(OnlineResource.OSM_API));
632 }
633
634 /**
635 * Starts the download and closes the dialog, if all requirements for the current download source are met.
636 * Otherwise the download is not started and the dialog remains visible.
637 */
638 public void run() {
639 Component panel = downloadSourcesTab.getSelectedComponent();
640 if (panel instanceof AbstractDownloadSourcePanel) {
641 AbstractDownloadSourcePanel<?> pnl = (AbstractDownloadSourcePanel<?>) panel;
642 DownloadSettings downloadSettings = getDownloadSettings();
643 if (pnl.checkDownload(downloadSettings)) {
644 rememberSettings();
645 setCanceled(false);
646 setVisible(false);
647 pnl.triggerDownload(downloadSettings);
648 }
649 }
650 }
651
652 @Override
653 public void actionPerformed(ActionEvent e) {
654 run();
655 }
656 }
657
658 class WindowEventHandler extends WindowAdapter {
659 @Override
660 public void windowClosing(WindowEvent e) {
661 new CancelAction().run();
662 }
663
664 @Override
665 public void windowActivated(WindowEvent e) {
666 btnDownload.requestFocusInWindow();
667 }
668 }
669}
Note: See TracBrowser for help on using the repository browser.