diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index a24423eb3..8b85cfd95 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -1611,7 +1611,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc final Account account = Preferences.getPreferences(this).getAccount(mMessageReference.accountUuid); final String folderName = mMessageReference.folderName; final String sourceMessageUid = mMessageReference.uid; - MessagingController.getInstance(getApplication()).setFlag(account, folderName, new String[] {sourceMessageUid}, mMessageReference.flag, true); + MessagingController.getInstance(getApplication()).setFlag(account, folderName, sourceMessageUid, mMessageReference.flag, true); } mDraftNeedsSaving = false; diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 1d2c8f59e..89d1366ef 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -70,6 +70,7 @@ import com.fsck.k9.mail.Folder; import com.fsck.k9.mail.Message; import com.fsck.k9.mail.store.LocalStore; import com.fsck.k9.mail.store.LocalStore.LocalFolder; +import com.fsck.k9.mail.store.LocalStore.LocalMessage; import com.fsck.k9.mail.store.StorageManager; @@ -1384,13 +1385,21 @@ public class MessageList } private void onToggleRead(MessageInfoHolder holder) { - mController.setFlag(holder.message.getFolder().getAccount(), holder.message.getFolder().getName(), new String[] { holder.uid }, Flag.SEEN, !holder.read); + LocalMessage message = holder.message; + Folder folder = message.getFolder(); + Account account = folder.getAccount(); + String folderName = folder.getName(); + mController.setFlag(account, folderName, new Message[] { message }, Flag.SEEN, !holder.read); holder.read = !holder.read; mHandler.sortMessages(); } private void onToggleFlag(MessageInfoHolder holder) { - mController.setFlag(holder.message.getFolder().getAccount(), holder.message.getFolder().getName(), new String[] { holder.uid }, Flag.FLAGGED, !holder.flagged); + LocalMessage message = holder.message; + Folder folder = message.getFolder(); + Account account = folder.getAccount(); + String folderName = folder.getName(); + mController.setFlag(account, folderName, new Message[] { message }, Flag.FLAGGED, !holder.flagged); holder.flagged = !holder.flagged; mHandler.sortMessages(); } diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java index 64f4c9208..221d195c9 100644 --- a/src/com/fsck/k9/activity/MessageView.java +++ b/src/com/fsck/k9/activity/MessageView.java @@ -20,7 +20,6 @@ import com.fsck.k9.crypto.PgpData; import com.fsck.k9.helper.FileBrowserHelper; import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback; import com.fsck.k9.mail.*; -import com.fsck.k9.mail.store.LocalStore.LocalMessage; import com.fsck.k9.mail.store.StorageManager; import com.fsck.k9.view.AttachmentView; import com.fsck.k9.view.ToggleScrollView; @@ -729,17 +728,8 @@ public class MessageView extends K9Activity implements OnClickListener { if (mMessage != null) { boolean newState = !mMessage.isSet(Flag.FLAGGED); mController.setFlag(mAccount, mMessage.getFolder().getName(), - new String[] {mMessage.getUid()}, Flag.FLAGGED, newState); - try { - // FIXME: This is a hack to change the flagged state of our message object. We - // can't call Message.setFlag() because that would "adjust" the flagged count - // another time (first time by MessagingController.setFlag(...)). - ((LocalMessage)mMessage).setFlagInternal(Flag.FLAGGED, newState); - - mMessageView.setHeaders(mMessage, mAccount); - } catch (MessagingException me) { - Log.e(K9.LOG_TAG, "Could not set flag on local message", me); - } + new Message[] { mMessage }, Flag.FLAGGED, newState); + mMessageView.setHeaders(mMessage, mAccount); } } @@ -883,18 +873,10 @@ public class MessageView extends K9Activity implements OnClickListener { private void onMarkAsUnread() { if (mMessage != null) { mController.setFlag(mAccount, mMessage.getFolder().getName(), - new String[] { mMessage.getUid() }, Flag.SEEN, false); - try { - // FIXME: This is a hack to mark our message object as unread. We can't call - // Message.setFlag() because that would "adjust" the unread count twice. - ((LocalMessage)mMessage).setFlagInternal(Flag.SEEN, false); - - mMessageView.setHeaders(mMessage, mAccount); - String subject = mMessage.getSubject(); - setTitle(subject); - } catch (Exception e) { - Log.e(K9.LOG_TAG, "Unable to unset SEEN flag on message", e); - } + new Message[] { mMessage }, Flag.SEEN, false); + mMessageView.setHeaders(mMessage, mAccount); + String subject = mMessage.getSubject(); + setTitle(subject); } } diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 389e6f2a4..6a9081c28 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -2519,65 +2519,118 @@ public class MessagingController implements Runnable { @Override public void act(final Account account, final Folder folder, final List messages) { - String[] uids = new String[messages.size()]; - for (int i = 0; i < messages.size(); i++) { - uids[i] = messages.get(i).getUid(); - } - setFlag(account, folder.getName(), uids, flag, newState); + setFlag(account, folder.getName(), messages.toArray(EMPTY_MESSAGE_ARRAY), flag, + newState); } }); } - public void setFlag( - final Account account, - final String folderName, - final String[] uids, - final Flag flag, - final boolean newState) { - // TODO: put this into the background, but right now that causes odd behavior - // because the FolderMessageList doesn't have its own cache of the flag states + /** + * Set or remove a flag for a set of messages in a specific folder. + * + *

+ * The {@link Message} objects passed in are updated to reflect the new flag state. + *

+ * + * @param account + * The account the folder containing the messages belongs to. + * @param folderName + * The name of the folder. + * @param messages + * The messages to change the flag for. + * @param flag + * The flag to change. + * @param newState + * {@code true}, if the flag should be set. {@code false} if it should be removed. + */ + public void setFlag(Account account, String folderName, Message[] messages, Flag flag, + boolean newState) { + // TODO: Put this into the background, but right now some callers depend on the message + // objects being modified right after this method returns. Folder localFolder = null; try { Store localStore = account.getLocalStore(); localFolder = localStore.getFolder(folderName); localFolder.open(OpenMode.READ_WRITE); - ArrayList messages = new ArrayList(); - for (String uid : uids) { - // Allows for re-allowing sending of messages that could not be sent - if (flag == Flag.FLAGGED && !newState - && uid != null - && account.getOutboxFolderName().equals(folderName)) { - sendCount.remove(uid); - } - Message msg = localFolder.getMessage(uid); - if (msg != null) { - messages.add(msg); + + // Allows for re-allowing sending of messages that could not be sent + if (flag == Flag.FLAGGED && !newState && + account.getOutboxFolderName().equals(folderName)) { + for (Message message : messages) { + String uid = message.getUid(); + if (uid != null) { + sendCount.remove(uid); + } } } - localFolder.setFlags(messages.toArray(EMPTY_MESSAGE_ARRAY), new Flag[] {flag}, newState); - + // Update the messages in the local store + localFolder.setFlags(messages, new Flag[] {flag}, newState); for (MessagingListener l : getListeners()) { l.folderStatusChanged(account, folderName, localFolder.getUnreadMessageCount()); } + + /* + * Handle the remote side + */ + + // The error folder is always a local folder + // TODO: Skip the remote part for all local-only folders if (account.getErrorFolderName().equals(folderName)) { return; } + String[] uids = new String[messages.length]; + for (int i = 0, end = uids.length; i < end; i++) { + uids[i] = messages[i].getUid(); + } + queueSetFlag(account, folderName, Boolean.toString(newState), flag.toString(), uids); processPendingCommands(account); } catch (MessagingException me) { addErrorMessage(account, null, me); - throw new RuntimeException(me); } finally { closeFolder(localFolder); } - }//setMesssageFlag + } + + /** + * Set or remove a flag for a message referenced by message UID. + * + * @param account + * The account the folder containing the message belongs to. + * @param folderName + * The name of the folder. + * @param message + * The message to change the flag for. + * @param flag + * The flag to change. + * @param newState + * {@code true}, if the flag should be set. {@code false} if it should be removed. + */ + public void setFlag(Account account, String folderName, String uid, Flag flag, + boolean newState) { + Folder localFolder = null; + try { + LocalStore localStore = account.getLocalStore(); + localFolder = localStore.getFolder(folderName); + localFolder.open(OpenMode.READ_WRITE); + + Message message = localFolder.getMessage(uid); + setFlag(account, folderName, new Message[] { message }, flag, newState); + + } catch (MessagingException me) { + addErrorMessage(account, null, me); + throw new RuntimeException(me); + } finally { + closeFolder(localFolder); + } + } public void clearAllPending(final Account account) { try {