replicant-packages_apps_Email/src/com/android/email/activity/AccountsAdapter.java

382 lines
14 KiB
Java

/*
* Copyright (C) 2010 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.FolderProperties;
import com.android.email.R;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Mailbox;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import android.content.Context;
import android.database.Cursor;
import android.database.MergeCursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Adapter that presents a combined list of smart mailboxes (e.g. combined inbox, all drafts, etc),
* a non-selectable separator, and the list of accounts.
*/
public class AccountsAdapter extends CursorAdapter {
/**
* Reduced mailbox projection used by AccountsAdapter
*/
public final static String[] MAILBOX_PROJECTION = new String[] {
EmailContent.RECORD_ID, MailboxColumns.DISPLAY_NAME,
MailboxColumns.ACCOUNT_KEY, MailboxColumns.TYPE,
MailboxColumns.UNREAD_COUNT,
MailboxColumns.FLAG_VISIBLE, MailboxColumns.FLAGS
};
public final static int MAILBOX_COLUMN_ID = 0;
public final static int MAILBOX_DISPLAY_NAME = 1;
public final static int MAILBOX_ACCOUNT_KEY = 2;
public final static int MAILBOX_TYPE = 3;
public final static int MAILBOX_UNREAD_COUNT = 4;
public final static int MAILBOX_FLAG_VISIBLE = 5;
public final static int MAILBOX_FLAGS = 6;
private static final String[] MAILBOX_UNREAD_COUNT_PROJECTION = new String [] {
MailboxColumns.UNREAD_COUNT
};
private static final int MAILBOX_UNREAD_COUNT_COLUMN_UNREAD_COUNT = 0;
private static final String MAILBOX_INBOX_SELECTION =
MailboxColumns.ACCOUNT_KEY + " =?" + " AND " + MailboxColumns.TYPE +" = "
+ Mailbox.TYPE_INBOX;
private final LayoutInflater mInflater;
private final int mMailboxesCount;
private final int mSeparatorPosition;
private final long mDefaultAccountId;
private final ArrayList<Long> mOnDeletingAccounts = new ArrayList<Long>();
private Callback mCallback;
public static AccountsAdapter getInstance(Cursor mailboxesCursor, Cursor accountsCursor,
Context context, long defaultAccountId, Callback callback) {
Cursor[] cursors = new Cursor[] { mailboxesCursor, accountsCursor };
Cursor mc = new MergeCursor(cursors);
return new AccountsAdapter(mc, context, mailboxesCursor.getCount(), defaultAccountId,
callback);
}
private AccountsAdapter(Cursor c, Context context, int mailboxesCount, long defaultAccountId,
Callback callback) {
super(context, c, true);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMailboxesCount = mailboxesCount;
mSeparatorPosition = mailboxesCount;
mDefaultAccountId = defaultAccountId;
mCallback = callback;
}
/**
* When changeCursor(null) is called, drop reference(s) to make sure we don't leak the activity
*/
@Override
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
if (cursor == null) {
mCallback = null;
}
}
/**
* Callback interface used to report clicks other than the basic list item click or longpress.
*/
public interface Callback {
/**
* Callback for clicks on the "folder" icon (to open MailboxList)
*/
public void onClickAccountFolders(long accountId);
}
public boolean isMailbox(int position) {
return position < mMailboxesCount;
}
public boolean isAccount(int position) {
return position > mMailboxesCount;
}
public void addOnDeletingAccount(long accountId) {
mOnDeletingAccounts.add(accountId);
}
public boolean isOnDeletingAccountView(long accountId) {
return mOnDeletingAccounts.contains(accountId);
}
/**
* This is an entry point called by the list item for clicks in the folder "button"
*
* @param itemView the item in which the click occurred
*/
public void onClickFolder(AccountFolderListItem itemView) {
if (mCallback != null) {
mCallback.onClickAccountFolders(itemView.mAccountId);
}
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
if (cursor.getPosition() < mMailboxesCount) {
bindMailboxItem(view, context, cursor, false);
} else {
bindAccountItem(view, context, cursor, false);
}
}
private void bindMailboxItem(View view, Context context, Cursor cursor, boolean isLastChild)
{
// Reset the view (in case it was recycled) and prepare for binding
AccountFolderListItem itemView = (AccountFolderListItem) view;
itemView.bindViewInit(this, false);
// Invisible (not "gone") to maintain spacing
view.findViewById(R.id.chip).setVisibility(View.INVISIBLE);
String text = cursor.getString(MAILBOX_DISPLAY_NAME);
if (text != null) {
TextView nameView = (TextView) view.findViewById(R.id.name);
nameView.setText(text);
}
// TODO get/track live folder status
text = null;
TextView statusView = (TextView) view.findViewById(R.id.status);
if (text != null) {
statusView.setText(text);
statusView.setVisibility(View.VISIBLE);
} else {
statusView.setVisibility(View.GONE);
}
int count = -1;
text = cursor.getString(MAILBOX_UNREAD_COUNT);
if (text != null) {
count = Integer.valueOf(text);
}
TextView unreadCountView = (TextView) view.findViewById(R.id.new_message_count);
TextView allCountView = (TextView) view.findViewById(R.id.all_message_count);
int id = cursor.getInt(MAILBOX_COLUMN_ID);
// If the unread count is zero, not to show countView.
if (count > 0) {
if (id == Mailbox.QUERY_ALL_FAVORITES
|| id == Mailbox.QUERY_ALL_DRAFTS
|| id == Mailbox.QUERY_ALL_OUTBOX) {
unreadCountView.setVisibility(View.GONE);
allCountView.setVisibility(View.VISIBLE);
allCountView.setText(text);
} else {
allCountView.setVisibility(View.GONE);
unreadCountView.setVisibility(View.VISIBLE);
unreadCountView.setText(text);
}
} else {
allCountView.setVisibility(View.GONE);
unreadCountView.setVisibility(View.GONE);
}
view.findViewById(R.id.folder_button).setVisibility(View.GONE);
view.findViewById(R.id.folder_separator).setVisibility(View.GONE);
view.findViewById(R.id.default_sender).setVisibility(View.GONE);
view.findViewById(R.id.folder_icon).setVisibility(View.VISIBLE);
((ImageView)view.findViewById(R.id.folder_icon)).setImageDrawable(
FolderProperties.getInstance(context).getSummaryMailboxIconIds(id));
}
private void bindAccountItem(View view, Context context, Cursor cursor, boolean isExpanded)
{
// Reset the view (in case it was recycled) and prepare for binding
AccountFolderListItem itemView = (AccountFolderListItem) view;
itemView.bindViewInit(this, true);
itemView.mAccountId = cursor.getLong(Account.CONTENT_ID_COLUMN);
long accountId = cursor.getLong(Account.CONTENT_ID_COLUMN);
// No color chip for now. TODO Revisit for phone UI
view.findViewById(R.id.chip).setVisibility(View.GONE);
String text = cursor.getString(Account.CONTENT_DISPLAY_NAME_COLUMN);
if (text != null) {
TextView descriptionView = (TextView) view.findViewById(R.id.name);
descriptionView.setText(text);
}
text = cursor.getString(Account.CONTENT_EMAIL_ADDRESS_COLUMN);
if (text != null) {
TextView emailView = (TextView) view.findViewById(R.id.status);
emailView.setText(text);
emailView.setVisibility(View.VISIBLE);
}
// TODO: We should not be doing a query inside bindAccountItem
int unreadMessageCount = 0;
Cursor c = context.getContentResolver().query(Mailbox.CONTENT_URI,
MAILBOX_UNREAD_COUNT_PROJECTION,
MAILBOX_INBOX_SELECTION,
new String[] { String.valueOf(accountId) }, null);
try {
if (c.moveToFirst()) {
String count = c.getString(MAILBOX_UNREAD_COUNT_COLUMN_UNREAD_COUNT);
if (count != null) {
unreadMessageCount = Integer.valueOf(count);
}
}
} finally {
c.close();
}
view.findViewById(R.id.all_message_count).setVisibility(View.GONE);
TextView unreadCountView = (TextView) view.findViewById(R.id.new_message_count);
if (unreadMessageCount > 0) {
unreadCountView.setText(String.valueOf(unreadMessageCount));
unreadCountView.setVisibility(View.VISIBLE);
} else {
unreadCountView.setVisibility(View.GONE);
}
view.findViewById(R.id.folder_icon).setVisibility(View.GONE);
view.findViewById(R.id.folder_button).setVisibility(View.VISIBLE);
view.findViewById(R.id.folder_separator).setVisibility(View.VISIBLE);
if (accountId == mDefaultAccountId) {
view.findViewById(R.id.default_sender).setVisibility(View.VISIBLE);
} else {
view.findViewById(R.id.default_sender).setVisibility(View.GONE);
}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.account_folder_list_item, parent, false);
}
/*
* The following series of overrides insert the "Accounts" separator
*/
/**
* Prevents the separator view from recycling into the other views
*/
@Override
public int getItemViewType(int position) {
if (position == mSeparatorPosition) {
return IGNORE_ITEM_VIEW_TYPE;
}
return super.getItemViewType(position);
}
/**
* Injects the separator view when required, and fudges the cursor for other views
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// The base class's getView() checks for mDataValid at the beginning, but we don't have
// to do that, because if the cursor is invalid getCount() returns 0, in which case this
// method wouldn't get called.
// Handle the separator here - create & bind
if (position == mSeparatorPosition) {
TextView view;
view = (TextView) mInflater.inflate(R.layout.list_separator, parent, false);
view.setText(R.string.account_folder_list_separator_accounts);
return view;
}
return super.getView(getRealPosition(position), convertView, parent);
}
/**
* Forces navigation to skip over the separator
*/
@Override
public boolean areAllItemsEnabled() {
return false;
}
/**
* Forces navigation to skip over the separator
*/
@Override
public boolean isEnabled(int position) {
if (position == mSeparatorPosition) {
return false;
} else if (isAccount(position)) {
Long id = ((MergeCursor)getItem(position)).getLong(Account.CONTENT_ID_COLUMN);
return !isOnDeletingAccountView(id);
} else {
return true;
}
}
/**
* Adjusts list count to include separator
*/
@Override
public int getCount() {
int count = super.getCount();
if (count > 0 && (mSeparatorPosition != ListView.INVALID_POSITION)) {
// Increment for separator, if we have anything to show.
count += 1;
}
return count;
}
/**
* Converts list position to cursor position
*/
private int getRealPosition(int pos) {
if (mSeparatorPosition == ListView.INVALID_POSITION) {
// No separator, identity map
return pos;
} else if (pos <= mSeparatorPosition) {
// Before or at the separator, identity map
return pos;
} else {
// After the separator, remove 1 from the pos to get the real underlying pos
return pos - 1;
}
}
/**
* Returns the item using external position numbering (no separator)
*/
@Override
public Object getItem(int pos) {
return super.getItem(getRealPosition(pos));
}
/**
* Returns the item id using external position numbering (no separator)
*/
@Override
public long getItemId(int pos) {
return super.getItemId(getRealPosition(pos));
}
}