MenuBuilder.java revision 696cba573e651b0e4f18a4718627c8ccecb3bda0
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.view.menu;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ResolveInfo;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Configuration;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
29696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.util.Log;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray;
3136fced9b211255e2137014e21fb3259042d8da85Adam Powellimport android.view.ContextMenu.ContextMenuInfo;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyCharacterMap;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Menu;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MenuItem;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SubMenu;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
41696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport java.util.Iterator;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
43696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport java.util.concurrent.CopyOnWriteArrayList;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implementation of the {@link android.view.Menu} interface for creating a
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * standard menu UI.
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MenuBuilder implements Menu {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String LOGTAG = "MenuBuilder";
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int[]  sCategoryToOrder = new int[] {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        1, /* No category */
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        4, /* CONTAINER */
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        5, /* SYSTEM */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        3, /* SECONDARY */
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        2, /* ALTERNATIVE */
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        0, /* SELECTED_ALTERNATIVE */
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Context mContext;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Resources mResources;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether the shortcuts should be qwerty-accessible. Use isQwertyMode()
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * instead of accessing this directly.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mQwertyMode;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether the shortcuts should be visible on menus. Use isShortcutsVisible()
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * instead of accessing this directly.
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mShortcutsVisible;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Callback that will receive the various menu-related events generated by
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this class. Use getCallback to get a reference to the callback.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Callback mCallback;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Contains all of the items for this menu */
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ArrayList<MenuItemImpl> mItems;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Contains only the items that are currently visible.  This will be created/refreshed from
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #getVisibleItems()} */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ArrayList<MenuItemImpl> mVisibleItems;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether or not the items (or any one item's shown state) has changed since it was last
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * fetched from {@link #getVisibleItems()}
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsVisibleItemsStale;
9396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell
9496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    /**
9596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     * Contains only the items that should appear in the Action Bar, if present.
9696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     */
9796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    private ArrayList<MenuItemImpl> mActionItems;
9896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    /**
9996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     * Contains items that should NOT appear in the Action Bar, if present.
10096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     */
10196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    private ArrayList<MenuItemImpl> mNonActionItems;
102696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
10336fced9b211255e2137014e21fb3259042d8da85Adam Powell    /**
10496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     * Whether or not the items (or any one item's action state) has changed since it was
10596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     * last fetched.
10696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     */
10796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    private boolean mIsActionItemsStale;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1104d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell     * Default value for how added items should show in the action list.
1114d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell     */
1124d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell    private int mDefaultShowAsAction = MenuItem.SHOW_AS_ACTION_NEVER;
1134d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell
1144d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell    /**
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Current use case is Context Menus: As Views populate the context menu, each one has
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extra information that should be passed along.  This is the current menu info that
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should be set on all items added to this menu.
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ContextMenuInfo mCurrentMenuInfo;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Header title for menu types that have a header (context and submenus) */
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CharSequence mHeaderTitle;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Header icon for menu types that have a header and support icons (context) */
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Drawable mHeaderIcon;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Header custom view for menu types that have a header and support custom views (context) */
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    View mHeaderView;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Contains the state of the View hierarchy for all menu views when the menu
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was frozen.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private SparseArray<Parcelable> mFrozenViewStates;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Prevents onItemsChanged from doing its junk, useful for batching commands
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that may individually call onItemsChanged.
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mPreventDispatchingItemsChanged = false;
139696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private boolean mItemsChangedWhileDispatchPrevented = false;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOptionalIconsVisible = false;
1422fbf4de64f0ec5052201cea9519c44d5b1789a40Adam Powell
143696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private boolean mIsClosing = false;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
145696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private ArrayList<MenuItemImpl> mTempShortcutItemList = new ArrayList<MenuItemImpl>();
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
147696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private CopyOnWriteArrayList<WeakReference<MenuPresenter>> mPresenters =
148696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            new CopyOnWriteArrayList<WeakReference<MenuPresenter>>();
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
151696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Called by menu to notify of close and selection changes.
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface Callback {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when a menu item is selected.
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param menu The menu that is the parent of the item
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param item The menu item that is selected
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return whether the menu item selection was handled
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when the mode of the menu changes (for example, from icon to expanded).
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param menu the menu that has changed modes
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onMenuModeChange(MenuBuilder menu);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by menu items to execute their associated action
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface ItemInvoker {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean invokeItem(MenuItemImpl item);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuBuilder(Context context) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mResources = context.getResources();
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mItems = new ArrayList<MenuItemImpl>();
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mVisibleItems = new ArrayList<MenuItemImpl>();
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsVisibleItemsStale = true;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        mActionItems = new ArrayList<MenuItemImpl>();
18796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        mNonActionItems = new ArrayList<MenuItemImpl>();
18896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        mIsActionItemsStale = true;
18996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell
1904aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown        setShortcutsVisibleInner(true);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1934d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell    public MenuBuilder setDefaultShowAsAction(int defaultShowAsAction) {
1944d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell        mDefaultShowAsAction = defaultShowAsAction;
1954d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell        return this;
1964d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell    }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
198696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
199696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Add a presenter to this menu. This will only hold a WeakReference;
200696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * you do not need to explicitly remove a presenter, but you can using
201696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * {@link #removeMenuPresenter(MenuPresenter)}.
202696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
203696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param presenter The presenter to add
204696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
205696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void addMenuPresenter(MenuPresenter presenter) {
206696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mPresenters.add(new WeakReference<MenuPresenter>(presenter));
207696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        presenter.initForMenu(mContext, this);
208696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mIsActionItemsStale = true;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
210696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
212696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Remove a presenter from this menu. That presenter will no longer
213696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * receive notifications of updates to this menu's data.
214696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
215696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param presenter The presenter to remove
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
217696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void removeMenuPresenter(MenuPresenter presenter) {
218696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (WeakReference<MenuPresenter> ref : mPresenters) {
219696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final MenuPresenter item = ref.get();
220696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (item == null || item == presenter) {
221696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mPresenters.remove(ref);
222696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
226696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private void dispatchPresenterUpdate(boolean cleared) {
227696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mPresenters.isEmpty()) return;
228696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
229696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (WeakReference<MenuPresenter> ref : mPresenters) {
230696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final MenuPresenter presenter = ref.get();
231696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (presenter == null) {
232696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mPresenters.remove(ref);
233696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            } else {
234696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                presenter.updateMenuView(cleared);
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) {
240696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mPresenters.isEmpty()) return false;
241696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
242696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        boolean result = false;
243696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
244696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (WeakReference<MenuPresenter> ref : mPresenters) {
245696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final MenuPresenter presenter = ref.get();
246696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (presenter == null) {
247696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mPresenters.remove(ref);
248696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            } else if (!result) {
249696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                result = presenter.onSubMenuSelected(subMenu);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
252696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return result;
253696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
254696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
255696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void setCallback(Callback cb) {
256696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mCallback = cb;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds an item to the menu.  The other add methods funnel to this.
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int ordering = getOrdering(categoryOrder);
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2654d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell        final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder,
2664d9861e7ec8488634d316b20981464de2ab7b6feAdam Powell                ordering, title, mDefaultShowAsAction);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrentMenuInfo != null) {
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pass along the current menu info
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            item.setMenuInfo(mCurrentMenuInfo);
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mItems.add(findInsertIndex(mItems, ordering), item);
274696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        onItemsChanged(true);
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return item;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuItem add(CharSequence title) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addInternal(0, 0, 0, title);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuItem add(int titleRes) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addInternal(0, 0, 0, mResources.getString(titleRes));
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuItem add(int group, int id, int categoryOrder, CharSequence title) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addInternal(group, id, categoryOrder, title);
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuItem add(int group, int id, int categoryOrder, int title) {
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addInternal(group, id, categoryOrder, mResources.getString(title));
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SubMenu addSubMenu(CharSequence title) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addSubMenu(0, 0, 0, title);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SubMenu addSubMenu(int titleRes) {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addSubMenu(0, 0, 0, mResources.getString(titleRes));
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SubMenu addSubMenu(int group, int id, int categoryOrder, CharSequence title) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final MenuItemImpl item = (MenuItemImpl) addInternal(group, id, categoryOrder, title);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final SubMenuBuilder subMenu = new SubMenuBuilder(mContext, this, item);
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        item.setSubMenu(subMenu);
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return subMenu;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SubMenu addSubMenu(int group, int id, int categoryOrder, int title) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addSubMenu(group, id, categoryOrder, mResources.getString(title));
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int addIntentOptions(int group, int id, int categoryOrder, ComponentName caller,
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PackageManager pm = mContext.getPackageManager();
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final List<ResolveInfo> lri =
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pm.queryIntentActivityOptions(caller, specifics, intent, 0);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = lri != null ? lri.size() : 0;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags & FLAG_APPEND_TO_GROUP) == 0) {
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            removeGroup(group);
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ResolveInfo ri = lri.get(i);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Intent rintent = new Intent(
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ri.specificIndex < 0 ? intent : specifics[ri.specificIndex]);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            rintent.setComponent(new ComponentName(
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ri.activityInfo.applicationInfo.packageName,
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ri.activityInfo.name));
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final MenuItem item = add(group, id, categoryOrder, ri.loadLabel(pm))
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setIcon(ri.loadIcon(pm))
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setIntent(rintent);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (outSpecificItems != null && ri.specificIndex >= 0) {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outSpecificItems[ri.specificIndex] = item;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return N;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeItem(int id) {
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeItemAtInt(findItemIndex(id), true);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeGroup(int group) {
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int i = findGroupIndex(group);
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i >= 0) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int maxRemovable = mItems.size() - i;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int numRemoved = 0;
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while ((numRemoved++ < maxRemovable) && (mItems.get(i).getGroupId() == group)) {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Don't force update for each one, this method will do it at the end
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                removeItemAtInt(i, false);
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Notify menu views
360696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            onItemsChanged(true);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Remove the item at the given index and optionally forces menu views to
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * update.
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The index of the item to be removed. If this index is
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            invalid an exception is thrown.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param updateChildrenOnMenuViews Whether to force update on menu views.
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            Please make sure you eventually call this after your batch of
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            removals.
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void removeItemAtInt(int index, boolean updateChildrenOnMenuViews) {
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((index < 0) || (index >= mItems.size())) return;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mItems.remove(index);
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (updateChildrenOnMenuViews) onItemsChanged(true);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeItemAt(int index) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeItemAtInt(index, true);
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearAll() {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPreventDispatchingItemsChanged = true;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clear();
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clearHeader();
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPreventDispatchingItemsChanged = false;
391696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mItemsChangedWhileDispatchPrevented = false;
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onItemsChanged(true);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clear() {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mItems.clear();
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onItemsChanged(true);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void setExclusiveItemChecked(MenuItem item) {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int group = item.getGroupId();
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mItems.size();
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < N; i++) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl curItem = mItems.get(i);
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (curItem.getGroupId() == group) {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!curItem.isExclusiveCheckable()) continue;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!curItem.isCheckable()) continue;
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Check the item meant to be checked, uncheck the others (that are in the group)
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curItem.setCheckedInt(curItem == item);
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setGroupCheckable(int group, boolean checkable, boolean exclusive) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mItems.size();
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < N; i++) {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = mItems.get(i);
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.getGroupId() == group) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                item.setExclusiveCheckable(exclusive);
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                item.setCheckable(checkable);
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setGroupVisible(int group, boolean visible) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mItems.size();
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We handle the notification of items being changed ourselves, so we use setVisibleInt rather
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // than setVisible and at the end notify of items being changed
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changedAtLeastOneItem = false;
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < N; i++) {
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = mItems.get(i);
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.getGroupId() == group) {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (item.setVisibleInt(visible)) changedAtLeastOneItem = true;
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (changedAtLeastOneItem) onItemsChanged(false);
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setGroupEnabled(int group, boolean enabled) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mItems.size();
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < N; i++) {
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = mItems.get(i);
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.getGroupId() == group) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                item.setEnabled(enabled);
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasVisibleItems() {
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int size = size();
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < size; i++) {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = mItems.get(i);
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.isVisible()) {
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuItem findItem(int id) {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int size = size();
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < size; i++) {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = mItems.get(i);
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.getItemId() == id) {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return item;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (item.hasSubMenu()) {
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                MenuItem possibleItem = item.getSubMenu().findItem(id);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (possibleItem != null) {
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return possibleItem;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int findItemIndex(int id) {
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int size = size();
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < size; i++) {
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = mItems.get(i);
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.getItemId() == id) {
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return i;
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int findGroupIndex(int group) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return findGroupIndex(group, 0);
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int findGroupIndex(int group, int start) {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int size = size();
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (start < 0) {
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            start = 0;
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = start; i < size; i++) {
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final MenuItemImpl item = mItems.get(i);
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.getGroupId() == group) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return i;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int size() {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mItems.size();
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** {@inheritDoc} */
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuItem getItem(int index) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mItems.get(index);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShortcutKey(int keyCode, KeyEvent event) {
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return findItemWithShortcutForKey(keyCode, event) != null;
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setQwertyMode(boolean isQwerty) {
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mQwertyMode = isQwerty;
538696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
539696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        onItemsChanged(false);
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the ordering across all items. This will grab the category from
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the upper bits, find out how to order the category with respect to other
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * categories, and combine it with the lower bits.
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param categoryOrder The category order for a particular item (if it has
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            not been or/add with a category, the default category is
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            assumed).
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return An ordering integer that can be used to order this item across
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         all the items (even from other categories).
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
553696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private static int getOrdering(int categoryOrder) {
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int index = (categoryOrder & CATEGORY_MASK) >> CATEGORY_SHIFT;
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index < 0 || index >= sCategoryToOrder.length) {
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("order does not contain a valid category.");
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (sCategoryToOrder[index] << CATEGORY_SHIFT) | (categoryOrder & USER_MASK);
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return whether the menu shortcuts are in qwerty mode or not
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean isQwertyMode() {
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mQwertyMode;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets whether the shortcuts should be visible on menus.  Devices without hardware
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * key input will never make shortcuts visible even if this method is passed 'true'.
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param shortcutsVisible Whether shortcuts should be visible (if true and a
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            menu item does not have a shortcut defined, that item will
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            still NOT show a shortcut)
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setShortcutsVisible(boolean shortcutsVisible) {
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mShortcutsVisible == shortcutsVisible) return;
5804aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown
5814aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown        setShortcutsVisibleInner(shortcutsVisible);
582696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        onItemsChanged(false);
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5854aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown    private void setShortcutsVisibleInner(boolean shortcutsVisible) {
5864aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown        mShortcutsVisible = shortcutsVisible
5874aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown                && mResources.getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS
5884aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown                && mResources.getBoolean(
5894aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown                        com.android.internal.R.bool.config_showMenuShortcutsWhenKeyboardPresent);
5904aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown    }
5914aed78b5056560f499e5953f659fa90a06ecc38aJeff Brown
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether shortcuts should be visible on menus.
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShortcutsVisible() {
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mShortcutsVisible;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Resources getResources() {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mResources;
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Context getContext() {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContext;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
607696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) {
608696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return mCallback != null && mCallback.onMenuItemSelected(menu, item);
609696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
610696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
611696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
612696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Dispatch a mode change event to this menu's callback.
613696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
614696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void changeMenuMode() {
615696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mCallback != null) {
616696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mCallback.onMenuModeChange(this);
617696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
618696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
619696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static int findInsertIndex(ArrayList<MenuItemImpl> items, int ordering) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = items.size() - 1; i >= 0; i--) {
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = items.get(i);
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.getOrdering() <= ordering) {
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return i + 1;
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean performShortcut(int keyCode, KeyEvent event, int flags) {
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final MenuItemImpl item = findItemWithShortcutForKey(keyCode, event);
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean handled = false;
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (item != null) {
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            handled = performItemAction(item, flags);
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags & FLAG_ALWAYS_PERFORM_CLOSE) != 0) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            close(true);
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return handled;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
647e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard    /*
648e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * This function will return all the menu and sub-menu items that can
649e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * be directly (the shortcut directly corresponds) and indirectly
650e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * (the ALT-enabled char corresponds to the shortcut) associated
651e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * with the keyCode.
652e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     */
653696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    void findItemsWithShortcutForKey(List<MenuItemImpl> items, int keyCode, KeyEvent event) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean qwerty = isQwertyMode();
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int metaState = event.getMetaState();
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData();
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get the chars associated with the keyCode (i.e using any chording combo)
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean isKeyCodeMapped = event.getKeyData(possibleChars);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The delete key is not mapped to '\b' so we treat it specially
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isKeyCodeMapped && (keyCode != KeyEvent.KEYCODE_DEL)) {
661696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return;
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Look for an item whose shortcut is this key.
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mItems.size();
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < N; i++) {
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MenuItemImpl item = mItems.get(i);
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.hasSubMenu()) {
669696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                ((MenuBuilder)item.getSubMenu()).findItemsWithShortcutForKey(items, keyCode, event);
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
671e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard            final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut();
672e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard            if (((metaState & (KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON)) == 0) &&
673e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                  (shortcutChar != 0) &&
674e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                  (shortcutChar == possibleChars.meta[0]
675e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                      || shortcutChar == possibleChars.meta[2]
676e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                      || (qwerty && shortcutChar == '\b' &&
677e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                          keyCode == KeyEvent.KEYCODE_DEL)) &&
678e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                  item.isEnabled()) {
679e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                items.add(item);
680e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard            }
681e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        }
682e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard    }
683e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard
684e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard    /*
685e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * We want to return the menu item associated with the key, but if there is no
686e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * ambiguity (i.e. there is only one menu item corresponding to the key) we want
687e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * to return it even if it's not an exact match; this allow the user to
688e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * _not_ use the ALT key for example, making the use of shortcuts slightly more
689e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * user-friendly. An example is on the G1, '!' and '1' are on the same key, and
690e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * in Gmail, Menu+1 will trigger Menu+! (the actual shortcut).
691e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     *
692e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * On the other hand, if two (or more) shortcuts corresponds to the same key,
693e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     * we have to only return the exact match.
694e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard     */
695e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard    MenuItemImpl findItemWithShortcutForKey(int keyCode, KeyEvent event) {
696e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        // Get all items that can be associated directly or indirectly with the keyCode
697696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        ArrayList<MenuItemImpl> items = mTempShortcutItemList;
698696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        items.clear();
699696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        findItemsWithShortcutForKey(items, keyCode, event);
700e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard
701696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (items.isEmpty()) {
702e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard            return null;
703e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        }
704e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard
705e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        final int metaState = event.getMetaState();
706e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData();
707e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        // Get the chars associated with the keyCode (i.e using any chording combo)
708e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        event.getKeyData(possibleChars);
709e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard
710e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        // If we have only one element, we can safely returns it
711696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final int size = items.size();
712696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (size == 1) {
713e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard            return items.get(0);
714e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        }
715e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard
716e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        final boolean qwerty = isQwertyMode();
717e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        // If we found more than one item associated with the key,
718e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard        // we have to return the exact match
719696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (int i = 0; i < size; i++) {
720696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final MenuItemImpl item = items.get(i);
721696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final char shortcutChar = qwerty ? item.getAlphabeticShortcut() :
722696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    item.getNumericShortcut();
723e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard            if ((shortcutChar == possibleChars.meta[0] &&
724e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                    (metaState & KeyEvent.META_ALT_ON) == 0)
725e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                || (shortcutChar == possibleChars.meta[2] &&
726e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                    (metaState & KeyEvent.META_ALT_ON) != 0)
727e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                || (qwerty && shortcutChar == '\b' &&
728e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                    keyCode == KeyEvent.KEYCODE_DEL)) {
729e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard                return item;
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
734e0fc838ebc18e327a399902cacae16bdbbc09627Nicolas Roard
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean performIdentifierAction(int id, int flags) {
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Look for an item whose identifier is the id.
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return performItemAction(findItem(id), flags);
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean performItemAction(MenuItem item, int flags) {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MenuItemImpl itemImpl = (MenuItemImpl) item;
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (itemImpl == null || !itemImpl.isEnabled()) {
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean invoked = itemImpl.invoke();
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (item.hasSubMenu()) {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            close(false);
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
752696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            invoked |= dispatchSubMenuSelected((SubMenuBuilder) item.getSubMenu());
753696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (!invoked) close(true);
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) {
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close(true);
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return invoked;
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Closes the visible menu.
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param allMenusAreClosing Whether the menus are completely closing (true),
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            or whether there is another menu coming in this menu's place
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            (false). For example, if the menu is closing because a
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            sub menu is about to be shown, <var>allMenusAreClosing</var>
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            is false.
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final void close(boolean allMenusAreClosing) {
773696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mIsClosing) return;
774696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
775696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mIsClosing = true;
776696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (WeakReference<MenuPresenter> ref : mPresenters) {
777696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final MenuPresenter presenter = ref.get();
778696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (presenter == null) {
779696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mPresenters.remove(ref);
780696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            } else {
781696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                presenter.onCloseMenu(this, allMenusAreClosing);
782696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
784696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mIsClosing = false;
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** {@inheritDoc} */
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void close() {
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        close(true);
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when an item is added or removed.
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
795696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param structureChanged true if the menu structure changed,
796696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *                         false if only item properties changed.
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
798696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    void onItemsChanged(boolean structureChanged) {
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mPreventDispatchingItemsChanged) {
800696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (structureChanged) {
801696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mIsVisibleItemsStale = true;
802696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mIsActionItemsStale = true;
803696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
8041821ff9022f0ea5f5c5d82a96a05f46192d50c26Adam Powell
805696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            dispatchPresenterUpdate(structureChanged);
806696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        } else {
807696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mItemsChangedWhileDispatchPrevented = true;
808696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
809696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
8101821ff9022f0ea5f5c5d82a96a05f46192d50c26Adam Powell
811696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
812696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Stop dispatching item changed events to presenters until
813696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * {@link #startDispatchingItemsChanged()} is called. Useful when
814696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * many menu operations are going to be performed as a batch.
815696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
816696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void stopDispatchingItemsChanged() {
817696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mPreventDispatchingItemsChanged = true;
818696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mItemsChangedWhileDispatchPrevented = false;
819696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
820696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
821696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void startDispatchingItemsChanged() {
822696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mPreventDispatchingItemsChanged = false;
823696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
824696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mItemsChangedWhileDispatchPrevented) {
825696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mItemsChangedWhileDispatchPrevented = false;
826696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            onItemsChanged(true);
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by {@link MenuItemImpl} when its visible flag is changed.
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param item The item that has gone through a visibility change.
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void onItemVisibleChanged(MenuItemImpl item) {
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Notify of items being changed
836696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mIsVisibleItemsStale = true;
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onItemsChanged(false);
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
84096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    /**
84196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     * Called by {@link MenuItemImpl} when its action request status is changed.
84296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     * @param item The item that has gone through a change in action request status.
84396675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell     */
84496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    void onItemActionRequestChanged(MenuItemImpl item) {
84596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        // Notify of items being changed
846696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mIsActionItemsStale = true;
84796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        onItemsChanged(false);
84896675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    }
84996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ArrayList<MenuItemImpl> getVisibleItems() {
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mIsVisibleItemsStale) return mVisibleItems;
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Refresh the visible items
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mVisibleItems.clear();
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int itemsSize = mItems.size();
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MenuItemImpl item;
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < itemsSize; i++) {
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            item = mItems.get(i);
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (item.isVisible()) mVisibleItems.add(item);
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsVisibleItemsStale = false;
86496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        mIsActionItemsStale = true;
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mVisibleItems;
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
86836fced9b211255e2137014e21fb3259042d8da85Adam Powell
86936fced9b211255e2137014e21fb3259042d8da85Adam Powell    /**
87036fced9b211255e2137014e21fb3259042d8da85Adam Powell     * This method determines which menu items get to be 'action items' that will appear
87136fced9b211255e2137014e21fb3259042d8da85Adam Powell     * in an action bar and which items should be 'overflow items' in a secondary menu.
87236fced9b211255e2137014e21fb3259042d8da85Adam Powell     * The rules are as follows:
87336fced9b211255e2137014e21fb3259042d8da85Adam Powell     *
87436fced9b211255e2137014e21fb3259042d8da85Adam Powell     * <p>Items are considered for inclusion in the order specified within the menu.
87536fced9b211255e2137014e21fb3259042d8da85Adam Powell     * There is a limit of mMaxActionItems as a total count, optionally including the overflow
87636fced9b211255e2137014e21fb3259042d8da85Adam Powell     * menu button itself. This is a soft limit; if an item shares a group ID with an item
87736fced9b211255e2137014e21fb3259042d8da85Adam Powell     * previously included as an action item, the new item will stay with its group and become
87836fced9b211255e2137014e21fb3259042d8da85Adam Powell     * an action item itself even if it breaks the max item count limit. This is done to
87936fced9b211255e2137014e21fb3259042d8da85Adam Powell     * limit the conceptual complexity of the items presented within an action bar. Only a few
88036fced9b211255e2137014e21fb3259042d8da85Adam Powell     * unrelated concepts should be presented to the user in this space, and groups are treated
88136fced9b211255e2137014e21fb3259042d8da85Adam Powell     * as a single concept.
88236fced9b211255e2137014e21fb3259042d8da85Adam Powell     *
88336fced9b211255e2137014e21fb3259042d8da85Adam Powell     * <p>There is also a hard limit of consumed measurable space: mActionWidthLimit. This
88436fced9b211255e2137014e21fb3259042d8da85Adam Powell     * limit may be broken by a single item that exceeds the remaining space, but no further
88536fced9b211255e2137014e21fb3259042d8da85Adam Powell     * items may be added. If an item that is part of a group cannot fit within the remaining
88636fced9b211255e2137014e21fb3259042d8da85Adam Powell     * measured width, the entire group will be demoted to overflow. This is done to ensure room
88736fced9b211255e2137014e21fb3259042d8da85Adam Powell     * for navigation and other affordances in the action bar as well as reduce general UI clutter.
88836fced9b211255e2137014e21fb3259042d8da85Adam Powell     *
88936fced9b211255e2137014e21fb3259042d8da85Adam Powell     * <p>The space freed by demoting a full group cannot be consumed by future menu items.
89036fced9b211255e2137014e21fb3259042d8da85Adam Powell     * Once items begin to overflow, all future items become overflow items as well. This is
89136fced9b211255e2137014e21fb3259042d8da85Adam Powell     * to avoid inadvertent reordering that may break the app's intended design.
89236fced9b211255e2137014e21fb3259042d8da85Adam Powell     */
893696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void flagActionItems() {
89496675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        if (!mIsActionItemsStale) {
89596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell            return;
89696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        }
8978028dd32a4a04154050220dd0693583d5b750330Adam Powell
898696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        // Presenters flag action items as needed.
899696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        boolean flagged = false;
900696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (WeakReference<MenuPresenter> ref : mPresenters) {
901696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final MenuPresenter presenter = ref.get();
902696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (presenter == null) {
903696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mPresenters.remove(ref);
9048028dd32a4a04154050220dd0693583d5b750330Adam Powell            } else {
905696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                flagged |= presenter.flagActionItems();
90696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell            }
90796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        }
9088028dd32a4a04154050220dd0693583d5b750330Adam Powell
909696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (flagged) {
910696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mActionItems.clear();
911696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mNonActionItems.clear();
912696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            ArrayList<MenuItemImpl> visibleItems = getVisibleItems();
913696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final int itemsSize = visibleItems.size();
914696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            for (int i = 0; i < itemsSize; i++) {
915696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                MenuItemImpl item = visibleItems.get(i);
916696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                if (item.isActionButton()) {
917696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    mActionItems.add(item);
918696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                } else {
919696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    mNonActionItems.add(item);
92036fced9b211255e2137014e21fb3259042d8da85Adam Powell                }
92196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell            }
922696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        } else if (mActionItems.size() + mNonActionItems.size() != getVisibleItems().size()) {
923696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            // Nobody flagged anything, but if something doesn't add up then treat everything
924696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            // as non-action items.
925696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            // (This happens during a first pass with no action-item presenters.)
926696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mActionItems.clear();
927696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mNonActionItems.clear();
928696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mNonActionItems.addAll(getVisibleItems());
92996675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        }
93096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        mIsActionItemsStale = false;
93196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    }
93296675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell
933696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    ArrayList<MenuItemImpl> getActionItems() {
934696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        flagActionItems();
93596675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        return mActionItems;
93696675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    }
93796675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell
938696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    ArrayList<MenuItemImpl> getNonActionItems() {
939696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        flagActionItems();
94096675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell        return mNonActionItems;
94196675b1df3969f2d313b68f60ed9fa36805db8ceAdam Powell    }
94236fced9b211255e2137014e21fb3259042d8da85Adam Powell
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearHeader() {
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeaderIcon = null;
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeaderTitle = null;
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeaderView = null;
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onItemsChanged(false);
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void setHeaderInternal(final int titleRes, final CharSequence title, final int iconRes,
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final Drawable icon, final View view) {
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Resources r = getResources();
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (view != null) {
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHeaderView = view;
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If using a custom view, then the title and icon aren't used
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHeaderTitle = null;
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHeaderIcon = null;
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (titleRes > 0) {
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHeaderTitle = r.getText(titleRes);
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (title != null) {
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHeaderTitle = title;
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (iconRes > 0) {
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHeaderIcon = r.getDrawable(iconRes);
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (icon != null) {
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHeaderIcon = icon;
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If using the title or icon, then a custom view isn't used
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHeaderView = null;
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Notify of change
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onItemsChanged(false);
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the header's title. This replaces the header view. Called by the
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * builder-style methods of subclasses.
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param title The new title.
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This MenuBuilder so additional setters can be called.
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected MenuBuilder setHeaderTitleInt(CharSequence title) {
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeaderInternal(0, title, 0, null, null);
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the header's title. This replaces the header view. Called by the
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * builder-style methods of subclasses.
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param titleRes The new title (as a resource ID).
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This MenuBuilder so additional setters can be called.
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected MenuBuilder setHeaderTitleInt(int titleRes) {
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeaderInternal(titleRes, null, 0, null, null);
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the header's icon. This replaces the header view. Called by the
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * builder-style methods of subclasses.
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param icon The new icon.
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This MenuBuilder so additional setters can be called.
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected MenuBuilder setHeaderIconInt(Drawable icon) {
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeaderInternal(0, null, 0, icon, null);
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the header's icon. This replaces the header view. Called by the
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * builder-style methods of subclasses.
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param iconRes The new icon (as a resource ID).
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This MenuBuilder so additional setters can be called.
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected MenuBuilder setHeaderIconInt(int iconRes) {
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeaderInternal(0, null, iconRes, null, null);
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the header's view. This replaces the title and icon. Called by the
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * builder-style methods of subclasses.
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param view The new view.
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return This MenuBuilder so additional setters can be called.
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected MenuBuilder setHeaderViewInt(View view) {
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeaderInternal(0, null, 0, null, view);
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence getHeaderTitle() {
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeaderTitle;
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getHeaderIcon() {
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeaderIcon;
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getHeaderView() {
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeaderView;
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets the root menu (if this is a submenu, find its root menu).
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The root menu.
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuBuilder getRootMenu() {
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the current menu info that is set on all items added to this menu
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (until this is called again with different menu info, in which case that
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * one will be added to all subsequent item additions).
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param menuInfo The extra menu information to add.
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCurrentMenuInfo(ContextMenuInfo menuInfo) {
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurrentMenuInfo = menuInfo;
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void setOptionalIconsVisible(boolean visible) {
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOptionalIconsVisible = visible;
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean getOptionalIconsVisible() {
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mOptionalIconsVisible;
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1081