001    // License: GPL. Copyright 2007 by Immanuel Scholz and others
002    package org.openstreetmap.josm.actions;
003    
004    import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005    import static org.openstreetmap.josm.tools.I18n.tr;
006    
007    import java.awt.GridBagConstraints;
008    import java.awt.GridBagLayout;
009    import java.awt.event.ActionEvent;
010    import java.awt.event.KeyEvent;
011    import java.util.ArrayList;
012    import java.util.Collections;
013    import java.util.LinkedList;
014    import java.util.List;
015    import java.util.concurrent.Future;
016    
017    import javax.swing.JCheckBox;
018    import javax.swing.JLabel;
019    import javax.swing.JOptionPane;
020    import javax.swing.JPanel;
021    import javax.swing.SwingUtilities;
022    
023    import org.openstreetmap.josm.Main;
024    import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
025    import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmChangeCompressedTask;
026    import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmCompressedTask;
027    import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmChangeTask;
028    import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
029    import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmUrlTask;
030    import org.openstreetmap.josm.actions.downloadtasks.DownloadTask;
031    import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
032    import org.openstreetmap.josm.gui.ExtendedDialog;
033    import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
034    import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
035    import org.openstreetmap.josm.tools.Shortcut;
036    
037    /**
038     * Open an URL input dialog and load data from the given URL.
039     *
040     * @author imi
041     */
042    public class OpenLocationAction extends JosmAction {
043    
044        protected final List<Class<? extends DownloadTask>> downloadTasks;
045        
046        /**
047         * Create an open action. The name is "Open a file".
048         */
049        public OpenLocationAction() {
050            /* I18N: Command to download a specific location/URL */
051            super(tr("Open Location..."), "openlocation", tr("Open an URL."),
052                    Shortcut.registerShortcut("system:open_location", tr("File: {0}", tr("Open Location...")), KeyEvent.VK_L, Shortcut.CTRL), true);
053            putValue("help", ht("/Action/OpenLocation"));
054            this.downloadTasks = new ArrayList<Class<? extends DownloadTask>>();
055            addDownloadTaskClass(DownloadOsmTask.class);
056            addDownloadTaskClass(DownloadGpsTask.class);
057            addDownloadTaskClass(DownloadOsmChangeTask.class);
058            addDownloadTaskClass(DownloadOsmUrlTask.class);
059            addDownloadTaskClass(DownloadOsmCompressedTask.class);
060            addDownloadTaskClass(DownloadOsmChangeCompressedTask.class);
061        }
062    
063        /**
064         * Restore the current history from the preferences
065         *
066         * @param cbHistory
067         */
068        protected void restoreUploadAddressHistory(HistoryComboBox cbHistory) {
069            List<String> cmtHistory = new LinkedList<String>(Main.pref.getCollection(getClass().getName() + ".uploadAddressHistory", new LinkedList<String>()));
070            // we have to reverse the history, because ComboBoxHistory will reverse it again
071            // in addElement()
072            //
073            Collections.reverse(cmtHistory);
074            cbHistory.setPossibleItems(cmtHistory);
075        }
076    
077        /**
078         * Remind the current history in the preferences
079         * @param cbHistory
080         */
081        protected void remindUploadAddressHistory(HistoryComboBox cbHistory) {
082            cbHistory.addCurrentItemToHistory();
083            Main.pref.putCollection(getClass().getName() + ".uploadAddressHistory", cbHistory.getHistory());
084        }
085    
086        public void actionPerformed(ActionEvent e) {
087    
088            JCheckBox layer = new JCheckBox(tr("Separate Layer"));
089            layer.setToolTipText(tr("Select if the data should be downloaded into a new layer"));
090            layer.setSelected(Main.pref.getBoolean("download.newlayer"));
091            JPanel all = new JPanel(new GridBagLayout());
092            GridBagConstraints gc = new GridBagConstraints();
093            gc.fill = GridBagConstraints.HORIZONTAL;
094            gc.weightx = 1.0;
095            gc.anchor = GridBagConstraints.FIRST_LINE_START;
096            all.add(new JLabel(tr("Enter URL to download:")), gc);
097            HistoryComboBox uploadAddresses = new HistoryComboBox();
098            uploadAddresses.setToolTipText(tr("Enter an URL from where data should be downloaded"));
099            restoreUploadAddressHistory(uploadAddresses);
100            gc.gridy = 1;
101            all.add(uploadAddresses, gc);
102            gc.gridy = 2;
103            gc.fill = GridBagConstraints.BOTH;
104            gc.weighty = 1.0;
105            all.add(layer, gc);
106            ExtendedDialog dialog = new ExtendedDialog(Main.parent,
107                    tr("Download Location"),
108                    new String[] {tr("Download URL"), tr("Cancel")}
109            );
110            dialog.setContent(all, false /* don't embedded content in JScrollpane  */);
111            dialog.setButtonIcons(new String[] {"download.png", "cancel.png"});
112            dialog.setToolTipTexts(new String[] {
113                    tr("Start downloading data"),
114                    tr("Close dialog and cancel downloading")
115            });
116            dialog.configureContextsensitiveHelp("/Action/OpenLocation", true /* show help button */);
117            dialog.showDialog();
118            if (dialog.getValue() != 1) return;
119            remindUploadAddressHistory(uploadAddresses);
120            openUrl(layer.isSelected(), uploadAddresses.getText());
121        }
122    
123        /**
124         * Open the given URL.
125         */
126        public void openUrl(boolean new_layer, final String url) {
127            PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download Data"));
128            DownloadTask task = null;
129            Future<?> future = null;
130            for (int i = 0; future == null && i < downloadTasks.size(); i++) {
131                Class<? extends DownloadTask> taskClass = downloadTasks.get(i);
132                if (taskClass != null) {
133                    try {
134                        task = taskClass.getConstructor().newInstance();
135                        if (task.acceptsUrl(url)) {
136                            future = task.loadUrl(new_layer, url, monitor);
137                        }
138                    } catch (Exception e) {
139                        e.printStackTrace();
140                    }
141                }
142            }
143            if (future != null) {
144                Main.worker.submit(new PostDownloadHandler(task, future));
145            } else {
146                SwingUtilities.invokeLater(new Runnable() {
147                    public void run() {
148                        JOptionPane.showMessageDialog(Main.parent, tr(
149                                "<html>Cannot open URL ''{0}'' because no suitable download task is available.</html>",
150                                url), tr("Download Location"), JOptionPane.ERROR_MESSAGE);
151                    }
152                });
153            }
154        }
155        
156        public boolean addDownloadTaskClass(Class<? extends DownloadTask> taskClass) {
157            return this.downloadTasks.add(taskClass);
158        }
159    }