* incrementally update flags later, this won't stop us syncing */
else if ((mutt_strncasecmp("FLAGS", pc, 5) == 0) && !h->changed)
{
- if ((pc = imap_set_flags(idata, h, pc)) == NULL)
+ if ((pc = imap_set_flags(idata, h, pc, NULL)) == NULL)
goto bail;
}
}
}
}
+/* Sets server_changes to 1 if a change to a flag is made, or in the
+ * case of local_changes, if a change to a flag _would_ have been
+ * made. */
+static void imap_set_changed_flag(struct Context *ctx, struct Header *h,
+ int local_changes, int *server_changes, int flag_name,
+ int old_hd_flag, int new_hd_flag, int h_flag)
+{
+ /* If there are local_changes, we only want to note if the server
+ * flags have changed, so we can set a reopen flag in
+ * cmd_parse_fetch(). We don't want to count a local modification
+ * to the header flag as a "change".
+ */
+ if ((old_hd_flag != new_hd_flag) || (!local_changes))
+ {
+ if (new_hd_flag != h_flag)
+ {
+ if (server_changes)
+ *server_changes = 1;
+
+ /* Local changes have priority */
+ if (!local_changes)
+ mutt_set_flag(ctx, h, flag_name, new_hd_flag);
+ }
+ }
+}
+
/**
* imap_set_flags - fill the message header according to the server flags
*
* Expects a flags line of the form "FLAGS (flag flag ...)"
*/
-char *imap_set_flags(struct ImapData *idata, struct Header *h, char *s)
+
+/* imap_set_flags: fill out the message header according to the flags from
+ * the server. Expects a flags line of the form "FLAGS (flag flag ...)"
+ *
+ * Sets server_changes to 1 if a change to a flag is made, or in the
+ * case of h->changed, if a change to a flag _would_ have been
+ * made. */
+char *imap_set_flags(struct ImapData *idata, struct Header *h, char *s, int *server_changes)
{
struct Context *ctx = idata->ctx;
struct ImapHeader newh;
+ struct ImapHeaderData old_hd;
struct ImapHeaderData *hd = NULL;
bool readonly;
+ int local_changes;
+
+ local_changes = h->changed;
memset(&newh, 0, sizeof(newh));
hd = h->data;
newh.data = hd;
+ memcpy(&old_hd, hd, sizeof(old_hd));
+
mutt_debug(2, "imap_set_flags: parsing FLAGS\n");
if ((s = msg_parse_flags(&newh, s)) == NULL)
return NULL;
readonly = ctx->readonly;
ctx->readonly = false;
- mutt_set_flag(ctx, h, MUTT_NEW, !(hd->read || hd->old));
- mutt_set_flag(ctx, h, MUTT_OLD, hd->old);
- mutt_set_flag(ctx, h, MUTT_READ, hd->read);
- mutt_set_flag(ctx, h, MUTT_DELETE, hd->deleted);
- mutt_set_flag(ctx, h, MUTT_FLAG, hd->flagged);
- mutt_set_flag(ctx, h, MUTT_REPLIED, hd->replied);
+ /* This is redundant with the following two checks. Removing:
+ * mutt_set_flag (ctx, h, MUTT_NEW, !(hd->read || hd->old));
+ */
+ imap_set_changed_flag(ctx, h, local_changes, server_changes, MUTT_OLD,
+ old_hd.old, hd->old, h->old);
+ imap_set_changed_flag(ctx, h, local_changes, server_changes, MUTT_READ,
+ old_hd.read, hd->read, h->read);
+ imap_set_changed_flag(ctx, h, local_changes, server_changes, MUTT_DELETE,
+ old_hd.deleted, hd->deleted, h->deleted);
+ imap_set_changed_flag(ctx, h, local_changes, server_changes, MUTT_FLAG,
+ old_hd.flagged, hd->flagged, h->flagged);
+ imap_set_changed_flag(ctx, h, local_changes, server_changes, MUTT_REPLIED,
+ old_hd.replied, hd->replied, h->replied);
/* this message is now definitively *not* changed (mutt_set_flag
* marks things changed as a side-effect) */
- h->changed = false;
+ if (!local_changes)
+ h->changed = false;
ctx->changed &= !readonly;
ctx->readonly = readonly;