[evolution-mapi] Bug #612395 - Folder unread count disappears
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Bug #612395 - Folder unread count disappears
- Date: Wed, 9 Jun 2010 16:04:09 +0000 (UTC)
commit 3a1045dec046573c76975f453569fbaa741dbee5
Author: Milan Crha <mcrha redhat com>
Date: Wed Jun 9 18:03:22 2010 +0200
Bug #612395 - Folder unread count disappears
src/camel/camel-mapi-folder.c | 151 ++++++++++++------------
src/camel/camel-mapi-store.c | 3 +
src/camel/camel-mapi-summary.c | 39 ++++++
src/camel/camel-mapi-summary.h | 1 +
src/libexchangemapi/exchange-mapi-connection.c | 8 +-
src/libexchangemapi/exchange-mapi-connection.h | 1 +
6 files changed, 125 insertions(+), 78 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 8428539..a544714 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -105,47 +105,45 @@ mapi_folder_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrAr
return matches;
}
-static gboolean
-mapi_refresh_info(CamelFolder *folder, CamelException *ex)
+static void
+update_store_summary (CamelFolder *folder, CamelException *ex)
{
CamelStore *parent_store;
+ CamelStoreSummary *store_summary;
CamelStoreInfo *si;
const gchar *full_name;
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
+ store_summary = (CamelStoreSummary *)((CamelMapiStore *)parent_store)->summary;
- /*
- * Checking for the summary->time_string here since the first the a
- * user views a folder, the read cursor is in progress, and the getQM
- * should not interfere with the process
- */
- // if (summary->time_string && (strlen (summary->time_string) > 0)) {
- if (1) {
- mapi_refresh_folder(folder, ex);
- si = camel_store_summary_path ((CamelStoreSummary *)((CamelMapiStore *)parent_store)->summary, full_name);
-
- if (si) {
- guint32 unread, total;
-
- unread = folder->summary->unread_count;
- total = camel_folder_summary_count (folder->summary);
- if (si->total != total || si->unread != unread) {
- si->total = total;
- si->unread = unread;
- camel_store_summary_touch ((CamelStoreSummary *)((CamelMapiStore *)parent_store)->summary);
- }
- camel_store_summary_info_free ((CamelStoreSummary *)((CamelMapiStore *)parent_store)->summary, si);
+ si = camel_store_summary_path (store_summary, full_name);
+
+ if (si) {
+ guint32 unread, total;
+
+ unread = folder->summary->unread_count;
+ total = camel_folder_summary_count (folder->summary);
+
+ if (si->total != total || si->unread != unread) {
+ si->total = total;
+ si->unread = unread;
+ camel_store_summary_touch (store_summary);
}
- camel_folder_summary_save_to_db (folder->summary, ex);
- camel_store_summary_save ((CamelStoreSummary *)((CamelMapiStore *)parent_store)->summary);
- } else {
- /* We probably could not get the messages the first time. (get_folder) failed???!
- * so do a get_folder again. And hope that it works
- */
- g_print("Reloading folder...something wrong with the summary....\n");
+ camel_store_summary_info_free (store_summary, si);
}
- //#endif
+ camel_folder_summary_save_to_db (folder->summary, ex);
+ camel_store_summary_save (store_summary);
+}
+
+static gboolean
+mapi_refresh_info (CamelFolder *folder, CamelException *ex)
+{
+ mapi_refresh_folder (folder, ex);
+ if (camel_exception_is_set (ex))
+ return FALSE;
+
+ update_store_summary (folder, ex);
return !camel_exception_is_set (ex);
}
@@ -521,18 +519,6 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
}
static void
-mapi_sync_summary (CamelFolder *folder, CamelException *ex)
-{
- CamelStore *parent_store;
-
- parent_store = camel_folder_get_parent_store (folder);
-
- camel_folder_summary_save_to_db (folder->summary, ex);
- camel_store_summary_touch ((CamelStoreSummary *)((CamelMapiStore *)parent_store)->summary);
- camel_store_summary_save ((CamelStoreSummary *)((CamelMapiStore *)parent_store)->summary);
-}
-
-static void
mapi_utils_do_flags_diff (flags_diff_t *diff, guint32 old, guint32 _new)
{
diff->changed = old ^ _new;
@@ -550,11 +536,17 @@ struct mapi_update_deleted_msg {
static gboolean
deleted_items_sync_cb (FetchItemsCallbackData *item_data, gpointer data)
{
- GSList **uid_list = (GSList **) data;
+ guint32 msg_flags = CAMEL_MESSAGE_FOLDER_FLAGGED; /* to not have 0 in the hash table */
+ GHashTable *uids = data;
gchar *msg_uid = exchange_mapi_util_mapi_ids_to_uid (item_data->fid,
item_data->mid);
- *uid_list = g_slist_prepend (*uid_list, msg_uid);
+ if ((item_data->msg_flags & MSGFLAG_READ) != 0)
+ msg_flags |= CAMEL_MESSAGE_SEEN;
+ if ((item_data->msg_flags & MSGFLAG_HASATTACH) != 0)
+ msg_flags |= CAMEL_MESSAGE_ATTACHMENTS;
+
+ g_hash_table_insert (uids, msg_uid, GINT_TO_POINTER (msg_flags));
/* Progress update */
if (item_data->total > 0)
@@ -567,18 +559,6 @@ deleted_items_sync_cb (FetchItemsCallbackData *item_data, gpointer data)
return TRUE;
}
-static gboolean
-mapi_camel_get_last_modif_list (ExchangeMapiConnection *conn, mapi_id_t fid, TALLOC_CTX *mem_ctx, struct SPropTagArray *props, gpointer data)
-{
- static const uint32_t prop_list[] = {
- PR_LAST_MODIFICATION_TIME
- };
-
- g_return_val_if_fail (props != NULL, FALSE);
-
- return exchange_mapi_utils_add_props_to_props_array (mem_ctx, props, prop_list, G_N_ELEMENTS (prop_list));
-}
-
static void
mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
{
@@ -591,8 +571,9 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
CamelStore *parent_store;
guint32 index, count, options = 0;
- GSList *server_uid_list = NULL;
+ GHashTable *server_messages = NULL;
const gchar *uid = NULL;
+ gboolean flags_changed = FALSE;
parent_store = camel_folder_get_parent_store (m->folder);
@@ -614,10 +595,12 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
if (mapi_folder->type & CAMEL_MAPI_FOLDER_PUBLIC)
options |= MAPI_OPTIONS_USE_PFSTORE;
+ server_messages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
/*Get the UID list from server.*/
exchange_mapi_connection_fetch_items (camel_mapi_store_get_exchange_connection (mapi_store), m->folder_id, NULL, NULL,
- mapi_camel_get_last_modif_list, NULL,
- deleted_items_sync_cb, &server_uid_list,
+ NULL, NULL,
+ deleted_items_sync_cb, server_messages,
options | MAPI_OPTIONS_DONT_OPEN_MESSAGE);
camel_operation_end (NULL);
@@ -625,8 +608,10 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
/* Check if we have to stop */
- if (camel_operation_cancel_check(NULL))
+ if (camel_operation_cancel_check(NULL)) {
+ g_hash_table_destroy (server_messages);
return;
+ }
changes = camel_folder_change_info_new ();
@@ -637,34 +622,47 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
/* Iterate over cache and check if the UID is in server*/
for (index = 0; index < count; index++) {
- GSList *tmp_list_item = NULL;
+ guint32 msg_flags;
/* Iterate in a reverse order, thus removal will not hurt */
info = camel_folder_summary_index (m->folder->summary, count - index - 1);
if (!info) continue; /*This is bad. *Should* not happen*/
uid = camel_message_info_uid (info);
-
- if (server_uid_list) {
- /* TODO : Find a better way and avoid this linear search */
- tmp_list_item = g_slist_find_custom (server_uid_list, (gconstpointer) uid,
- (GCompareFunc) g_strcmp0);
+ if (!uid) {
+ camel_message_info_free (info);
+ continue;
}
+ msg_flags = GPOINTER_TO_INT (g_hash_table_lookup (server_messages, uid));
+
/* If it is not in server list, clean our cache */
- if ((!tmp_list_item || !tmp_list_item->data) && uid) {
+ if (!msg_flags) {
CAMEL_MAPI_FOLDER_REC_LOCK (m->folder, cache_lock);
camel_folder_summary_remove_uid (m->folder->summary, uid);
camel_data_cache_remove (mapi_folder->cache, "cache", uid, NULL);
camel_folder_change_info_remove_uid (changes, uid);
CAMEL_MAPI_FOLDER_REC_UNLOCK (m->folder, cache_lock);
+ } else {
+ CamelMapiMessageInfo *mapi_info = (CamelMapiMessageInfo *) info;
+
+ msg_flags = msg_flags & (~CAMEL_MESSAGE_FOLDER_FLAGGED);
+ if (mapi_info->server_flags != msg_flags) {
+ mapi_info->server_flags = msg_flags;
+ camel_message_info_set_flags (info, msg_flags, CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS);
+ camel_folder_change_info_change_uid (changes, uid);
+ flags_changed = TRUE;
+ }
}
+ camel_message_info_free (info);
+
/* Progress update */
camel_operation_progress (NULL, (index * 100)/count); /* ;-) */
/* Check if we have to stop */
if (camel_operation_cancel_check(NULL)) {
+ g_hash_table_destroy (server_messages);
if (camel_folder_change_info_changed (changes))
camel_folder_changed (m->folder, changes);
camel_folder_change_info_free (changes);
@@ -674,15 +672,16 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
camel_operation_end (NULL);
- if (camel_folder_change_info_changed (changes))
+ if (camel_folder_change_info_changed (changes)) {
+ if (flags_changed)
+ camel_mapi_summary_update_store_info_counts (CAMEL_MAPI_SUMMARY (CAMEL_FOLDER (mapi_folder)->summary));
camel_folder_changed (m->folder, changes);
+ }
camel_folder_change_info_free (changes);
- m->need_refresh = camel_folder_summary_count (m->folder->summary) != g_slist_length (server_uid_list);
+ m->need_refresh = camel_folder_summary_count (m->folder->summary) != g_hash_table_size (server_messages);
- /* Discard server uid list */
- g_slist_foreach (server_uid_list, (GFunc) g_free, NULL);
- g_slist_free (server_uid_list);
+ g_hash_table_destroy (server_messages);
}
static void
@@ -745,7 +744,7 @@ mapi_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
if (((CamelOfflineStore *) mapi_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL ||
((CamelService *)mapi_store)->status == CAMEL_SERVICE_DISCONNECTED) {
- mapi_sync_summary (folder, ex);
+ update_store_summary (folder, ex);
return !camel_exception_is_set (ex);
}
@@ -891,7 +890,7 @@ mapi_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
}
camel_service_lock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
- mapi_sync_summary (folder, ex);
+ update_store_summary (folder, ex);
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
return !camel_exception_is_set (ex);
@@ -1068,7 +1067,7 @@ mapi_refresh_folder(CamelFolder *folder, CamelException *ex)
mapi_summary->sync_time_stamp = g_time_val_to_iso8601 (&fetch_data->last_modification_time);
camel_folder_summary_touch (folder->summary);
- mapi_sync_summary (folder, ex);
+ update_store_summary (folder, ex);
camel_service_unlock (CAMEL_SERVICE (mapi_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
is_locked = FALSE;
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index 04ad241..7dbbc10 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -1671,6 +1671,9 @@ mapi_subscribe_folder(CamelStore *store, const gchar *folder_name, CamelExceptio
camel_url_free (url);
}
+ fi->unread = si->unread;
+ fi->total = si->total;
+ fi->flags = si->flags;
camel_store_summary_info_free((CamelStoreSummary *)mapi_store->summary, si);
}
diff --git a/src/camel/camel-mapi-summary.c b/src/camel/camel-mapi-summary.c
index 9823a5d..73011f2 100644
--- a/src/camel/camel-mapi-summary.c
+++ b/src/camel/camel-mapi-summary.c
@@ -33,6 +33,7 @@
#include "camel-mapi-folder.h"
#include "camel-mapi-summary.h"
+#include "camel-mapi-store.h"
#define CAMEL_MAPI_SUMMARY_VERSION (1)
@@ -148,6 +149,41 @@ camel_mapi_summary_new (CamelFolder *folder, const gchar *filename)
return summary;
}
+void
+camel_mapi_summary_update_store_info_counts (CamelMapiSummary *mapi_summary)
+{
+ CamelFolderSummary *summary;
+
+ g_return_if_fail (mapi_summary != NULL);
+
+ summary = CAMEL_FOLDER_SUMMARY (mapi_summary);
+ g_return_if_fail (summary != NULL);
+
+ if (summary->folder) {
+ CamelMapiStore *mapi_store;
+
+ mapi_store = CAMEL_MAPI_STORE (camel_folder_get_parent_store (summary->folder));
+ if (mapi_store && mapi_store->summary) {
+ CamelStoreInfo *si;
+ CamelStoreSummary *store_summary = CAMEL_STORE_SUMMARY (mapi_store->summary);
+
+ g_return_if_fail (store_summary != NULL);
+
+ si = camel_store_summary_path (store_summary, camel_folder_get_full_name (summary->folder));
+ if (si) {
+ if (si->unread != summary->unread_count || si->total != summary->saved_count) {
+ si->unread = summary->unread_count;
+ si->total = summary->saved_count;
+
+ camel_store_summary_touch (store_summary);
+ }
+
+ camel_store_summary_info_free (store_summary, si);
+ }
+ }
+ }
+}
+
static gint
mapi_summary_header_from_db (CamelFolderSummary *summary, CamelFIRecord *fir)
{
@@ -173,6 +209,7 @@ mapi_summary_header_from_db (CamelFolderSummary *summary, CamelFIRecord *fir)
return 0;
}
+
static CamelFIRecord *
mapi_summary_header_to_db (CamelFolderSummary *summary, CamelException *ex)
{
@@ -190,6 +227,8 @@ mapi_summary_header_to_db (CamelFolderSummary *summary, CamelException *ex)
fir->bdata = g_strdup_printf ("%d %s", CAMEL_MAPI_SUMMARY_VERSION, mapi_summary->sync_time_stamp);
+ camel_mapi_summary_update_store_info_counts (mapi_summary);
+
return fir;
}
diff --git a/src/camel/camel-mapi-summary.h b/src/camel/camel-mapi-summary.h
index 2311a19..a657faa 100644
--- a/src/camel/camel-mapi-summary.h
+++ b/src/camel/camel-mapi-summary.h
@@ -85,6 +85,7 @@ GType camel_mapi_summary_get_type (void);
CamelFolderSummary *camel_mapi_summary_new (struct _CamelFolder *folder, const gchar *filename);
void mapi_summary_clear (CamelFolderSummary *summary, gboolean uncache);
+void camel_mapi_summary_update_store_info_counts (CamelMapiSummary *mapi_summary);
G_END_DECLS
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index a63fb52..5de210f 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -1439,11 +1439,12 @@ exchange_mapi_connection_fetch_items (ExchangeMapiConnection *conn, mapi_id_t
goto cleanup;
}
- SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
+ SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
PR_FID,
PR_MID,
PR_LAST_MODIFICATION_TIME,
- PR_HASATTACH);
+ PR_HASATTACH,
+ PR_MESSAGE_FLAGS);
/* Set primary columns to be fetched */
retval = SetColumns(&obj_table, SPropTagArray);
@@ -1500,6 +1501,7 @@ exchange_mapi_connection_fetch_items (ExchangeMapiConnection *conn, mapi_id_t
const mapi_id_t *pfid;
const mapi_id_t *pmid;
const bool *has_attach = NULL;
+ const uint32_t *msg_flags;
GSList *attach_list = NULL;
GSList *recip_list = NULL;
GSList *stream_list = NULL;
@@ -1511,6 +1513,7 @@ exchange_mapi_connection_fetch_items (ExchangeMapiConnection *conn, mapi_id_t
pmid = (const uint64_t *) get_SPropValue_SRow_data(&SRowSet.aRow[i], PR_MID);
has_attach = (const bool *) get_SPropValue_SRow_data(&SRowSet.aRow[i], PR_HASATTACH);
+ msg_flags = get_SPropValue_SRow_data (&SRowSet.aRow[i], PR_MESSAGE_FLAGS);
if (options & MAPI_OPTIONS_DONT_OPEN_MESSAGE)
goto relax;
@@ -1588,6 +1591,7 @@ exchange_mapi_connection_fetch_items (ExchangeMapiConnection *conn, mapi_id_t
item_data->conn = conn;
item_data->fid = *pfid;
item_data->mid = *pmid;
+ item_data->msg_flags = msg_flags ? *msg_flags : 0;
item_data->properties = &properties_array;
item_data->streams = stream_list;
item_data->recipients = recip_list;
diff --git a/src/libexchangemapi/exchange-mapi-connection.h b/src/libexchangemapi/exchange-mapi-connection.h
index 8a4a595..ff83637 100644
--- a/src/libexchangemapi/exchange-mapi-connection.h
+++ b/src/libexchangemapi/exchange-mapi-connection.h
@@ -115,6 +115,7 @@ typedef struct {
struct mapi_SPropValue_array *properties;
mapi_id_t fid;
mapi_id_t mid;
+ uint32_t msg_flags; /* used only with fetch_items */
GSList *attachments;
GSList *recipients;
GSList *gallist;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]