diff --git a/src/com/android/email/activity/MailboxFragmentAdapter.java b/src/com/android/email/activity/MailboxFragmentAdapter.java new file mode 100644 index 000000000..24ac60f81 --- /dev/null +++ b/src/com/android/email/activity/MailboxFragmentAdapter.java @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.email.activity; + +import com.android.email.Email; +import com.android.email.FolderProperties; +import com.android.email.R; +import com.android.email.data.ClosingMatrixCursor; +import com.android.email.data.ThrottlingCursorLoader; +import com.android.emailcommon.Logging; +import com.android.emailcommon.provider.EmailContent; +import com.android.emailcommon.provider.EmailContent.Account; +import com.android.emailcommon.provider.EmailContent.AccountColumns; +import com.android.emailcommon.provider.EmailContent.Mailbox; +import com.android.emailcommon.provider.EmailContent.Message; +import com.android.emailcommon.utility.Utility; + +import android.content.Context; +import android.content.Loader; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.database.MatrixCursor.RowBuilder; +import android.database.MergeCursor; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +/** + * Cursor adapter for a fragment mailbox list. + */ +/*package*/ class MailboxFragmentAdapter extends MailboxesAdapter { + public MailboxFragmentAdapter(Context context, Callback callback) { + super(context, callback); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + final boolean isAccount = isAccountRow(cursor); + final int type = cursor.getInt(COLUMN_TYPE); + final long id = cursor.getLong(COLUMN_ID); + + MailboxListItem listItem = (MailboxListItem)view; + listItem.mMailboxType = type; + listItem.mMailboxId = id; + listItem.mAdapter = this; + + // Set the background depending on whether we're in drag mode, the mailbox is a valid + // target, etc. + mCallback.onSetDropTargetBackground(listItem); + + // Set mailbox name + final TextView nameView = (TextView) view.findViewById(R.id.mailbox_name); + nameView.setText(getDisplayName(context, cursor)); + + // Set count + final int count; + switch (getCountTypeForMailboxType(cursor)) { + case COUNT_TYPE_UNREAD: + count = cursor.getInt(COLUMN_UNREAD_COUNT); + break; + case COUNT_TYPE_TOTAL: + count = cursor.getInt(COLUMN_MESSAGE_COUNT); + break; + default: // no count + count = 0; + break; + } + final TextView countView = (TextView) view.findViewById(R.id.message_count); + + // If the unread count is zero, not to show countView. + if (count > 0) { + countView.setVisibility(View.VISIBLE); + countView.setText(Integer.toString(count)); + } else { + countView.setVisibility(View.GONE); + } + + // Set folder icon + ((ImageView) view.findViewById(R.id.folder_icon)).setImageDrawable( + FolderProperties.getInstance(context).getIcon(type, id)); + + final View chipView = view.findViewById(R.id.color_chip); + if (isAccount) { + chipView.setVisibility(View.VISIBLE); + chipView.setBackgroundColor(mResourceHelper.getAccountColor(id)); + } else { + chipView.setVisibility(View.GONE); + } + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(R.layout.mailbox_list_item, parent, false); + } + + /** + * @return mailboxes Loader for an account. + */ + public static Loader createLoader(Context context, long accountId) { + if (Email.DEBUG_LIFECYCLE && Email.DEBUG) { + Log.d(Logging.LOG_TAG, "MailboxFragmentAdapter#createLoader accountId=" + accountId); + } + if (accountId != Account.ACCOUNT_ID_COMBINED_VIEW) { + return new MailboxFragmentLoader(context, accountId); + } else { + return new CombinedMailboxLoader(context); + } + } + + /** + * Adds a new row into the specified cursor. + */ + private static void addSummaryMailboxRow(MatrixCursor cursor, long id, int type, int count, + boolean showAlways) { + if (id >= 0) { + throw new IllegalArgumentException(); // Must be QUERY_ALL_*, which are all negative. + } + if (showAlways || (count > 0)) { + RowBuilder row = cursor.newRow(); + row.add(Long.MAX_VALUE + id); // Map QUERY_ALL_* constants to positive ints. + row.add(id); // The real mailbox ID. + row.add(""); // Display name. We get it from FolderProperties. + row.add(type); + row.add(count); + row.add(count); + row.add(ROW_TYPE_MAILBOX); + } + } + + /** + * Loader for mailboxes of an account. + */ + private static class MailboxFragmentLoader extends ThrottlingCursorLoader { + private final Context mContext; + private final long mAccountId; + + public MailboxFragmentLoader(Context context, long accountId) { + super(context, EmailContent.Mailbox.CONTENT_URI, + MailboxesAdapter.PROJECTION, MAILBOX_SELECTION, + new String[] { String.valueOf(accountId) }, MAILBOX_ORDER_BY); + mContext = context; + mAccountId = accountId; + } + + @Override + public void onContentChanged() { + if (sEnableUpdate) { + super.onContentChanged(); + } + } + + @Override + public Cursor loadInBackground() { + final Cursor mailboxesCursor = super.loadInBackground(); + + // Add "Starred", only if the account has at least one starred message. + // TODO It's currently "combined starred", but the plan is to make it per-account + // starred. + final int accountStarredCount = Message.getFavoriteMessageCount(mContext, mAccountId); + if (accountStarredCount == 0) { + return Utility.CloseTraceCursorWrapper.get(mailboxesCursor); // no starred message + } + + final MatrixCursor starredCursor = new MatrixCursor(getProjection()); + + final int totalStarredCount = Message.getFavoriteMessageCount(mContext); + addSummaryMailboxRow(starredCursor, Mailbox.QUERY_ALL_FAVORITES, Mailbox.TYPE_MAIL, + totalStarredCount, true); + + return Utility.CloseTraceCursorWrapper.get( + new MergeCursor(new Cursor[] {starredCursor, mailboxesCursor})); + } + } + + /** + * Loader for mailboxes in "Combined view". + */ + /*package*/ static class CombinedMailboxLoader extends ThrottlingCursorLoader { + private static final String[] ACCOUNT_PROJECTION = new String[] { + EmailContent.RECORD_ID, AccountColumns.DISPLAY_NAME, + }; + private static final int COLUMN_ACCOUND_ID = 0; + private static final int COLUMN_ACCOUNT_DISPLAY_NAME = 1; + + private final Context mContext; + + public CombinedMailboxLoader(Context context) { + super(context, Account.CONTENT_URI, ACCOUNT_PROJECTION, null, null, null); + mContext = context; + } + + @Override + public Cursor loadInBackground() { + final Cursor accounts = super.loadInBackground(); + final MatrixCursor combinedWithAccounts = getCursor(mContext, accounts); + + accounts.moveToPosition(-1); + while (accounts.moveToNext()) { + RowBuilder row = combinedWithAccounts.newRow(); + final long accountId = accounts.getLong(COLUMN_ACCOUND_ID); + row.add(accountId); + row.add(accountId); + row.add(accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME)); + row.add(-1); // No mailbox type. Shouldn't really be used. + final int unreadCount = Mailbox.getUnreadCountByAccountAndMailboxType( + mContext, accountId, Mailbox.TYPE_INBOX); + row.add(unreadCount); + row.add(unreadCount); + row.add(ROW_TYPE_ACCOUNT); + } + return Utility.CloseTraceCursorWrapper.get(combinedWithAccounts); + } + + /*package*/ static MatrixCursor getCursor(Context context, + Cursor innerCursor) { + MatrixCursor cursor = new ClosingMatrixCursor(PROJECTION, innerCursor); + // Combined inbox -- show unread count + addSummaryMailboxRow(cursor, Mailbox.QUERY_ALL_INBOXES, Mailbox.TYPE_INBOX, + Mailbox.getUnreadCountByMailboxType(context, Mailbox.TYPE_INBOX), true); + + // Favorite (starred) -- show # of favorites + addSummaryMailboxRow(cursor, Mailbox.QUERY_ALL_FAVORITES, Mailbox.TYPE_MAIL, + Message.getFavoriteMessageCount(context), false); + + // Drafts -- show # of drafts + addSummaryMailboxRow(cursor, Mailbox.QUERY_ALL_DRAFTS, Mailbox.TYPE_DRAFTS, + Mailbox.getMessageCountByMailboxType(context, Mailbox.TYPE_DRAFTS), false); + + // Outbox -- # of outstanding messages + addSummaryMailboxRow(cursor, Mailbox.QUERY_ALL_OUTBOX, Mailbox.TYPE_OUTBOX, + Mailbox.getMessageCountByMailboxType(context, Mailbox.TYPE_OUTBOX), false); + + return cursor; + } + } +} diff --git a/src/com/android/email/activity/MailboxListFragment.java b/src/com/android/email/activity/MailboxListFragment.java index 5facf2f98..e7a2a2629 100644 --- a/src/com/android/email/activity/MailboxListFragment.java +++ b/src/com/android/email/activity/MailboxListFragment.java @@ -24,6 +24,7 @@ import com.android.email.provider.EmailProvider; import com.android.emailcommon.Logging; import com.android.emailcommon.provider.EmailContent.Mailbox; import com.android.emailcommon.provider.EmailContent.Message; +import com.android.emailcommon.utility.EmailAsyncTask; import com.android.emailcommon.utility.Utility; import android.app.Activity; @@ -160,8 +161,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList mActivity = getActivity(); mRefreshManager = RefreshManager.getInstance(mActivity); - mListAdapter = new MailboxesAdapter(mActivity, MailboxesAdapter.MODE_NORMAL, - mMailboxesAdapterCallback); + mListAdapter = new MailboxFragmentAdapter(mActivity, mMailboxesAdapterCallback); if (savedInstanceState != null) { restoreInstanceState(savedInstanceState); } @@ -357,8 +357,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList if (Email.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(Logging.LOG_TAG, "MailboxListFragment onCreateLoader"); } - return MailboxesAdapter.createLoader(getActivity(), mAccountId, - MailboxesAdapter.MODE_NORMAL); + return MailboxFragmentAdapter.createLoader(getActivity(), mAccountId); } @Override @@ -452,7 +451,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList if (ensureSelectionVisible) { Utility.listViewSmoothScrollToPosition(getActivity(), mListView, i); } - mailboxName = mListAdapter.getDisplayName(i); + mailboxName = mListAdapter.getDisplayName(mActivity, i); unreadCount = mListAdapter.getUnreadCount(i); break; } @@ -593,7 +592,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList if (mDragInProgress) { mDragInProgress = false; // Reenable updates to the view and redraw (in case it changed) - mListAdapter.enableUpdates(true); + MailboxesAdapter.enableUpdates(true); mListAdapter.notifyDataSetChanged(); // Stop highlighting targets updateChildViews(); @@ -626,7 +625,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList } mDragInProgress = true; // Stop the list from updating - mListAdapter.enableUpdates(false); + MailboxesAdapter.enableUpdates(false); // Update the backgrounds of our child views to highlight drop targets updateChildViews(); return true; @@ -654,7 +653,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList messageIds[i] = id; } // Call either deleteMessage or moveMessage, depending on the target - Utility.runAsync(new Runnable() { + EmailAsyncTask.runAsyncSerial(new Runnable() { @Override public void run() { if (mDropTargetView.mMailboxType == Mailbox.TYPE_TRASH) { @@ -668,7 +667,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList } else { controller.moveMessage(messageIds, mDropTargetView.mMailboxId); } - }}); + } + }); return true; } diff --git a/src/com/android/email/activity/MailboxMoveToAdapter.java b/src/com/android/email/activity/MailboxMoveToAdapter.java new file mode 100644 index 000000000..25b2fdecb --- /dev/null +++ b/src/com/android/email/activity/MailboxMoveToAdapter.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.email.activity; + +import com.android.email.Email; +import com.android.email.data.ThrottlingCursorLoader; +import com.android.emailcommon.Logging; +import com.android.emailcommon.provider.EmailContent; +import com.android.emailcommon.provider.EmailContent.Mailbox; +import com.android.emailcommon.utility.Utility; + +import android.content.Context; +import android.content.Loader; +import android.database.Cursor; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +/** + * Cursor adapter for the "move to mailbox" dialog. + */ +/*package*/ class MailboxMoveToAdapter extends MailboxesAdapter { + private static final String MAILBOX_SELECTION_MOVE_TO_FOLDER = + MAILBOX_SELECTION + " AND " + Mailbox.MOVE_TO_TARGET_MAILBOX_SELECTION; + + public MailboxMoveToAdapter(Context context, Callback callback) { + super(context, callback); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + TextView t = (TextView) view; + t.setText(getDisplayName(context, cursor)); + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); + } + + public static Loader createLoader(Context context, long accountId) { + if (Email.DEBUG_LIFECYCLE && Email.DEBUG) { + Log.d(Logging.LOG_TAG, "MailboxDialogAdapter#createLoader accountId=" + accountId); + } + return new MailboxMoveToLoader(context, accountId); + } + + /** + * Loader for the "move to mailbox" dialog. + */ + private static class MailboxMoveToLoader extends ThrottlingCursorLoader { + public MailboxMoveToLoader(Context context, long accountId) { + super(context, EmailContent.Mailbox.CONTENT_URI, + MailboxesAdapter.PROJECTION, MAILBOX_SELECTION_MOVE_TO_FOLDER, + new String[] { String.valueOf(accountId) }, MAILBOX_ORDER_BY); + } + + @Override + public void onContentChanged() { + if (sEnableUpdate) { + super.onContentChanged(); + } + } + + @Override + public Cursor loadInBackground() { + final Cursor mailboxesCursor = super.loadInBackground(); + return Utility.CloseTraceCursorWrapper.get(mailboxesCursor); + } + } +} diff --git a/src/com/android/email/activity/MailboxesAdapter.java b/src/com/android/email/activity/MailboxesAdapter.java index 2bb121098..63fba272a 100644 --- a/src/com/android/email/activity/MailboxesAdapter.java +++ b/src/com/android/email/activity/MailboxesAdapter.java @@ -16,58 +16,26 @@ package com.android.email.activity; -import com.android.email.Email; import com.android.email.FolderProperties; -import com.android.email.R; import com.android.email.ResourceHelper; -import com.android.email.data.ClosingMatrixCursor; -import com.android.email.data.ThrottlingCursorLoader; -import com.android.emailcommon.Logging; -import com.android.emailcommon.provider.EmailContent; -import com.android.emailcommon.provider.EmailContent.Account; -import com.android.emailcommon.provider.EmailContent.AccountColumns; import com.android.emailcommon.provider.EmailContent.Mailbox; import com.android.emailcommon.provider.EmailContent.MailboxColumns; -import com.android.emailcommon.provider.EmailContent.Message; -import com.android.emailcommon.utility.Utility; import android.content.Context; -import android.content.Loader; import android.database.Cursor; -import android.database.MatrixCursor; -import android.database.MatrixCursor.RowBuilder; -import android.database.MergeCursor; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CursorAdapter; -import android.widget.ImageView; -import android.widget.TextView; /** - * The adapter for displaying mailboxes. - * - * Do not use {@link #getItemId(int)} -- It's only for ListView. Use {@link #getMailboxId} - * instead. (See the comment below) + * Super class adapter for displaying a mailbox list. + * NOTE: Do not use {@link #getItemId(int)}; it's only for ListView. Instead, use {@link #getId}. * * TODO Show "Starred" per account * TODO Unit test, when UI is settled. */ -/* package */ class MailboxesAdapter extends CursorAdapter { - public static final String TAG = "MailboxesAdapter"; - - public static final int MODE_NORMAL = 0; - public static final int MODE_MOVE_TO_TARGET = 1; - - /** - * Row type, used in the "row_type" in {@link PROJECTION}. - * {@link #ROW_TYPE_MAILBOX} for regular mailboxes and combined mailboxes. - * {@link #ROW_TYPE_ACCOUNT} for account row in the combined view. - */ - private static final int ROW_TYPE_MAILBOX = 0; - private static final int ROW_TYPE_ACCOUNT = 1; - +/*package*/ abstract class MailboxesAdapter extends CursorAdapter { /** * Return value from {@link #getCountType}. */ @@ -75,6 +43,22 @@ import android.widget.TextView; public static final int COUNT_TYPE_TOTAL = 1; public static final int COUNT_TYPE_NO_COUNT = 2; + /** + * Callback interface used to report clicks other than the basic list item click or long press. + */ + public interface Callback { + /** Callback for setting background of mailbox list items during a drag */ + public void onSetDropTargetBackground(MailboxListItem listItem); + } + + /** + * Row type, used in the "row_type" in {@link #PROJECTION}. + * {@link #ROW_TYPE_MAILBOX} for regular mailboxes and combined mailboxes. + * {@link #ROW_TYPE_ACCOUNT} for account row in the combined view. + */ + static final int ROW_TYPE_MAILBOX = 0; + static final int ROW_TYPE_ACCOUNT = 1; + /* * Note here we have two ID columns. The first one is for ListView, which doesn't like ID * values to be negative. The second one is the actual mailbox ID, which we use in the rest @@ -84,25 +68,23 @@ import android.widget.TextView; * Because ListView finds the ID column by name ("_id"), we rename the second column * so that ListView gets the correct column. */ - /* package */ static final String[] PROJECTION = new String[] { MailboxColumns.ID, + /*package*/ static final String[] PROJECTION = new String[] { MailboxColumns.ID, MailboxColumns.ID + " AS org_mailbox_id", MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, MailboxColumns.UNREAD_COUNT, - MailboxColumns.MESSAGE_COUNT, ROW_TYPE_MAILBOX + " AS row_type"}; - // Column 0 is only for ListView; we don't use it in our code. - private static final int COLUMN_ID = 1; - private static final int COLUMN_DISPLAY_NAME = 2; - private static final int COLUMN_TYPE = 3; - private static final int COLUMN_UNREAD_COUNT = 4; - private static final int COLUMN_MESSAGE_COUNT = 5; - private static final int COLUMN_ROW_TYPE = 6; + MailboxColumns.MESSAGE_COUNT, ROW_TYPE_MAILBOX + " AS row_type" }; - private static final String MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" + + // Column 0 is only for ListView; we don't use it in our code. + static final int COLUMN_ID = 1; + static final int COLUMN_DISPLAY_NAME = 2; + static final int COLUMN_TYPE = 3; + static final int COLUMN_UNREAD_COUNT = 4; + static final int COLUMN_MESSAGE_COUNT = 5; + static final int COLUMN_ROW_TYPE = 6; + + static final String MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" + " AND " + Mailbox.USER_VISIBLE_MAILBOX_SELECTION; - private static final String MAILBOX_SELECTION_MOVE_TO_FOLDER = - MAILBOX_SELECTION + " AND " + Mailbox.MOVE_TO_TARGET_MAILBOX_SELECTION; - - private static final String MAILBOX_ORDER_BY = "CASE " + MailboxColumns.TYPE + + static final String MAILBOX_ORDER_BY = "CASE " + MailboxColumns.TYPE + " WHEN " + Mailbox.TYPE_INBOX + " THEN 0" + " WHEN " + Mailbox.TYPE_DRAFTS + " THEN 1" + " WHEN " + Mailbox.TYPE_OUTBOX + " THEN 2" + @@ -113,42 +95,28 @@ import android.widget.TextView; " ELSE 10 END" + " ," + MailboxColumns.DISPLAY_NAME; - private final Context mContext; - private final LayoutInflater mInflater; - private final ResourceHelper mResourceHelper; + static boolean sEnableUpdate = true; + final LayoutInflater mInflater; + final ResourceHelper mResourceHelper; + final Callback mCallback; - private final int mMode; - private static boolean sEnableUpdate = true; - private Callback mCallback; - - public MailboxesAdapter(Context context, int mode, Callback callback) { - super(context, null, 0 /* no auto-requery */); - mContext = context; + /*package*/ MailboxesAdapter(Context context, Callback callback) { + super(context, null, 0 /* flags; no content observer */); mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mMode = mode; mCallback = callback; - mResourceHelper = ResourceHelper.getInstance(mContext); + mResourceHelper = ResourceHelper.getInstance(context); } - /** - * Callback interface used to report clicks other than the basic list item click or longpress. - */ - public interface Callback { - /** - * Callback for setting background of mailbox list items during a drag - */ - public void onSetDropTargetBackground(MailboxListItem listItem); - } + @Override + public abstract void bindView(View view, Context context, Cursor cursor); - public static class EmptyCallback implements Callback { - @Override - public void onSetDropTargetBackground(MailboxListItem listItem) {}; - } + @Override + public abstract View newView(Context context, Cursor cursor, ViewGroup parent); /** * @return true if the current row is of an account in the combined view. */ - private static boolean isAccountRow(Cursor c) { + static boolean isAccountRow(Cursor c) { return c.getInt(COLUMN_ROW_TYPE) == ROW_TYPE_ACCOUNT; } @@ -163,7 +131,7 @@ import android.widget.TextView; * @return which type of count should be used for the current row. * Possible return values are COUNT_TYPE_*. */ - private static int getCountTypeForMailboxType(Cursor c) { + static int getCountTypeForMailboxType(Cursor c) { if (isAccountRow(c)) { return COUNT_TYPE_UNREAD; // Use the unread count for account rows. } @@ -202,9 +170,9 @@ import android.widget.TextView; /** * @return display name for the specified row. */ - public String getDisplayName(int position) { + public String getDisplayName(Context context, int position) { Cursor c = (Cursor) getItem(position); - return getDisplayName(mContext, c); + return getDisplayName(context, c); } /** @@ -221,35 +189,11 @@ import android.widget.TextView; * mailboxes to update, as this would be visually jarring * @param state whether or not the MailboxList can be updated */ - public void enableUpdates(boolean state) { + public static void enableUpdates(boolean state) { sEnableUpdate = state; } - @Override - public void bindView(View view, Context context, Cursor cursor) { - switch (mMode) { - case MODE_NORMAL: - bindViewNormalMode(view, context, cursor); - return; - case MODE_MOVE_TO_TARGET: - bindViewMoveToTargetMode(view, context, cursor); - return; - } - throw new IllegalStateException(); - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - switch (mMode) { - case MODE_NORMAL: - return newViewNormalMode(context, cursor, parent); - case MODE_MOVE_TO_TARGET: - return newViewMoveToTargetMode(context, cursor, parent); - } - throw new IllegalStateException(); - } - - private static String getDisplayName(Context context, Cursor cursor) { + static String getDisplayName(Context context, Cursor cursor) { String name = null; if (cursor.getInt(COLUMN_ROW_TYPE) == ROW_TYPE_MAILBOX) { // If it's a mailbox (as opposed to account row in combined view), and of certain types, @@ -264,232 +208,6 @@ import android.widget.TextView; return name; } - private void bindViewNormalMode(View view, Context context, Cursor cursor) { - final boolean isAccount = isAccountRow(cursor); - final int type = cursor.getInt(COLUMN_TYPE); - final long id = cursor.getLong(COLUMN_ID); - - MailboxListItem listItem = (MailboxListItem)view; - listItem.mMailboxType = type; - listItem.mMailboxId = id; - listItem.mAdapter = this; - - // Set the background depending on whether we're in drag mode, the mailbox is a valid - // target, etc. - mCallback.onSetDropTargetBackground(listItem); - - // Set mailbox name - final TextView nameView = (TextView) view.findViewById(R.id.mailbox_name); - nameView.setText(getDisplayName(context, cursor)); - - // Set count - final int count; - switch (getCountTypeForMailboxType(cursor)) { - case COUNT_TYPE_UNREAD: - count = cursor.getInt(COLUMN_UNREAD_COUNT); - break; - case COUNT_TYPE_TOTAL: - count = cursor.getInt(COLUMN_MESSAGE_COUNT); - break; - default: // no count - count = 0; - break; - } - final TextView countView = (TextView) view.findViewById(R.id.message_count); - - // If the unread count is zero, not to show countView. - if (count > 0) { - countView.setVisibility(View.VISIBLE); - countView.setText(Integer.toString(count)); - } else { - countView.setVisibility(View.GONE); - } - - // Set folder icon - ((ImageView) view.findViewById(R.id.folder_icon)).setImageDrawable( - FolderProperties.getInstance(context).getIcon(type, id)); - - final View chipView = view.findViewById(R.id.color_chip); - if (isAccount) { - chipView.setVisibility(View.VISIBLE); - chipView.setBackgroundColor(mResourceHelper.getAccountColor(id)); - } else { - chipView.setVisibility(View.GONE); - } - } - - private View newViewNormalMode(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(R.layout.mailbox_list_item, parent, false); - } - - private void bindViewMoveToTargetMode(View view, Context context, Cursor cursor) { - TextView t = (TextView) view; - t.setText(getDisplayName(context, cursor)); - } - - private View newViewMoveToTargetMode(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); - } - - /** - * @return mailboxes Loader for an account. - */ - public static Loader createLoader(Context context, long accountId, - int mode) { - if (Email.DEBUG_LIFECYCLE && Email.DEBUG) { - Log.d(Logging.LOG_TAG, "MailboxesAdapter createLoader accountId=" + accountId); - } - if (accountId != Account.ACCOUNT_ID_COMBINED_VIEW) { - return new MailboxesLoader(context, accountId, mode); - } else { - return new CombinedMailboxesLoader(context); - } - } - - /** - * Loader for mailboxes of an account. - */ - private static class MailboxesLoader extends ThrottlingCursorLoader { - private final Context mContext; - private final int mMode; - private final long mAccountId; - - private static String getSelection(int mode) { - if (mode == MODE_MOVE_TO_TARGET) { - return MAILBOX_SELECTION_MOVE_TO_FOLDER; - } else { - return MAILBOX_SELECTION; - } - } - - public MailboxesLoader(Context context, long accountId, int mode) { - super(context, EmailContent.Mailbox.CONTENT_URI, - MailboxesAdapter.PROJECTION, getSelection(mode), - new String[] { String.valueOf(accountId) }, MAILBOX_ORDER_BY); - mContext = context; - mMode = mode; - mAccountId = accountId; - } - - @Override - public void onContentChanged() { - if (sEnableUpdate) { - super.onContentChanged(); - } - } - - @Override - public Cursor loadInBackground() { - final Cursor mailboxesCursor = super.loadInBackground(); - if (mMode == MODE_MOVE_TO_TARGET) { - return Utility.CloseTraceCursorWrapper.get(mailboxesCursor); - } - - // Add "Starred", only if the account has at least one starred message. - // TODO It's currently "combined starred", but the plan is to make it per-account - // starred. - final int accountStarredCount = Message.getFavoriteMessageCount(mContext, mAccountId); - if (accountStarredCount == 0) { - return Utility.CloseTraceCursorWrapper.get(mailboxesCursor); // no starred message - } - - final MatrixCursor starredCursor = new MatrixCursor(getProjection()); - - final int totalStarredCount = Message.getFavoriteMessageCount(mContext); - addSummaryMailboxRow(mContext, starredCursor, - Mailbox.QUERY_ALL_FAVORITES, Mailbox.TYPE_MAIL, totalStarredCount, true); - - return Utility.CloseTraceCursorWrapper.get( - new MergeCursor(new Cursor[] {starredCursor, mailboxesCursor})); - } - } - - /** - * Loader for mailboxes in "Combined view". - */ - private static class CombinedMailboxesLoader extends ThrottlingCursorLoader { - private static final String[] ACCOUNT_PROJECTION = new String[] { - EmailContent.RECORD_ID, AccountColumns.DISPLAY_NAME, - }; - private static final int COLUMN_ACCOUND_ID = 0; - private static final int COLUMN_ACCOUNT_DISPLAY_NAME = 1; - - private final Context mContext; - - public CombinedMailboxesLoader(Context context) { - // Tell the super class to load accounts. - // But we don't directly return that... - super(context, Account.CONTENT_URI, ACCOUNT_PROJECTION, null, null, null); - mContext = context; - } - - @Override - public Cursor loadInBackground() { - final Cursor accounts = super.loadInBackground(); - final MatrixCursor combinedWithAccounts = getSpecialMailboxesCursor(mContext, accounts); - - accounts.moveToPosition(-1); - while (accounts.moveToNext()) { - RowBuilder row = combinedWithAccounts.newRow(); - final long accountId = accounts.getLong(COLUMN_ACCOUND_ID); - row.add(accountId); - row.add(accountId); - row.add(accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME)); - row.add(-1); // No mailbox type. Shouldn't really be used. - final int unreadCount = Mailbox.getUnreadCountByAccountAndMailboxType( - mContext, accountId, Mailbox.TYPE_INBOX); - row.add(unreadCount); - row.add(unreadCount); - row.add(ROW_TYPE_ACCOUNT); - } - - return Utility.CloseTraceCursorWrapper.get(combinedWithAccounts); - } - } - - /* package */ static MatrixCursor getSpecialMailboxesCursor(Context context, - Cursor innerCursor) { - MatrixCursor cursor = new ClosingMatrixCursor(PROJECTION, innerCursor); - // Combined inbox -- show unread count - addSummaryMailboxRow(context, cursor, - Mailbox.QUERY_ALL_INBOXES, Mailbox.TYPE_INBOX, - Mailbox.getUnreadCountByMailboxType(context, Mailbox.TYPE_INBOX), true); - - // Favorite (starred) -- show # of favorites - addSummaryMailboxRow(context, cursor, - Mailbox.QUERY_ALL_FAVORITES, Mailbox.TYPE_MAIL, - Message.getFavoriteMessageCount(context), false); - - // Drafts -- show # of drafts - addSummaryMailboxRow(context, cursor, - Mailbox.QUERY_ALL_DRAFTS, Mailbox.TYPE_DRAFTS, - Mailbox.getMessageCountByMailboxType(context, Mailbox.TYPE_DRAFTS), false); - - // Outbox -- # of outstanding messages - addSummaryMailboxRow(context, cursor, - Mailbox.QUERY_ALL_OUTBOX, Mailbox.TYPE_OUTBOX, - Mailbox.getMessageCountByMailboxType(context, Mailbox.TYPE_OUTBOX), false); - - return cursor; - } - - private static void addSummaryMailboxRow(Context context, MatrixCursor cursor, - long id, int type, int count, boolean showAlways) { - if (id >= 0) { - throw new IllegalArgumentException(); // Must be QUERY_ALL_*, which are all negative. - } - if (showAlways || (count > 0)) { - RowBuilder row = cursor.newRow(); - row.add(Long.MAX_VALUE + id); // Map QUERY_ALL_* constants to positive ints. - row.add(id); // The real mailbox ID. - row.add(""); // Display name. We get it from FolderProperties. - row.add(type); - row.add(count); - row.add(count); - row.add(ROW_TYPE_MAILBOX); - } - } - /* package */ static long getIdForTest(Cursor cursor) { return cursor.getLong(COLUMN_ID); } diff --git a/src/com/android/email/activity/MoveMessageToDialog.java b/src/com/android/email/activity/MoveMessageToDialog.java index 658234a1f..90555653e 100644 --- a/src/com/android/email/activity/MoveMessageToDialog.java +++ b/src/com/android/email/activity/MoveMessageToDialog.java @@ -110,8 +110,10 @@ public class MoveMessageToDialog extends DialogFragment implements DialogInterfa .setTitle(activity.getResources().getString(R.string.move_to_folder_dialog_title)); mAdapter = - new MailboxesAdapter(builder.getContext(), MailboxesAdapter.MODE_MOVE_TO_TARGET, - new MailboxesAdapter.EmptyCallback()); + new MailboxMoveToAdapter(builder.getContext(), + new MailboxesAdapter.Callback() { + public void onSetDropTargetBackground(MailboxListItem listItem) {} + }); builder.setSingleChoiceItems(mAdapter, -1, this); getLoaderManager().initLoader( @@ -192,8 +194,8 @@ public class MoveMessageToDialog extends DialogFragment implements DialogInterfa private class MailboxesLoaderCallbacks implements LoaderManager.LoaderCallbacks { @Override public Loader onCreateLoader(int id, Bundle args) { - return MailboxesAdapter.createLoader(getActivity().getApplicationContext(), mAccountId, - MailboxesAdapter.MODE_MOVE_TO_TARGET); + return MailboxMoveToAdapter.createLoader(getActivity().getApplicationContext(), + mAccountId); } @Override diff --git a/tests/src/com/android/email/activity/MailboxesAdapterTest.java b/tests/src/com/android/email/activity/MailboxesAdapterTest.java index fbfa5a492..d5ddae7e3 100644 --- a/tests/src/com/android/email/activity/MailboxesAdapterTest.java +++ b/tests/src/com/android/email/activity/MailboxesAdapterTest.java @@ -79,7 +79,7 @@ public class MailboxesAdapterTest extends ProviderTestCase2 { createMessage(c, b2t, true, true, Message.FLAG_LOADED_UNLOADED); // Kick the method - Cursor cursor = MailboxesAdapter.getSpecialMailboxesCursor(c, null); + Cursor cursor = MailboxFragmentAdapter.CombinedMailboxLoader.getCursor(c, null); // Check the result assertEquals(4, cursor.getCount());