MessagesAdapter.java revision 31d9acbf0623872f9d4a2b3210b5970854b654c7
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.email.activity; 18 19import com.android.email.Email; 20import com.android.email.ResourceHelper; 21import com.android.email.data.ThrottlingCursorLoader; 22import com.android.emailcommon.Logging; 23import com.android.emailcommon.provider.EmailContent; 24import com.android.emailcommon.provider.EmailContent.Message; 25import com.android.emailcommon.provider.EmailContent.MessageColumns; 26import com.android.emailcommon.utility.Utility; 27 28import android.content.Context; 29import android.content.Loader; 30import android.database.Cursor; 31import android.os.Bundle; 32import android.util.Log; 33import android.view.View; 34import android.view.ViewGroup; 35import android.widget.CursorAdapter; 36 37import java.util.HashSet; 38import java.util.Set; 39 40 41/** 42 * This class implements the adapter for displaying messages based on cursors. 43 */ 44/* package */ class MessagesAdapter extends CursorAdapter { 45 private static final String STATE_CHECKED_ITEMS = 46 "com.android.email.activity.MessagesAdapter.checkedItems"; 47 48 /* package */ static final String[] MESSAGE_PROJECTION = new String[] { 49 EmailContent.RECORD_ID, MessageColumns.MAILBOX_KEY, MessageColumns.ACCOUNT_KEY, 50 MessageColumns.DISPLAY_NAME, MessageColumns.SUBJECT, MessageColumns.TIMESTAMP, 51 MessageColumns.FLAG_READ, MessageColumns.FLAG_FAVORITE, MessageColumns.FLAG_ATTACHMENT, 52 MessageColumns.FLAGS, MessageColumns.SNIPPET 53 }; 54 55 public static final int COLUMN_ID = 0; 56 public static final int COLUMN_MAILBOX_KEY = 1; 57 public static final int COLUMN_ACCOUNT_KEY = 2; 58 public static final int COLUMN_DISPLAY_NAME = 3; 59 public static final int COLUMN_SUBJECT = 4; 60 public static final int COLUMN_DATE = 5; 61 public static final int COLUMN_READ = 6; 62 public static final int COLUMN_FAVORITE = 7; 63 public static final int COLUMN_ATTACHMENTS = 8; 64 public static final int COLUMN_FLAGS = 9; 65 public static final int COLUMN_SNIPPET = 10; 66 67 private final ResourceHelper mResourceHelper; 68 69 /** If true, show color chips. */ 70 private boolean mShowColorChips; 71 72 /** 73 * Set of seleced message IDs. 74 */ 75 private final HashSet<Long> mSelectedSet = new HashSet<Long>(); 76 77 /** 78 * Callback from MessageListAdapter. All methods are called on the UI thread. 79 */ 80 public interface Callback { 81 /** Called when the use starts/unstars a message */ 82 void onAdapterFavoriteChanged(MessageListItem itemView, boolean newFavorite); 83 /** Called when the user selects/unselects a message */ 84 void onAdapterSelectedChanged(MessageListItem itemView, boolean newSelected, 85 int mSelectedCount); 86 } 87 88 private final Callback mCallback; 89 90 public MessagesAdapter(Context context, Callback callback) { 91 super(context.getApplicationContext(), null, 0 /* no auto requery */); 92 mResourceHelper = ResourceHelper.getInstance(context); 93 mCallback = callback; 94 } 95 96 public void onSaveInstanceState(Bundle outState) { 97 Set<Long> checkedset = getSelectedSet(); 98 long[] checkedarray = new long[checkedset.size()]; 99 int i = 0; 100 for (Long l : checkedset) { 101 checkedarray[i] = l; 102 i++; 103 } 104 outState.putLongArray(STATE_CHECKED_ITEMS, checkedarray); 105 } 106 107 public void loadState(Bundle savedInstanceState) { 108 Set<Long> checkedset = getSelectedSet(); 109 for (long l: savedInstanceState.getLongArray(STATE_CHECKED_ITEMS)) { 110 checkedset.add(l); 111 } 112 } 113 114 /** 115 * Set true for combined mailboxes. 116 */ 117 public void setShowColorChips(boolean show) { 118 mShowColorChips = show; 119 } 120 121 public Set<Long> getSelectedSet() { 122 return mSelectedSet; 123 } 124 125 public boolean isSelected(MessageListItem itemView) { 126 return mSelectedSet.contains(itemView.mMessageId); 127 } 128 129 @Override 130 public void bindView(View view, Context context, Cursor cursor) { 131 // Reset the view (in case it was recycled) and prepare for binding 132 MessageListItem itemView = (MessageListItem) view; 133 itemView.bindViewInit(this); 134 135 // Load the public fields in the view (for later use) 136 itemView.mMessageId = cursor.getLong(COLUMN_ID); 137 itemView.mMailboxId = cursor.getLong(COLUMN_MAILBOX_KEY); 138 final long accountId = cursor.getLong(COLUMN_ACCOUNT_KEY); 139 itemView.mAccountId = accountId; 140 itemView.mRead = cursor.getInt(COLUMN_READ) != 0; 141 itemView.mIsFavorite = cursor.getInt(COLUMN_FAVORITE) != 0; 142 itemView.mHasInvite = 143 (cursor.getInt(COLUMN_FLAGS) & Message.FLAG_INCOMING_MEETING_INVITE) != 0; 144 itemView.mHasAttachment = cursor.getInt(COLUMN_ATTACHMENTS) != 0; 145 itemView.mTimestamp = cursor.getLong(COLUMN_DATE); 146 itemView.mSender = cursor.getString(COLUMN_DISPLAY_NAME); 147 itemView.mSnippet = cursor.getString(COLUMN_SNIPPET); 148 itemView.mSubject = cursor.getString(COLUMN_SUBJECT); 149 itemView.mSnippetLineCount = MessageListItem.NEEDS_LAYOUT; 150 itemView.mColorChipPaint = 151 mShowColorChips ? mResourceHelper.getAccountColorPaint(accountId) : null; 152 } 153 154 @Override 155 public View newView(Context context, Cursor cursor, ViewGroup parent) { 156 //return mInflater.inflate(R.layout.message_list_item, parent, false); 157 MessageListItem item = new MessageListItem(context); 158 item.setVisibility(View.VISIBLE); 159 return item; 160 } 161 162 public void toggleSelected(MessageListItem itemView) { 163 updateSelected(itemView, !isSelected(itemView)); 164 } 165 166 /** 167 * This is used as a callback from the list items, to set the selected state 168 * 169 * <p>Must be called on the UI thread. 170 * 171 * @param itemView the item being changed 172 * @param newSelected the new value of the selected flag (checkbox state) 173 */ 174 private void updateSelected(MessageListItem itemView, boolean newSelected) { 175 if (newSelected) { 176 mSelectedSet.add(itemView.mMessageId); 177 } else { 178 mSelectedSet.remove(itemView.mMessageId); 179 } 180 if (mCallback != null) { 181 mCallback.onAdapterSelectedChanged(itemView, newSelected, mSelectedSet.size()); 182 } 183 } 184 185 /** 186 * This is used as a callback from the list items, to set the favorite state 187 * 188 * <p>Must be called on the UI thread. 189 * 190 * @param itemView the item being changed 191 * @param newFavorite the new value of the favorite flag (star state) 192 */ 193 public void updateFavorite(MessageListItem itemView, boolean newFavorite) { 194 changeFavoriteIcon(itemView, newFavorite); 195 if (mCallback != null) { 196 mCallback.onAdapterFavoriteChanged(itemView, newFavorite); 197 } 198 } 199 200 private void changeFavoriteIcon(MessageListItem view, boolean isFavorite) { 201 view.invalidate(); 202 } 203 204 public static Loader<Cursor> createLoader(Context context, long mailboxId) { 205 if (Email.DEBUG_LIFECYCLE && Email.DEBUG) { 206 Log.d(Logging.LOG_TAG, "MessagesAdapter createLoader mailboxId=" + mailboxId); 207 } 208 return new MessagesCursorLoader(context, mailboxId); 209 210 } 211 212 private static class MessagesCursorLoader extends ThrottlingCursorLoader { 213 private final Context mContext; 214 private final long mMailboxId; 215 216 public MessagesCursorLoader(Context context, long mailboxId) { 217 // Initialize with no where clause. We'll set it later. 218 super(context, EmailContent.Message.CONTENT_URI, 219 MESSAGE_PROJECTION, null, null, 220 EmailContent.MessageColumns.TIMESTAMP + " DESC"); 221 mContext = context; 222 mMailboxId = mailboxId; 223 } 224 225 @Override 226 public Cursor loadInBackground() { 227 // Determine the where clause. (Can't do this on the UI thread.) 228 setSelection(Utility.buildMailboxIdSelection(mContext, mMailboxId)); 229 230 // Then do a query. 231 return Utility.CloseTraceCursorWrapper.get(super.loadInBackground()); 232 } 233 } 234} 235