aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-folder.c
diff options
context:
space:
mode:
author8 <NotZed@Ximian.com>2001-09-19 05:43:00 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-09-19 05:43:00 +0800
commit8347ce1403c68a408a3b9952f6486b5ac584104b (patch)
tree3df009be2f1e694e277133818acb872904d10392 /camel/camel-folder.c
parent390621f624b0be7485abdba29d0fe46c905156c8 (diff)
downloadgsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.tar.gz
gsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.tar.zst
gsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.zip
If filter inbox is set on the store, and we're opening inbox '', then
2001-09-18 <NotZed@Ximian.com> * providers/local/camel-maildir-folder.c (camel_maildir_folder_new): If filter inbox is set on the store, and we're opening inbox '', then enable filtering on new messages. * providers/local/camel-local-folder.c (camel_local_folder_construct): After loading the summary, check it, and only abort if that fails. Also maintain the changes count. * providers/local/camel-local-summary.c (camel_local_summary_load): Remove summary_check code from here. (camel_local_summary_check): Sync index/summary here, if we were successful. * providers/local/camel-spool-folder.c (camel_spool_folder_new): If we have filter-new-messages-on-inbox set and we just opened inbox, turn on filtering on this folder. (camel_spool_folder_construct): Keep track of changes for the folder, so that filter-new-messages works right (?) * providers/local/camel-spool-store.c (get_folder): Pass 'INBOX' as the folder name, not the path. * camel-folder-search.c (search_not): Modified patch from <peterw@ximian.com> since the summary is messageinfo's, not strings. ** Ok so the problem with the stuff below is that maildir/spool 'summary_load' throws away all events, including recents, joy eh? * providers/local/camel-maildir-summary.c (maildir_summary_check): Add new messages to the recent changeinfo. * providers/local/camel-spool-summary.c: Mark 'new' message as recent, for later processing if required (i.e. 'filter new messages'). * camel-store.c (construct): new function, cascade up construct method and check for 'filter' param, and set accordingly for any one that might want it. * providers/imap/camel-imap-store.c (construct): map the param_filter_inbox flag to the store->flags as CAMEL_STORE_FILTER_INBOX. * camel-store.h (CAMEL_STORE_FILTER_INBOX): new flag to tell it to filter inbox. * providers/imap/camel-imap-folder.h: Removed do_filtering flag from CamelImapFolder. * providers/imap/camel-imap-folder.c (imap_update_summary): Remove the 'recents' parameter, use the 'changes' parameter instead to convey this info. (camel_imap_folder_changed): Changed for update_summary api change. Now always just emit the changed event if we have any changes to report, filtering code removed, handled upstream. (filter_proc): (filter_free): Removed old filtering code. (camel_imap_folder_new): Set the filter_recent flag on the folder if we're the inbox and filtering of inbox is enabled. * camel-folder.c (folder_changed): If we have 'recent' messages, and are set to filter recents, then freeze the folder and launch a thread to do the processing (or similar if threading not enabled). (thaw): Make sure we emit the changed signal outside of owning the lock and if things have changed. Also, no longer bother downgrading folder_changed events to message_changed events. * camel-folder.h (struct _CamelFolder): Added filter_recent flag -> signifies all recent messages in folder should be filtered. * camel-session.c: (camel_session_thread_msg_new, camel_session_thread_msg_free, camel_session_thread_queue, camel_session_thread_wait): code to handle async operations as part of camel processing. (camel_session_finalise): free thread_lock, destroy thread, active hash, etc. (camel_session_init): init thread, active hash, etc. (camel_session_class_init): Init virtual functions. (session_thread_msg_new, session_thread_msg_free, session_thread_destroy, session_thread_received, session_thread_queue, session_thread_wait): default implementation of session threads stuff. 2001-09-17 <NotZed@Ximian.com> * camel-folder.c (camel_folder_change_info_recent_uid): New function to add a 'recent' uid to the change info. (camel_folder_change_info_clear): Clear recent list. (camel_folder_change_info_free): Free recent list. (camel_folder_change_info_new): Setup recent list. * camel-folder.h: Added a uid_recent item to the folder_changed event data. * providers/local/camel-maildir-store.c (scan_dir): Free new in the right block. * providers/local/camel-local-provider.c: Add local config entries to filter on new messages in spool and maildir provider. * camel-vee-folder.c (vee_folder_construct): Remove the assertion which stops ? in names from being allowed. svn path=/trunk/; revision=12956
Diffstat (limited to 'camel/camel-folder.c')
-rw-r--r--camel/camel-folder.c144
1 files changed, 119 insertions, 25 deletions
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index dc93443c7c..dd76c36673 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -36,6 +36,8 @@
#include "e-util/e-memory.h"
#include "camel-operation.h"
+#include "camel-session.h"
+#include "camel-filter-driver.h"
#include "camel-private.h"
#define d(x)
@@ -1257,7 +1259,7 @@ freeze (CamelFolder *folder)
folder->priv->frozen++;
- d(printf ("freeze(%p) = %d\n", folder, folder->priv->frozen));
+ d(printf ("freeze(%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
CAMEL_FOLDER_UNLOCK(folder, change_lock);
}
@@ -1281,31 +1283,26 @@ camel_folder_freeze (CamelFolder * folder)
static void
thaw (CamelFolder * folder)
{
- int i;
- CamelFolderChangeInfo *info;
+ CamelFolderChangeInfo *info = NULL;
CAMEL_FOLDER_LOCK(folder, change_lock);
folder->priv->frozen--;
- d(printf ("thaw(%p) = %d\n", folder, folder->priv->frozen));
+ d(printf ("thaw(%p '%s') = %d\n", folder, folder->full_name, folder->priv->frozen));
- if (folder->priv->frozen == 0) {
- /* If we have more or less messages, do a folder changed, otherwise just
- do a message changed for each one.
- TODO: message_changed is now probably irrelevant and not required */
+ if (folder->priv->frozen == 0
+ && camel_folder_change_info_changed(folder->priv->changed_frozen)) {
info = folder->priv->changed_frozen;
- if (info->uid_added->len > 0 || info->uid_removed->len > 0 || info->uid_changed->len > 10) {
- camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", info);
- } else if (info->uid_changed->len > 0) {
- for (i=0;i<info->uid_changed->len;i++) {
- camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", info->uid_changed->pdata[i]);
- }
- }
- camel_folder_change_info_clear(info);
+ folder->priv->changed_frozen = camel_folder_change_info_new();
}
-
+
CAMEL_FOLDER_UNLOCK(folder, change_lock);
+
+ if (info) {
+ camel_object_trigger_event(CAMEL_OBJECT(folder), "folder_changed", info);
+ camel_folder_change_info_free(info);
+ }
}
/**
@@ -1344,6 +1341,43 @@ camel_folder_is_frozen (CamelFolder *folder)
return CF_CLASS (folder)->is_frozen (folder);
}
+#ifdef ENABLE_THREADS
+struct _folder_filter_msg {
+ CamelSessionThreadMsg msg;
+
+ GPtrArray *recents;
+ CamelFolder *folder;
+ CamelFilterDriver *driver;
+ CamelException ex;
+};
+
+static void
+filter_filter(CamelSession *session, CamelSessionThreadMsg *msg)
+{
+ struct _folder_filter_msg *m = (struct _folder_filter_msg *)msg;
+
+ camel_filter_driver_filter_folder(m->driver, m->folder, NULL, m->recents, FALSE, &m->ex);
+}
+
+static void
+filter_free(CamelSession *session, CamelSessionThreadMsg *msg)
+{
+ struct _folder_filter_msg *m = (struct _folder_filter_msg *)msg;
+ int i;
+
+ camel_folder_thaw(m->folder);
+ camel_object_unref((CamelObject *)m->folder);
+ camel_object_unref((CamelObject *)m->driver);
+ for (i=0;i<m->recents->len;i++)
+ g_free(m->recents->pdata[i]);
+ g_ptr_array_free(m->recents, TRUE);
+}
+
+static CamelSessionThreadOps filter_ops = {
+ filter_filter,
+ filter_free,
+};
+#endif
/* Event hooks that block emission when frozen */
static gboolean
@@ -1354,18 +1388,56 @@ folder_changed (CamelObject *obj, gpointer event_data)
gboolean ret = TRUE;
d(printf ("folder_changed(%p, %p), frozen=%d\n", obj, event_data, folder->priv->frozen));
+ d(printf(" added %d remoded %d changed %d recent %d\n",
+ changed->uid_added->len, changed->uid_removed->len,
+ changed->uid_changed->len, changed->uid_recent->len));
- if (folder->priv->frozen) {
- CAMEL_FOLDER_LOCK(folder, change_lock);
+ if (changed != NULL) {
+ CamelSession *session = ((CamelService *)folder->parent_store)->session;
+ CamelFilterDriver *driver;
- if (changed != NULL)
+ CAMEL_FOLDER_LOCK(folder, change_lock);
+ if (folder->filter_recent
+ && changed->uid_recent->len>0
+ && (driver = camel_session_get_filter_driver(session, "incoming", NULL))) {
+#ifdef ENABLE_THREADS
+ GPtrArray *recents = g_ptr_array_new();
+ int i;
+ struct _folder_filter_msg *msg;
+
+ (printf("** Have '%d' recent messages, launching thread to process them\n", changed->uid_recent->len));
+
+ folder->priv->frozen++;
+ msg = camel_session_thread_msg_new(session, &filter_ops, sizeof(*msg));
+ for (i=0;i<changed->uid_recent->len;i++)
+ g_ptr_array_add(recents, g_strdup(changed->uid_recent->pdata[i]));
+ msg->recents = recents;
+ msg->folder = folder;
+ camel_object_ref((CamelObject *)folder);
+ msg->driver = driver;
+ camel_exception_init(&msg->ex);
+ camel_session_thread_queue(session, &msg->msg, 0);
+#else
+ d(printf("Have '%d' recent messages, filtering\n", changed->recent->len));
+ folder->priv->frozen++;
+ camel_filter_driver_filter_folder(driver, folder, NULL, changed->recent, FALSE, NULL);
+ camel_object_unref((CamelObject *)driver);
+ folder->priv->frozen--;
+#endif
+ /* zero out the recent list so we dont reprocess */
+ /* this pokes past abstraction, but changeinfo is our structure anyway */
+ /* the only other alternative is to recognise when trigger is called from
+ thaw(), but thats a pita */
+ g_ptr_array_set_size(changed->uid_recent, 0);
+ }
+ if (folder->priv->frozen) {
camel_folder_change_info_cat(folder->priv->changed_frozen, changed);
- else
+ ret = FALSE;
+ }
+ CAMEL_FOLDER_UNLOCK(folder, change_lock);
+ } else {
g_warning("Class %s is passing NULL to folder_changed event",
camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
- ret = FALSE;
-
- CAMEL_FOLDER_UNLOCK(folder, change_lock);
}
return ret;
@@ -1468,6 +1540,7 @@ camel_folder_change_info_new(void)
info->uid_added = g_ptr_array_new();
info->uid_removed = g_ptr_array_new();
info->uid_changed = g_ptr_array_new();
+ info->uid_recent = g_ptr_array_new();
info->priv = g_malloc0(sizeof(*info->priv));
info->priv->uid_stored = g_hash_table_new(g_str_hash, g_str_equal);
info->priv->uid_source = NULL;
@@ -1648,6 +1721,7 @@ camel_folder_change_info_cat(CamelFolderChangeInfo *info, CamelFolderChangeInfo
change_info_cat(info, source->uid_added, camel_folder_change_info_add_uid);
change_info_cat(info, source->uid_removed, camel_folder_change_info_remove_uid);
change_info_cat(info, source->uid_changed, camel_folder_change_info_change_uid);
+ change_info_cat(info, source->uid_recent, camel_folder_change_info_recent_uid);
}
/**
@@ -1745,6 +1819,24 @@ camel_folder_change_info_change_uid(CamelFolderChangeInfo *info, const char *uid
g_hash_table_insert(p->uid_stored, olduid, info->uid_changed);
}
+void
+camel_folder_change_info_recent_uid(CamelFolderChangeInfo *info, const char *uid)
+{
+ struct _CamelFolderChangeInfoPrivate *p;
+ GPtrArray *olduids;
+ char *olduid;
+
+ g_assert(info != NULL);
+
+ p = info->priv;
+
+ /* always add to recent, but dont let anyone else know */
+ if (!g_hash_table_lookup_extended(p->uid_stored, uid, (void **)&olduid, (void **)&olduids)) {
+ olduid = e_mempool_strdup(p->uid_pool, uid);
+ }
+ g_ptr_array_add(info->uid_recent, olduid);
+}
+
/**
* camel_folder_change_info_changed:
* @info:
@@ -1758,7 +1850,7 @@ camel_folder_change_info_changed(CamelFolderChangeInfo *info)
{
g_assert(info != NULL);
- return (info->uid_added->len || info->uid_removed->len || info->uid_changed->len);
+ return (info->uid_added->len || info->uid_removed->len || info->uid_changed->len || info->uid_recent->len);
}
/**
@@ -1779,6 +1871,7 @@ camel_folder_change_info_clear(CamelFolderChangeInfo *info)
g_ptr_array_set_size(info->uid_added, 0);
g_ptr_array_set_size(info->uid_removed, 0);
g_ptr_array_set_size(info->uid_changed, 0);
+ g_ptr_array_set_size(info->uid_recent, 0);
if (p->uid_source) {
g_hash_table_destroy(p->uid_source);
p->uid_source = NULL;
@@ -1813,5 +1906,6 @@ camel_folder_change_info_free(CamelFolderChangeInfo *info)
g_ptr_array_free(info->uid_added, TRUE);
g_ptr_array_free(info->uid_removed, TRUE);
g_ptr_array_free(info->uid_changed, TRUE);
+ g_ptr_array_free(info->uid_recent, TRUE);
g_free(info);
}