diff --git a/res/menu/message_list_context.xml b/res/menu/message_list_context.xml new file mode 100644 index 000000000..8a3cf957c --- /dev/null +++ b/res/menu/message_list_context.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/src/com/android/email/activity/MessageList.java b/src/com/android/email/activity/MessageList.java index c742a4e2a..a75ae4be8 100644 --- a/src/com/android/email/activity/MessageList.java +++ b/src/com/android/email/activity/MessageList.java @@ -25,20 +25,25 @@ import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent.MessageColumns; import android.app.ListActivity; +import android.content.ContentUris; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; +import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.Window; +import android.view.ContextMenu.ContextMenuInfo; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.CursorAdapter; @@ -136,18 +141,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On } public void onItemClick(AdapterView parent, View view, int position, long id) { - // TODO these can be lighter-weight lookups - EmailContent.Message message = EmailContent.Message.restoreMessageWithId(this, id); - EmailContent.Mailbox mailbox = - EmailContent.Mailbox.restoreMailboxWithId(this, message.mMailboxKey); - - if (mailbox.mType == EmailContent.Mailbox.TYPE_DRAFTS) { - // TODO need id-based API for MessageCompose - // MessageCompose.actionEditDraft(this, id); - } - else { - MessageView.actionView(this, id); - } + onOpenMessage(id); } public void onClick(View v) { @@ -182,6 +176,49 @@ public class MessageList extends ListActivity implements OnItemClickListener, On } } + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; + + // TODO: There is no context menu for the outbox + // TODO: There is probably a special context menu for the trash + + getMenuInflater().inflate(R.menu.message_list_context, menu); + + // TODO: flip the "mark as read" string if the message is already read + // In order to do this, I really should cache the read state in the item view, + // instead of re-reading data from the cursor. + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterView.AdapterContextMenuInfo info = + (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); + + switch (item.getItemId()) { + case R.id.open: + onOpenMessage(info.id); + break; + case R.id.delete: + //onDelete(holder); + break; + case R.id.reply: + //onReply(holder); + break; + case R.id.reply_all: + //onReplyAll(holder); + break; + case R.id.forward: + //onForward(holder); + break; + case R.id.mark_as_read: + onToggleRead(info.id, info.targetView); + break; + } + return super.onContextItemSelected(item); + } + private void onRefresh() { // TODO: This needs to loop through all open mailboxes (there might be more than one) EmailContent.Mailbox mailbox = @@ -212,6 +249,38 @@ public class MessageList extends ListActivity implements OnItemClickListener, On AccountSettings.actionSettings(this, mailbox.mAccountKey); } + public void onOpenMessage(long messageId) { + // TODO Necessary info about the mailbox should have been cached in the listview item + // Instead, we're going to pull it from the DB here (expensively and in the wrong thread) + EmailContent.Message message = EmailContent.Message.restoreMessageWithId(this, messageId); + EmailContent.Mailbox mailbox = + EmailContent.Mailbox.restoreMailboxWithId(this, message.mMailboxKey); + + if (mailbox.mType == EmailContent.Mailbox.TYPE_DRAFTS) { + // TODO need id-based API for MessageCompose + // MessageCompose.actionEditDraft(this, messageId); + } + else { + MessageView.actionView(this, messageId); + } + } + + private void onToggleRead(long messageId, View itemView) { + // TODO the read-unread state of the given message should be cached in the listview item. + // Instead, we're going to pull it from the DB here (expensively and in the wrong thread) + EmailContent.Message message = EmailContent.Message.restoreMessageWithId(this, messageId); + boolean isRead = ! message.mFlagRead; + + // TODO this should be a call to the controller, since it may possibly kick off + // more than just a DB update. Also, the DB update shouldn't be in the UI thread + // as it is here. + ContentValues cv = new ContentValues(); + cv.put(EmailContent.MessageColumns.FLAG_READ, isRead ? 1 : 0); + Uri uri = ContentUris.withAppendedId( + EmailContent.Message.SYNCED_CONTENT_URI, messageId); + getContentResolver().update(uri, cv, null, null); + } + /** * Async task for loading a single folder out of the UI thread * diff --git a/src/com/android/email/activity/MessageView.java b/src/com/android/email/activity/MessageView.java index 717b24016..2504cf4e3 100644 --- a/src/com/android/email/activity/MessageView.java +++ b/src/com/android/email/activity/MessageView.java @@ -569,6 +569,9 @@ public class MessageView extends Activity mFavoriteIcon.setImageDrawable(newFavorite ? mFavoriteIconOn : mFavoriteIconOff); // Update provider + // TODO this should be a call to the controller, since it may possibly kick off + // more than just a DB update. Also, the DB update shouldn't be in the UI thread + // as it is here. mMessage.mFlagFavorite = newFavorite; ContentValues cv = new ContentValues(); cv.put(EmailContent.MessageColumns.FLAG_FAVORITE, newFavorite ? 1 : 0); @@ -619,13 +622,17 @@ public class MessageView extends Activity */ } - private void onMarkAsUnread() { - if (mOldMessage != null) { - MessagingController.getInstance(getApplication()).markMessageRead( - mAccount, - mFolder, - mOldMessage.getUid(), - false); + private void onMarkAsRead(boolean isRead) { + if (mMessage != null && mMessage.mFlagRead != isRead) { + // TODO this should be a call to the controller, since it may possibly kick off + // more than just a DB update. Also, the DB update shouldn't be in the UI thread + // as it is here. + mMessage.mFlagFavorite = isRead; + ContentValues cv = new ContentValues(); + cv.put(EmailContent.MessageColumns.FLAG_READ, isRead ? 1 : 0); + Uri uri = ContentUris.withAppendedId( + EmailContent.Message.SYNCED_CONTENT_URI, mMessageId); + getContentResolver().update(uri, cv, null, null); } } @@ -763,7 +770,8 @@ public class MessageView extends Activity onForward(); break; case R.id.mark_as_unread: - onMarkAsUnread(); + onMarkAsRead(false); + finish(); break; default: return false; @@ -1050,6 +1058,9 @@ public class MessageView extends Activity // toast? why would this fail? reloadBodyFromCursor(null); // hack to force text for display } + + // At this point it's fair to mark the message as "read" + onMarkAsRead(true); } }