aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog20
-rw-r--r--camel/camel-private.h3
-rw-r--r--camel/camel-vee-folder.c63
-rw-r--r--camel/camel-vee-store.c18
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 <NotZed@Ximian.com>
+
+ * 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 <NotZed@Ximian.com>
* 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;i<data.infos->len;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));