1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/*
2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Copyright (C) 2011 The Android Open Source Project
3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed under the Apache License, Version 2.0 (the "License");
5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * you may not use this file except in compliance with the License.
6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * You may obtain a copy of the License at
7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      http://www.apache.org/licenses/LICENSE-2.0
9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software
11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS,
12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and
14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License.
15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */
16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage com.android.email.activity;
18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.ActionBar;
20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.LoaderManager;
21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.LoaderManager.LoaderCallbacks;
22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.content.Context;
23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.content.Loader;
24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.database.Cursor;
25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.graphics.drawable.Drawable;
26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.Bundle;
274c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwalimport android.text.SpannableString;
284c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwalimport android.text.SpannableStringBuilder;
29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.text.TextUtils;
304c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwalimport android.text.style.TextAppearanceSpan;
31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.LayoutInflater;
32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.View;
33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.ViewGroup;
34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.widget.AdapterView;
35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.widget.AdapterView.OnItemClickListener;
36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.widget.ListPopupWindow;
37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.widget.ListView;
38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.widget.SearchView;
39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.widget.TextView;
40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.R;
42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Account;
43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Mailbox;
44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.utility.DelayedOperations;
45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.utility.Utility;
46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/**
48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Manages the account name and the custom view part on the action bar.
49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */
50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class ActionBarController {
51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private static final String BUNDLE_KEY_MODE = "ActionBarController.BUNDLE_KEY_MODE";
52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Constants for {@link #mSearchMode}.
55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * In {@link #MODE_NORMAL} mode, we don't show the search box.
57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * In {@link #MODE_SEARCH} mode, we do show the search box.
58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The action bar doesn't really care if the activity is showing search results.
59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * If the activity is showing search results, and the {@link Callback#onSearchExit} is called,
60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * the activity probably wants to close itself, but this class doesn't make the desision.
61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private static final int MODE_NORMAL = 0;
63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private static final int MODE_SEARCH = 1;
64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private static final int LOADER_ID_ACCOUNT_LIST
66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            = EmailActivity.ACTION_BAR_CONTROLLER_LOADER_ID_BASE + 0;
67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
6809a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    private static final int DISPLAY_TITLE_MULTIPLE_LINES = 0x20;
6909a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    private static final int ACTION_BAR_MASK =
7009a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM
7109a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook                    | ActionBar.DISPLAY_SHOW_TITLE | DISPLAY_TITLE_MULTIPLE_LINES;
7209a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    private static final int CUSTOM_ACTION_BAR_OPTIONS =
7309a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM;
7409a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook
75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final Context mContext;
76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final LoaderManager mLoaderManager;
77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final ActionBar mActionBar;
78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final DelayedOperations mDelayedOperations;
79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** "Folders" label shown with account name on 1-pane mailbox list */
81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final String mAllFoldersLabel;
82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final ViewGroup mActionBarCustomView;
84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final ViewGroup mAccountSpinnerContainer;
85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final View mAccountSpinner;
86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final Drawable mAccountSpinnerDefaultBackground;
87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final TextView mAccountSpinnerLine1View;
88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final TextView mAccountSpinnerLine2View;
89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final TextView mAccountSpinnerCountView;
90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private View mSearchContainer;
92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private SearchView mSearchView;
93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final AccountDropdownPopup mAccountDropdown;
95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final AccountSelectorAdapter mAccountsSelectorAdapter;
97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private AccountSelectorAdapter.CursorWithExtras mCursor;
99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** The current account ID; used to determine if the account has changed. */
101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private long mLastAccountIdForDirtyCheck = Account.NO_ACCOUNT;
102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** The current mailbox ID; used to determine if the mailbox has changed. */
104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private long mLastMailboxIdForDirtyCheck = Mailbox.NO_MAILBOX;
105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** Either {@link #MODE_NORMAL} or {@link #MODE_SEARCH}. */
107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private int mSearchMode = MODE_NORMAL;
108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** The current title mode, which should be one of {@code Callback TITLE_MODE_*} */
110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private int mTitleMode;
111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public final Callback mCallback;
113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public interface SearchContext {
115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public long getTargetMailboxId();
116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private static final int TITLE_MODE_SPINNER_ENABLED = 0x10;
119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public interface Callback {
121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /** Values for {@link #getTitleMode}.  Show only account name */
122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public static final int TITLE_MODE_ACCOUNT_NAME_ONLY = 0 | TITLE_MODE_SPINNER_ENABLED;
123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Show the current account name with "Folders"
126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * The account spinner will be disabled in this mode.
127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public static final int TITLE_MODE_ACCOUNT_WITH_ALL_FOLDERS_LABEL = 1;
129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Show the current account name and the current mailbox name.
132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public static final int TITLE_MODE_ACCOUNT_WITH_MAILBOX = 2 | TITLE_MODE_SPINNER_ENABLED;
134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Show the current message subject.  Actual subject is obtained via
136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * {@link #getMessageSubject()}.
137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         *
138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * The account spinner will be disabled in this mode.
139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public static final int TITLE_MODE_MESSAGE_SUBJECT = 3;
141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /** @return true if an account is selected. */
143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public boolean isAccountSelected();
144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @return currently selected account ID, {@link Account#ACCOUNT_ID_COMBINED_VIEW},
147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * or -1 if no account is selected.
148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public long getUIAccountId();
150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @return currently selected mailbox ID, or {@link Mailbox#NO_MAILBOX} if no mailbox is
153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * selected.
154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public long getMailboxId();
156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @return constants such as {@link #TITLE_MODE_ACCOUNT_NAME_ONLY}.
159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public int getTitleMode();
161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /** @see #TITLE_MODE_MESSAGE_SUBJECT */
163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public String getMessageSubject();
164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /** @return the "UP" arrow should be shown. */
166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public boolean shouldShowUp();
167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Called when an account is selected on the account spinner.
170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @param accountId ID of the selected account, or {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void onAccountSelected(long accountId);
173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Invoked when a recent mailbox is selected on the account spinner.
176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         *
177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @param accountId ID of the selected account, or {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @param mailboxId The ID of the selected mailbox, or {@link Mailbox#NO_MAILBOX} if the
179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         *          special option "show all mailboxes" was selected.
180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void onMailboxSelected(long accountId, long mailboxId);
182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /** Called when no accounts are found in the database. */
184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void onNoAccountsFound();
185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Retrieves the hint text to be shown for when a search entry is being made.
188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public String getSearchHint();
190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Called when the action bar initially shows the search entry field.
193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void onSearchStarted();
195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Called when a search is submitted.
198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         *
199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @param queryTerm query string
200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void onSearchSubmit(String queryTerm);
202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * Called when the search box is closed.
205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void onSearchExit();
207ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang
208ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        public void onUpPressed();
209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public ActionBarController(Context context, LoaderManager loaderManager,
212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ActionBar actionBar, Callback callback) {
213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mContext = context;
214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mLoaderManager = loaderManager;
215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mActionBar = actionBar;
216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mCallback = callback;
217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mDelayedOperations = new DelayedOperations(Utility.getMainThreadHandler());
218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAllFoldersLabel = mContext.getResources().getString(
219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                R.string.action_bar_mailbox_list_title);
220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountsSelectorAdapter = new AccountSelectorAdapter(mContext);
221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // Configure action bar.
22309a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook        enterCustomActionBarMode();
224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // Prepare the custom view
226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mActionBar.setCustomView(R.layout.action_bar_custom_view);
227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mActionBarCustomView = (ViewGroup) mActionBar.getCustomView();
228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // Account spinner
230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinnerContainer =
231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                UiUtilities.getView(mActionBarCustomView, R.id.account_spinner_container);
232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinner = UiUtilities.getView(mActionBarCustomView, R.id.account_spinner);
233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinnerDefaultBackground = mAccountSpinner.getBackground();
234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinnerLine1View = UiUtilities.getView(mActionBarCustomView, R.id.spinner_line_1);
236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinnerLine2View = UiUtilities.getView(mActionBarCustomView, R.id.spinner_line_2);
237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinnerCountView = UiUtilities.getView(mActionBarCustomView, R.id.spinner_count);
238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // Account dropdown
240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountDropdown = new AccountDropdownPopup(mContext);
241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountDropdown.setAdapter(mAccountsSelectorAdapter);
242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinner.setOnClickListener(new View.OnClickListener() {
244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            @Override public void onClick(View v) {
245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                if (mAccountsSelectorAdapter.getCount() > 0) {
246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    mAccountDropdown.show();
247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                }
248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        });
250ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        // this other click listener handles clicks that ought to be aliased to "up"
251ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        // only one or the other listener should be active at any time
252ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        mActionBarCustomView.setOnClickListener(new View.OnClickListener() {
253ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang            @Override
254ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang            public void onClick(View v) {
255ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang                mCallback.onUpPressed();
256ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang            }
257ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        });
258ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        // pick a sane default. later enabled in updateTitle().
259ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        mActionBarCustomView.setClickable(false);
260bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
261bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
262bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private void initSearchViews() {
263bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mSearchContainer == null) {
264bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            final LayoutInflater inflater = LayoutInflater.from(mContext);
265bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchContainer = inflater.inflate(R.layout.action_bar_search, null);
266bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchView = UiUtilities.getView(mSearchContainer, R.id.search_view);
267bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchView.setSubmitButtonEnabled(false);
268bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchView.setOnQueryTextListener(mOnQueryText);
269bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchView.onActionViewExpanded();
270bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mActionBarCustomView.addView(mSearchContainer);
271bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
272bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
273bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
274bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
275bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** Must be called from {@link UIControllerBase#onActivityCreated()} */
276bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void onActivityCreated() {
277bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        refresh();
278bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
279bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
280bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** Must be called from {@link UIControllerBase#onActivityDestroy()} */
281bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void onActivityDestroy() {
282bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mAccountDropdown.isShowing()) {
283bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountDropdown.dismiss();
284bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
285bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
286bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
287bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** Must be called from {@link UIControllerBase#onSaveInstanceState} */
288bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void onSaveInstanceState(Bundle outState) {
289bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mDelayedOperations.removeCallbacks(); // Remove all pending operations
290bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        outState.putInt(BUNDLE_KEY_MODE, mSearchMode);
291bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
292bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
293bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** Must be called from {@link UIControllerBase#onRestoreInstanceState} */
294bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void onRestoreInstanceState(Bundle savedState) {
295bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        int mode = savedState.getInt(BUNDLE_KEY_MODE);
296bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mode == MODE_SEARCH) {
297bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // No need to re-set the initial query, as the View tree restoration does that
298bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            enterSearchMode(null);
299bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
300bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
301bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
302bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
303bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return true if the search box is shown.
304bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
305bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public boolean isInSearchMode() {
306bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return mSearchMode == MODE_SEARCH;
307bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
308bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
309bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
310bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return Whether or not the search bar should be shown. This is a function of whether or not a
311bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *     search is active, and if the current layout supports it.
312bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
313bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private boolean shouldShowSearchBar() {
314bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return isInSearchMode() && (mTitleMode != Callback.TITLE_MODE_MESSAGE_SUBJECT);
315bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
316bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
317bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
318bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Show the search box.
319bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
320bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param initialQueryTerm if non-empty, set to the search box.
321bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
322bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void enterSearchMode(String initialQueryTerm) {
323bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        initSearchViews();
324bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (isInSearchMode()) {
325bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
326bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
327bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (!TextUtils.isEmpty(initialQueryTerm)) {
328bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchView.setQuery(initialQueryTerm, false);
329bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        } else {
330bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchView.setQuery("", false);
331bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
332bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mSearchView.setQueryHint(mCallback.getSearchHint());
333bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
334bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mSearchMode = MODE_SEARCH;
335bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
336bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // Focus on the search input box and throw up the IME if specified.
337bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // TODO: HACK. this is a workaround IME not popping up.
338bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mSearchView.setIconified(false);
339bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
340bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        refresh();
341bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mCallback.onSearchStarted();
342bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
343bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
344bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void exitSearchMode() {
345bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (!isInSearchMode()) {
346bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
347bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
348bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mSearchMode = MODE_NORMAL;
349bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
350bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        refresh();
351bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mCallback.onSearchExit();
352bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
353bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
354bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
355bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Performs the back action.
356bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
357bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param isSystemBackKey <code>true</code> if the system back key was pressed.
358bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>false</code> if it's caused by the "home" icon click on the action bar.
359bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
360bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public boolean onBackPressed(boolean isSystemBackKey) {
361bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (shouldShowSearchBar()) {
362bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            exitSearchMode();
363bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return true;
364bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
365bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return false;
366bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
367bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
368bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /** Refreshes the action bar display. */
369bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void refresh() {
370bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // The actual work is in refreshInernal(), but we don't call it directly here, because:
371bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // 1. refresh() is called very often.
372bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // 2. to avoid nested fragment transaction.
373bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        //    refresh is often called during a fragment transaction, but updateTitle() may call
374bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        //    a callback which would initiate another fragment transaction.
375bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mDelayedOperations.removeCallbacks(mRefreshRunnable);
376bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mDelayedOperations.post(mRefreshRunnable);
377bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
378bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
379bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final Runnable mRefreshRunnable = new Runnable() {
380bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        @Override public void run() {
381bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            refreshInernal();
382bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
383bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    };
384bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private void refreshInernal() {
385bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        final boolean showUp = isInSearchMode() || mCallback.shouldShowUp();
386bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mActionBar.setDisplayOptions(showUp
387bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                ? ActionBar.DISPLAY_HOME_AS_UP : 0, ActionBar.DISPLAY_HOME_AS_UP);
388bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
389bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        final long accountId = mCallback.getUIAccountId();
390bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        final long mailboxId = mCallback.getMailboxId();
391bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if ((mLastAccountIdForDirtyCheck != accountId)
392bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                || (mLastMailboxIdForDirtyCheck != mailboxId)) {
393bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mLastAccountIdForDirtyCheck = accountId;
394bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mLastMailboxIdForDirtyCheck = mailboxId;
395bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
396bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            if (accountId != Account.NO_ACCOUNT) {
397bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                loadAccountMailboxInfo(accountId, mailboxId);
398bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
399bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
400bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
401bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        updateTitle();
402bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
403bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
404bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
405bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Load account/mailbox info, and account/recent mailbox list.
406bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
407bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private void loadAccountMailboxInfo(final long accountId, final long mailboxId) {
408bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mLoaderManager.restartLoader(LOADER_ID_ACCOUNT_LIST, null,
409bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                new LoaderCallbacks<Cursor>() {
410bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            @Override
411bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            public Loader<Cursor> onCreateLoader(int id, Bundle args) {
412bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                return AccountSelectorAdapter.createLoader(mContext, accountId, mailboxId);
413bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
414bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
415bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            @Override
416bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
417bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mCursor = (AccountSelectorAdapter.CursorWithExtras) data;
418bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                updateTitle();
419bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
420bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
421bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            @Override
422bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            public void onLoaderReset(Loader<Cursor> loader) {
423bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mCursor = null;
424bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                updateTitle();
425bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
426bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        });
427bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
428bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
429bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
430bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Update the "title" part.
431bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
432bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private void updateTitle() {
433bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountsSelectorAdapter.swapCursor(mCursor);
434bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
43509a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook        enterCustomActionBarMode();
436bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mCursor == null) {
437bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // Initial load not finished.
438bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mActionBarCustomView.setVisibility(View.GONE);
439bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
440bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
441bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mActionBarCustomView.setVisibility(View.VISIBLE);
442bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
443bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mCursor.getAccountCount() == 0) {
444bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mCallback.onNoAccountsFound();
445bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
446bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
447bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
448bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if ((mCursor.getAccountId() != Account.NO_ACCOUNT) && !mCursor.accountExists()) {
449bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // Account specified, but does not exist.
450bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            if (isInSearchMode()) {
451bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                exitSearchMode();
452bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
453bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
454bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // Switch to the default account.
455bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mCallback.onAccountSelected(Account.getDefaultAccountId(mContext));
456bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
457bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
458bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
459bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mTitleMode = mCallback.getTitleMode();
460bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
461bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (shouldShowSearchBar()) {
462bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            initSearchViews();
463bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // In search mode, the search box is a replacement of the account spinner, so ignore
464bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // the work needed to update that. It will get updated when it goes visible again.
465bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountSpinnerContainer.setVisibility(View.GONE);
466bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mSearchContainer.setVisibility(View.VISIBLE);
467bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
468bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
469bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
470bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // Account spinner visible.
471bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinnerContainer.setVisibility(View.VISIBLE);
472bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        UiUtilities.setVisibilitySafe(mSearchContainer, View.GONE);
473bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
474bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mTitleMode == Callback.TITLE_MODE_MESSAGE_SUBJECT) {
47509a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            // Use two line title action bar mode
47609a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            enterMultiLineTitleActionBarMode();
4774c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            String subject = mCallback.getMessageSubject();
4784c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            if (subject == null) {
4794c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal                subject = "";
4804c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            }
4814c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            final SpannableString title = new SpannableString(subject);
4824c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            final SpannableStringBuilder builder = new SpannableStringBuilder();
4834c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            title.setSpan(new TextAppearanceSpan(mContext, R.style.subject_action_bar_title_text),
4844c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal                    0, subject.length(), 0);
4854c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            builder.append(title);
4864c13e1cf4ac82d53093c99ecedf83fee738e8af8Vikram Aggarwal            mActionBar.setTitle(builder);
48709a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            mActionBar.setSubtitle(null);
48809a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook        } else if (mTitleMode == Callback.TITLE_MODE_ACCOUNT_WITH_ALL_FOLDERS_LABEL) {
48909a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            enterSingleLineTitleActionBarMode();
49009a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            mActionBar.setTitle(mAllFoldersLabel);
49109a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            mActionBar.setSubtitle(mCursor.getAccountDisplayName());
492bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        } else {
493bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // Get mailbox name
494bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            final String mailboxName;
49509a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook            if (mTitleMode == Callback.TITLE_MODE_ACCOUNT_WITH_MAILBOX) {
496bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mailboxName = mCursor.getMailboxDisplayName();
497bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            } else {
498bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mailboxName = null;
499bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
500bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
501bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // Note - setSingleLine is needed as well as setMaxLines since they set different
502bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // flags on the view.
503bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountSpinnerLine1View.setSingleLine();
504bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountSpinnerLine1View.setMaxLines(1);
505bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            if (TextUtils.isEmpty(mailboxName)) {
506bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mAccountSpinnerLine1View.setText(mCursor.getAccountDisplayName());
507bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
508bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                // Change the visibility of line 2, so line 1 will be vertically-centered.
509bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mAccountSpinnerLine2View.setVisibility(View.GONE);
510bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            } else {
511bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mAccountSpinnerLine1View.setText(mailboxName);
512bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mAccountSpinnerLine2View.setVisibility(View.VISIBLE);
513bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mAccountSpinnerLine2View.setText(mCursor.getAccountDisplayName());
514bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
515bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
516bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountSpinnerCountView.setVisibility(View.VISIBLE);
517bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountSpinnerCountView.setText(UiUtilities.getMessageCountForUi(
518bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    mContext, mCursor.getMailboxMessageCount(), true));
519bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
520bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
521bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        boolean spinnerEnabled =
522bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ((mTitleMode & TITLE_MODE_SPINNER_ENABLED) != 0) && mCursor.shouldEnableSpinner();
523bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
524bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        setSpinnerEnabled(spinnerEnabled);
525bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
526bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
52709a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    private void enterCustomActionBarMode() {
52809a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook        mActionBar.setDisplayOptions(CUSTOM_ACTION_BAR_OPTIONS, ACTION_BAR_MASK);
52909a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    }
53009a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook
53109a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    private void enterMultiLineTitleActionBarMode() {
53209a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook        mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE
53309a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook                | DISPLAY_TITLE_MULTIPLE_LINES, ACTION_BAR_MASK);
53409a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    }
53509a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook
53609a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    private void enterSingleLineTitleActionBarMode() {
53709a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook        mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE,
53809a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook                ACTION_BAR_MASK);
53909a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook    }
54009a09623952011e72b28d0fd3e6b9845477a6a52Paul Westbrook
541bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private void setSpinnerEnabled(boolean enabled) {
542bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (enabled == mAccountSpinner.isEnabled()) {
543bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
544bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
545bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
546bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinner.setEnabled(enabled);
547ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        mAccountSpinner.setClickable(enabled);
548ed060515f11fd22b2f8e32eacab28a720ea552caAndy Huang        mActionBarCustomView.setClickable(!enabled);
549bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (enabled) {
550bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountSpinner.setBackgroundDrawable(mAccountSpinnerDefaultBackground);
551bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        } else {
552bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mAccountSpinner.setBackgroundDrawable(null);
553bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
554bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
555bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // For some reason, changing the background mucks with the padding so we have to manually
556bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // reset vertical padding here (also specified in XML, but it seems to be ignored for
557bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // some reason.
558bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mAccountSpinner.setPadding(
559bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mAccountSpinner.getPaddingLeft(),
560bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                0,
561bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                mAccountSpinner.getPaddingRight(),
562bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                0);
563bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
564bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
565bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
566bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private final SearchView.OnQueryTextListener mOnQueryText
567bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            = new SearchView.OnQueryTextListener() {
568bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        @Override
569bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public boolean onQueryTextChange(String newText) {
570bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // Event not handled.  Let the search do the default action.
571bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return false;
572bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
573bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
574bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        @Override
575bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public boolean onQueryTextSubmit(String query) {
576bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mCallback.onSearchSubmit(mSearchView.getQuery().toString());
577bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return true; // Event handled.
578bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
579bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    };
580bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
581bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private void onAccountSpinnerItemClicked(int position) {
582bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mAccountsSelectorAdapter == null) { // just in case...
583bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return;
584bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
585bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        final long accountId = mAccountsSelectorAdapter.getAccountId(position);
586bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
587bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mAccountsSelectorAdapter.isAccountItem(position)) {
588bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mCallback.onAccountSelected(accountId);
589bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        } else if (mAccountsSelectorAdapter.isMailboxItem(position)) {
590bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mCallback.onMailboxSelected(accountId,
591bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    mAccountsSelectorAdapter.getId(position));
592bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
593bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
594bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
595bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // Based on Spinner.DropdownPopup
596bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private class AccountDropdownPopup extends ListPopupWindow {
597bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public AccountDropdownPopup(Context context) {
598bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            super(context);
599bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            setAnchorView(mAccountSpinner);
600bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            setModal(true);
601bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            setPromptPosition(POSITION_PROMPT_ABOVE);
602bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            setOnItemClickListener(new OnItemClickListener() {
603bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
604bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    onAccountSpinnerItemClicked(position);
605bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    dismiss();
606bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                }
607bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            });
608bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
609bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
610bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        @Override
611bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void show() {
612bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            setWidth(mContext.getResources().getDimensionPixelSize(
613bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    R.dimen.account_dropdown_dropdownwidth));
614bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
615bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            super.show();
616bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            // List view is instantiated in super.show(), so we need to do this after...
617bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
618bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
619bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
620bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook}
621