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.io.Serializable; 009import java.util.ArrayList; 010import java.util.List; 011 012import javax.swing.AbstractAction; 013import javax.swing.JOptionPane; 014 015import org.openstreetmap.josm.gui.HelpAwareOptionPane; 016import org.openstreetmap.josm.gui.MainApplication; 017import org.openstreetmap.josm.gui.help.HelpUtil; 018import org.openstreetmap.josm.tools.ImageProvider; 019import org.openstreetmap.josm.tools.OpenBrowser; 020import org.openstreetmap.josm.tools.Utils; 021 022/** 023 * Action to open browser on given URL. 024 * @see OpenBrowser 025 * @since 15706 026 */ 027public class OpenBrowserAction extends AbstractAction { 028 029 private final List<String> urls = new ArrayList<>(); 030 private final String originalName; 031 032 /** 033 * Constructs a new {@link OpenBrowserAction}. 034 * @param name the name of this action 035 * @param url the URL to launch 036 */ 037 public OpenBrowserAction(String name, String url) { 038 new ImageProvider("help/internet").getResource().attachImageIcon(this, true); 039 this.urls.add(url); 040 this.originalName = name; 041 updateNameAndDescription(); 042 } 043 044 /** 045 * Adds an additional URL to be launched. 046 * @param url the URL to launch 047 */ 048 public void addUrl(String url) { 049 urls.add(url); 050 updateNameAndDescription(); 051 } 052 053 private void updateNameAndDescription() { 054 final Serializable countString = urls.size() > 1 ? tr(" ({0})", urls.size()) : ""; 055 putValue(NAME, originalName + countString); 056 putValue(SHORT_DESCRIPTION, Utils.shortenString(tr("Open {0}", String.join(", ", urls)), 256)); 057 058 } 059 060 @Override 061 public void actionPerformed(ActionEvent e) { 062 final int size = urls.size(); 063 if (size > 10 && !confirmLaunchMultiple(size)) { 064 return; 065 } 066 for (String url : urls) { 067 OpenBrowser.displayUrl(url); 068 } 069 } 070 071 /** 072 * Asks user confirmation before launching a large number of browser windows. 073 * @param numBrowsers the number of browser windows to open 074 * @return {@code true} if the user confirms, {@code false} otherwise 075 */ 076 public static boolean confirmLaunchMultiple(int numBrowsers) { 077 String msg = /* for correct i18n of plural forms - see #9110 */ trn( 078 "You are about to launch {0} browser window.<br>" 079 + "This may both clutter your screen with browser windows<br>" 080 + "and take some time to finish.", 081 "You are about to launch {0} browser windows.<br>" 082 + "This may both clutter your screen with browser windows<br>" 083 + "and take some time to finish.", numBrowsers, numBrowsers); 084 HelpAwareOptionPane.ButtonSpec[] spec = { 085 new HelpAwareOptionPane.ButtonSpec( 086 tr("Continue"), 087 new ImageProvider("ok"), 088 trn("Click to continue and to open {0} browser", "Click to continue and to open {0} browsers", 089 numBrowsers, numBrowsers), 090 null // no specific help topic 091 ), 092 new HelpAwareOptionPane.ButtonSpec( 093 tr("Cancel"), 094 new ImageProvider("cancel"), 095 tr("Click to abort launching external browsers"), 096 null // no specific help topic 097 ) 098 }; 099 return 0 == HelpAwareOptionPane.showOptionDialog( 100 MainApplication.getMainFrame(), 101 new StringBuilder(msg).insert(0, "<html>").append("</html>").toString(), 102 tr("Warning"), 103 JOptionPane.WARNING_MESSAGE, 104 null, 105 spec, 106 spec[0], 107 HelpUtil.ht("/WarningMessages#ToManyBrowsersToOpen") 108 ); 109 } 110}