001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007import java.net.URL;
008import java.util.ArrayList;
009import java.util.Collection;
010import java.util.Iterator;
011import java.util.List;
012import java.util.regex.Pattern;
013
014import javax.swing.JOptionPane;
015
016import org.openstreetmap.josm.Main;
017import org.openstreetmap.josm.data.osm.OsmPrimitive;
018import org.openstreetmap.josm.gui.HelpAwareOptionPane;
019import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
020import org.openstreetmap.josm.gui.help.HelpUtil;
021import org.openstreetmap.josm.io.OsmApi;
022import org.openstreetmap.josm.tools.ImageProvider;
023import org.openstreetmap.josm.tools.OpenBrowser;
024import org.openstreetmap.josm.tools.Shortcut;
025
026public abstract class AbstractInfoAction extends JosmAction {
027
028    public AbstractInfoAction(boolean installAdapters) {
029        super(installAdapters);
030    }
031
032    public AbstractInfoAction(String name, String iconName, String tooltip, Shortcut shortcut, boolean register, String toolbarId, boolean installAdapters) {
033        super(name, iconName, tooltip, shortcut, register, toolbarId, installAdapters);
034    }
035
036    /**
037     * replies the base URL for browsing information about about a primitive
038     *
039     * @return the base URL, i.e. http://api.openstreetmap.org/browse
040     */
041    static public String getBaseBrowseUrl() {
042        String baseUrl = Main.pref.get("osm-server.url", OsmApi.DEFAULT_API_URL);
043        Pattern pattern = Pattern.compile("/api/?$");
044        String ret =  pattern.matcher(baseUrl).replaceAll("/browse");
045        if (ret.equals(baseUrl)) {
046            Main.warn(tr("Unexpected format of API base URL. Redirection to info or history page for OSM object will probably fail. API base URL is: ''{0}''",baseUrl));
047        }
048        if (ret.startsWith("http://api.openstreetmap.org/")) {
049            ret = ret.substring("http://api.openstreetmap.org/".length());
050            ret = Main.OSM_WEBSITE + "/" + ret;
051        }
052        return ret;
053    }
054
055    /**
056     * replies the base URL for browsing information about a user
057     *
058     * @return the base URL, i.e. http://www.openstreetmap.org/user
059     */
060    static public String getBaseUserUrl() {
061        String baseUrl = Main.pref.get("osm-server.url", OsmApi.DEFAULT_API_URL);
062        Pattern pattern = Pattern.compile("/api/?$");
063        String ret =  pattern.matcher(baseUrl).replaceAll("/user");
064        if (ret.equals(baseUrl)) {
065            Main.warn(tr("Unexpected format of API base URL. Redirection to user page for OSM user will probably fail. API base URL is: ''{0}''",baseUrl));
066        }
067        if (ret.startsWith("http://api.openstreetmap.org/")) {
068            ret = ret.substring("http://api.openstreetmap.org/".length());
069            ret = Main.OSM_WEBSITE + "/" + ret;
070        }
071        return ret;
072    }
073
074    protected void launchBrowser(URL url) {
075        OpenBrowser.displayUrl(
076                url.toString()
077        );
078    }
079
080    protected void launchBrowser(String url) {
081        OpenBrowser.displayUrl(
082                url
083        );
084    }
085
086    public static boolean confirmLaunchMultiple(int numBrowsers) {
087        String msg  = tr(
088                "You are about to launch {0} browser windows.<br>"
089                + "This may both clutter your screen with browser windows<br>"
090                + "and take some time to finish.", numBrowsers);
091        msg = "<html>" + msg + "</html>";
092        ButtonSpec[] spec = new ButtonSpec[] {
093                new ButtonSpec(
094                        tr("Continue"),
095                        ImageProvider.get("ok"),
096                        tr("Click to continue and to open {0} browsers", numBrowsers),
097                        null // no specific help topic
098                ),
099                new ButtonSpec(
100                        tr("Cancel"),
101                        ImageProvider.get("cancel"),
102                        tr("Click to abort launching external browsers"),
103                        null // no specific help topic
104                )
105        };
106        int ret = HelpAwareOptionPane.showOptionDialog(
107                Main.parent,
108                msg,
109                tr("Warning"),
110                JOptionPane.WARNING_MESSAGE,
111                null,
112                spec,
113                spec[0],
114                HelpUtil.ht("/WarningMessages#ToManyBrowsersToOpen")
115        );
116        return ret == 0;
117    }
118
119    protected void launchInfoBrowsersForSelectedPrimitives() {
120        List<OsmPrimitive> primitivesToShow = new ArrayList<OsmPrimitive>(getCurrentDataSet().getAllSelected());
121
122        // filter out new primitives which are not yet uploaded to the server
123        //
124        Iterator<OsmPrimitive> it = primitivesToShow.iterator();
125        while(it.hasNext()) {
126            if (it.next().isNew()) {
127                it.remove();
128            }
129        }
130
131        if (primitivesToShow.isEmpty()) {
132            JOptionPane.showMessageDialog(
133                    Main.parent,
134                    tr("Please select at least one already uploaded node, way, or relation."),
135                    tr("Warning"),
136                    JOptionPane.WARNING_MESSAGE
137            );
138            return;
139        }
140
141        // don't launch more than 10 browser instances / browser windows
142        //
143        int max = Math.min(10, primitivesToShow.size());
144        if (primitivesToShow.size() > max && ! confirmLaunchMultiple(primitivesToShow.size()))
145            return;
146        for(int i = 0; i < max; i++) {
147            launchBrowser(createInfoUrl(primitivesToShow.get(i)));
148        }
149    }
150
151    @Override
152    public void actionPerformed(ActionEvent e) {
153        launchInfoBrowsersForSelectedPrimitives();
154    }
155
156    protected abstract String createInfoUrl(Object infoObject);
157
158    @Override
159    protected void updateEnabledState() {
160        setEnabled(getCurrentDataSet() != null && !getCurrentDataSet().getSelected().isEmpty());
161    }
162
163    @Override
164    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
165        setEnabled(selection != null && !selection.isEmpty());
166    }
167}