From 0f0f01c1e0b40b513d82ef05082edfc3acf76d9e Mon Sep 17 00:00:00 2001 From: 1 Date: Fri, 21 Sep 2001 05:58:53 +0000 Subject: Force a refresh of vfolders before storing their count. This essentially 2001-09-21 * camel-vee-store.c (vee_get_folder_info): Force a refresh of vfolders before storing their count. This essentially makes 'get_folderinfo' refresh all vfolders, so that get-mail works as expected. * camel-vee-folder.c (camel_vee_folder_finalise): Clear lists. (folder_changed): If we're not autoupdating the folder, then add this folder to the list of 'changed' folders for this vfolder. (camel_vee_folder_set_expression): Reset the folders_changed list. (camel_vee_folder_remove_folder): Remove the folder from the folders_changed list. (camel_vee_folder_set_folders): If we have a folder already, but its changed, use this opportunity to update it. (vee_sync): Remove any synced folders from the folders_changed list. (vee_refresh_info): Refresh folder, re-run queries on any changed folders. svn path=/trunk/; revision=13045 --- camel/ChangeLog | 20 +++++++++++++++ camel/camel-private.h | 3 ++- camel/camel-vee-folder.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++- camel/camel-vee-store.c | 18 +++++++++++++- 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index c624a6fc90..9ce9e3e9dd 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,23 @@ +2001-09-21 + + * camel-vee-store.c (vee_get_folder_info): Force a refresh of + vfolders before storing their count. This essentially makes + 'get_folderinfo' refresh all vfolders, so that get-mail works as + expected. + + * camel-vee-folder.c (camel_vee_folder_finalise): Clear lists. + (folder_changed): If we're not autoupdating the folder, then + add this folder to the list of 'changed' folders for this vfolder. + (camel_vee_folder_set_expression): Reset the folders_changed list. + (camel_vee_folder_remove_folder): Remove the folder from the + folders_changed list. + (camel_vee_folder_set_folders): If we have a folder already, but + its changed, use this opportunity to update it. + (vee_sync): Remove any synced folders from the folders_changed + list. + (vee_refresh_info): Refresh folder, re-run queries on any changed + folders. + 2001-09-20 * camel-folder-summary.c (camel_folder_summary_header_load): New diff --git a/camel/camel-private.h b/camel/camel-private.h index 34f393b00f..8d65e0ace1 100644 --- a/camel/camel-private.h +++ b/camel/camel-private.h @@ -176,7 +176,8 @@ struct _CamelVeeStorePrivate { #endif struct _CamelVeeFolderPrivate { - GList *folders; /* lock using subfolder_lock before changing/accessing */ + GList *folders; /* lock using subfolder_lock before changing/accessing */ + GList *folders_changed; /* for list of folders that have changed between updates */ #ifdef ENABLE_THREADS GMutex *summary_lock; /* for locking vfolder summary */ diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index 59bbcfcbf2..5cafadc7f5 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -46,6 +46,8 @@ #define _PRIVATE(o) (((CamelVeeFolder *)(o))->priv) +static void vee_refresh_info(CamelFolder *folder, CamelException *ex); + static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex); static void vee_expunge (CamelFolder *folder, CamelException *ex); @@ -109,6 +111,7 @@ camel_vee_folder_class_init (CamelVeeFolderClass *klass) camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ())); + folder_class->refresh_info = vee_refresh_info; folder_class->sync = vee_sync; folder_class->expunge = vee_expunge; @@ -176,6 +179,9 @@ camel_vee_folder_finalise (CamelObject *obj) g_free(vf->expression); g_free(vf->vname); + g_list_free(p->folders); + g_list_free(p->folders_changed); + camel_folder_change_info_free(vf->changes); camel_object_unref((CamelObject *)vf->search); @@ -295,6 +301,9 @@ camel_vee_folder_set_expression(CamelVeeFolder *vf, const char *query) node = node->next; } + g_list_free(p->folders_changed); + p->folders_changed = NULL; + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); } @@ -350,6 +359,9 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched); CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); + + p->folders_changed = g_list_remove(p->folders_changed, sub); + if (g_list_find(p->folders, sub) == NULL) { CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); return; @@ -385,13 +397,15 @@ remove_folders(CamelFolder *folder, CamelFolder *foldercopy, CamelVeeFolder *vf) void camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders) { + struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); GHashTable *remove = g_hash_table_new(NULL, NULL); GList *l; CamelFolder *folder; + int changed; /* setup a table of all folders we have currently */ CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); - l = vf->priv->folders; + l = p->folders; while (l) { g_hash_table_insert(remove, l->data, l->data); camel_object_ref((CamelObject *)l->data); @@ -405,6 +419,15 @@ camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders) if ((folder = g_hash_table_lookup(remove, l->data))) { g_hash_table_remove(remove, folder); camel_object_unref((CamelObject *)folder); + + /* if this was a changed folder, re-update it while we're here */ + CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); + changed = g_list_find(p->folders_changed, folder) != NULL; + if (changed) + p->folders_changed = g_list_remove(p->folders_changed, folder); + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); + if (changed) + vee_folder_build_folder(vf, folder, NULL); } else { camel_vee_folder_add_folder(vf, l->data); } @@ -449,6 +472,30 @@ camel_vee_folder_hash_folder(CamelFolder *folder, char buffer[8]) } } +static void vee_refresh_info(CamelFolder *folder, CamelException *ex) +{ + CamelVeeFolder *vf = (CamelVeeFolder *)folder; + struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); + GList *node; + + CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); + + node = p->folders_changed; + while (node) { + CamelFolder *f = node->data; + + if (vee_folder_build_folder(vf, f, ex) == -1) + break; + + node = node->next; + } + + g_list_free(p->folders_changed); + p->folders_changed = NULL; + + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); +} + static void vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) { @@ -472,6 +519,9 @@ vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) node = node->next; } + g_list_free(p->folders_changed); + p->folders_changed = NULL; + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); } @@ -964,6 +1014,17 @@ folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder /* if not auto-updating, only propagate changed/removed events, not added items */ if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) { + + CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); + /* add this folder to our changed folders list if we have stuff we can't catch easily */ + /* Unfortuantely if its a change that doesn't affect the match, we're still going to + rerun it :( */ + if (changes->uid_changed->len > 0 || changes->uid_added->len > 0) + if (g_list_find(vf->priv->folders_changed, sub) != NULL) + vf->priv->folders_changed = g_list_prepend(vf->priv->folders_changed, sub); + + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); + CAMEL_VEE_FOLDER_LOCK(vf, summary_lock); CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock); diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index dc3febc85d..b8974e5d44 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -160,6 +160,7 @@ struct _build_info { const char *top; guint32 flags; GPtrArray *infos; + GPtrArray *folders; }; static void @@ -188,8 +189,10 @@ build_info(char *name, CamelVeeFolder *folder, struct _build_info *data) ((CamelFolder *)folder)->full_name); info->full_name = g_strdup(((CamelFolder *)folder)->full_name); info->name = g_strdup(((CamelFolder *)folder)->name); - info->unread_message_count = camel_folder_get_unread_message_count((CamelFolder *)folder); + info->unread_message_count = -1; g_ptr_array_add(data->infos, info); + camel_object_ref((CamelObject *)folder); + g_ptr_array_add(data->folders, folder); } static CamelFolderInfo * @@ -197,15 +200,28 @@ vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExce { struct _build_info data; CamelFolderInfo *info; + int i; /* first, build the info list */ data.top = top; data.flags = flags; data.infos = g_ptr_array_new(); + data.folders = g_ptr_array_new(); CAMEL_STORE_LOCK(store, cache_lock); g_hash_table_foreach(store->folders, (GHFunc)build_info, &data); CAMEL_STORE_UNLOCK(store, cache_lock); + /* then make sure the unread counts are accurate */ + for (i=0;ilen;i++) { + CamelFolderInfo *info = data.infos->pdata[i]; + CamelFolder *folder = data.folders->pdata[i]; + + camel_folder_refresh_info(folder, NULL); + info->unread_message_count = camel_folder_get_unread_message_count(folder); + camel_object_unref((CamelObject *)folder); + } + g_ptr_array_free(data.folders, TRUE); + /* and always add UNMATCHED, if scanning from top/etc */ if (top == NULL || top[0] == 0 || strncmp(top, CAMEL_UNMATCHED_NAME, strlen(CAMEL_UNMATCHED_NAME)) == 0) { info = g_malloc0(sizeof(*info)); -- cgit