Add "guint32 server_flags" to CamelImapMessageInfo to keep track of the

* providers/imap/camel-imap-summary.c: Add "guint32 server_flags"
        to CamelImapMessageInfo to keep track of the last known message
        flag state on the server.
        (message_info_save, message_info_load): Save/load the
        server_flags.

        * providers/imap/camel-imap-folder.c: Make this use
        CamelFolderChangeInfo and emit folder_changed notifications as it
        gets them rather than only on refresh_info.
        (imap_refresh_info): Notice flags that get cleared on the server
        as well as flags that get set.
        (imap_update_summary): Remove a comment that never actually
        applied to the committed code.

svn path=/trunk/; revision=7086
This commit is contained in:
Dan Winship
2000-12-19 19:42:15 +00:00
parent 0e2e343361
commit fb91cdbd3a
4 changed files with 105 additions and 62 deletions

View File

@ -1,3 +1,19 @@
2000-12-18 Dan Winship <danw@helixcode.com>
* providers/imap/camel-imap-summary.c: Add "guint32 server_flags"
to CamelImapMessageInfo to keep track of the last known message
flag state on the server.
(message_info_save, message_info_load): Save/load the
server_flags.
* providers/imap/camel-imap-folder.c: Make this use
CamelFolderChangeInfo and emit folder_changed notifications as it
gets them rather than only on refresh_info.
(imap_refresh_info): Notice flags that get cleared on the server
as well as flags that get set.
(imap_update_summary): Remove a comment that never actually
applied to the committed code.
2000-12-15 Dan Winship <danw@helixcode.com>
* providers/imap/camel-imap-command.c (camel_imap_command): Change

View File

@ -88,6 +88,7 @@ static GPtrArray *imap_get_summary (CamelFolder *folder);
static const CamelMessageInfo *imap_get_message_info (CamelFolder *folder, const char *uid);
static void imap_update_summary (CamelFolder *folder, int first, int last,
CamelFolderChangeInfo *changes,
CamelException *ex);
/* searching */
@ -249,16 +250,8 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
const char *uid, *flags;
int i, seq, summary_len;
CamelMessageInfo *info;
gboolean folder_changed = FALSE;
if (imap_folder->exists == 0) {
if (camel_folder_summary_count (imap_folder->summary) != 0) {
camel_folder_summary_clear (imap_folder->summary);
camel_object_trigger_event (CAMEL_OBJECT (folder),
"folder_changed", NULL);
}
return;
}
CamelImapMessageInfo *iinfo;
CamelFolderChangeInfo *changes;
/* Get UIDs and flags of all messages. */
response = camel_imap_command (store, folder, ex,
@ -267,6 +260,7 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
if (!response)
return;
changes = camel_folder_change_info_new ();
new = g_malloc0 (imap_folder->exists * sizeof (*new));
for (i = 0; i < response->untagged->len; i++) {
resp = response->untagged->pdata[i];
@ -296,30 +290,31 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
summary_len = camel_folder_summary_count (imap_folder->summary);
for (i = 0; i < summary_len && i < imap_folder->exists; i++) {
info = camel_folder_summary_index (imap_folder->summary, i);
iinfo = (CamelImapMessageInfo *)info;
/* Shouldn't happen, but... */
if (!new[i].uid)
continue;
if (strcmp (camel_message_info_uid(info), new[i].uid) != 0) {
camel_folder_summary_remove (imap_folder->summary,
info);
folder_changed = TRUE;
if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
camel_folder_summary_remove (imap_folder->summary, info);
i--;
summary_len--;
continue;
}
/* Update summary flags */
if (info->flags != new[i].flags) {
/* Keep the flags that we have set locally and set
any additional flags that a parallel connection
may have set. */
info->flags |= new[i].flags;
camel_object_trigger_event (CAMEL_OBJECT (folder),
"message_changed",
(char *)camel_message_info_uid(info));
if (new[i].flags != iinfo->server_flags) {
guint32 server_set, server_cleared;
server_set = new[i].flags & ~iinfo->server_flags;
server_cleared = iinfo->server_flags & ~new[i].flags;
info->flags = (info->flags | server_set) & ~server_cleared;
iinfo->server_flags = new[i].flags;
camel_folder_change_info_change_uid (changes, new[i].uid);
}
g_free (new[i].uid);
@ -327,26 +322,27 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
/* Remove any leftover cached summary messages. */
while (summary_len > i + 1) {
camel_folder_summary_remove_index (imap_folder->summary,
--summary_len);
folder_changed = TRUE;
info = camel_folder_summary_index (imap_folder->summary, --summary_len);
camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
camel_folder_summary_remove (imap_folder->summary, info);
}
/* Add any new folder messages. */
if (i < imap_folder->exists) {
/* Fetch full summary for the remaining messages. */
imap_update_summary (folder, i + 1, imap_folder->exists, ex);
folder_changed = TRUE;
imap_update_summary (folder, i + 1, imap_folder->exists,
changes, ex);
while (i < imap_folder->exists)
g_free (new[i++].uid);
}
g_free (new);
if (folder_changed) {
if (camel_folder_change_info_changed (changes)) {
camel_object_trigger_event (CAMEL_OBJECT (folder),
"folder_changed", NULL);
"folder_changed", changes);
}
camel_folder_change_info_free (changes);
}
static void
@ -504,14 +500,6 @@ imap_copy_message_to (CamelFolder *source, const char *uid,
response = camel_imap_command (store, source, ex, "UID COPY %s %S",
uid, destination->full_name);
camel_imap_response_free (response);
/* FIXME: This should go away once folder_changed is being
* emitted by camel_imap_folder_changed on appends again.
*/
if (!camel_exception_is_set (ex)) {
camel_object_trigger_event (CAMEL_OBJECT (destination),
"folder_changed", NULL);
}
}
static void
@ -528,12 +516,6 @@ imap_move_message_to (CamelFolder *source, const char *uid,
if (camel_exception_is_set (ex))
return;
/* FIXME: This should go away once folder_changed is being
* emitted by camel_imap_folder_changed on appends again.
*/
camel_object_trigger_event (CAMEL_OBJECT (destination),
"folder_changed", NULL);
camel_folder_delete_message (source, uid);
}
@ -629,7 +611,7 @@ imap_protocol_get_summary_specifier (CamelImapStore *store)
static void
imap_update_summary (CamelFolder *folder, int first, int last,
CamelException *ex)
CamelFolderChangeInfo *changes, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@ -639,13 +621,6 @@ imap_update_summary (CamelFolder *folder, int first, int last,
struct _header_raw *h = NULL;
int i;
/* If the range we're updating overlaps with the range we already
* know about, then fetch just flags + uids first. If uids
* aren't "right", reorder them. Update flags appropriately.
* If that returned unknown UIDs, or we're updating unknown
* sequence numbers, do the full fetch for those.
*/
summary_specifier = imap_protocol_get_summary_specifier (store);
if (first == last) {
response = camel_imap_command (store, folder, ex,
@ -664,6 +639,7 @@ imap_update_summary (CamelFolder *folder, int first, int last,
headers = response->untagged;
for (i = 0; i < headers->len; i++) {
CamelMessageInfo *info;
CamelImapMessageInfo *iinfo;
char *uid, *flags, *header;
/* Grab the UID... */
@ -700,10 +676,13 @@ imap_update_summary (CamelFolder *folder, int first, int last,
* because it will assign the wrong UID, and thus get the
* uid hash table wrong and all that. FIXME some day.
*/
info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(imap_folder->summary)))->message_info_new(imap_folder->summary, h);
info = camel_folder_summary_info_new_from_header (
imap_folder->summary, h);
iinfo = (CamelImapMessageInfo *)info;
header_raw_clear (&h);
uid = g_strndup(uid, q-uid);
camel_message_info_set_uid(info, uid);
uid = g_strndup (uid, q - uid);
camel_folder_change_info_add_uid (changes, uid);
camel_message_info_set_uid (info, uid);
/* now lets grab the FLAGS */
if (!(flags = strstr (headers->pdata[i], "FLAGS "))) {
@ -712,6 +691,7 @@ imap_update_summary (CamelFolder *folder, int first, int last,
for (flags += 6; *flags && *flags != '('; flags++)
;
info->flags = imap_parse_flag_list (flags);
iinfo->server_flags = info->flags;
}
camel_folder_summary_add (imap_folder->summary, info);
@ -840,19 +820,28 @@ camel_imap_folder_changed (CamelFolder *folder, int exists,
GArray *expunged, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelFolderChangeInfo *changes;
CamelMessageInfo *info;
changes = camel_folder_change_info_new ();
if (expunged) {
int i, id;
for (i = 0; i < expunged->len; i++) {
id = g_array_index (expunged, int, i);
camel_folder_summary_remove_index (
imap_folder->summary, id - 1);
info = camel_folder_summary_index (imap_folder->summary, id - 1);
camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
camel_folder_summary_remove (imap_folder->summary, info);
}
camel_object_trigger_event (CAMEL_OBJECT (folder),
"folder_changed", NULL);
}
if (exists != 0)
imap_folder->exists = exists;
imap_update_summary (folder, imap_folder->exists + 1, exists,
changes, ex);
imap_folder->exists = exists;
if (camel_folder_change_info_changed (changes)) {
camel_object_trigger_event (CAMEL_OBJECT (folder),
"folder_changed", changes);
}
camel_folder_change_info_free (changes);
}

View File

@ -32,11 +32,15 @@
#include <string.h>
#include <stdlib.h>
#define CAMEL_IMAP_SUMMARY_VERSION (0x1000)
#define CAMEL_IMAP_SUMMARY_VERSION (0x2000)
static int summary_header_load (CamelFolderSummary *, FILE *);
static int summary_header_save (CamelFolderSummary *, FILE *);
static CamelMessageInfo *message_info_load (CamelFolderSummary *s, FILE *in);
static int message_info_save (CamelFolderSummary *s, FILE *out,
CamelMessageInfo *info);
static void camel_imap_summary_class_init (CamelImapSummaryClass *klass);
static void camel_imap_summary_init (CamelImapSummary *obj);
@ -70,6 +74,8 @@ camel_imap_summary_class_init (CamelImapSummaryClass *klass)
cfs_class->summary_header_load = summary_header_load;
cfs_class->summary_header_save = summary_header_save;
cfs_class->message_info_load = message_info_load;
cfs_class->message_info_save = message_info_save;
}
static void
@ -149,3 +155,34 @@ summary_header_save (CamelFolderSummary *s, FILE *out)
return camel_folder_summary_encode_uint32 (out, ims->validity);
}
static CamelMessageInfo *
message_info_load (CamelFolderSummary *s, FILE *in)
{
CamelMessageInfo *info;
CamelImapMessageInfo *iinfo;
info = camel_imap_summary_parent->message_info_load (s, in);
if (!info)
return NULL;
iinfo = (CamelImapMessageInfo *)info;
if (camel_folder_summary_decode_uint32 (in, &iinfo->server_flags) == -1) {
camel_folder_summary_info_free (s, info);
return NULL;
}
return info;
}
static int
message_info_save (CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
{
CamelImapMessageInfo *iinfo = (CamelImapMessageInfo *)info;
if (camel_imap_summary_parent->message_info_save (s, out, info) == -1)
return -1;
return camel_folder_summary_encode_uint32 (out, iinfo->server_flags);
}

View File

@ -42,6 +42,7 @@ typedef struct _CamelImapMessageContentInfo {
typedef struct _CamelImapMessageInfo {
CamelMessageInfo info;
guint32 server_flags;
} CamelImapMessageInfo;
struct _CamelImapSummary {