1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/* 2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Copyright (C) 2010 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.content.Context; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.content.Loader; 21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.database.Cursor; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.database.CursorWrapper; 23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.Bundle; 24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.util.Log; 25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.View; 26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.ViewGroup; 27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.widget.CursorAdapter; 28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.Controller; 30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.Email; 31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.MessageListContext; 32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.ResourceHelper; 33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.data.ThrottlingCursorLoader; 34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.Logging; 35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.mail.MessagingException; 36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Account; 37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.EmailContent; 38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.EmailContent.Message; 39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.EmailContent.MessageColumns; 40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Mailbox; 41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.utility.TextUtilities; 42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.utility.Utility; 43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.google.common.base.Preconditions; 44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.util.HashSet; 46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.util.Set; 47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/** 50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This class implements the adapter for displaying messages based on cursors. 51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/* package */ class MessagesAdapter extends CursorAdapter { 53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private static final String STATE_CHECKED_ITEMS = 54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook "com.android.email.activity.MessagesAdapter.checkedItems"; 55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /* package */ static final String[] MESSAGE_PROJECTION = new String[] { 57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook EmailContent.RECORD_ID, MessageColumns.MAILBOX_KEY, MessageColumns.ACCOUNT_KEY, 58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageColumns.DISPLAY_NAME, MessageColumns.SUBJECT, MessageColumns.TIMESTAMP, 59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageColumns.FLAG_READ, MessageColumns.FLAG_FAVORITE, MessageColumns.FLAG_ATTACHMENT, 60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageColumns.FLAGS, MessageColumns.SNIPPET 61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }; 62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_ID = 0; 64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_MAILBOX_KEY = 1; 65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_ACCOUNT_KEY = 2; 66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_DISPLAY_NAME = 3; 67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_SUBJECT = 4; 68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_DATE = 5; 69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_READ = 6; 70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_FAVORITE = 7; 71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_ATTACHMENTS = 8; 72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_FLAGS = 9; 73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static final int COLUMN_SNIPPET = 10; 74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final ResourceHelper mResourceHelper; 76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** If true, show color chips. */ 78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean mShowColorChips; 79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** If not null, the query represented by this group of messages */ 81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private String mQuery; 82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Set of seleced message IDs. 85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final HashSet<Long> mSelectedSet = new HashSet<Long>(); 87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Callback from MessageListAdapter. All methods are called on the UI thread. 90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public interface Callback { 92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Called when the use starts/unstars a message */ 93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook void onAdapterFavoriteChanged(MessageListItem itemView, boolean newFavorite); 94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Called when the user selects/unselects a message */ 95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook void onAdapterSelectedChanged(MessageListItem itemView, boolean newSelected, 96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook int mSelectedCount); 97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final Callback mCallback; 100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private ThreePaneLayout mLayout; 102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean mIsSearchResult = false; 104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The actual return type from the loader. 107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static class MessagesCursor extends CursorWrapper { 109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Whether the mailbox is found. */ 110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final boolean mIsFound; 111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** {@link Account} that owns the mailbox. Null for combined mailboxes. */ 112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final Account mAccount; 113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** {@link Mailbox} for the loaded mailbox. Null for combined mailboxes. */ 114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final Mailbox mMailbox; 115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** {@code true} if the account is an EAS account */ 116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final boolean mIsEasAccount; 117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** {@code true} if the loaded mailbox can be refreshed. */ 118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final boolean mIsRefreshable; 119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** the number of accounts currently configured. */ 120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final int mCountTotalAccounts; 121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private MessagesCursor(Cursor cursor, 123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean found, Account account, Mailbox mailbox, boolean isEasAccount, 124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isRefreshable, int countTotalAccounts) { 125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super(cursor); 126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mIsFound = found; 127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mAccount = account; 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMailbox = mailbox; 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mIsEasAccount = isEasAccount; 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mIsRefreshable = isRefreshable; 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mCountTotalAccounts = countTotalAccounts; 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public MessagesAdapter(Context context, Callback callback, boolean isSearchResult) { 136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super(context.getApplicationContext(), null, 0 /* no auto requery */); 137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mResourceHelper = ResourceHelper.getInstance(context); 138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mCallback = callback; 139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mIsSearchResult = isSearchResult; 140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void setLayout(ThreePaneLayout layout) { 143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mLayout = layout; 144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onSaveInstanceState(Bundle outState) { 147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook outState.putLongArray(STATE_CHECKED_ITEMS, Utility.toPrimitiveLongArray(getSelectedSet())); 148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void loadState(Bundle savedInstanceState) { 151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Set<Long> checkedset = getSelectedSet(); 152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook checkedset.clear(); 153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook for (long l: savedInstanceState.getLongArray(STATE_CHECKED_ITEMS)) { 154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook checkedset.add(l); 155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook notifyDataSetChanged(); 157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Set true for combined mailboxes. 161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void setShowColorChips(boolean show) { 163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mShowColorChips = show; 164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void setQuery(String query) { 167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mQuery = query; 168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Set<Long> getSelectedSet() { 171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mSelectedSet; 172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Clear the selection. It's preferable to calling {@link Set#clear()} on 176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link #getSelectedSet()}, because it also notifies observers. 177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void clearSelection() { 179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Set<Long> checkedset = getSelectedSet(); 180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (checkedset.size() > 0) { 181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook checkedset.clear(); 182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook notifyDataSetChanged(); 183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public boolean isSelected(MessageListItem itemView) { 187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return getSelectedSet().contains(itemView.mMessageId); 188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void bindView(View view, Context context, Cursor cursor) { 192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Reset the view (in case it was recycled) and prepare for binding 193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageListItem itemView = (MessageListItem) view; 194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.bindViewInit(this, mLayout, mIsSearchResult); 195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO: just move thise all to a MessageListItem.bindTo(cursor) so that the fields can 197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // be private, and their inter-dependence when they change can be abstracted away. 198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Load the public fields in the view (for later use) 200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mMessageId = cursor.getLong(COLUMN_ID); 201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mMailboxId = cursor.getLong(COLUMN_MAILBOX_KEY); 202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long accountId = cursor.getLong(COLUMN_ACCOUNT_KEY); 203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mAccountId = accountId; 204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isRead = cursor.getInt(COLUMN_READ) != 0; 206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean readChanged = isRead != itemView.mRead; 207bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mRead = isRead; 208bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mIsFavorite = cursor.getInt(COLUMN_FAVORITE) != 0; 209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final int flags = cursor.getInt(COLUMN_FLAGS); 210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mHasInvite = (flags & Message.FLAG_INCOMING_MEETING_INVITE) != 0; 211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mHasBeenRepliedTo = (flags & Message.FLAG_REPLIED_TO) != 0; 212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mHasBeenForwarded = (flags & Message.FLAG_FORWARDED) != 0; 213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mHasAttachment = cursor.getInt(COLUMN_ATTACHMENTS) != 0; 214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.setTimestamp(cursor.getLong(COLUMN_DATE)); 215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mSender = cursor.getString(COLUMN_DISPLAY_NAME); 216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.setText( 217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook cursor.getString(COLUMN_SUBJECT), cursor.getString(COLUMN_SNIPPET), readChanged); 218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mColorChipPaint = 219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mShowColorChips ? mResourceHelper.getAccountColorPaint(accountId) : null; 220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mQuery != null && itemView.mSnippet != null) { 222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook itemView.mSnippet = 223bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook TextUtilities.highlightTermsInText(cursor.getString(COLUMN_SNIPPET), mQuery); 224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public View newView(Context context, Cursor cursor, ViewGroup parent) { 229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageListItem item = new MessageListItem(context); 230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook item.setVisibility(View.VISIBLE); 231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return item; 232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void toggleSelected(MessageListItem itemView) { 235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateSelected(itemView, !isSelected(itemView)); 236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This is used as a callback from the list items, to set the selected state 240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>Must be called on the UI thread. 242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param itemView the item being changed 244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param newSelected the new value of the selected flag (checkbox state) 245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private void updateSelected(MessageListItem itemView, boolean newSelected) { 247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (newSelected) { 248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mSelectedSet.add(itemView.mMessageId); 249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 250bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mSelectedSet.remove(itemView.mMessageId); 251bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 252bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mCallback != null) { 253bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mCallback.onAdapterSelectedChanged(itemView, newSelected, mSelectedSet.size()); 254bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 255bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 256bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 257bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 258bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This is used as a callback from the list items, to set the favorite state 259bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 260bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>Must be called on the UI thread. 261bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 262bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param itemView the item being changed 263bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param newFavorite the new value of the favorite flag (star state) 264bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 265bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void updateFavorite(MessageListItem itemView, boolean newFavorite) { 266bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook changeFavoriteIcon(itemView, newFavorite); 267bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mCallback != null) { 268bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mCallback.onAdapterFavoriteChanged(itemView, newFavorite); 269bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 270bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 271bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 272bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private void changeFavoriteIcon(MessageListItem view, boolean isFavorite) { 273bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook view.invalidate(); 274bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 275bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 276bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 277bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Creates the loader for {@link MessageListFragment}. 278bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 279bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return always of {@link MessagesCursor}. 280bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 281bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static Loader<Cursor> createLoader(Context context, MessageListContext listContext) { 282bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 283bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, "MessagesAdapter createLoader listContext=" + listContext); 284bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 285bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return listContext.isSearch() 286bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ? new SearchCursorLoader(context, listContext) 287bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook : new MessagesCursorLoader(context, listContext); 288bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 289bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 290bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private static class MessagesCursorLoader extends ThrottlingCursorLoader { 291bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final Context mContext; 292bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final long mAccountId; 293bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final long mMailboxId; 294bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 295bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public MessagesCursorLoader(Context context, MessageListContext listContext) { 296bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Initialize with no where clause. We'll set it later. 297bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super(context, EmailContent.Message.CONTENT_URI, 298bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MESSAGE_PROJECTION, null, null, 299bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook EmailContent.MessageColumns.TIMESTAMP + " DESC"); 300bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mContext = context; 301bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mAccountId = listContext.mAccountId; 302bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMailboxId = listContext.getMailboxId(); 303bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 304bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 305bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 306bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Cursor loadInBackground() { 307bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Build the where cause (which can't be done on the UI thread.) 308bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook setSelection(Message.buildMessageListSelection(mContext, mAccountId, mMailboxId)); 309bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Then do a query to get the cursor 310bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return loadExtras(super.loadInBackground()); 311bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 312bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 313bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private Cursor loadExtras(Cursor baseCursor) { 314bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean found = false; 315bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Account account = null; 316bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Mailbox mailbox = null; 317bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isEasAccount = false; 318bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isRefreshable = false; 319bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 320bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mMailboxId < 0) { 321bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Magic mailbox. 322bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook found = true; 323bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 324bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mailbox = Mailbox.restoreMailboxWithId(mContext, mMailboxId); 325bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mailbox != null) { 326bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook account = Account.restoreAccountWithId(mContext, mailbox.mAccountKey); 327bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (account != null) { 328bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook found = true; 329bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook isEasAccount = account.isEasAccount(mContext) ; 330bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook isRefreshable = Mailbox.isRefreshable(mContext, mMailboxId); 331bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { // Account removed? 332bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mailbox = null; 333bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 334bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 335bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 336bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final int countAccounts = EmailContent.count(mContext, Account.CONTENT_URI); 337bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return wrapCursor(baseCursor, found, account, mailbox, isEasAccount, 338bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook isRefreshable, countAccounts); 339bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 340bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 341bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 342bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Wraps a basic cursor containing raw messages with information about the context of 343bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the list that's being loaded, such as the account and the mailbox the messages 344bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * are for. 345bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Subclasses may extend this to wrap with additional data. 346bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 347bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected Cursor wrapCursor(Cursor cursor, 348bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean found, Account account, Mailbox mailbox, boolean isEasAccount, 349bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isRefreshable, int countTotalAccounts) { 350bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return new MessagesCursor(cursor, found, account, mailbox, isEasAccount, 351bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook isRefreshable, countTotalAccounts); 352bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 353bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 354bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 355bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public static class SearchResultsCursor extends MessagesCursor { 356bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final Mailbox mSearchedMailbox; 357bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final int mResultsCount; 358bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private SearchResultsCursor(Cursor cursor, 359bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean found, Account account, Mailbox mailbox, boolean isEasAccount, 360bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isRefreshable, int countTotalAccounts, 361bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Mailbox searchedMailbox, int resultsCount) { 362bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super(cursor, found, account, mailbox, isEasAccount, 363bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook isRefreshable, countTotalAccounts); 364bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mSearchedMailbox = searchedMailbox; 365bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mResultsCount = resultsCount; 366bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 367bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 368bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 369bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return the total number of results that match the given search query. Note that 370bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * there may not be that many items loaded in the cursor yet. 371bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 372bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public int getResultsCount() { 373bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mResultsCount; 374bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 375bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 376bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Mailbox getSearchedMailbox() { 377bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mSearchedMailbox; 378bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 379bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 380bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 381bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 382bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * A special loader used to perform a search. 383bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 384bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private static class SearchCursorLoader extends MessagesCursorLoader { 385bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final MessageListContext mListContext; 386bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private int mResultsCount = -1; 387bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private Mailbox mSearchedMailbox = null; 388bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 389bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public SearchCursorLoader(Context context, MessageListContext listContext) { 390bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super(context, listContext); 391bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Preconditions.checkArgument(listContext.isSearch()); 392bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mListContext = listContext; 393bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 394bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 395bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 396bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Cursor loadInBackground() { 397bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mResultsCount >= 0) { 398bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Result count known - the initial search meta data must have completed. 399bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return super.loadInBackground(); 400bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 401bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 402bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mSearchedMailbox == null) { 403bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mSearchedMailbox = Mailbox.restoreMailboxWithId( 404bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mContext, mListContext.getSearchedMailbox()); 405bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 406bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 407bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // The search results info hasn't even been loaded yet, so the Controller has not yet 408bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // initialized the search mailbox properly. Kick off the search first. 409bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Controller controller = Controller.getInstance(mContext); 410bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook try { 411bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mResultsCount = controller.searchMessages( 412bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mListContext.mAccountId, mListContext.getSearchParams()); 413bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } catch (MessagingException e) { 414bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 415bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 416bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Return whatever the super would do, now that we know the results are ready. 417bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // After this point, it should behave as a normal mailbox load for messages. 418bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return super.loadInBackground(); 419bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 420bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 421bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 422bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected Cursor wrapCursor(Cursor cursor, 423bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean found, Account account, Mailbox mailbox, boolean isEasAccount, 424bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isRefreshable, int countTotalAccounts) { 425bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return new SearchResultsCursor(cursor, found, account, mailbox, isEasAccount, 426bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook isRefreshable, countTotalAccounts, mSearchedMailbox, mResultsCount); 427bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 428bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 429bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook} 430