Re: [evolution-patches] 63881 (dragging messages from vfolders)
- From: Edward Catmur <ed catmur co uk>
- To: Not Zed <notzed ximian com>
- Cc: asdf <evolution-patches lists ximian com>
- Subject: Re: [evolution-patches] 63881 (dragging messages from vfolders)
- Date: Sat, 11 Sep 2004 00:43:04 +0100
On Mon, 2004-08-30 at 14:05 +0800, Not Zed wrote:
>
> Hmm, if we're going to go to this much effort, i'd rather the
> unmatched folder was moved onto the vfolder store itself, and also be
> optional on that store. This seems to expose too many internals that
> the client code shouldn't need to know about in the first place.
OK, here's the patch, finally. The idea is to move folder_unmatched and
unmatched_uids to CamelVeeStore, and have them created at init time (not
optional currently but that wouldn't be difficult). I think this means
that a lock is not needed, as init is called before the constructed
object is returned so it won't reach other threads yet? Then, a
CamelVeeFolder created on a CamelVeeStore will pick up the
folder_unmatched and unmatched_uids, otherwise they remain NULL; this
can be tested by anything that accesses folder_unmatched.
This means:
* vtrash and junk folders now avoid the folder_unmatched code
* UNMATCHED could be made optional
* multiple UNMATCHED folders for multiple sets (stores) of vee-folders
would be possible
Unfortunately there's quite a bit of re-indenting and changes to
identifier names, so the diff is a little big. Also I've shuffled some
code to reduce the number of times (vf->folder_unmatched != NULL) is
tested. I'm fairly certain this will not break anything.
Changes in full (all in camel/):
* camel-vee-store.h (struct _CamelVeeStore): add folder_unmatched and
unmatched_uids members (previously camel-vee-folder.c global variables)
* camel-vee-store.c (camel_vee_store_init): set up unmatched_uids and
folder_unmatched members
(camel_vee_store_finalise): and free them
* camel-vee-folder.h (struct _CamelVeeFolder): add folder_unmatched and
unmatched_uids members mirroring those on CamelVeeStore
* camel-vee-folder.c: get rid of global variables folder_unmatched,
unmatched_uids, unmatched_lock, related macros
(various): adjust folder_unmatched and unmatched_uids to being on
CamelVeeStore rather than global, mirrored on CamelVeeFolder and NULL
there if parent store is not a CamelVeeStore; add tests to guard against
folder_unmatched and unmatched_uids being NULL
The patch is against the 1.5.94.1 release.
Ed
--- camel/camel-vee-folder.c 2004/09/09 17:46:36 1.1
+++ camel/camel-vee-folder.c 2004/09/10 14:29:48
@@ -85,16 +85,6 @@ static void folder_changed_remove_uid(Ca
static CamelFolderClass *camel_vee_folder_parent;
-/* a vfolder for unmatched messages */
-/* use folder_unmatched->summary_lock for access to unmatched_uids or appropriate internals, for consistency */
-static CamelVeeFolder *folder_unmatched;
-static GHashTable *unmatched_uids; /* a refcount of uid's that are matched by any rules */
-static pthread_mutex_t unmatched_lock = PTHREAD_MUTEX_INITIALIZER;
-/* only used to initialise folder_unmatched */
-#define UNMATCHED_LOCK() pthread_mutex_lock(&unmatched_lock)
-#define UNMATCHED_UNLOCK() pthread_mutex_unlock(&unmatched_lock)
-
-
CamelType
camel_vee_folder_get_type (void)
{
@@ -176,21 +166,28 @@ camel_vee_folder_finalise (CamelObject *
/* FIXME: check leaks */
node = p->folders;
- while (node) {
- CamelFolder *f = node->data;
+ if (vf == vf->folder_unmatched)
+ while (node) {
+ CamelFolder *f = node->data;
+
+ camel_object_unref((CamelObject *)f);
- if (vf != folder_unmatched) {
+ node = g_list_next(node);
+ }
+ else
+ while (node) {
+ CamelFolder *f = node->data;
+
camel_object_unhook_event((CamelObject *)f, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
camel_object_unhook_event((CamelObject *)f, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
camel_object_unhook_event((CamelObject *)f, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf);
/* this updates the vfolder */
if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0)
vee_folder_remove_folder(vf, f, FALSE);
- }
- camel_object_unref((CamelObject *)f);
+ camel_object_unref((CamelObject *)f);
- node = g_list_next(node);
- }
+ node = g_list_next(node);
+ }
g_free(vf->expression);
g_free(vf->vname);
@@ -226,24 +223,16 @@ vee_folder_construct (CamelVeeFolder *vf
/* should CamelVeeMessageInfo be subclassable ..? */
folder->summary = camel_folder_summary_new();
folder->summary->message_info_size = sizeof(CamelVeeMessageInfo);
+
+ if (CAMEL_IS_VEE_STORE (parent_store)) {
+ vf->folder_unmatched = ((CamelVeeStore *) parent_store)->folder_unmatched;
+ vf->unmatched_uids = ((CamelVeeStore *) parent_store)->unmatched_uids;
+ }
}
void
camel_vee_folder_construct(CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags)
{
- UNMATCHED_LOCK();
-
- /* setup unmatched folder if we haven't yet */
- if (folder_unmatched == NULL) {
- unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal);
- folder_unmatched = (CamelVeeFolder *)camel_object_new (camel_vee_folder_get_type ());
- d(printf("created foldeer unmatched %p\n", folder_unmatched));
-
- vee_folder_construct (folder_unmatched, parent_store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
- }
-
- UNMATCHED_UNLOCK();
-
vee_folder_construct (vf, parent_store, name, flags);
}
@@ -262,21 +251,9 @@ camel_vee_folder_new(CamelStore *parent_
{
CamelVeeFolder *vf;
char *tmp;
-
- UNMATCHED_LOCK();
-
- /* setup unmatched folder if we haven't yet */
- if (folder_unmatched == NULL) {
- unmatched_uids = g_hash_table_new(g_str_hash, g_str_equal);
- folder_unmatched = vf = (CamelVeeFolder *)camel_object_new(camel_vee_folder_get_type());
- d(printf("created foldeer unmatched %p\n", folder_unmatched));
- vee_folder_construct (vf, parent_store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
- }
-
- UNMATCHED_UNLOCK();
-
- if (strcmp(name, CAMEL_UNMATCHED_NAME) == 0) {
- vf = folder_unmatched;
+
+ if (CAMEL_IS_VEE_STORE(parent_store) && strcmp(name, CAMEL_UNMATCHED_NAME) == 0) {
+ vf = ((CamelVeeStore *)parent_store)->folder_unmatched;
camel_object_ref(vf);
} else {
vf = (CamelVeeFolder *)camel_object_new(camel_vee_folder_get_type());
@@ -342,7 +319,7 @@ camel_vee_folder_set_expression(CamelVee
void
camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
- struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched);
+ struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
int i;
if (vf == (CamelVeeFolder *)sub) {
@@ -365,17 +342,18 @@ camel_vee_folder_add_folder(CamelVeeFold
CAMEL_FOLDER_UNLOCK(vf, change_lock);
}
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL) {
+ struct _CamelVeeFolderPrivate *up = _PRIVATE(vf->folder_unmatched);
camel_object_ref((CamelObject *)sub);
up->folders = g_list_append(up->folders, sub);
- CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
+ CAMEL_FOLDER_LOCK(vf->folder_unmatched, change_lock);
/* update the freeze state of 'sub' to match Unmatched's freeze state */
- for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
+ for (i = 0; i < ((CamelFolder *)vf->folder_unmatched)->priv->frozen; i++)
camel_folder_freeze(sub);
- CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
+ CAMEL_FOLDER_UNLOCK(vf->folder_unmatched, change_lock);
}
CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
@@ -399,7 +377,7 @@ camel_vee_folder_add_folder(CamelVeeFold
void
camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
- struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched);
+ struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
int killun = FALSE;
int i;
@@ -428,36 +406,40 @@ camel_vee_folder_remove_folder(CamelVeeF
CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
- /* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
- if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
- while (g_list_find(up->folders, sub)) {
- killun = TRUE;
- up->folders = g_list_remove(up->folders, sub);
- camel_object_unref((CamelObject *)sub);
-
- /* undo the freeze state that Unmatched has imposed on this source folder */
- CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
- for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
- camel_folder_thaw(sub);
- CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
- }
- } else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
- if (g_list_find(up->folders, sub) != NULL) {
- up->folders = g_list_remove(up->folders, sub);
- camel_object_unref((CamelObject *)sub);
-
- /* undo the freeze state that Unmatched has imposed on this source folder */
- CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
- for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
- camel_folder_thaw(sub);
- CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
- }
- if (g_list_find(up->folders, sub) == NULL) {
- killun = TRUE;
+ if (vf->folder_unmatched != NULL) {
+ struct _CamelVeeFolderPrivate *up = _PRIVATE(vf->folder_unmatched);
+
+ CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, subfolder_lock);
+ /* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
+ if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
+ while (g_list_find(up->folders, sub)) {
+ killun = TRUE;
+ up->folders = g_list_remove(up->folders, sub);
+ camel_object_unref((CamelObject *)sub);
+
+ /* undo the freeze state that Unmatched has imposed on this source folder */
+ CAMEL_FOLDER_LOCK(vf->folder_unmatched, change_lock);
+ for (i = 0; i < ((CamelFolder *)vf->folder_unmatched)->priv->frozen; i++)
+ camel_folder_thaw(sub);
+ CAMEL_FOLDER_UNLOCK(vf->folder_unmatched, change_lock);
+ }
+ } else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
+ if (g_list_find(up->folders, sub) != NULL) {
+ up->folders = g_list_remove(up->folders, sub);
+ camel_object_unref((CamelObject *)sub);
+
+ /* undo the freeze state that Unmatched has imposed on this source folder */
+ CAMEL_FOLDER_LOCK(vf->folder_unmatched, change_lock);
+ for (i = 0; i < ((CamelFolder *)vf->folder_unmatched)->priv->frozen; i++)
+ camel_folder_thaw(sub);
+ CAMEL_FOLDER_UNLOCK(vf->folder_unmatched, change_lock);
+ }
+ if (g_list_find(up->folders, sub) == NULL) {
+ killun = TRUE;
+ }
}
+ CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, subfolder_lock);
}
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
vee_folder_remove_folder(vf, sub, killun);
@@ -691,7 +673,7 @@ vee_search_by_expression(CamelFolder *fo
CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
- if (vf != folder_unmatched)
+ if (vf != vf->folder_unmatched)
expr = g_strdup_printf ("(and %s %s)", vf->expression, expression);
else
expr = g_strdup (expression);
@@ -918,7 +900,7 @@ vee_folder_add_uid(CamelVeeFolder *vf, C
static void
vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
{
- int i, count, n, still, start, last;
+ int i, count, n, still = FALSE, start, last;
char *oldkey;
CamelFolder *folder = (CamelFolder *)vf;
char hash[8];
@@ -926,48 +908,49 @@ vee_folder_remove_folder(CamelVeeFolder
CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
void *oldval;
- if (vf == folder_unmatched)
+ if (vf == vf->folder_unmatched)
return;
- /* check if this folder is still to be part of unmatched */
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) {
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
- still = g_list_find(_PRIVATE(folder_unmatched)->folders, source) != NULL;
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
- camel_vee_folder_hash_folder(source, hash);
- } else {
- still = FALSE;
- }
-
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
- /* See if we just blow all uid's from this folder away from unmatched, regardless */
- if (killun) {
- start = -1;
- last = -1;
- count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
- for (i=0;i<count;i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
-
- if (mi) {
- if (mi->folder == source) {
- camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
- if (last == -1) {
- last = start = i;
- } else if (last+1 == i) {
- last = i;
- } else {
- camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
- i -= (last-start)+1;
- start = last = i;
+ if (vf->folder_unmatched != NULL) {
+ /* check if this folder is still to be part of unmatched */
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) {
+ CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, subfolder_lock);
+ still = g_list_find(_PRIVATE(vf->folder_unmatched)->folders, source) != NULL;
+ CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, subfolder_lock);
+ camel_vee_folder_hash_folder(source, hash);
+ }
+
+ CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, summary_lock);
+
+ /* See if we just blow all uid's from this folder away from unmatched, regardless */
+ if (killun) {
+ start = -1;
+ last = -1;
+ count = camel_folder_summary_count(((CamelFolder *)vf->folder_unmatched)->summary);
+ for (i=0;i<count;i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)vf->folder_unmatched)->summary, i);
+
+ if (mi) {
+ if (mi->folder == source) {
+ camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, camel_message_info_uid(mi));
+ if (last == -1) {
+ last = start = i;
+ } else if (last+1 == i) {
+ last = i;
+ } else {
+ camel_folder_summary_remove_range(((CamelFolder *)vf->folder_unmatched)->summary, start, last);
+ i -= (last-start)+1;
+ start = last = i;
+ }
}
+ camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
+ if (last != -1)
+ camel_folder_summary_remove_range(((CamelFolder *)vf->folder_unmatched)->summary, start, last);
}
- if (last != -1)
- camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
}
start = -1;
@@ -990,22 +973,22 @@ vee_folder_remove_folder(CamelVeeFolder
i -= (last-start)+1;
start = last = i;
}
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && vf->folder_unmatched != NULL) {
if (still) {
- if (g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+ if (g_hash_table_lookup_extended(vf->unmatched_uids, uid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
if (n == 1) {
- g_hash_table_remove(unmatched_uids, oldkey);
- if (vee_folder_add_uid(folder_unmatched, source, oldkey+8, hash))
- camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
+ g_hash_table_remove(vf->unmatched_uids, oldkey);
+ if (vee_folder_add_uid(vf->folder_unmatched, source, oldkey+8, hash))
+ camel_folder_change_info_add_uid(vf->folder_unmatched->changes, oldkey);
g_free(oldkey);
} else {
- g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
+ g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
}
}
} else {
- if (g_hash_table_lookup_extended(unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
- g_hash_table_remove(unmatched_uids, oldkey);
+ if (g_hash_table_lookup_extended(vf->unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
+ g_hash_table_remove(vf->unmatched_uids, oldkey);
g_free(oldkey);
}
}
@@ -1018,9 +1001,18 @@ vee_folder_remove_folder(CamelVeeFolder
if (last != -1)
camel_folder_summary_remove_range(folder->summary, start, last);
- if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- unmatched_changes = folder_unmatched->changes;
- folder_unmatched->changes = camel_folder_change_info_new();
+ if (vf->folder_unmatched) {
+ if (camel_folder_change_info_changed(vf->folder_unmatched->changes)) {
+ unmatched_changes = vf->folder_unmatched->changes;
+ vf->folder_unmatched->changes = camel_folder_change_info_new();
+ }
+
+ CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, summary_lock);
+
+ if (unmatched_changes) {
+ camel_object_trigger_event((CamelObject *)vf->folder_unmatched, "folder_changed", unmatched_changes);
+ camel_folder_change_info_free(unmatched_changes);
+ }
}
if (camel_folder_change_info_changed(vf->changes)) {
@@ -1028,14 +1020,8 @@ vee_folder_remove_folder(CamelVeeFolder
vf->changes = camel_folder_change_info_new();
}
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
- if (unmatched_changes) {
- camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
- camel_folder_change_info_free(unmatched_changes);
- }
-
if (vf_changes) {
camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf_changes);
camel_folder_change_info_free(vf_changes);
@@ -1054,19 +1040,21 @@ unmatched_check_uid(char *uidin, void *v
char *uid;
int n;
+ g_return_if_fail(u->vf->folder_unmatched != NULL);
+
uid = alloca(strlen(uidin)+9);
memcpy(uid, u->hash, 8);
strcpy(uid+8, uidin);
- n = GPOINTER_TO_INT(g_hash_table_lookup(unmatched_uids, uid));
+ n = GPOINTER_TO_INT(g_hash_table_lookup(u->vf->unmatched_uids, uid));
if (n == 0) {
- if (vee_folder_add_uid(folder_unmatched, u->source, uidin, u->hash))
- camel_folder_change_info_add_uid(folder_unmatched->changes, uid);
+ if (vee_folder_add_uid(u->vf->folder_unmatched, u->source, uidin, u->hash))
+ camel_folder_change_info_add_uid(u->vf->folder_unmatched->changes, uid);
} else {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)folder_unmatched)->summary, uid);
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)u->vf->folder_unmatched)->summary, uid);
if (mi) {
- camel_folder_summary_remove(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
- camel_folder_change_info_remove_uid(folder_unmatched->changes, uid);
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
+ camel_folder_summary_remove(((CamelFolder *)u->vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
+ camel_folder_change_info_remove_uid(u->vf->folder_unmatched->changes, uid);
+ camel_folder_summary_info_free(((CamelFolder *)u->vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
}
}
@@ -1082,12 +1070,12 @@ folder_added_uid(char *uidin, void *valu
if ( (mi = vee_folder_add_uid(u->vf, u->source, uidin, u->hash)) ) {
camel_folder_change_info_add_uid(u->vf->changes, camel_message_info_uid(mi));
- if (!CAMEL_IS_VEE_FOLDER(u->source)) {
- if (g_hash_table_lookup_extended(unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
+ if (!CAMEL_IS_VEE_FOLDER(u->source) && u->vf->unmatched_uids != NULL) {
+ if (g_hash_table_lookup_extended(u->vf->unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
- g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
+ g_hash_table_insert(u->vf->unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
} else {
- g_hash_table_insert(unmatched_uids, g_strdup(camel_message_info_uid(mi)), GINT_TO_POINTER(1));
+ g_hash_table_insert(u->vf->unmatched_uids, g_strdup(camel_message_info_uid(mi)), GINT_TO_POINTER(1));
}
}
}
@@ -1105,7 +1093,7 @@ vee_folder_build_folder(CamelVeeFolder *
struct _update_data u;
CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
- if (vf == folder_unmatched)
+ if (vf == vf->folder_unmatched)
return 0;
/* if we have no expression, or its been cleared, then act as if no matches */
@@ -1135,8 +1123,6 @@ vee_folder_build_folder(CamelVeeFolder *
if (g_hash_table_lookup(matchhash, all->pdata[i]) == NULL)
g_hash_table_insert(allhash, all->pdata[i], GINT_TO_POINTER (1));
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
-
/* scan, looking for "old" uid's to be removed */
start = -1;
last = -1;
@@ -1161,13 +1147,14 @@ vee_folder_build_folder(CamelVeeFolder *
}
camel_folder_change_info_remove_uid(vf->changes, camel_message_info_uid(mi));
if (!CAMEL_IS_VEE_FOLDER(source)
- && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+ && vf->unmatched_uids != NULL
+ && g_hash_table_lookup_extended(vf->unmatched_uids, uid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
if (n == 1) {
- g_hash_table_remove(unmatched_uids, oldkey);
+ g_hash_table_remove(vf->unmatched_uids, oldkey);
g_free(oldkey);
} else {
- g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
+ g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
}
}
} else {
@@ -1183,36 +1170,47 @@ vee_folder_build_folder(CamelVeeFolder *
/* now matchhash contains any new uid's, add them, etc */
g_hash_table_foreach(matchhash, (GHFunc)folder_added_uid, &u);
- /* scan unmatched, remove any that have vanished, etc */
- count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
- for (i=0;i<count;i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
+ if (vf->folder_unmatched != NULL) {
+ CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, summary_lock);
- if (mi) {
- if (mi->folder == source) {
- char *uid = (char *)camel_message_info_uid(mi);
+ /* scan unmatched, remove any that have vanished, etc */
+ count = camel_folder_summary_count(((CamelFolder *)vf->folder_unmatched)->summary);
+ for (i=0;i<count;i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)vf->folder_unmatched)->summary, i);
- if (g_hash_table_lookup(allhash, uid+8) == NULL) {
- /* no longer exists at all, just remove it entirely */
- camel_folder_summary_remove_index(((CamelFolder *)folder_unmatched)->summary, i);
- camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
- i--;
- } else {
- g_hash_table_remove(allhash, uid+8);
+ if (mi) {
+ if (mi->folder == source) {
+ char *uid = (char *)camel_message_info_uid(mi);
+
+ if (g_hash_table_lookup(allhash, uid+8) == NULL) {
+ /* no longer exists at all, just remove it entirely */
+ camel_folder_summary_remove_index(((CamelFolder *)vf->folder_unmatched)->summary, i);
+ camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, camel_message_info_uid(mi));
+ i--;
+ } else {
+ g_hash_table_remove(allhash, uid+8);
+ }
}
+ camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
- }
- /* now allhash contains all potentially new uid's for the unmatched folder, process */
- if (!CAMEL_IS_VEE_FOLDER(source))
- g_hash_table_foreach(allhash, (GHFunc)unmatched_check_uid, &u);
+ /* now allhash contains all potentially new uid's for the unmatched folder, process */
+ if (!CAMEL_IS_VEE_FOLDER(source))
+ g_hash_table_foreach(allhash, (GHFunc)unmatched_check_uid, &u);
+
+ /* copy any changes so we can raise them outside the lock */
+ if (camel_folder_change_info_changed(vf->folder_unmatched->changes)) {
+ unmatched_changes = vf->folder_unmatched->changes;
+ vf->folder_unmatched->changes = camel_folder_change_info_new();
+ }
+
+ CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, summary_lock);
- /* copy any changes so we can raise them outside the lock */
- if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- unmatched_changes = folder_unmatched->changes;
- folder_unmatched->changes = camel_folder_change_info_new();
+ if (unmatched_changes) {
+ camel_object_trigger_event((CamelObject *)vf->folder_unmatched, "folder_changed", unmatched_changes);
+ camel_folder_change_info_free(unmatched_changes);
+ }
}
if (camel_folder_change_info_changed(vf->changes)) {
@@ -1220,7 +1218,6 @@ vee_folder_build_folder(CamelVeeFolder *
vf->changes = camel_folder_change_info_new();
}
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
g_hash_table_destroy(matchhash);
@@ -1232,11 +1229,6 @@ vee_folder_build_folder(CamelVeeFolder *
camel_folder_search_free(f, match);
camel_folder_free_uids(f, all);
- if (unmatched_changes) {
- camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
- camel_folder_change_info_free(unmatched_changes);
- }
-
if (vf_changes) {
camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf_changes);
camel_folder_change_info_free(vf_changes);
@@ -1269,18 +1261,18 @@ folder_changed_add_uid(CamelFolder *sub,
vuid = camel_message_info_uid(vinfo);
camel_folder_change_info_add_uid(vf->changes, vuid);
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
- if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL) {
+ if (g_hash_table_lookup_extended(vf->unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
- g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
+ g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
} else {
- g_hash_table_insert(unmatched_uids, g_strdup(vuid), GINT_TO_POINTER (1));
+ g_hash_table_insert(vf->unmatched_uids, g_strdup(vuid), GINT_TO_POINTER (1));
}
- vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)folder_unmatched, vuid);
+ vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)vf->folder_unmatched, vuid);
if (vinfo) {
- camel_folder_change_info_remove_uid(folder_unmatched->changes, vuid);
- camel_folder_summary_remove(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)vinfo);
- camel_folder_free_message_info((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
+ camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, vuid);
+ camel_folder_summary_remove(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)vinfo);
+ camel_folder_free_message_info((CamelFolder *)vf->folder_unmatched, (CamelMessageInfo *)vinfo);
}
}
}
@@ -1305,33 +1297,33 @@ folder_changed_remove_uid(CamelFolder *s
camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL) {
if (keep) {
- if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
+ if (g_hash_table_lookup_extended(vf->unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
if (n == 1) {
- g_hash_table_remove(unmatched_uids, oldkey);
- if (vee_folder_add_uid(folder_unmatched, sub, uid, hash))
- camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
+ g_hash_table_remove(vf->unmatched_uids, oldkey);
+ if (vee_folder_add_uid(vf->folder_unmatched, sub, uid, hash))
+ camel_folder_change_info_add_uid(vf->folder_unmatched->changes, oldkey);
g_free(oldkey);
} else {
- g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
+ g_hash_table_insert(vf->unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
}
} else {
- if (vee_folder_add_uid(folder_unmatched, sub, uid, hash))
- camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
+ if (vee_folder_add_uid(vf->folder_unmatched, sub, uid, hash))
+ camel_folder_change_info_add_uid(vf->folder_unmatched->changes, oldkey);
}
} else {
- if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
- g_hash_table_remove(unmatched_uids, oldkey);
+ if (g_hash_table_lookup_extended(vf->unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
+ g_hash_table_remove(vf->unmatched_uids, oldkey);
g_free(oldkey);
}
- vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)folder_unmatched, vuid);
+ vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)vf->folder_unmatched, vuid);
if (vinfo) {
- camel_folder_change_info_remove_uid(folder_unmatched->changes, vuid);
- camel_folder_summary_remove_uid(((CamelFolder *)folder_unmatched)->summary, vuid);
- camel_folder_free_message_info((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
+ camel_folder_change_info_remove_uid(vf->folder_unmatched->changes, vuid);
+ camel_folder_summary_remove_uid(((CamelFolder *)vf->folder_unmatched)->summary, vuid);
+ camel_folder_free_message_info((CamelFolder *)vf->folder_unmatched, (CamelMessageInfo *)vinfo);
}
}
}
@@ -1341,7 +1333,7 @@ static void
folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8], CamelVeeFolder *vf)
{
char *vuid;
- CamelVeeMessageInfo *vinfo, *uinfo;
+ CamelVeeMessageInfo *vinfo, *uinfo = NULL;
CamelMessageInfo *info;
CamelFolder *folder = (CamelFolder *)vf;
@@ -1350,7 +1342,8 @@ folder_changed_change_uid(CamelFolder *s
strcpy(vuid+8, uid);
vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, vuid);
- uinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)folder_unmatched)->summary, vuid);
+ if (vf->folder_unmatched != NULL)
+ uinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)vf->folder_unmatched)->summary, vuid);
if (vinfo || uinfo) {
info = camel_folder_get_message_info(sub, uid);
if (info) {
@@ -1370,7 +1363,7 @@ folder_changed_change_uid(CamelFolder *s
camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
- if (uinfo) {
+ if (vf->folder_unmatched != NULL && uinfo) {
int changed = FALSE;
if (uinfo->info.flags != info->flags){
@@ -1381,9 +1374,9 @@ folder_changed_change_uid(CamelFolder *s
changed |= camel_flag_list_copy(&uinfo->info.user_flags, &info->user_flags);
changed |= camel_tag_list_copy(&uinfo->info.user_tags, &info->user_tags);
if (changed)
- camel_folder_change_info_change_uid(folder_unmatched->changes, vuid);
+ camel_folder_change_info_change_uid(vf->folder_unmatched->changes, vuid);
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
+ camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
}
camel_folder_free_message_info(sub, info);
@@ -1392,8 +1385,8 @@ folder_changed_change_uid(CamelFolder *s
folder_changed_remove_uid(sub, uid, hash, FALSE, vf);
camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
- if (uinfo)
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
+ if (vf->folder_unmatched != NULL && uinfo)
+ camel_folder_summary_info_free(((CamelFolder *)vf->folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
}
}
}
@@ -1478,7 +1471,8 @@ folder_changed_change(CamelSession *sess
}
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
+ if (vf->folder_unmatched != NULL)
+ CAMEL_VEE_FOLDER_LOCK(vf->folder_unmatched, summary_lock);
dd(printf("Vfolder '%s' subfolder changed '%s'\n", folder->full_name, sub->full_name));
dd(printf(" changed %d added %d removed %d\n", changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len));
@@ -1509,14 +1503,14 @@ folder_changed_change(CamelSession *sess
memcpy(vuid, hash, 8);
strcpy(vuid+8, uid);
- if (!CAMEL_IS_VEE_FOLDER(sub) && g_hash_table_lookup(unmatched_uids, vuid) == NULL) {
+ if (!CAMEL_IS_VEE_FOLDER(sub) && vf->folder_unmatched != NULL && g_hash_table_lookup(vf->unmatched_uids, vuid) == NULL) {
dd(printf(" adding uid '%s' to Unmatched [newly unmatched]\n", (char *)uid));
- vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)folder_unmatched, vuid);
+ vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)vf->folder_unmatched, vuid);
if (vinfo == NULL) {
- if (vee_folder_add_uid(folder_unmatched, sub, uid, hash))
- camel_folder_change_info_add_uid(folder_unmatched->changes, vuid);
+ if (vee_folder_add_uid(vf->folder_unmatched, sub, uid, hash))
+ camel_folder_change_info_add_uid(vf->folder_unmatched->changes, vuid);
} else {
- camel_folder_free_message_info((CamelFolder *)folder_unmatched, (CamelMessageInfo *)vinfo);
+ camel_folder_free_message_info((CamelFolder *)vf->folder_unmatched, (CamelMessageInfo *)vinfo);
}
}
}
@@ -1580,19 +1574,6 @@ folder_changed_change(CamelSession *sess
folder_changed_change_uid(sub, changed->pdata[i], hash, vf);
}
- if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- unmatched_changes = folder_unmatched->changes;
- folder_unmatched->changes = camel_folder_change_info_new();
- }
-
- if (camel_folder_change_info_changed(vf->changes)) {
- vf_changes = vf->changes;
- vf->changes = camel_folder_change_info_new();
- }
-
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
- CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
-
/* Cleanup stuff on our folder */
if (matches_added)
camel_folder_search_free(sub, matches_added);
@@ -1607,12 +1588,28 @@ folder_changed_change(CamelSession *sess
g_ptr_array_free(newchanged, TRUE);
g_free(vuid);
+
+ if (vf->folder_unmatched != NULL) {
+ if (camel_folder_change_info_changed(vf->folder_unmatched->changes)) {
+ unmatched_changes = vf->folder_unmatched->changes;
+ vf->folder_unmatched->changes = camel_folder_change_info_new();
+ }
+
+ CAMEL_VEE_FOLDER_UNLOCK(vf->folder_unmatched, summary_lock);
- if (unmatched_changes) {
- camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
- camel_folder_change_info_free(unmatched_changes);
+ if (unmatched_changes) {
+ camel_object_trigger_event((CamelObject *)vf->folder_unmatched, "folder_changed", unmatched_changes);
+ camel_folder_change_info_free(unmatched_changes);
+ }
}
-
+
+ if (camel_folder_change_info_changed(vf->changes)) {
+ vf_changes = vf->changes;
+ vf->changes = camel_folder_change_info_new();
+ }
+
+ CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
+
if (vf_changes) {
/* If not auto-updating, keep track of changed folders for later re-sync */
if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) {
@@ -1698,10 +1695,10 @@ subfolder_renamed_update(CamelVeeFolder
camel_folder_change_info_add_uid(vf->changes, camel_message_info_uid(vinfo));
/* check unmatched uid's table for any matches */
- if (vf == folder_unmatched
- && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
- g_hash_table_remove(unmatched_uids, oldkey);
- g_hash_table_insert(unmatched_uids, g_strdup(camel_message_info_uid(vinfo)), oldval);
+ if (vf == vf->folder_unmatched
+ && g_hash_table_lookup_extended(vf->unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+ g_hash_table_remove(vf->unmatched_uids, oldkey);
+ g_hash_table_insert(vf->unmatched_uids, g_strdup(camel_message_info_uid(vinfo)), oldval);
g_free(oldkey);
}
}
@@ -1735,7 +1732,8 @@ subfolder_renamed(CamelFolder *f, void *
camel_vee_folder_hash_folder(f, hash);
subfolder_renamed_update(vf, f, hash);
- subfolder_renamed_update(folder_unmatched, f, hash);
+ if (vf->folder_unmatched != NULL)
+ subfolder_renamed_update(vf->folder_unmatched, f, hash);
}
static void
--- camel/camel-vee-folder.h 2004/09/09 17:46:38 1.1
+++ camel/camel-vee-folder.h 2004/09/10 12:41:51
@@ -56,6 +56,9 @@ struct _CamelVeeFolder {
CamelFolderChangeInfo *changes;
CamelFolderSearch *search;
+
+ CamelVeeFolder *folder_unmatched; /* for ease of access */
+ GHashTable *unmatched_uids;
};
struct _CamelVeeFolderClass {
--- camel/camel-vee-store.c 2004/09/09 17:46:42 1.1
+++ camel/camel-vee-store.c 2004/09/10 12:41:51
@@ -92,12 +92,18 @@ camel_vee_store_init (CamelVeeStore *obj
/* we dont want a vtrash/vjunk on this one */
store->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK);
+
+ /* Set up unmatched folder */
+ obj->unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal);
+ obj->folder_unmatched = (CamelVeeFolder *)camel_object_new (camel_vee_folder_get_type ());
+ camel_vee_folder_construct (obj->folder_unmatched, store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
}
static void
camel_vee_store_finalise (CamelObject *obj)
{
- ;
+ g_hash_table_destroy (((CamelVeeStore *)obj)->unmatched_uids);
+ camel_object_unref (((CamelVeeStore *)obj)->folder_unmatched);
}
/**
--- camel/camel-vee-store.h 2004/09/09 17:46:43 1.1
+++ camel/camel-vee-store.h 2004/09/10 12:41:51
@@ -30,6 +30,7 @@ extern "C" {
#include <glib.h>
#include <camel/camel-store.h>
+#include <camel/camel-vee-folder.h>
#define CAMEL_VEE_STORE(obj) CAMEL_CHECK_CAST (obj, camel_vee_store_get_type (), CamelVeeStore)
#define CAMEL_VEE_STORE_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_store_get_type (), CamelVeeStoreClass)
@@ -44,6 +45,9 @@ typedef struct _CamelVeeStoreClass Camel
struct _CamelVeeStore {
CamelStore parent;
+ /* Unmatched folder, set up in camel_vee_store_init */
+ CamelVeeFolder *folder_unmatched;
+ GHashTable *unmatched_uids;
};
struct _CamelVeeStoreClass {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]