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