001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005import static org.openstreetmap.josm.tools.I18n.trn; 006 007import java.awt.event.ActionEvent; 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. https://www.openstreetmap.org 040 */ 041 public static 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(""); 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 for (String prefix : new String[]{"http://api.openstreetmap.org/", "https://api.openstreetmap.org/"}) { 049 if (ret.startsWith(prefix)) { 050 ret = Main.getOSMWebsite() + "/" + ret.substring(prefix.length()); 051 break; 052 } 053 } 054 return ret; 055 } 056 057 /** 058 * Replies the base URL for browsing information about a user. 059 * 060 * @return the base URL, i.e. https://www.openstreetmap.org/user 061 */ 062 public static String getBaseUserUrl() { 063 String baseUrl = Main.pref.get("osm-server.url", OsmApi.DEFAULT_API_URL); 064 Pattern pattern = Pattern.compile("/api/?$"); 065 String ret = pattern.matcher(baseUrl).replaceAll("/user"); 066 if (ret.equals(baseUrl)) { 067 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)); 068 } 069 for (String prefix : new String[]{"http://api.openstreetmap.org/", "https://api.openstreetmap.org/"}) { 070 if (ret.startsWith(prefix)) { 071 ret = Main.getOSMWebsite() + "/" + ret.substring(prefix.length()); 072 break; 073 } 074 } 075 return ret; 076 } 077 078 public static boolean confirmLaunchMultiple(int numBrowsers) { 079 String msg = /* for correct i18n of plural forms - see #9110 */ trn( 080 "You are about to launch {0} browser window.<br>" 081 + "This may both clutter your screen with browser windows<br>" 082 + "and take some time to finish.", 083 "You are about to launch {0} browser windows.<br>" 084 + "This may both clutter your screen with browser windows<br>" 085 + "and take some time to finish.", numBrowsers, numBrowsers); 086 msg = "<html>" + msg + "</html>"; 087 ButtonSpec[] spec = new ButtonSpec[] { 088 new ButtonSpec( 089 tr("Continue"), 090 ImageProvider.get("ok"), 091 trn("Click to continue and to open {0} browser", "Click to continue and to open {0} browsers", numBrowsers, numBrowsers), 092 null // no specific help topic 093 ), 094 new ButtonSpec( 095 tr("Cancel"), 096 ImageProvider.get("cancel"), 097 tr("Click to abort launching external browsers"), 098 null // no specific help topic 099 ) 100 }; 101 int ret = HelpAwareOptionPane.showOptionDialog( 102 Main.parent, 103 msg, 104 tr("Warning"), 105 JOptionPane.WARNING_MESSAGE, 106 null, 107 spec, 108 spec[0], 109 HelpUtil.ht("/WarningMessages#ToManyBrowsersToOpen") 110 ); 111 return ret == 0; 112 } 113 114 protected void launchInfoBrowsersForSelectedPrimitives() { 115 List<OsmPrimitive> primitivesToShow = new ArrayList<>(getCurrentDataSet().getAllSelected()); 116 117 // filter out new primitives which are not yet uploaded to the server 118 // 119 Iterator<OsmPrimitive> it = primitivesToShow.iterator(); 120 while(it.hasNext()) { 121 if (it.next().isNew()) { 122 it.remove(); 123 } 124 } 125 126 if (primitivesToShow.isEmpty()) { 127 JOptionPane.showMessageDialog( 128 Main.parent, 129 tr("Please select at least one already uploaded node, way, or relation."), 130 tr("Warning"), 131 JOptionPane.WARNING_MESSAGE 132 ); 133 return; 134 } 135 136 // don't launch more than 10 browser instances / browser windows 137 // 138 int max = Math.min(10, primitivesToShow.size()); 139 if (primitivesToShow.size() > max && ! confirmLaunchMultiple(primitivesToShow.size())) 140 return; 141 for(int i = 0; i < max; i++) { 142 OpenBrowser.displayUrl(createInfoUrl(primitivesToShow.get(i))); 143 } 144 } 145 146 @Override 147 public void actionPerformed(ActionEvent e) { 148 launchInfoBrowsersForSelectedPrimitives(); 149 } 150 151 protected abstract String createInfoUrl(Object infoObject); 152 153 @Override 154 protected void updateEnabledState() { 155 setEnabled(getCurrentDataSet() != null && !getCurrentDataSet().getSelected().isEmpty()); 156 } 157 158 @Override 159 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) { 160 setEnabled(selection != null && !selection.isEmpty()); 161 } 162}