aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-vee-folder.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2001-03-29 10:03:06 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-03-29 10:03:06 +0800
commit90f1194b43faa8dba68271439c20607f3a723187 (patch)
treeaad0625ad20eb54cd39e782379b6f412fa8e2a7a /camel/camel-vee-folder.c
parentf4f6f8ceb5c086d92b6e4c16bdaa97289e09b709 (diff)
downloadgsoc2013-evolution-90f1194b43faa8dba68271439c20607f3a723187.tar.gz
gsoc2013-evolution-90f1194b43faa8dba68271439c20607f3a723187.tar.zst
gsoc2013-evolution-90f1194b43faa8dba68271439c20607f3a723187.zip
Access the folder directly from the message info.
2001-03-29 Not Zed <NotZed@Ximian.com> * camel-vtrash-folder.c (vtrash_move_messages_to): Access the folder directly from the message info. (vtrash_move_messages_to): I think we also need to call the real move_messages_to, and not try and bypass the lock, since we dont have the lock for that folder. * camel-vee-folder.h: Move CamelVeeMessageInfo to public, so subclasses can get to it. * camel-vee-folder.c (camel_vee_folder_add_folder): Dont let you add a vfolder to itself. (folder_changed): (vee_folder_remove_folder): (vee_folder_build_folder): Copy changes before triggering changed events, so we can do them outside of locks. (camel_vee_folder_get_message_folder): Removed function. (camel_vee_folder_hash_folder): Made public (renamed from hash_folder), simply for subclasses (probably not needed). svn path=/trunk/; revision=9004
Diffstat (limited to 'camel/camel-vee-folder.c')
-rw-r--r--camel/camel-vee-folder.c187
1 files changed, 95 insertions, 92 deletions
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index b6dba402f1..a4585eec17 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -42,16 +42,8 @@
#define d(x)
-/* our message info includes the parent folder */
-typedef struct _CamelVeeMessageInfo {
- CamelMessageInfo info;
- CamelFolder *folder;
-} CamelVeeMessageInfo;
-
#define _PRIVATE(o) (((CamelVeeFolder *)(o))->priv)
-static void hash_folder(CamelFolder *folder, char buffer[8]);
-
static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
static void vee_expunge (CamelFolder *folder, CamelException *ex);
@@ -319,6 +311,11 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched);
+ if (vf == (CamelVeeFolder *)sub) {
+ g_warning("Adding a virtual folder to itself as source, ignored");
+ return;
+ }
+
CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
/* for normal vfolders we want only unique ones, for unmatched we want them all recorded */
@@ -372,6 +369,39 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
camel_object_unref((CamelObject *)sub);
}
+/**
+ * camel_vee_folder_hash_folder:
+ * @folder:
+ * @:
+ *
+ * Create a hash string representing the folder name, which should be
+ * unique, and remain static for a given folder.
+ **/
+void
+camel_vee_folder_hash_folder(CamelFolder *folder, char buffer[8])
+{
+ MD5Context ctx;
+ unsigned char digest[16];
+ unsigned int state = 0, save = 0;
+ char *tmp;
+ int i;
+
+ md5_init(&ctx);
+ tmp = camel_service_get_url((CamelService *)folder->parent_store);
+ md5_update(&ctx, tmp, strlen(tmp));
+ g_free(tmp);
+ md5_update(&ctx, folder->full_name, strlen(folder->full_name));
+ md5_final(&ctx, digest);
+ base64_encode_close(digest, 6, FALSE, buffer, &state, &save);
+
+ for (i=0;i<8;i++) {
+ if (buffer[i] == '+')
+ buffer[i] = '.';
+ if (buffer[i] == '/')
+ buffer[i] = '_';
+ }
+}
+
static void
vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex)
{
@@ -444,7 +474,7 @@ vee_search_by_expression(CamelFolder *folder, const char *expression, CamelExcep
/* make sure we only search each folder once - for unmatched folder to work right */
if (g_hash_table_lookup(searched, f) == NULL) {
- hash_folder(f, hash);
+ camel_vee_folder_hash_folder(f, hash);
matches = camel_folder_search_by_expression(f, expression, ex);
for (i = 0; i < matches->len; i++) {
char *uid = matches->pdata[i];
@@ -518,32 +548,6 @@ vee_move_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *dest, C
/* ********************************************************************** *
utility functions */
-/* convert a folder name (full path) into a 8 character identifier that should be static */
-static void
-hash_folder(CamelFolder *folder, char buffer[8])
-{
- MD5Context ctx;
- unsigned char digest[16];
- unsigned int state = 0, save = 0;
- char *tmp;
- int i;
-
- md5_init(&ctx);
- tmp = camel_service_get_url((CamelService *)folder->parent_store);
- md5_update(&ctx, tmp, strlen(tmp));
- g_free(tmp);
- md5_update(&ctx, folder->full_name, strlen(folder->full_name));
- md5_final(&ctx, digest);
- base64_encode_close(digest, 6, FALSE, buffer, &state, &save);
-
- for (i=0;i<8;i++) {
- if (buffer[i] == '+')
- buffer[i] = '.';
- if (buffer[i] == '/')
- buffer[i] = '_';
- }
-}
-
/* must be called with summary_lock held */
static CamelVeeMessageInfo *
vee_folder_add_info(CamelVeeFolder *vf, CamelFolder *f, CamelMessageInfo *info, const char hash[8])
@@ -602,6 +606,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
CamelFolder *folder = (CamelFolder *)vf;
char hash[8];
struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
+ CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
if (vf == folder_unmatched)
return;
@@ -611,7 +616,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
still = g_list_find(p->folders, source) != NULL;
CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
- hash_folder(source, hash);
+ camel_vee_folder_hash_folder(source, hash);
} else {
still = FALSE;
}
@@ -654,19 +659,28 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
}
}
- if (camel_folder_change_info_changed(vf->changes)) {
- camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf->changes);
- camel_folder_change_info_clear(vf->changes);
+ 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(folder_unmatched->changes)) {
- camel_object_trigger_event((CamelObject *)vf, "folder_changed", folder_unmatched->changes);
- camel_folder_change_info_clear(folder_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(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);
+ }
}
struct _update_data {
@@ -725,6 +739,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
CamelFolder *folder = (CamelFolder *)vf;
int i, n, count;
struct _update_data u;
+ CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
if (vf == folder_unmatched)
return 0;
@@ -735,7 +750,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
u.source = source;
u.vf = vf;
- hash_folder(source, u.hash);
+ camel_vee_folder_hash_folder(source, u.hash);
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
@@ -810,26 +825,35 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
/* now allhash contains all potentially new uid's for the unmatched folder, process */
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(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);
g_hash_table_destroy(matchhash);
g_hash_table_destroy(allhash);
camel_folder_search_free(f, match);
camel_folder_free_uids(f, all);
- if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", folder_unmatched->changes);
- camel_folder_change_info_clear(folder_unmatched->changes);
+ if (unmatched_changes) {
+ camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
+ camel_folder_change_info_free(unmatched_changes);
}
-
- if (camel_folder_change_info_changed(vf->changes)) {
- camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf->changes);
- camel_folder_change_info_clear(vf->changes);
+ if (vf_changes) {
+ camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf_changes);
+ camel_folder_change_info_free(vf_changes);
}
- CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
-
return 0;
}
@@ -875,8 +899,9 @@ folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder
CamelMessageInfo *info;
char *oldkey;
int n;
+ CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
- hash_folder(sub, hash);
+ camel_vee_folder_hash_folder(sub, hash);
/* if not auto-updating, only propagate changed/removed events, not added items */
if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0) {
@@ -916,19 +941,29 @@ folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder
g_free(vuid);
}
- if (camel_folder_change_info_changed(vf->changes)) {
- camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf->changes);
- camel_folder_change_info_clear(vf->changes);
- }
-
if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", folder_unmatched->changes);
- camel_folder_change_info_clear(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);
+ 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);
+ }
+
return;
}
@@ -1013,35 +1048,3 @@ message_changed(CamelFolder *f, const char *uid, CamelVeeFolder *vf)
folder_changed(f, changes, vf);
camel_folder_change_info_free(changes);
}
-
-
-/**
- * camel_vee_folder_get_message_folder:
- * @vf: Virtual Folder object
- * @uid: message uid
- *
- * Returns the parent folder of @uid if it exists, otherwise NULL.
- * Note: You must unref the folder when finished with it.
- **/
-CamelFolder *
-camel_vee_folder_get_message_folder (CamelVeeFolder *vf, const gchar *uid)
-{
- CamelVeeMessageInfo *mi;
- CamelFolder *folder;
-
- CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
-
- mi = (CamelVeeMessageInfo *)camel_folder_summary_uid (CAMEL_FOLDER (vf)->summary, uid);
- if (mi) {
- camel_object_ref (CAMEL_OBJECT (mi->folder));
- folder = mi->folder;
- } else {
- folder = NULL;
- }
-
- CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
-
- return folder;
-}
-
-