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