Changed the way we set flags to update the original Message object

This commit is contained in:
cketti 2012-02-04 14:52:45 +01:00
parent 46bf2c5be7
commit 898f65e081
4 changed files with 99 additions and 55 deletions

View file

@ -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;

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -2519,65 +2519,118 @@ public class MessagingController implements Runnable {
@Override
public void act(final Account account, final Folder folder,
final List<Message> 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.
*
* <p>
* The {@link Message} objects passed in are updated to reflect the new flag state.
* </p>
*
* @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<Message> messages = new ArrayList<Message>();
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 {