Create separate adapters for mailbox lists
There are currently two places where we use a mailbox list -- in the main view and in the "move to" dialog. We've replaced the single, modally configured adapter with two specialized subclasses. Change-Id: I5dfd5ccd435fefbab4b7647c2bd7a14818f73bf3
This commit is contained in:
parent
5e4f1c3872
commit
74bf57cfaf
|
@ -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<Cursor> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Cursor> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Cursor> 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);
|
||||
}
|
||||
|
|
|
@ -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<Cursor> {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
return MailboxesAdapter.createLoader(getActivity().getApplicationContext(), mAccountId,
|
||||
MailboxesAdapter.MODE_MOVE_TO_TARGET);
|
||||
return MailboxMoveToAdapter.createLoader(getActivity().getApplicationContext(),
|
||||
mAccountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -79,7 +79,7 @@ public class MailboxesAdapterTest extends ProviderTestCase2<EmailProvider> {
|
|||
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());
|
||||
|
|
Loading…
Reference in New Issue