aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2000-12-20 03:42:15 +0800
committerDan Winship <danw@src.gnome.org>2000-12-20 03:42:15 +0800
commitfb91cdbd3af111928ca64f7df6342d70c3447c67 (patch)
tree290ad8f12d52d167ab2ab0bdb319b9700e056166 /camel/providers/imap
parent0e2e34336151ca1dfc434658175814c48045828f (diff)
downloadgsoc2013-evolution-fb91cdbd3af111928ca64f7df6342d70c3447c67.tar.gz
gsoc2013-evolution-fb91cdbd3af111928ca64f7df6342d70c3447c67.tar.zst
gsoc2013-evolution-fb91cdbd3af111928ca64f7df6342d70c3447c67.zip
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
Diffstat (limited to 'camel/providers/imap')
-rw-r--r--camel/providers/imap/camel-imap-folder.c111
-rw-r--r--camel/providers/imap/camel-imap-summary.c39
-rw-r--r--camel/providers/imap/camel-imap-summary.h1
3 files changed, 89 insertions, 62 deletions
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index ae3fe15822..3299b2c551 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -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);
}
diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c
index 9a0a638f96..5d657b6d68 100644
--- a/camel/providers/imap/camel-imap-summary.c
+++ b/camel/providers/imap/camel-imap-summary.c
@@ -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);
+}
diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h
index 0b844fdd7e..cd3556b23b 100644
--- a/camel/providers/imap/camel-imap-summary.h
+++ b/camel/providers/imap/camel-imap-summary.h
@@ -42,6 +42,7 @@ typedef struct _CamelImapMessageContentInfo {
typedef struct _CamelImapMessageInfo {
CamelMessageInfo info;
+ guint32 server_flags;
} CamelImapMessageInfo;
struct _CamelImapSummary {