194986e745141118cace0391da1b4dc8533408751Tor Norbye/*
294986e745141118cace0391da1b4dc8533408751Tor Norbye * Copyright (C) 2010 The Android Open Source Project
394986e745141118cace0391da1b4dc8533408751Tor Norbye *
494986e745141118cace0391da1b4dc8533408751Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License");
594986e745141118cace0391da1b4dc8533408751Tor Norbye * you may not use this file except in compliance with the License.
694986e745141118cace0391da1b4dc8533408751Tor Norbye * You may obtain a copy of the License at
794986e745141118cace0391da1b4dc8533408751Tor Norbye *
894986e745141118cace0391da1b4dc8533408751Tor Norbye *      http://www.eclipse.org/org/documents/epl-v10.php
994986e745141118cace0391da1b4dc8533408751Tor Norbye *
1094986e745141118cace0391da1b4dc8533408751Tor Norbye * Unless required by applicable law or agreed to in writing, software
1194986e745141118cace0391da1b4dc8533408751Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS,
1294986e745141118cace0391da1b4dc8533408751Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1394986e745141118cace0391da1b4dc8533408751Tor Norbye * See the License for the specific language governing permissions and
1494986e745141118cace0391da1b4dc8533408751Tor Norbye * limitations under the License.
1594986e745141118cace0391da1b4dc8533408751Tor Norbye */
1694986e745141118cace0391da1b4dc8533408751Tor Norbye
1794986e745141118cace0391da1b4dc8533408751Tor Norbyepackage com.android.ide.common.api;
1894986e745141118cace0391da1b4dc8533408751Tor Norbye
195d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbyeimport com.android.annotations.NonNull;
205d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbyeimport com.android.annotations.Nullable;
2185e4a1a9dd133abb879ec211ce8dd385004edf22Xavier Ducrohetimport com.android.utils.Pair;
223db9393ba06bbf70fa7b4a6db1ef60396979a1d4Tor Norbyeimport com.google.common.annotations.Beta;
2394986e745141118cace0391da1b4dc8533408751Tor Norbye
2494986e745141118cace0391da1b4dc8533408751Tor Norbyeimport java.net.URL;
2594986e745141118cace0391da1b4dc8533408751Tor Norbyeimport java.util.ArrayList;
2694986e745141118cace0391da1b4dc8533408751Tor Norbyeimport java.util.List;
2794986e745141118cace0391da1b4dc8533408751Tor Norbyeimport java.util.regex.Pattern;
2894986e745141118cace0391da1b4dc8533408751Tor Norbye
2994986e745141118cace0391da1b4dc8533408751Tor Norbye/**
3094986e745141118cace0391da1b4dc8533408751Tor Norbye * A {@link RuleAction} represents an action provided by an {@link IViewRule}, typically
3194986e745141118cace0391da1b4dc8533408751Tor Norbye * shown in a context menu or in the layout actions bar.
3294986e745141118cace0391da1b4dc8533408751Tor Norbye * <p/>
3394986e745141118cace0391da1b4dc8533408751Tor Norbye * Each action should have a reasonably unique ID. This is used when multiple nodes
3494986e745141118cace0391da1b4dc8533408751Tor Norbye * are selected to filter the actions down to just those actions that are supported
3594986e745141118cace0391da1b4dc8533408751Tor Norbye * across all selected nodes. If an action does not support multiple nodes, it can
3694986e745141118cace0391da1b4dc8533408751Tor Norbye * return false from {@link #supportsMultipleNodes()}.
3794986e745141118cace0391da1b4dc8533408751Tor Norbye * <p/>
3894986e745141118cace0391da1b4dc8533408751Tor Norbye * Actions can be grouped into a hierarchy of sub-menus using the {@link NestedAction} class,
3994986e745141118cace0391da1b4dc8533408751Tor Norbye * or into a flat submenu using the {@link Choices} class.
4094986e745141118cace0391da1b4dc8533408751Tor Norbye * <p/>
4194986e745141118cace0391da1b4dc8533408751Tor Norbye * Actions (including separators) all have a "sort priority", and this is used to
4294986e745141118cace0391da1b4dc8533408751Tor Norbye * sort the menu items or toolbar buttons into a specific order.
4394986e745141118cace0391da1b4dc8533408751Tor Norbye * <p>
4494986e745141118cace0391da1b4dc8533408751Tor Norbye * <b>NOTE: This is not a public or final API; if you rely on this be prepared
4594986e745141118cace0391da1b4dc8533408751Tor Norbye * to adjust your code for the next tools release.</b>
4694986e745141118cace0391da1b4dc8533408751Tor Norbye * </p>
4794986e745141118cace0391da1b4dc8533408751Tor Norbye */
483db9393ba06bbf70fa7b4a6db1ef60396979a1d4Tor Norbye@Beta
4994986e745141118cace0391da1b4dc8533408751Tor Norbyepublic class RuleAction implements Comparable<RuleAction> {
5094986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
5194986e745141118cace0391da1b4dc8533408751Tor Norbye     * Character used to split multiple checked choices.
5294986e745141118cace0391da1b4dc8533408751Tor Norbye     * The pipe character "|" is used, to natively match Android resource flag separators.
5394986e745141118cace0391da1b4dc8533408751Tor Norbye     */
5494986e745141118cace0391da1b4dc8533408751Tor Norbye    public final static String CHOICE_SEP = "|"; //$NON-NLS-1$
5594986e745141118cace0391da1b4dc8533408751Tor Norbye
5694986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
5794986e745141118cace0391da1b4dc8533408751Tor Norbye     * Same as {@link #CHOICE_SEP} but safe for use in regular expressions.
5894986e745141118cace0391da1b4dc8533408751Tor Norbye     */
5994986e745141118cace0391da1b4dc8533408751Tor Norbye    public final static String CHOICE_SEP_PATTERN = Pattern.quote(CHOICE_SEP);
6094986e745141118cace0391da1b4dc8533408751Tor Norbye
6194986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
6294986e745141118cace0391da1b4dc8533408751Tor Norbye     * The unique id of the action.
6394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @see #getId()
6494986e745141118cace0391da1b4dc8533408751Tor Norbye     */
6594986e745141118cace0391da1b4dc8533408751Tor Norbye    private final String mId;
6694986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
6794986e745141118cace0391da1b4dc8533408751Tor Norbye     * The UI-visible title of the action.
6894986e745141118cace0391da1b4dc8533408751Tor Norbye     */
6994986e745141118cace0391da1b4dc8533408751Tor Norbye    private final String mTitle;
7094986e745141118cace0391da1b4dc8533408751Tor Norbye
7194986e745141118cace0391da1b4dc8533408751Tor Norbye    /** A URL pointing to an icon, or null */
7294986e745141118cace0391da1b4dc8533408751Tor Norbye    private URL mIconUrl;
7394986e745141118cace0391da1b4dc8533408751Tor Norbye
7494986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
7594986e745141118cace0391da1b4dc8533408751Tor Norbye     * A callback executed when the action is selected in the context menu.
7694986e745141118cace0391da1b4dc8533408751Tor Norbye     */
7794986e745141118cace0391da1b4dc8533408751Tor Norbye    private final IMenuCallback mCallback;
7894986e745141118cace0391da1b4dc8533408751Tor Norbye
7994986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
8094986e745141118cace0391da1b4dc8533408751Tor Norbye     * The sorting priority of this item; actions can be sorted according to these
8194986e745141118cace0391da1b4dc8533408751Tor Norbye     */
8294986e745141118cace0391da1b4dc8533408751Tor Norbye    protected final int mSortPriority;
8394986e745141118cace0391da1b4dc8533408751Tor Norbye
8494986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
8594986e745141118cace0391da1b4dc8533408751Tor Norbye     * Whether this action supports multiple nodes, see
8694986e745141118cace0391da1b4dc8533408751Tor Norbye     * {@link #supportsMultipleNodes()} for details.
8794986e745141118cace0391da1b4dc8533408751Tor Norbye     */
8894986e745141118cace0391da1b4dc8533408751Tor Norbye    private final boolean mSupportsMultipleNodes;
8994986e745141118cace0391da1b4dc8533408751Tor Norbye
9094986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
9194986e745141118cace0391da1b4dc8533408751Tor Norbye     * Special value which will insert a separator in the choices' submenu.
9294986e745141118cace0391da1b4dc8533408751Tor Norbye     */
9394986e745141118cace0391da1b4dc8533408751Tor Norbye    public final static String SEPARATOR = "----";
9494986e745141118cace0391da1b4dc8533408751Tor Norbye
9594986e745141118cace0391da1b4dc8533408751Tor Norbye    // Factories
9694986e745141118cace0391da1b4dc8533408751Tor Norbye
9794986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
9894986e745141118cace0391da1b4dc8533408751Tor Norbye     * Constructs a new separator which will be shown in places where separators
9994986e745141118cace0391da1b4dc8533408751Tor Norbye     * are supported such as context menus
10094986e745141118cace0391da1b4dc8533408751Tor Norbye     *
10194986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority a priority used for sorting this action
10294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return a new separator
10394986e745141118cace0391da1b4dc8533408751Tor Norbye     */
1045d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
10594986e745141118cace0391da1b4dc8533408751Tor Norbye    public static Separator createSeparator(int sortPriority) {
10694986e745141118cace0391da1b4dc8533408751Tor Norbye        return new Separator(sortPriority, true /* supportsMultipleNodes*/);
10794986e745141118cace0391da1b4dc8533408751Tor Norbye    }
10894986e745141118cace0391da1b4dc8533408751Tor Norbye
10994986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
11094986e745141118cace0391da1b4dc8533408751Tor Norbye     * Constructs a new base {@link RuleAction} with its ID, title and action callback.
11194986e745141118cace0391da1b4dc8533408751Tor Norbye     *
11294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param id The unique ID of the action. Must not be null.
11394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param title The title of the action. Must not be null.
11494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param callback The callback executed when the action is selected.
11594986e745141118cace0391da1b4dc8533408751Tor Norbye     *            Must not be null.
11694986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrl a URL pointing to an icon to use for this action, or null
11794986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority a priority used for sorting this action
11894986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param supportsMultipleNodes whether this action supports multiple nodes,
11994986e745141118cace0391da1b4dc8533408751Tor Norbye     *            see {@link #supportsMultipleNodes()} for details
12094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the new {@link RuleAction}
12194986e745141118cace0391da1b4dc8533408751Tor Norbye     */
1225d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
1235d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    public static RuleAction createAction(
1245d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String id,
1255d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String title,
1265d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull IMenuCallback callback,
1275d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable URL iconUrl,
1285d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            int sortPriority,
1295d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            boolean supportsMultipleNodes) {
13094986e745141118cace0391da1b4dc8533408751Tor Norbye        RuleAction action = new RuleAction(id, title, callback, sortPriority,
13194986e745141118cace0391da1b4dc8533408751Tor Norbye                supportsMultipleNodes);
13294986e745141118cace0391da1b4dc8533408751Tor Norbye        action.setIconUrl(iconUrl);
13394986e745141118cace0391da1b4dc8533408751Tor Norbye
13494986e745141118cace0391da1b4dc8533408751Tor Norbye        return action;
13594986e745141118cace0391da1b4dc8533408751Tor Norbye    }
13694986e745141118cace0391da1b4dc8533408751Tor Norbye
13794986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
13894986e745141118cace0391da1b4dc8533408751Tor Norbye     * Creates a new immutable toggle action.
13994986e745141118cace0391da1b4dc8533408751Tor Norbye     *
14094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param id The unique id of the action. Cannot be null.
14194986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param title The UI-visible title of the context menu item. Cannot be null.
14294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param isChecked Whether the context menu item has a check mark.
14394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param callback A callback to execute when the context menu item is
14494986e745141118cace0391da1b4dc8533408751Tor Norbye     *            selected.
14594986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrl a URL pointing to an icon to use for this action, or null
14694986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority a priority used for sorting this action
14794986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param supportsMultipleNodes whether this action supports multiple nodes,
14894986e745141118cace0391da1b4dc8533408751Tor Norbye     *            see {@link #supportsMultipleNodes()} for details
14994986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the new {@link Toggle}
15094986e745141118cace0391da1b4dc8533408751Tor Norbye     */
1515d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
1525d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    public static Toggle createToggle(
1535d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String id,
1545d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String title,
1555d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            boolean isChecked,
1565d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull IMenuCallback callback,
1575d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable URL iconUrl,
1585d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            int sortPriority,
15994986e745141118cace0391da1b4dc8533408751Tor Norbye            boolean supportsMultipleNodes) {
16094986e745141118cace0391da1b4dc8533408751Tor Norbye        Toggle toggle = new Toggle(id, title, isChecked, callback, sortPriority,
16194986e745141118cace0391da1b4dc8533408751Tor Norbye                supportsMultipleNodes);
16294986e745141118cace0391da1b4dc8533408751Tor Norbye        toggle.setIconUrl(iconUrl);
16394986e745141118cace0391da1b4dc8533408751Tor Norbye        return toggle;
16494986e745141118cace0391da1b4dc8533408751Tor Norbye    }
16594986e745141118cace0391da1b4dc8533408751Tor Norbye
16694986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
16794986e745141118cace0391da1b4dc8533408751Tor Norbye     * Creates a new immutable multiple-choice action with a defined ordered set
16894986e745141118cace0391da1b4dc8533408751Tor Norbye     * of action children.
16994986e745141118cace0391da1b4dc8533408751Tor Norbye     *
17094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param id The unique id of the action. Cannot be null.
17194986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param title The title of the action to be displayed to the user
17294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param provider Provides the actions to be shown as children of this
17394986e745141118cace0391da1b4dc8533408751Tor Norbye     *            action
17494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param callback A callback to execute when the context menu item is
17594986e745141118cace0391da1b4dc8533408751Tor Norbye     *            selected.
17694986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrl the icon to use for the multiple choice action itself
17794986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority the sorting priority to use for the multiple choice
17894986e745141118cace0391da1b4dc8533408751Tor Norbye     *            action itself
17994986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param supportsMultipleNodes whether this action supports multiple nodes,
18094986e745141118cace0391da1b4dc8533408751Tor Norbye     *            see {@link #supportsMultipleNodes()} for details
18194986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the new {@link NestedAction}
18294986e745141118cace0391da1b4dc8533408751Tor Norbye     */
1835d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
1845d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    public static NestedAction createChoices(
1855d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String id,
1865d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String title,
1875d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull IMenuCallback callback,
1885d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable URL iconUrl,
1895d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            int sortPriority,
1905d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            boolean supportsMultipleNodes,
1915d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull ActionProvider provider) {
19294986e745141118cace0391da1b4dc8533408751Tor Norbye        NestedAction choices = new NestedAction(id, title, provider, callback,
19394986e745141118cace0391da1b4dc8533408751Tor Norbye                sortPriority, supportsMultipleNodes);
19494986e745141118cace0391da1b4dc8533408751Tor Norbye        choices.setIconUrl(iconUrl);
19594986e745141118cace0391da1b4dc8533408751Tor Norbye        return choices;
19694986e745141118cace0391da1b4dc8533408751Tor Norbye    }
19794986e745141118cace0391da1b4dc8533408751Tor Norbye
19894986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
19994986e745141118cace0391da1b4dc8533408751Tor Norbye     * Creates a new immutable multiple-choice action with a defined ordered set
20094986e745141118cace0391da1b4dc8533408751Tor Norbye     * of children.
20194986e745141118cace0391da1b4dc8533408751Tor Norbye     *
20294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param id The unique id of the action. Cannot be null.
20394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param title The title of the action to be displayed to the user
20494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrls The icon urls for the children items (may be null)
20594986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param ids The internal ids for the children
20694986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param current The id(s) of the current choice(s) that will be check
20794986e745141118cace0391da1b4dc8533408751Tor Norbye     *            marked. Can be null. Can be an id not present in the choices
20894986e745141118cace0391da1b4dc8533408751Tor Norbye     *            map. There can be more than one id separated by
20994986e745141118cace0391da1b4dc8533408751Tor Norbye     *            {@link #CHOICE_SEP}.
21094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param callback A callback to execute when the context menu item is
21194986e745141118cace0391da1b4dc8533408751Tor Norbye     *            selected.
21294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param titles The UI-visible titles of the children
21394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrl the icon to use for the multiple choice action itself
21494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority the sorting priority to use for the multiple choice
21594986e745141118cace0391da1b4dc8533408751Tor Norbye     *            action itself
21694986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param supportsMultipleNodes whether this action supports multiple nodes,
21794986e745141118cace0391da1b4dc8533408751Tor Norbye     *            see {@link #supportsMultipleNodes()} for details
21894986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the new {@link Choices}
21994986e745141118cace0391da1b4dc8533408751Tor Norbye     */
2205d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
2215d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    public static Choices createChoices(
2225d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String id,
2235d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String title,
2245d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull IMenuCallback callback,
2255d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull List<String> titles,
2265d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable List<URL> iconUrls,
2275d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull List<String> ids,
2285d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable String current,
2295d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable URL iconUrl,
2305d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            int sortPriority,
2315d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            boolean supportsMultipleNodes) {
23294986e745141118cace0391da1b4dc8533408751Tor Norbye        Choices choices = new Choices(id, title, callback, titles, iconUrls,
23394986e745141118cace0391da1b4dc8533408751Tor Norbye                ids, current, sortPriority, supportsMultipleNodes);
23494986e745141118cace0391da1b4dc8533408751Tor Norbye        choices.setIconUrl(iconUrl);
23594986e745141118cace0391da1b4dc8533408751Tor Norbye
23694986e745141118cace0391da1b4dc8533408751Tor Norbye        return choices;
23794986e745141118cace0391da1b4dc8533408751Tor Norbye    }
23894986e745141118cace0391da1b4dc8533408751Tor Norbye
23994986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
24094986e745141118cace0391da1b4dc8533408751Tor Norbye     * Creates a new immutable multiple-choice action with a defined ordered set
24194986e745141118cace0391da1b4dc8533408751Tor Norbye     * of children.
24294986e745141118cace0391da1b4dc8533408751Tor Norbye     *
24394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param id The unique id of the action. Cannot be null.
24494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param title The title of the action to be displayed to the user
24594986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrls The icon urls for the children items (may be null)
24694986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param current The id(s) of the current choice(s) that will be check
24794986e745141118cace0391da1b4dc8533408751Tor Norbye     *            marked. Can be null. Can be an id not present in the choices
24894986e745141118cace0391da1b4dc8533408751Tor Norbye     *            map. There can be more than one id separated by
24994986e745141118cace0391da1b4dc8533408751Tor Norbye     *            {@link #CHOICE_SEP}.
25094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param callback A callback to execute when the context menu item is
25194986e745141118cace0391da1b4dc8533408751Tor Norbye     *            selected.
25294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrl the icon to use for the multiple choice action itself
25394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority the sorting priority to use for the multiple choice
25494986e745141118cace0391da1b4dc8533408751Tor Norbye     *            action itself
25594986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param supportsMultipleNodes whether this action supports multiple nodes,
25694986e745141118cace0391da1b4dc8533408751Tor Norbye     *            see {@link #supportsMultipleNodes()} for details
25794986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param idsAndTitles a list of pairs (of ids and titles) to use for the
25894986e745141118cace0391da1b4dc8533408751Tor Norbye     *            menu items
25994986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the new {@link Choices}
26094986e745141118cace0391da1b4dc8533408751Tor Norbye     */
2615d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
2625d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    public static Choices createChoices(
2635d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String id,
2645d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String title,
2655d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull IMenuCallback callback,
2665d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable List<URL> iconUrls,
2675d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable String current,
2685d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable URL iconUrl,
2695d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            int sortPriority,
2705d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            boolean supportsMultipleNodes,
2715d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull List<Pair<String, String>> idsAndTitles) {
27294986e745141118cace0391da1b4dc8533408751Tor Norbye        int itemCount = idsAndTitles.size();
27394986e745141118cace0391da1b4dc8533408751Tor Norbye        List<String> titles = new ArrayList<String>(itemCount);
27494986e745141118cace0391da1b4dc8533408751Tor Norbye        List<String> ids = new ArrayList<String>(itemCount);
27594986e745141118cace0391da1b4dc8533408751Tor Norbye        for (Pair<String, String> pair : idsAndTitles) {
27694986e745141118cace0391da1b4dc8533408751Tor Norbye            ids.add(pair.getFirst());
27794986e745141118cace0391da1b4dc8533408751Tor Norbye            titles.add(pair.getSecond());
27894986e745141118cace0391da1b4dc8533408751Tor Norbye        }
27994986e745141118cace0391da1b4dc8533408751Tor Norbye        Choices choices = new Choices(id, title, callback, titles, iconUrls,
28094986e745141118cace0391da1b4dc8533408751Tor Norbye                ids, current, sortPriority, supportsMultipleNodes);
28194986e745141118cace0391da1b4dc8533408751Tor Norbye        choices.setIconUrl(iconUrl);
28294986e745141118cace0391da1b4dc8533408751Tor Norbye        return choices;
28394986e745141118cace0391da1b4dc8533408751Tor Norbye    }
28494986e745141118cace0391da1b4dc8533408751Tor Norbye
28594986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
28694986e745141118cace0391da1b4dc8533408751Tor Norbye     * Creates a new immutable multiple-choice action with lazily computed children.
28794986e745141118cace0391da1b4dc8533408751Tor Norbye     *
28894986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param id The unique id of the action. Cannot be null.
28994986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param title The title of the multiple-choice itself
29094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param callback A callback to execute when the context menu item is
29194986e745141118cace0391da1b4dc8533408751Tor Norbye     *            selected.
29294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param provider the provider which provides choices lazily
29394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param current The id(s) of the current choice(s) that will be check
29494986e745141118cace0391da1b4dc8533408751Tor Norbye     *            marked. Can be null. Can be an id not present in the choice
29594986e745141118cace0391da1b4dc8533408751Tor Norbye     *            alternatives. There can be more than one id separated by
29694986e745141118cace0391da1b4dc8533408751Tor Norbye     *            {@link #CHOICE_SEP}.
29794986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrl the icon to use for the multiple choice action itself
29894986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority the sorting priority to use for the multiple choice
29994986e745141118cace0391da1b4dc8533408751Tor Norbye     *            action itself
30094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param supportsMultipleNodes whether this action supports multiple nodes,
30194986e745141118cace0391da1b4dc8533408751Tor Norbye     *            see {@link #supportsMultipleNodes()} for details
30294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the new {@link Choices}
30394986e745141118cace0391da1b4dc8533408751Tor Norbye     */
3045d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
3055d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    public static Choices createChoices(
3065d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String id,
3075d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String title,
3085d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            IMenuCallback callback,
3095d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull ChoiceProvider provider,
3105d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable String current,
3115d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @Nullable URL iconUrl,
3125d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            int sortPriority,
3135d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            boolean supportsMultipleNodes) {
31494986e745141118cace0391da1b4dc8533408751Tor Norbye        Choices choices = new DelayedChoices(id, title, callback,
31594986e745141118cace0391da1b4dc8533408751Tor Norbye                current, provider, sortPriority, supportsMultipleNodes);
31694986e745141118cace0391da1b4dc8533408751Tor Norbye        choices.setIconUrl(iconUrl);
31794986e745141118cace0391da1b4dc8533408751Tor Norbye        return choices;
31894986e745141118cace0391da1b4dc8533408751Tor Norbye    }
31994986e745141118cace0391da1b4dc8533408751Tor Norbye
32094986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
32194986e745141118cace0391da1b4dc8533408751Tor Norbye     * Creates a new {@link RuleAction} with the given id and the given title.
32294986e745141118cace0391da1b4dc8533408751Tor Norbye     * Actions which have the same id and the same title are deemed equivalent.
32394986e745141118cace0391da1b4dc8533408751Tor Norbye     *
32494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param id The unique id of the action, which must be similar for all actions that
32594986e745141118cace0391da1b4dc8533408751Tor Norbye     *           perform the same task. Cannot be null.
32694986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param title The UI-visible title of the action.
32794986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param callback A callback to execute when the context menu item is
32894986e745141118cace0391da1b4dc8533408751Tor Norbye     *            selected.
32994986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param sortPriority a priority used for sorting this action
33094986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param supportsMultipleNodes the new return value for
33194986e745141118cace0391da1b4dc8533408751Tor Norbye     *            {@link #supportsMultipleNodes()}
33294986e745141118cace0391da1b4dc8533408751Tor Norbye     */
3335d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    private RuleAction(
3345d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String id,
3355d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull String title,
3365d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            @NonNull IMenuCallback callback,
3375d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            int sortPriority,
33894986e745141118cace0391da1b4dc8533408751Tor Norbye            boolean supportsMultipleNodes) {
33994986e745141118cace0391da1b4dc8533408751Tor Norbye        mId = id;
34094986e745141118cace0391da1b4dc8533408751Tor Norbye        mTitle = title;
34194986e745141118cace0391da1b4dc8533408751Tor Norbye        mSortPriority = sortPriority;
34294986e745141118cace0391da1b4dc8533408751Tor Norbye        mSupportsMultipleNodes = supportsMultipleNodes;
34394986e745141118cace0391da1b4dc8533408751Tor Norbye        mCallback = callback;
34494986e745141118cace0391da1b4dc8533408751Tor Norbye    }
34594986e745141118cace0391da1b4dc8533408751Tor Norbye
34694986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
34794986e745141118cace0391da1b4dc8533408751Tor Norbye     * Returns the unique id of the action. In the context of a multiple selection,
34894986e745141118cace0391da1b4dc8533408751Tor Norbye     * actions which have the same id are collapsed together and must represent the same
34994986e745141118cace0391da1b4dc8533408751Tor Norbye     * action. Cannot be null.
35094986e745141118cace0391da1b4dc8533408751Tor Norbye     *
35194986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the unique id of the action, never null
35294986e745141118cace0391da1b4dc8533408751Tor Norbye     */
3535d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
35494986e745141118cace0391da1b4dc8533408751Tor Norbye    public String getId() {
35594986e745141118cace0391da1b4dc8533408751Tor Norbye        return mId;
35694986e745141118cace0391da1b4dc8533408751Tor Norbye    }
35794986e745141118cace0391da1b4dc8533408751Tor Norbye
35894986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
35994986e745141118cace0391da1b4dc8533408751Tor Norbye     * Returns the UI-visible title of the action, shown in the context menu.
36094986e745141118cace0391da1b4dc8533408751Tor Norbye     * Cannot be null.
36194986e745141118cace0391da1b4dc8533408751Tor Norbye     *
36294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the user name of the action, never null
36394986e745141118cace0391da1b4dc8533408751Tor Norbye     */
3645d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
36594986e745141118cace0391da1b4dc8533408751Tor Norbye    public String getTitle() {
36694986e745141118cace0391da1b4dc8533408751Tor Norbye        return mTitle;
36794986e745141118cace0391da1b4dc8533408751Tor Norbye    }
36894986e745141118cace0391da1b4dc8533408751Tor Norbye
36994986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
37094986e745141118cace0391da1b4dc8533408751Tor Norbye     * Actions which have the same id and the same title are deemed equivalent.
37194986e745141118cace0391da1b4dc8533408751Tor Norbye     */
37294986e745141118cace0391da1b4dc8533408751Tor Norbye    @Override
37394986e745141118cace0391da1b4dc8533408751Tor Norbye    public boolean equals(Object obj) {
37494986e745141118cace0391da1b4dc8533408751Tor Norbye        if (obj instanceof RuleAction) {
37594986e745141118cace0391da1b4dc8533408751Tor Norbye            RuleAction rhs = (RuleAction) obj;
37694986e745141118cace0391da1b4dc8533408751Tor Norbye
37794986e745141118cace0391da1b4dc8533408751Tor Norbye            if (mId != rhs.mId && !(mId != null && mId.equals(rhs.mId))) return false;
37894986e745141118cace0391da1b4dc8533408751Tor Norbye            if (mTitle != rhs.mTitle &&
37994986e745141118cace0391da1b4dc8533408751Tor Norbye                    !(mTitle != null && mTitle.equals(rhs.mTitle))) return false;
38094986e745141118cace0391da1b4dc8533408751Tor Norbye            return true;
38194986e745141118cace0391da1b4dc8533408751Tor Norbye        }
38294986e745141118cace0391da1b4dc8533408751Tor Norbye        return false;
38394986e745141118cace0391da1b4dc8533408751Tor Norbye    }
38494986e745141118cace0391da1b4dc8533408751Tor Norbye
38594986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
38694986e745141118cace0391da1b4dc8533408751Tor Norbye     * Whether this action supports multiple nodes. An action which supports
38794986e745141118cace0391da1b4dc8533408751Tor Norbye     * multiple nodes can be applied to different nodes by passing in different
38894986e745141118cace0391da1b4dc8533408751Tor Norbye     * nodes to its callback. Some actions are hardcoded for a specific node (typically
38994986e745141118cace0391da1b4dc8533408751Tor Norbye     * one that isn't selected, such as an action which affects the parent of a selected
39094986e745141118cace0391da1b4dc8533408751Tor Norbye     * node), and these actions will not be added to the context menu when more than
39194986e745141118cace0391da1b4dc8533408751Tor Norbye     * one node is selected.
39294986e745141118cace0391da1b4dc8533408751Tor Norbye     *
39394986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return true if this node supports multiple nodes
39494986e745141118cace0391da1b4dc8533408751Tor Norbye     */
39594986e745141118cace0391da1b4dc8533408751Tor Norbye    public boolean supportsMultipleNodes() {
39694986e745141118cace0391da1b4dc8533408751Tor Norbye        return mSupportsMultipleNodes;
39794986e745141118cace0391da1b4dc8533408751Tor Norbye    }
39894986e745141118cace0391da1b4dc8533408751Tor Norbye
39994986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
40094986e745141118cace0391da1b4dc8533408751Tor Norbye     * Actions which have the same id and the same title have the same hash code.
40194986e745141118cace0391da1b4dc8533408751Tor Norbye     */
40294986e745141118cace0391da1b4dc8533408751Tor Norbye    @Override
40394986e745141118cace0391da1b4dc8533408751Tor Norbye    public int hashCode() {
40494986e745141118cace0391da1b4dc8533408751Tor Norbye        int h = mId == null ? 0 : mId.hashCode();
40594986e745141118cace0391da1b4dc8533408751Tor Norbye        h = h ^ (mTitle == null ? 0 : mTitle.hashCode());
40694986e745141118cace0391da1b4dc8533408751Tor Norbye        return h;
40794986e745141118cace0391da1b4dc8533408751Tor Norbye    }
40894986e745141118cace0391da1b4dc8533408751Tor Norbye
40994986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
41094986e745141118cace0391da1b4dc8533408751Tor Norbye     * Gets a URL pointing to an icon to use for this action, if any.
41194986e745141118cace0391da1b4dc8533408751Tor Norbye     *
41294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return a URL pointing to an icon to use for this action, or null
41394986e745141118cace0391da1b4dc8533408751Tor Norbye     */
41494986e745141118cace0391da1b4dc8533408751Tor Norbye    public URL getIconUrl() {
41594986e745141118cace0391da1b4dc8533408751Tor Norbye        return mIconUrl;
41694986e745141118cace0391da1b4dc8533408751Tor Norbye    }
41794986e745141118cace0391da1b4dc8533408751Tor Norbye
41894986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
41994986e745141118cace0391da1b4dc8533408751Tor Norbye     * Sets a URL pointing to an icon to use for this action, if any.
42094986e745141118cace0391da1b4dc8533408751Tor Norbye     *
42194986e745141118cace0391da1b4dc8533408751Tor Norbye     * @param iconUrl a URL pointing to an icon to use for this action, or null
42294986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return this action, to allow setter chaining
42394986e745141118cace0391da1b4dc8533408751Tor Norbye     */
4245d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
42594986e745141118cace0391da1b4dc8533408751Tor Norbye    public RuleAction setIconUrl(URL iconUrl) {
42694986e745141118cace0391da1b4dc8533408751Tor Norbye        mIconUrl = iconUrl;
42794986e745141118cace0391da1b4dc8533408751Tor Norbye
42894986e745141118cace0391da1b4dc8533408751Tor Norbye        return this;
42994986e745141118cace0391da1b4dc8533408751Tor Norbye    }
43094986e745141118cace0391da1b4dc8533408751Tor Norbye
43194986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
43294986e745141118cace0391da1b4dc8533408751Tor Norbye     * Return a priority used for sorting this action
43394986e745141118cace0391da1b4dc8533408751Tor Norbye     *
43494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return a priority used for sorting this action
43594986e745141118cace0391da1b4dc8533408751Tor Norbye     */
43694986e745141118cace0391da1b4dc8533408751Tor Norbye    public int getSortPriority() {
43794986e745141118cace0391da1b4dc8533408751Tor Norbye        return mSortPriority;
43894986e745141118cace0391da1b4dc8533408751Tor Norbye    }
43994986e745141118cace0391da1b4dc8533408751Tor Norbye
44094986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
44194986e745141118cace0391da1b4dc8533408751Tor Norbye     * Returns the callback executed when the action is selected in the
44294986e745141118cace0391da1b4dc8533408751Tor Norbye     * context menu. Cannot be null.
44394986e745141118cace0391da1b4dc8533408751Tor Norbye     *
44494986e745141118cace0391da1b4dc8533408751Tor Norbye     * @return the callback, never null
44594986e745141118cace0391da1b4dc8533408751Tor Norbye     */
4465d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
44794986e745141118cace0391da1b4dc8533408751Tor Norbye    public IMenuCallback getCallback() {
44894986e745141118cace0391da1b4dc8533408751Tor Norbye        return mCallback;
44994986e745141118cace0391da1b4dc8533408751Tor Norbye    }
45094986e745141118cace0391da1b4dc8533408751Tor Norbye
4517e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye    // Implements Comparable<MenuAction>
452ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye    @Override
4537e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye    public int compareTo(RuleAction other) {
45494986e745141118cace0391da1b4dc8533408751Tor Norbye        if (mSortPriority != other.mSortPriority) {
45594986e745141118cace0391da1b4dc8533408751Tor Norbye            return mSortPriority - other.mSortPriority;
45694986e745141118cace0391da1b4dc8533408751Tor Norbye        }
45794986e745141118cace0391da1b4dc8533408751Tor Norbye
45894986e745141118cace0391da1b4dc8533408751Tor Norbye        return mTitle.compareTo(other.mTitle);
45994986e745141118cace0391da1b4dc8533408751Tor Norbye    }
46094986e745141118cace0391da1b4dc8533408751Tor Norbye
4615d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye    @NonNull
46294986e745141118cace0391da1b4dc8533408751Tor Norbye    @Override
46394986e745141118cace0391da1b4dc8533408751Tor Norbye    public String toString() {
46494986e745141118cace0391da1b4dc8533408751Tor Norbye        return "RuleAction [id=" + mId + ", title=" + mTitle + ", priority=" + mSortPriority + "]";
46594986e745141118cace0391da1b4dc8533408751Tor Norbye    }
46694986e745141118cace0391da1b4dc8533408751Tor Norbye
46794986e745141118cace0391da1b4dc8533408751Tor Norbye    /** A separator to display between actions */
46894986e745141118cace0391da1b4dc8533408751Tor Norbye    public static class Separator extends RuleAction {
46994986e745141118cace0391da1b4dc8533408751Tor Norbye        /** Construct using the factory {@link #createSeparator(int)} */
47094986e745141118cace0391da1b4dc8533408751Tor Norbye        private Separator(int sortPriority, boolean supportsMultipleNodes) {
4717e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye            super("_separator", "", IMenuCallback.NONE, sortPriority,  //$NON-NLS-1$ //$NON-NLS-2$
47294986e745141118cace0391da1b4dc8533408751Tor Norbye                    supportsMultipleNodes);
47394986e745141118cace0391da1b4dc8533408751Tor Norbye        }
47494986e745141118cace0391da1b4dc8533408751Tor Norbye    }
47594986e745141118cace0391da1b4dc8533408751Tor Norbye
47694986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
47794986e745141118cace0391da1b4dc8533408751Tor Norbye     * A toggle is a simple on/off action, displayed as an item in a context menu
47894986e745141118cace0391da1b4dc8533408751Tor Norbye     * with a check mark if the item is checked.
47994986e745141118cace0391da1b4dc8533408751Tor Norbye     * <p/>
48094986e745141118cace0391da1b4dc8533408751Tor Norbye     * Two toggles are equal if they have the same id, title and group-id.
48194986e745141118cace0391da1b4dc8533408751Tor Norbye     * It is expected for the checked state and action callback to be different.
48294986e745141118cace0391da1b4dc8533408751Tor Norbye     */
48394986e745141118cace0391da1b4dc8533408751Tor Norbye    public static class Toggle extends RuleAction {
48494986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
48594986e745141118cace0391da1b4dc8533408751Tor Norbye         * True if the item is displayed with a check mark.
48694986e745141118cace0391da1b4dc8533408751Tor Norbye         */
48794986e745141118cace0391da1b4dc8533408751Tor Norbye        private final boolean mIsChecked;
48894986e745141118cace0391da1b4dc8533408751Tor Norbye
48994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
49094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Creates a new immutable toggle action.
49194986e745141118cace0391da1b4dc8533408751Tor Norbye         *
49294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param id The unique id of the action. Cannot be null.
49394986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param title The UI-visible title of the context menu item. Cannot be null.
49494986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param isChecked Whether the context menu item has a check mark.
49594986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param callback A callback to execute when the context menu item is
49694986e745141118cace0391da1b4dc8533408751Tor Norbye         *            selected.
49794986e745141118cace0391da1b4dc8533408751Tor Norbye         */
4985d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        private Toggle(
4995d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String id,
5005d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String title,
5015d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                boolean isChecked,
5025d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull IMenuCallback callback,
5035d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                int sortPriority,
5045d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                boolean supportsMultipleNodes) {
50594986e745141118cace0391da1b4dc8533408751Tor Norbye            super(id, title, callback, sortPriority, supportsMultipleNodes);
50694986e745141118cace0391da1b4dc8533408751Tor Norbye            mIsChecked = isChecked;
50794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
50894986e745141118cace0391da1b4dc8533408751Tor Norbye
50994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
51094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns true if the item is displayed with a check mark.
51194986e745141118cace0391da1b4dc8533408751Tor Norbye         *
51294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return true if the item is displayed with a check mark.
51394986e745141118cace0391da1b4dc8533408751Tor Norbye         */
51494986e745141118cace0391da1b4dc8533408751Tor Norbye        public boolean isChecked() {
51594986e745141118cace0391da1b4dc8533408751Tor Norbye            return mIsChecked;
51694986e745141118cace0391da1b4dc8533408751Tor Norbye        }
51794986e745141118cace0391da1b4dc8533408751Tor Norbye
51894986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
51994986e745141118cace0391da1b4dc8533408751Tor Norbye         * Two toggles are equal if they have the same id and title.
52094986e745141118cace0391da1b4dc8533408751Tor Norbye         * It is acceptable for the checked state and action callback to be different.
52194986e745141118cace0391da1b4dc8533408751Tor Norbye         */
52294986e745141118cace0391da1b4dc8533408751Tor Norbye        @Override
52394986e745141118cace0391da1b4dc8533408751Tor Norbye        public boolean equals(Object obj) {
52494986e745141118cace0391da1b4dc8533408751Tor Norbye            return super.equals(obj);
52594986e745141118cace0391da1b4dc8533408751Tor Norbye        }
52694986e745141118cace0391da1b4dc8533408751Tor Norbye
52794986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
52894986e745141118cace0391da1b4dc8533408751Tor Norbye         * Two toggles have the same hash code if they have the same id and title.
52994986e745141118cace0391da1b4dc8533408751Tor Norbye         */
53094986e745141118cace0391da1b4dc8533408751Tor Norbye        @Override
53194986e745141118cace0391da1b4dc8533408751Tor Norbye        public int hashCode() {
53294986e745141118cace0391da1b4dc8533408751Tor Norbye            return super.hashCode();
53394986e745141118cace0391da1b4dc8533408751Tor Norbye        }
53494986e745141118cace0391da1b4dc8533408751Tor Norbye    }
53594986e745141118cace0391da1b4dc8533408751Tor Norbye
53694986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
53794986e745141118cace0391da1b4dc8533408751Tor Norbye     * An ordered list of choices the user can choose between. For choosing between
53894986e745141118cace0391da1b4dc8533408751Tor Norbye     * actions, there is a {@link NestedAction} class.
53994986e745141118cace0391da1b4dc8533408751Tor Norbye     */
54094986e745141118cace0391da1b4dc8533408751Tor Norbye    public static class Choices extends RuleAction {
54194986e745141118cace0391da1b4dc8533408751Tor Norbye        protected List<String> mTitles;
54294986e745141118cace0391da1b4dc8533408751Tor Norbye        protected List<URL> mIconUrls;
54394986e745141118cace0391da1b4dc8533408751Tor Norbye        protected List<String> mIds;
54494986e745141118cace0391da1b4dc8533408751Tor Norbye        private boolean mRadio;
54594986e745141118cace0391da1b4dc8533408751Tor Norbye
54694986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
54794986e745141118cace0391da1b4dc8533408751Tor Norbye         * One or more id for the checked choice(s) that will be check marked.
54894986e745141118cace0391da1b4dc8533408751Tor Norbye         * Can be null. Can be an id not present in the choices map.
54994986e745141118cace0391da1b4dc8533408751Tor Norbye         */
55094986e745141118cace0391da1b4dc8533408751Tor Norbye        protected final String mCurrent;
55194986e745141118cace0391da1b4dc8533408751Tor Norbye
5525d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        private Choices(
5535d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String id,
5545d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String title,
5555d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull IMenuCallback callback,
5565d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull List<String> titles,
5575d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @Nullable List<URL> iconUrls,
5585d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull List<String> ids,
5595d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @Nullable String current,
5605d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                int sortPriority,
5615d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                boolean supportsMultipleNodes) {
56294986e745141118cace0391da1b4dc8533408751Tor Norbye            super(id, title, callback, sortPriority, supportsMultipleNodes);
56394986e745141118cace0391da1b4dc8533408751Tor Norbye            mTitles = titles;
56494986e745141118cace0391da1b4dc8533408751Tor Norbye            mIconUrls = iconUrls;
56594986e745141118cace0391da1b4dc8533408751Tor Norbye            mIds = ids;
56694986e745141118cace0391da1b4dc8533408751Tor Norbye            mCurrent = current;
56794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
56894986e745141118cace0391da1b4dc8533408751Tor Norbye
56994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
57094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns the list of urls to icons to display for each choice, or null
57194986e745141118cace0391da1b4dc8533408751Tor Norbye         *
57294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return the list of urls to icons to display for each choice, or null
57394986e745141118cace0391da1b4dc8533408751Tor Norbye         */
5745d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        @Nullable
57594986e745141118cace0391da1b4dc8533408751Tor Norbye        public List<URL> getIconUrls() {
57694986e745141118cace0391da1b4dc8533408751Tor Norbye            return mIconUrls;
57794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
57894986e745141118cace0391da1b4dc8533408751Tor Norbye
57994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
58094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns the list of ids for the menu choices, never null
58194986e745141118cace0391da1b4dc8533408751Tor Norbye         *
58294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return the list of ids for the menu choices, never null
58394986e745141118cace0391da1b4dc8533408751Tor Norbye         */
5845d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        @NonNull
58594986e745141118cace0391da1b4dc8533408751Tor Norbye        public List<String> getIds() {
58694986e745141118cace0391da1b4dc8533408751Tor Norbye            return mIds;
58794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
58894986e745141118cace0391da1b4dc8533408751Tor Norbye
58994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
59094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns the titles to be displayed for the menu choices, never null
59194986e745141118cace0391da1b4dc8533408751Tor Norbye         *
59294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return the titles to be displayed for the menu choices, never null
59394986e745141118cace0391da1b4dc8533408751Tor Norbye         */
5945d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        @NonNull
59594986e745141118cace0391da1b4dc8533408751Tor Norbye        public List<String> getTitles() {
59694986e745141118cace0391da1b4dc8533408751Tor Norbye            return mTitles;
59794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
59894986e745141118cace0391da1b4dc8533408751Tor Norbye
59994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
60094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns the current value of the choice
60194986e745141118cace0391da1b4dc8533408751Tor Norbye         *
60294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return the current value of the choice, possibly null
60394986e745141118cace0391da1b4dc8533408751Tor Norbye         */
6045d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        @Nullable
60594986e745141118cace0391da1b4dc8533408751Tor Norbye        public String getCurrent() {
60694986e745141118cace0391da1b4dc8533408751Tor Norbye            return mCurrent;
60794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
60894986e745141118cace0391da1b4dc8533408751Tor Norbye
60994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
61094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Set whether this choice list is best visualized as a radio group (instead of a
61194986e745141118cace0391da1b4dc8533408751Tor Norbye         * dropdown)
61294986e745141118cace0391da1b4dc8533408751Tor Norbye         *
61394986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param radio true if this choice list should be visualized as a radio group
61494986e745141118cace0391da1b4dc8533408751Tor Norbye         */
61594986e745141118cace0391da1b4dc8533408751Tor Norbye        public void setRadio(boolean radio) {
61694986e745141118cace0391da1b4dc8533408751Tor Norbye            mRadio = radio;
61794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
61894986e745141118cace0391da1b4dc8533408751Tor Norbye
61994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
62094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns true if this choice list is best visualized as a radio group (instead
62194986e745141118cace0391da1b4dc8533408751Tor Norbye         * of a dropdown)
62294986e745141118cace0391da1b4dc8533408751Tor Norbye         *
62394986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return true if this choice list should be visualized as a radio group
62494986e745141118cace0391da1b4dc8533408751Tor Norbye         */
62594986e745141118cace0391da1b4dc8533408751Tor Norbye        public boolean isRadio() {
62694986e745141118cace0391da1b4dc8533408751Tor Norbye            return mRadio;
62794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
62894986e745141118cace0391da1b4dc8533408751Tor Norbye    }
62994986e745141118cace0391da1b4dc8533408751Tor Norbye
63094986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
63194986e745141118cace0391da1b4dc8533408751Tor Norbye     * An ordered list of actions the user can choose between. Similar to
63294986e745141118cace0391da1b4dc8533408751Tor Norbye     * {@link Choices} but for actions instead.
63394986e745141118cace0391da1b4dc8533408751Tor Norbye     */
63494986e745141118cace0391da1b4dc8533408751Tor Norbye    public static class NestedAction extends RuleAction {
63594986e745141118cace0391da1b4dc8533408751Tor Norbye        /** The provider to produce the list of nested actions when needed */
63694986e745141118cace0391da1b4dc8533408751Tor Norbye        private final ActionProvider mProvider;
63794986e745141118cace0391da1b4dc8533408751Tor Norbye
6385d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        private NestedAction(
6395d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String id,
6405d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String title,
6415d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull ActionProvider provider,
6425d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull IMenuCallback callback,
6435d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                int sortPriority,
64494986e745141118cace0391da1b4dc8533408751Tor Norbye                boolean supportsMultipleNodes) {
64594986e745141118cace0391da1b4dc8533408751Tor Norbye            super(id, title, callback, sortPriority, supportsMultipleNodes);
64694986e745141118cace0391da1b4dc8533408751Tor Norbye            mProvider = provider;
64794986e745141118cace0391da1b4dc8533408751Tor Norbye        }
64894986e745141118cace0391da1b4dc8533408751Tor Norbye
64994986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
65094986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns the nested actions available for the given node
65194986e745141118cace0391da1b4dc8533408751Tor Norbye         *
65294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param node the node to look up nested actions for
65394986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return a list of nested actions
65494986e745141118cace0391da1b4dc8533408751Tor Norbye         */
6555d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        @NonNull
6565d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        public List<RuleAction> getNestedActions(@NonNull INode node) {
65794986e745141118cace0391da1b4dc8533408751Tor Norbye            return mProvider.getNestedActions(node);
65894986e745141118cace0391da1b4dc8533408751Tor Norbye        }
65994986e745141118cace0391da1b4dc8533408751Tor Norbye    }
66094986e745141118cace0391da1b4dc8533408751Tor Norbye
66194986e745141118cace0391da1b4dc8533408751Tor Norbye    /** Like {@link Choices}, but the set of choices is computed lazily */
66294986e745141118cace0391da1b4dc8533408751Tor Norbye    private static class DelayedChoices extends Choices {
66394986e745141118cace0391da1b4dc8533408751Tor Norbye        private final ChoiceProvider mProvider;
6645d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        private boolean mInitialized;
6655d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye
6665d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        private DelayedChoices(
6675d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String id,
6685d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull String title,
6695d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull IMenuCallback callback,
6705d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @Nullable String current,
6715d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull ChoiceProvider provider,
67294986e745141118cace0391da1b4dc8533408751Tor Norbye                int sortPriority, boolean supportsMultipleNodes) {
6735d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            super(id, title, callback, new ArrayList<String>(), new ArrayList<URL>(),
6745d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                    new ArrayList<String>(), current, sortPriority, supportsMultipleNodes);
67594986e745141118cace0391da1b4dc8533408751Tor Norbye            mProvider = provider;
67694986e745141118cace0391da1b4dc8533408751Tor Norbye        }
67794986e745141118cace0391da1b4dc8533408751Tor Norbye
67894986e745141118cace0391da1b4dc8533408751Tor Norbye        private void ensureInitialized() {
6795d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye            if (!mInitialized) {
6805d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                mInitialized = true;
68194986e745141118cace0391da1b4dc8533408751Tor Norbye                mProvider.addChoices(mTitles, mIconUrls, mIds);
68294986e745141118cace0391da1b4dc8533408751Tor Norbye            }
68394986e745141118cace0391da1b4dc8533408751Tor Norbye        }
68494986e745141118cace0391da1b4dc8533408751Tor Norbye
68594986e745141118cace0391da1b4dc8533408751Tor Norbye        @Override
68694986e745141118cace0391da1b4dc8533408751Tor Norbye        public List<URL> getIconUrls() {
68794986e745141118cace0391da1b4dc8533408751Tor Norbye            ensureInitialized();
68894986e745141118cace0391da1b4dc8533408751Tor Norbye            return mIconUrls;
68994986e745141118cace0391da1b4dc8533408751Tor Norbye        }
69094986e745141118cace0391da1b4dc8533408751Tor Norbye
69194986e745141118cace0391da1b4dc8533408751Tor Norbye        @Override
6927e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye        public @NonNull List<String> getIds() {
69394986e745141118cace0391da1b4dc8533408751Tor Norbye            ensureInitialized();
69494986e745141118cace0391da1b4dc8533408751Tor Norbye            return mIds;
69594986e745141118cace0391da1b4dc8533408751Tor Norbye        }
69694986e745141118cace0391da1b4dc8533408751Tor Norbye
69794986e745141118cace0391da1b4dc8533408751Tor Norbye        @Override
6987e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye        public @NonNull List<String> getTitles() {
69994986e745141118cace0391da1b4dc8533408751Tor Norbye            ensureInitialized();
70094986e745141118cace0391da1b4dc8533408751Tor Norbye            return mTitles;
70194986e745141118cace0391da1b4dc8533408751Tor Norbye        }
70294986e745141118cace0391da1b4dc8533408751Tor Norbye    }
70394986e745141118cace0391da1b4dc8533408751Tor Norbye
70494986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
70594986e745141118cace0391da1b4dc8533408751Tor Norbye     * Provides the set of nested action choices associated with a {@link NestedAction}
70694986e745141118cace0391da1b4dc8533408751Tor Norbye     * object when they are needed. Useful for lazy initialization of context
70794986e745141118cace0391da1b4dc8533408751Tor Norbye     * menus and popup menus until they are actually needed.
70894986e745141118cace0391da1b4dc8533408751Tor Norbye     */
70994986e745141118cace0391da1b4dc8533408751Tor Norbye    public interface ActionProvider {
71094986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
71194986e745141118cace0391da1b4dc8533408751Tor Norbye         * Returns the nested actions available for the given node
71294986e745141118cace0391da1b4dc8533408751Tor Norbye         *
71394986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param node the node to look up nested actions for
71494986e745141118cace0391da1b4dc8533408751Tor Norbye         * @return a list of nested actions
71594986e745141118cace0391da1b4dc8533408751Tor Norbye         */
7165d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        @NonNull
7175d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        public List<RuleAction> getNestedActions(@NonNull INode node);
71894986e745141118cace0391da1b4dc8533408751Tor Norbye    }
71994986e745141118cace0391da1b4dc8533408751Tor Norbye
72094986e745141118cace0391da1b4dc8533408751Tor Norbye    /**
72194986e745141118cace0391da1b4dc8533408751Tor Norbye     * Provides the set of choices associated with an {@link Choices}
72294986e745141118cace0391da1b4dc8533408751Tor Norbye     * object when they are needed. Useful for lazy initialization of context
72394986e745141118cace0391da1b4dc8533408751Tor Norbye     * menus and popup menus until they are actually needed.
72494986e745141118cace0391da1b4dc8533408751Tor Norbye     */
72594986e745141118cace0391da1b4dc8533408751Tor Norbye    public interface ChoiceProvider {
72694986e745141118cace0391da1b4dc8533408751Tor Norbye        /**
72794986e745141118cace0391da1b4dc8533408751Tor Norbye         * Adds in the needed titles, iconUrls (if any) and ids.
72894986e745141118cace0391da1b4dc8533408751Tor Norbye         * Use {@link RuleAction#SEPARATOR} to create separators.
72994986e745141118cace0391da1b4dc8533408751Tor Norbye         *
73094986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param titles a list of titles that the provider should append to
73194986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param iconUrls a list of icon URLs that the provider should append to
73294986e745141118cace0391da1b4dc8533408751Tor Norbye         * @param ids a list of ids that the provider should append to
73394986e745141118cace0391da1b4dc8533408751Tor Norbye         */
7345d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye        public void addChoices(
7355d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull List<String> titles,
7365d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull List<URL> iconUrls,
7375d7dc30638953195ed55d32bc9dc37102a613ff8Tor Norbye                @NonNull List<String> ids);
73894986e745141118cace0391da1b4dc8533408751Tor Norbye    }
73994986e745141118cace0391da1b4dc8533408751Tor Norbye}
740