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