001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.properties;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007import java.io.IOException;
008import java.util.ArrayList;
009import java.util.Arrays;
010import java.util.List;
011
012import javax.swing.AbstractAction;
013import javax.swing.KeyStroke;
014import javax.xml.parsers.ParserConfigurationException;
015import javax.xml.xpath.XPathExpressionException;
016
017import org.openstreetmap.josm.data.osm.IRelation;
018import org.openstreetmap.josm.gui.MainApplication;
019import org.openstreetmap.josm.spi.preferences.Config;
020import org.openstreetmap.josm.tools.ImageProvider;
021import org.openstreetmap.josm.tools.LanguageInfo;
022import org.openstreetmap.josm.tools.Logging;
023import org.openstreetmap.josm.tools.Mediawiki;
024import org.openstreetmap.josm.tools.OpenBrowser;
025import org.openstreetmap.josm.tools.Utils;
026import org.xml.sax.SAXException;
027
028/**
029 * Launch browser with wiki help for selected object.
030 * @since 13521
031 */
032public abstract class HelpAction extends AbstractAction {
033
034    /**
035     * Constructs a new {@code HelpAction}.
036     */
037    protected HelpAction() {
038        putValue(SHORT_DESCRIPTION, tr("Launch browser with wiki help for selected object"));
039        new ImageProvider("help", "internet").getResource().attachImageIcon(this, true);
040        putValue(ACCELERATOR_KEY, getKeyStroke());
041    }
042
043    /**
044     * Returns the keystroke launching this action (F1 by default).
045     * @return the keystroke launching this action
046     */
047    public static KeyStroke getKeyStroke() {
048        return MainApplication.getMenu().help.getShortcut().getKeyStroke();
049    }
050
051    @Override
052    public void actionPerformed(ActionEvent e) {
053        // give the generic help page, if more than one element is selected
054        MainApplication.worker.execute(HelpAction::displayGenericHelp);
055    }
056
057    /**
058     * Displays the most specific wiki page for the given key/value.
059     * @param key Key
060     * @param val Value
061     * @since 14208
062     */
063    public static void displayTagHelp(String key, String val) {
064        final String lang = LanguageInfo.getWikiLanguagePrefix(LanguageInfo.LocaleType.OSM_WIKI);
065        final List<String> pages = Arrays.asList(
066                String.format("%sTag:%s=%s", lang, key, val),
067                String.format("Tag:%s=%s", key, val),
068                String.format("%sKey:%s", lang, key),
069                String.format("Key:%s", key),
070                String.format("%sMap_Features", lang),
071                "Map_Features"
072        );
073        displayHelp(pages);
074    }
075
076    /**
077     * Displays the most specific wiki page for the given relation.
078     * @param rel Relation
079     * @since 14208
080     */
081    public static void displayRelationHelp(IRelation<?> rel) {
082        final String lang = LanguageInfo.getWikiLanguagePrefix(LanguageInfo.LocaleType.OSM_WIKI);
083        final List<String> pages = new ArrayList<>();
084        String type = rel.get("type");
085        if (type != null) {
086            type = Utils.encodeUrl(type);
087        }
088
089        if (!Utils.isEmpty(type)) {
090            pages.add(String.format("%sRelation:%s", lang, type));
091            pages.add(String.format("Relation:%s", type));
092        }
093
094        pages.add(String.format("%sRelations", lang));
095        pages.add("Relations");
096        displayHelp(pages);
097    }
098
099    /**
100     * Displays the localized Map Features.
101     * @since 14208
102     */
103    public static void displayGenericHelp() {
104        final String lang = LanguageInfo.getWikiLanguagePrefix(LanguageInfo.LocaleType.OSM_WIKI);
105        final List<String> pages = Arrays.asList(
106                String.format("%sMap_Features", lang),
107                "Map_Features"
108        );
109        displayHelp(pages);
110    }
111
112    /**
113     * Display help by opening the first existing wiki page in the given list.
114     * @param pages list of wiki page names to test
115     * @since 14208
116     */
117    public static void displayHelp(final List<String> pages) {
118        try {
119            new Mediawiki(Config.getUrls().getOSMWiki())
120                    .findExistingPage(pages)
121                    .ifPresent(page -> OpenBrowser.displayUrl(Config.getUrls().getOSMWiki() + "/wiki/" + page));
122        } catch (IOException | ParserConfigurationException | XPathExpressionException | SAXException e1) {
123            Logging.error(e1);
124        }
125    }
126}