From 3a3dc2da431e40b1860e3bfa2f4504d39373ccf7 Mon Sep 17 00:00:00 2001 From: Daniel Applebaum Date: Wed, 7 Jan 2009 06:02:04 +0000 Subject: [PATCH] Instant deletes from FolderMessageList. Faster deletes from MessageView Deleting a message in Trash deletes it for real (permanently) All message operations are allowed on messages in the Outbox. Special handling for deleting, so that the message is copied to Trash, then copied asynchronously to the remote Trash. Add some more items to the hotkey help --- .../android/email/MessagingController.java | 78 ++++++++++++++----- src/com/android/email/MessagingListener.java | 5 +- .../email/activity/FolderMessageList.java | 33 ++++---- .../android/email/activity/MessageView.java | 54 +++++++++---- .../android/email/mail/store/ImapStore.java | 62 ++++++++------- 5 files changed, 151 insertions(+), 81 deletions(-) diff --git a/src/com/android/email/MessagingController.java b/src/com/android/email/MessagingController.java index 17b89958a..1dc8f441b 100644 --- a/src/com/android/email/MessagingController.java +++ b/src/com/android/email/MessagingController.java @@ -1860,39 +1860,77 @@ s * critical data as fast as possible, and then we'll fill in the de } } - - /** - * We do the local portion of this synchronously because other activities may have to make - * updates based on what happens here - * @param account - * @param folder - * @param message - * @param listener - */ + public void deleteMessage(final Account account, final String folder, final Message message, - MessagingListener listener) { - if (folder.equals(account.getTrashFolderName())) { - return; + final MessagingListener listener) { + put("deleteMessage", null, new Runnable() { + public void run() { + deleteMessageSynchronous(account, folder, message, listener); } + }); + } + + private void deleteMessageSynchronous(final Account account, final String folder, final Message message, + MessagingListener listener) { try { Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication); Folder localFolder = localStore.getFolder(folder); - Folder localTrashFolder = localStore.getFolder(account.getTrashFolderName()); - if (localTrashFolder.exists() == false) + + if (folder.equals(account.getTrashFolderName())) { - localTrashFolder.create(Folder.FolderType.HOLDS_MESSAGES); - } - if (localTrashFolder.exists() == true) - { - localFolder.copyMessages(new Message[] { message }, localTrashFolder); + if (Config.LOGD) + { + Log.d(Email.LOG_TAG, "Deleting message in trash folder, not copying"); + } message.setFlag(Flag.DELETED, true); } + else + { + Folder localTrashFolder = localStore.getFolder(account.getTrashFolderName()); + if (localTrashFolder.exists() == false) + { + localTrashFolder.create(Folder.FolderType.HOLDS_MESSAGES); + } + if (localTrashFolder.exists() == true) + { + if (Config.LOGD) + { + Log.d(Email.LOG_TAG, "Deleting message in normal folder, copying"); + } + FetchProfile fp = new FetchProfile(); + fp.add(FetchProfile.Item.ENVELOPE); + fp.add(FetchProfile.Item.BODY); + // TODO: Turn the fetch/copy/delete into an atomic move + localFolder.fetch(new Message[] { message }, fp, null); + localFolder.copyMessages(new Message[] { message }, localTrashFolder); + message.setFlag(Flag.DELETED, true); + } + } + if (listener != null) { + listener.messageDeleted(account, folder, message); + } +// for (MessagingListener l : getListeners()) { +// l.folderStatusChanged(account, account.getTrashFolderName()); +// } if (Config.LOGD) { Log.d(Email.LOG_TAG, "Delete policy for account " + account.getDescription() + " is " + account.getDeletePolicy()); } - if (account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE) { + if (folder.equals(account.getOutboxFolderName())) + { + // If the message was in the Outbox, then it has been copied to local Trash, and has + // to be copied to remote trash + PendingCommand command = new PendingCommand(); + command.command = PENDING_COMMAND_APPEND; + command.arguments = + new String[] { + account.getTrashFolderName(), + message.getUid() }; + queuePendingCommand(account, command); + processPendingCommands(account); + } + else if (account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE) { PendingCommand command = new PendingCommand(); command.command = PENDING_COMMAND_TRASH; command.arguments = new String[] { folder, message.getUid() }; diff --git a/src/com/android/email/MessagingListener.java b/src/com/android/email/MessagingListener.java index 52557ffd3..73f86c5b2 100644 --- a/src/com/android/email/MessagingListener.java +++ b/src/com/android/email/MessagingListener.java @@ -92,7 +92,10 @@ public class MessagingListener { public void sendPendingMessagesFailed(Account account) { } - + public void messageDeleted(Account account, String folder, Message message) + { + + } public void emptyTrashCompleted(Account account) { } diff --git a/src/com/android/email/activity/FolderMessageList.java b/src/com/android/email/activity/FolderMessageList.java index 4753c67d2..5a07fac11 100644 --- a/src/com/android/email/activity/FolderMessageList.java +++ b/src/com/android/email/activity/FolderMessageList.java @@ -546,18 +546,18 @@ public class FolderMessageList extends ExpandableListActivity @Override public void onResume() { - super.onResume(); + super.onResume(); clearFormats(); MessagingController.getInstance(getApplication()).addListener( mAdapter.mListener); - mAccount.refresh(Preferences.getPreferences(this)); - onRefresh(false); + mAccount.refresh(Preferences.getPreferences(this)); + onRefresh(false); NotificationManager notifMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notifMgr.cancel(mAccount.getAccountNumber()); - } + } @Override public void onSaveInstanceState(Bundle outState) @@ -651,10 +651,8 @@ public class FolderMessageList extends ExpandableListActivity public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { FolderInfoHolder folder = (FolderInfoHolder) mAdapter.getGroup(groupPosition); - if (folder.outbox) { - return false; - } - if (childPosition == folder.messages.size() && !folder.loading) + + if (!folder.outbox && childPosition == folder.messages.size() && !folder.loading) { if (folder.status == null) { @@ -759,12 +757,13 @@ public class FolderMessageList extends ExpandableListActivity { holder.folder.unreadMessageCount--; } - MessagingController.getInstance(getApplication()).deleteMessage(mAccount, - holder.message.getFolder().getName(), holder.message, null); + mAdapter.removeMessage(holder.message.getFolder().getName(), holder.uid); - Toast.makeText(this, R.string.message_deleted_toast, Toast.LENGTH_SHORT) - .show(); - // onRefresh(false); + mAdapter.addOrUpdateMessage(mAccount.getTrashFolderName(), holder.message); + + MessagingController.getInstance(getApplication()).deleteMessage(mAccount, + holder.message.getFolder().getName(), holder.message, null); + } private void onReply(MessageInfoHolder holder) @@ -950,10 +949,10 @@ public class FolderMessageList extends ExpandableListActivity .getPackedPositionChild(packedPosition); FolderInfoHolder folder = (FolderInfoHolder) mAdapter .getGroup(groupPosition); - if (folder.outbox) - { - return; - } +// if (folder.outbox) +// { +// return; +// } if (childPosition < folder.messages.size()) { getMenuInflater().inflate(R.menu.folder_message_list_context, menu); diff --git a/src/com/android/email/activity/MessageView.java b/src/com/android/email/activity/MessageView.java index f146e38ac..f1009808d 100644 --- a/src/com/android/email/activity/MessageView.java +++ b/src/com/android/email/activity/MessageView.java @@ -426,26 +426,48 @@ public class MessageView extends Activity private void onDelete() { if (mMessage != null) { - MessagingController.getInstance(getApplication()).deleteMessage( - mAccount, - mFolder, - mMessage, - null); - Toast.makeText(this, R.string.message_deleted_toast, Toast.LENGTH_SHORT).show(); + // Remove this message's Uid locally mFolderUids.remove(mMessage.getUid()); - // Check if we have previous/next messages available before choosing - // which one to display - findSurroundingMessagesUid(); - - if (mPreviousMessageUid != null) { - onPrevious(); - } else if (mNextMessageUid != null) { - onNext(); - } else { - finish(); + + findSurroundingMessagesUid(); + + MessagingListener listener = new MessagingListener() + { + public void messageDeleted(Account account, String folder, Message message) + { + // Toast.makeText(MessageView.this, R.string.message_deleted_toast, Toast.LENGTH_SHORT).show(); + + // Check if we have previous/next messages available before choosing + // which one to display + if (mPreviousMessageUid != null) { + onPrevious(); + } else if (mNextMessageUid != null) { + onNext(); + } else { + finish(); + } + } + }; + MessagingListener waitListener = null; + if (mPreviousMessageUid == null && mNextMessageUid == null) + { + // If we have no more messages to view, force the delete to be synchronous, so that + // when we return to the list, all of the localStore operations have completed. + waitListener = listener; } + else + { + listener.messageDeleted(mAccount, mFolder, mMessage); + } + + MessagingController.getInstance(getApplication()).deleteMessage( + mAccount, + mFolder, + mMessage, + waitListener); + } } diff --git a/src/com/android/email/mail/store/ImapStore.java b/src/com/android/email/mail/store/ImapStore.java index 9e5cc4883..5b6ebac52 100644 --- a/src/com/android/email/mail/store/ImapStore.java +++ b/src/com/android/email/mail/store/ImapStore.java @@ -1394,33 +1394,41 @@ public class ImapStore extends Store { public void delete(String trashFolderName) throws MessagingException { ImapFolder iFolder = (ImapFolder)getFolder(); - Folder remoteTrashFolder = iFolder.getStore().getFolder(trashFolderName); - /* - * Attempt to copy the remote message to the remote trash folder. - */ - if (!remoteTrashFolder.exists()) { - /* - * If the remote trash folder doesn't exist we try to create it. - */ - Log.i(Email.LOG_TAG, "IMAPMessage.delete: attempting to create remote " + trashFolderName + " folder"); - remoteTrashFolder.create(FolderType.HOLDS_MESSAGES); - } - - if (remoteTrashFolder.exists()) { - if (Config.LOGD) - { - Log.d(Email.LOG_TAG, "IMAPMessage.delete: copying remote message to " + trashFolderName); - } - iFolder.copyMessages(new Message[] { this }, remoteTrashFolder); - setFlag(Flag.DELETED, true); - iFolder.expunge(); - } - else - { - // Toast.makeText(context, R.string.message_delete_failed, Toast.LENGTH_SHORT).show(); - - Log.e(Email.LOG_TAG, "IMAPMessage.delete: remote Trash folder " + trashFolderName + " does not exist and could not be created"); - } + if (iFolder.getName().equals(trashFolderName)) + { + setFlag(Flag.DELETED, true); + iFolder.expunge(); + } + else + { + Folder remoteTrashFolder = iFolder.getStore().getFolder(trashFolderName); + /* + * Attempt to copy the remote message to the remote trash folder. + */ + if (!remoteTrashFolder.exists()) { + /* + * If the remote trash folder doesn't exist we try to create it. + */ + Log.i(Email.LOG_TAG, "IMAPMessage.delete: attempting to create remote " + trashFolderName + " folder"); + remoteTrashFolder.create(FolderType.HOLDS_MESSAGES); + } + + if (remoteTrashFolder.exists()) { + if (Config.LOGD) + { + Log.d(Email.LOG_TAG, "IMAPMessage.delete: copying remote message to " + trashFolderName); + } + iFolder.copyMessages(new Message[] { this }, remoteTrashFolder); + setFlag(Flag.DELETED, true); + iFolder.expunge(); + } + else + { + // Toast.makeText(context, R.string.message_delete_failed, Toast.LENGTH_SHORT).show(); + + Log.e(Email.LOG_TAG, "IMAPMessage.delete: remote Trash folder " + trashFolderName + " does not exist and could not be created"); + } + } } }