001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.download.overpass;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Component;
007import java.awt.event.ActionEvent;
008import java.util.ArrayList;
009import java.util.Collections;
010import java.util.List;
011import java.util.Objects;
012import java.util.function.Function;
013import java.util.stream.Collectors;
014
015import javax.swing.AbstractAction;
016import javax.swing.Action;
017
018import org.openstreetmap.josm.gui.download.OverpassQueryWizardDialog;
019import org.openstreetmap.josm.tools.ImageProvider;
020
021/**
022 * Registers the overpass query wizards.
023 * @author Michael Zangl
024 * @since 13930
025 */
026public final class OverpassWizardRegistration {
027    /**
028     * A list of all registered wizards. Needs to be synchronized since plugin registration may happen outside main thread / asynchronously.
029     */
030    private static final List<Function<OverpassWizardCallbacks, Action>> wizards = Collections.synchronizedList(new ArrayList<>());
031
032    /**
033     * Registers a wizard to be added to the overpass download dialog
034     * <p>
035     * To be called by plugins during the JOSM boot process or at least before opening the download dialog for the first time.
036     * @param wizard The wizard to register
037     * @since 13930, 16355 (signature)
038     */
039    public static void registerWizard(Function<OverpassWizardCallbacks, Action> wizard) {
040        Objects.requireNonNull(wizard, "wizard");
041        wizards.add(wizard);
042    }
043
044    /**
045     * Gets all wizards that are currently registered.
046     * @param callbacks wizard callbacks
047     * @return The list of wizards.
048     */
049    public static List<Action> getWizards(OverpassWizardCallbacks callbacks) {
050        return wizards.stream()
051                .map(x -> x.apply(callbacks))
052                .collect(Collectors.toList());
053    }
054
055    static {
056        // Register the default wizard
057        registerWizard(callbacks -> new AbstractAction(tr("Query Wizard")) {
058            {
059                putValue(SHORT_DESCRIPTION, tr("Build an Overpass query using the query wizard"));
060                new ImageProvider("dialogs/magic-wand").getResource().attachImageIcon(this, true);
061            }
062            @Override
063            public void actionPerformed(ActionEvent e) {
064                new OverpassQueryWizardDialog(callbacks).showDialog();
065            }
066        });
067    }
068
069    private OverpassWizardRegistration() {
070        // hidden
071    }
072
073    /**
074     * Wizard callbacks required by {@link #registerWizard}
075     * @author Michael Zangl
076     * @since 13930
077     */
078    public interface OverpassWizardCallbacks {
079        /**
080         * Send the resulting query
081         * @param resultingQuery The query that is used by the wizard
082         */
083        void submitWizardResult(String resultingQuery);
084
085        /**
086         * Get the parent component to use when opening the wizard dialog.
087         * @return The component.
088         */
089        Component getParent();
090    }
091}