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}