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