aboutsummaryrefslogtreecommitdiffstats
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
parent390621f624b0be7485abdba29d0fe46c905156c8 (diff)
downloadgsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.tar
gsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.tar.gz
gsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.tar.bz2
gsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.tar.lz
gsoc2013-evolution-8347ce1403c68a408a3b9952f6486b5ac584104b.tar.xz
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
-rw-r--r--camel/ChangeLog107
-rw-r--r--camel/camel-filter-driver.c2
-rw-r--r--camel/camel-folder-search.c9
-rw-r--r--camel/camel-folder.c144
-rw-r--r--camel/camel-folder.h3
-rw-r--r--camel/camel-private.h5
-rw-r--r--camel/camel-session.c186
-rw-r--r--camel/camel-session.h35
-rw-r--r--camel/camel-store.c24
-rw-r--r--camel/camel-store.h1
-rw-r--r--camel/camel-vee-folder.c4
-rw-r--r--camel/providers/imap/camel-imap-folder.c93
-rw-r--r--camel/providers/imap/camel-imap-folder.h2
-rw-r--r--camel/providers/imap/camel-imap-store.c4
-rw-r--r--camel/providers/local/camel-local-folder.c6
-rw-r--r--camel/providers/local/camel-local-provider.c8
-rw-r--r--camel/providers/local/camel-local-store.c3
-rw-r--r--camel/providers/local/camel-local-summary.c19
-rw-r--r--camel/providers/local/camel-maildir-folder.c5
-rw-r--r--camel/providers/local/camel-maildir-store.c2
-rw-r--r--camel/providers/local/camel-maildir-summary.c4
-rw-r--r--camel/providers/local/camel-spool-folder.c9
-rw-r--r--camel/providers/local/camel-spool-store.c10
-rw-r--r--camel/providers/local/camel-spool-summary.c5
24 files changed, 544 insertions, 146 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 18bf3b6dac..89b8afddc8 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,110 @@
+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.
+
2001-09-18 Dan Winship <danw@ximian.com>
* camel-data-wrapper.c (camel_data_wrapper_is_offline): Virtualize
diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c
index e7a430cdff..c309776790 100644
--- a/camel/camel-filter-driver.c
+++ b/camel/camel-filter-driver.c
@@ -819,7 +819,7 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelFolder *folde
report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Complete"));
g_free (source_url);
-
+
return status;
}
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 873934b67d..4d644a256a 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -499,16 +499,19 @@ search_not(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSe
/* 'not' against the whole summary */
GHashTable *have = g_hash_table_new(g_str_hash, g_str_equal);
char **s;
+ CamelMessageInfo **m;
s = (char **)v->pdata;
for (i=0;i<v->len;i++)
g_hash_table_insert(have, s[i], s[i]);
v = search->summary;
- s = (char **)v->pdata;
+ m = (CamelMessageInfo **)v->pdata;
for (i=0;i<v->len;i++) {
- if (g_hash_table_lookup(have, s[i]) == NULL)
- g_ptr_array_add(r->value.ptrarray, s[i]);
+ char *uid = (char *)camel_message_info_uid(m[i]);
+
+ if (g_hash_table_lookup(have, uid) == NULL)
+ g_ptr_array_add(r->value.ptrarray, uid);
}
g_hash_table_destroy(have);
}
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);
}
diff --git a/camel/camel-folder.h b/camel/camel-folder.h
index af86a9c5ed..0ff542afb9 100644
--- a/camel/camel-folder.h
+++ b/camel/camel-folder.h
@@ -47,6 +47,7 @@ struct _CamelFolderChangeInfo {
GPtrArray *uid_added;
GPtrArray *uid_removed;
GPtrArray *uid_changed;
+ GPtrArray *uid_recent;
struct _CamelFolderChangeInfoPrivate *priv;
};
@@ -65,6 +66,7 @@ struct _CamelFolder
guint32 permanent_flags;
gboolean has_summary_capability:1;
gboolean has_search_capability:1;
+ gboolean filter_recent:1;
};
@@ -301,6 +303,7 @@ void camel_folder_change_info_cat (CamelFolderChangeInfo *info, CamelFolderCh
void camel_folder_change_info_add_uid (CamelFolderChangeInfo *info, const char *uid);
void camel_folder_change_info_remove_uid (CamelFolderChangeInfo *info, const char *uid);
void camel_folder_change_info_change_uid (CamelFolderChangeInfo *info, const char *uid);
+void camel_folder_change_info_recent_uid (CamelFolderChangeInfo *info, const char *uid);
#ifdef __cplusplus
}
diff --git a/camel/camel-private.h b/camel/camel-private.h
index 4fb5bdb461..34f393b00f 100644
--- a/camel/camel-private.h
+++ b/camel/camel-private.h
@@ -104,6 +104,11 @@ struct _CamelServicePrivate {
struct _CamelSessionPrivate {
#ifdef ENABLE_THREADS
GMutex *lock; /* for locking everything basically */
+ GMutex *thread_lock; /* locking threads */
+
+ int thread_id;
+ GHashTable *thread_active;
+ EThread *thread_queue;
#endif
};
diff --git a/camel/camel-session.c b/camel/camel-session.c
index a6e70bcd98..06b7bb8799 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -61,6 +61,12 @@ static char *get_storage_path (CamelSession *session,
CamelService *service,
CamelException *ex);
+#ifdef ENABLE_THREADS
+static void *session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size);
+static void session_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *msg);
+static int session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
+static void session_thread_wait(CamelSession *session, int id);
+#endif
/* The vfolder provider is always avilable */
static CamelProvider vee_provider = {
@@ -87,6 +93,10 @@ camel_session_init (CamelSession *session)
session->priv = g_malloc0(sizeof(*session->priv));
#ifdef ENABLE_THREADS
session->priv->lock = g_mutex_new();
+ session->priv->thread_lock = g_mutex_new();
+ session->priv->thread_id = 1;
+ session->priv->thread_active = g_hash_table_new(NULL, NULL);
+ session->priv->thread_queue = NULL;
#endif
}
@@ -105,6 +115,12 @@ camel_session_finalise (CamelObject *o)
{
CamelSession *session = (CamelSession *)o;
+#ifdef ENABLE_THREADS
+ g_hash_table_destroy(session->priv->thread_active);
+ if (session->priv->thread_queue)
+ e_thread_destroy(session->priv->thread_queue);
+#endif
+
g_free(session->storage_path);
g_hash_table_foreach_remove (session->providers,
camel_session_destroy_provider, NULL);
@@ -112,8 +128,8 @@ camel_session_finalise (CamelObject *o)
#ifdef ENABLE_THREADS
g_mutex_free(session->priv->lock);
-#endif
-
+ g_mutex_free(session->priv->thread_lock);
+#endif
g_free(session->priv);
}
@@ -127,6 +143,13 @@ camel_session_class_init (CamelSessionClass *camel_session_class)
camel_session_class->get_service = get_service;
camel_session_class->get_storage_path = get_storage_path;
+#ifdef ENABLE_THREADS
+ camel_session_class->thread_msg_new = session_thread_msg_new;
+ camel_session_class->thread_msg_free = session_thread_msg_free;
+ camel_session_class->thread_queue = session_thread_queue;
+ camel_session_class->thread_wait = session_thread_wait;
+#endif
+
if (vee_provider.service_cache == NULL) {
vee_provider.object_types[CAMEL_PROVIDER_STORE] = camel_vee_store_get_type ();
vee_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal);
@@ -686,3 +709,162 @@ camel_session_get_filter_driver (CamelSession *session,
{
return CS_CLASS (session)->get_filter_driver (session, type, ex);
}
+
+#ifdef ENABLE_THREADS
+
+static void *session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size)
+{
+ CamelSessionThreadMsg *m;
+
+ g_assert(size >= sizeof(*m));
+
+ m = g_malloc0(size);
+ m->ops = ops;
+
+ CAMEL_SESSION_LOCK(session, thread_lock);
+ m->id = session->priv->thread_id++;
+ g_hash_table_insert(session->priv->thread_active, (void *)m->id, m);
+ CAMEL_SESSION_UNLOCK(session, thread_lock);
+
+ return m;
+}
+
+static void session_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *msg)
+{
+ g_assert(msg->ops != NULL);
+
+ printf("free message %p session %p\n", msg, session);
+
+ CAMEL_SESSION_LOCK(session, thread_lock);
+ g_hash_table_remove(session->priv->thread_active, (void *)msg->id);
+ CAMEL_SESSION_UNLOCK(session, thread_lock);
+
+ printf("free msg, ops->free = %p\n", msg->ops->free);
+
+ if (msg->ops->free)
+ msg->ops->free(session, msg);
+ g_free(msg);
+}
+
+static void session_thread_destroy(EThread *thread, CamelSessionThreadMsg *msg, CamelSession *session)
+{
+ printf("destroy message %p session %p\n", msg, session);
+ session_thread_msg_free(session, msg);
+}
+
+static void session_thread_received(EThread *thread, CamelSessionThreadMsg *msg, CamelSession *session)
+{
+ printf("receive message %p session %p\n", msg, session);
+ if (msg->ops->receive)
+ msg->ops->receive(session, msg);
+}
+
+static int session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags)
+{
+ int id;
+
+ CAMEL_SESSION_LOCK(session, thread_lock);
+ if (session->priv->thread_queue == NULL) {
+ session->priv->thread_queue = e_thread_new(E_THREAD_QUEUE);
+ e_thread_set_msg_destroy(session->priv->thread_queue, (EThreadFunc)session_thread_destroy, session);
+ e_thread_set_msg_received(session->priv->thread_queue, (EThreadFunc)session_thread_received, session);
+ }
+ CAMEL_SESSION_UNLOCK(session, thread_lock);
+
+ id = msg->id;
+ e_thread_put(session->priv->thread_queue, &msg->msg);
+
+ return id;
+}
+
+static void session_thread_wait(CamelSession *session, int id)
+{
+ int wait;
+
+ /* we just busy wait, only other alternative is to setup a reply port? */
+ do {
+ CAMEL_SESSION_LOCK(session, thread_lock);
+ wait = g_hash_table_lookup(session->priv->thread_active, (void *)id) != NULL;
+ CAMEL_SESSION_UNLOCK(session, thread_lock);
+ if (wait) {
+ usleep(20000);
+ }
+ } while (wait);
+}
+
+/**
+ * camel_session_thread_msg_new:
+ * @session:
+ * @ops:
+ * @size:
+ *
+ * Create a new thread message, using ops as the receive/reply/free
+ * ops, of @size bytes.
+ *
+ * @ops points to the operations used to recieve/process and finally
+ * free the message.
+ **/
+void *camel_session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size)
+{
+ g_assert(CAMEL_IS_SESSION(session));
+ g_assert(ops != NULL);
+ g_assert(size >= sizeof(CamelSessionThreadMsg));
+
+ return CS_CLASS (session)->thread_msg_new(session, ops, size);
+}
+
+/**
+ * camel_session_thread_msg_free:
+ * @session:
+ * @msg:
+ *
+ * Free a @msg. Note that the message must have been allocated using
+ * msg_new, and must nto have been submitted to any queue function.
+ **/
+void camel_session_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *msg)
+{
+ g_assert(CAMEL_IS_SESSION(session));
+ g_assert(msg != NULL);
+ g_assert(msg->ops != NULL);
+
+ return CS_CLASS (session)->thread_msg_free(session, msg);
+}
+
+/**
+ * camel_session_thread_queue:
+ * @session:
+ * @msg:
+ * @flags: queue type flags, currently 0.
+ *
+ * Queue a thread message in another thread for processing.
+ * The operation should be (but needn't) run in a queued manner
+ * with other operations queued in this manner.
+ *
+ * Return value: The id of the operation queued.
+ **/
+int camel_session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags)
+{
+ g_assert(CAMEL_IS_SESSION(session));
+ g_assert(msg != NULL);
+
+ return CS_CLASS (session)->thread_queue(session, msg, flags);
+}
+
+/**
+ * camel_session_thread_wait:
+ * @session:
+ * @id:
+ *
+ * Wait on an operation to complete (by id).
+ **/
+void camel_session_thread_wait(CamelSession *session, int id)
+{
+ g_assert(CAMEL_IS_SESSION(session));
+
+ if (id == -1)
+ return;
+
+ return CS_CLASS (session)->thread_wait(session, id);
+}
+
+#endif
diff --git a/camel/camel-session.h b/camel/camel-session.h
index 54eea0b1e6..0ae292f452 100644
--- a/camel/camel-session.h
+++ b/camel/camel-session.h
@@ -37,6 +37,8 @@ extern "C" {
#include <camel/camel-object.h>
#include <camel/camel-provider.h>
+#include <e-util/e-msgport.h>
+
#define CAMEL_SESSION_TYPE (camel_session_get_type ())
#define CAMEL_SESSION(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SESSION_TYPE, CamelSession))
#define CAMEL_SESSION_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SESSION_TYPE, CamelSessionClass))
@@ -60,6 +62,11 @@ struct _CamelSession
gboolean online;
};
+#ifdef ENABLE_THREADS
+typedef struct _CamelSessionThreadOps CamelSessionThreadOps;
+typedef struct _CamelSessionThreadMsg CamelSessionThreadMsg;
+#endif
+
typedef struct {
CamelObjectClass parent_class;
@@ -104,6 +111,14 @@ typedef struct {
CamelFilterDriver * (*get_filter_driver) (CamelSession *session,
const char *type,
CamelException *ex);
+#ifdef ENABLE_THREADS
+ /* mechanism for creating and maintaining multiple threads of control */
+ void *(*thread_msg_new)(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size);
+ void (*thread_msg_free)(CamelSession *session, CamelSessionThreadMsg *msg);
+ int (*thread_queue)(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
+ void (*thread_wait)(CamelSession *session, int id);
+#endif
+
} CamelSessionClass;
@@ -175,6 +190,26 @@ CamelFilterDriver *camel_session_get_filter_driver (CamelSession *session,
const char *type,
CamelException *ex);
+#ifdef ENABLE_THREADS
+struct _CamelSessionThreadOps {
+ void (*receive)(CamelSession *session, struct _CamelSessionThreadMsg *m);
+ void (*free)(CamelSession *session, struct _CamelSessionThreadMsg *m);
+};
+
+struct _CamelSessionThreadMsg {
+ EMsg msg;
+
+ CamelSessionThreadOps *ops;
+ int id;
+ /* user fields follow */
+};
+
+void *camel_session_thread_msg_new(CamelSession *session, CamelSessionThreadOps *ops, unsigned int size);
+void camel_session_thread_msg_free(CamelSession *session, CamelSessionThreadMsg *msg);
+int camel_session_thread_queue(CamelSession *session, CamelSessionThreadMsg *msg, int flags);
+void camel_session_thread_wait(CamelSession *session, int id);
+#endif
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 9722163cec..489d269991 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -67,12 +67,17 @@ static gboolean folder_subscribed (CamelStore *store, const char *folder_name);
static void subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
static void unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
+static void construct (CamelService *service, CamelSession *session,
+ CamelProvider *provider, CamelURL *url,
+ CamelException *ex);
+
static void
camel_store_class_init (CamelStoreClass *camel_store_class)
{
CamelObjectClass *camel_object_class =
CAMEL_OBJECT_CLASS (camel_store_class);
-
+ CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_store_class);
+
parent_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ()));
/* virtual method definition */
@@ -93,6 +98,8 @@ camel_store_class_init (CamelStoreClass *camel_store_class)
camel_store_class->unsubscribe_folder = unsubscribe_folder;
/* virtual method overload */
+ camel_service_class->construct = construct;
+
camel_object_class_declare_event (camel_object_class,
"folder_created", NULL);
camel_object_class_declare_event (camel_object_class,
@@ -184,6 +191,21 @@ folder_finalize (CamelObject *folder, gpointer event_data, gpointer user_data)
}
}
+static void
+construct (CamelService *service, CamelSession *session,
+ CamelProvider *provider, CamelURL *url,
+ CamelException *ex)
+{
+ CamelStore *store = CAMEL_STORE(service);
+
+ parent_class->construct(service, session, provider, url, ex);
+ if (camel_exception_is_set (ex))
+ return;
+
+ if (camel_url_get_param(url, "filter"))
+ store->flags |= CAMEL_STORE_FILTER_INBOX;
+}
+
static CamelFolder *
get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
{
diff --git a/camel/camel-store.h b/camel/camel-store.h
index 6983524091..e86c884a1a 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -56,6 +56,7 @@ typedef struct _CamelFolderInfo {
/* Flags for store flags */
#define CAMEL_STORE_SUBSCRIPTIONS (1 << 0)
#define CAMEL_STORE_VTRASH (1 << 1)
+#define CAMEL_STORE_FILTER_INBOX (1 << 2)
struct _CamelStore
{
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index e2e224da92..b001536bd8 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -193,10 +193,6 @@ vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *
char *tmp;
vf->flags = flags;
-
- /* We dont support ? syntax anymore */
- g_assert(strchr(name, '?') == NULL);
-
vf->vname = g_strdup(name);
tmp = strrchr(vf->vname, '/');
if (tmp)
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index fc873f9e85..5d2a8ba146 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -50,7 +50,6 @@
#include "camel-data-wrapper.h"
#include "camel-disco-diary.h"
#include "camel-exception.h"
-#include "camel-filter-driver.h"
#include "camel-mime-filter-crlf.h"
#include "camel-mime-filter-from.h"
#include "camel-mime-message.h"
@@ -220,7 +219,7 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name,
if ((imap_store->parameters & IMAP_PARAM_FILTER_INBOX) &&
!g_strcasecmp (folder_name, "INBOX"))
- imap_folder->do_filtering = TRUE;
+ folder->filter_recent = TRUE;
return folder;
}
@@ -1586,7 +1585,6 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
static void
imap_update_summary (CamelFolder *folder, int exists,
CamelFolderChangeInfo *changes,
- GPtrArray *recents,
CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
@@ -1775,8 +1773,8 @@ imap_update_summary (CamelFolder *folder, int exists,
camel_folder_summary_add (folder->summary, mi);
camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
- if (recents && (mi->flags & CAMEL_IMAP_MESSAGE_RECENT))
- g_ptr_array_add (recents, (char *)camel_message_info_uid (mi));
+ if ((mi->flags & CAMEL_IMAP_MESSAGE_RECENT))
+ camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
}
g_ptr_array_free (messages, TRUE);
return;
@@ -1798,44 +1796,6 @@ imap_update_summary (CamelFolder *folder, int exists,
}
}
-struct _filter_msg {
- CamelImapMsg msg;
-
- GPtrArray *recents;
- CamelFolder *folder;
- CamelFilterDriver *driver;
-};
-
-static void
-filter_proc(CamelImapStore *store, CamelImapMsg *mm)
-{
- struct _filter_msg *msg = (struct _filter_msg *)mm;
-
- printf("executing filtering %d messages folder %p\n", msg->recents->len, msg->folder);
-
- /* what about exceptions? */
- camel_filter_driver_filter_folder(msg->driver, msg->folder, NULL, msg->recents, FALSE, NULL);
-}
-
-static void
-filter_free(CamelImapStore *store, CamelImapMsg *mm)
-{
- struct _filter_msg *msg = (struct _filter_msg *)mm;
- int i;
-
- printf("freeing filtering %d messages folder %p\n", msg->recents->len, msg->folder);
-
- camel_object_unref((CamelObject *)msg->driver);
-
- camel_folder_thaw(msg->folder);
- camel_object_unref((CamelObject *)msg->folder);
-
- for (i=0;i<msg->recents->len;i++)
- g_free(msg->recents->pdata[i]);
-
- g_ptr_array_free(msg->recents, TRUE);
-}
-
/* Called with the store's command_lock locked */
void
camel_imap_folder_changed (CamelFolder *folder, int exists,
@@ -1872,50 +1832,11 @@ camel_imap_folder_changed (CamelFolder *folder, int exists,
}
len = camel_folder_summary_count (folder->summary);
- if (exists > len) {
- if (imap_folder->do_filtering)
- recents = g_ptr_array_new ();
- imap_update_summary (folder, exists, changes, recents, ex);
- }
+ if (exists > len)
+ imap_update_summary (folder, exists, changes, ex);
- /* if we have updates to make for filtering (probably), then we freeze the
- folder so we dont show them till they're complete, this may cause unacceptable
- delays for users, but the alternative isn't very nice either (show them and let
- them change as processed) */
- if (recents && !camel_exception_is_set (ex) && recents->len) {
- CamelFilterDriver *driver;
-
- camel_folder_freeze (folder);
-
- if (camel_folder_change_info_changed (changes))
- camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
-
- driver = camel_session_get_filter_driver (CAMEL_SERVICE (folder->parent_store)->session, "incoming", ex);
- if (driver) {
-#ifdef ENABLE_THREADS
- int i;
- struct _filter_msg *msg = (struct _filter_msg *)camel_imap_msg_new(filter_proc, filter_free, sizeof(*msg));
-
- msg->recents = g_ptr_array_new();
- for (i=0;i<recents->len;i++)
- g_ptr_array_add(msg->recents, g_strdup(recents->pdata[i]));
-
- camel_object_ref((CamelObject *)folder);
- msg->folder = folder;
- msg->driver = driver;
- printf("queueing filtering %d messages folder %p\n", msg->recents->len, folder);
- camel_imap_msg_queue((CamelImapStore *)folder->parent_store, (CamelImapMsg *)msg);
-#else
- camel_filter_driver_filter_folder (driver, folder, NULL, recents, FALSE, ex);
- camel_folder_thaw (folder);
- camel_object_unref (CAMEL_OBJECT (driver));
-#endif
- } else
- camel_folder_thaw (folder);
- } else {
- if (camel_folder_change_info_changed (changes))
- camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
- }
+ if (camel_folder_change_info_changed (changes))
+ camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
camel_folder_change_info_free (changes);
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
index db507d52d5..295cfd041e 100644
--- a/camel/providers/imap/camel-imap-folder.h
+++ b/camel/providers/imap/camel-imap-folder.h
@@ -48,7 +48,7 @@ struct _CamelImapFolder {
struct _CamelImapFolderPrivate *priv;
- gboolean need_rescan, need_refresh, do_filtering;
+ gboolean need_rescan, need_refresh;
CamelFolderSearch *search;
CamelImapMessageCache *cache;
};
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index d4cf4fb16c..b58b97fa83 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -285,8 +285,10 @@ construct (CamelService *service, CamelSession *session,
}
if (camel_url_get_param (url, "check_all"))
imap_store->parameters |= IMAP_PARAM_CHECK_ALL;
- if (camel_url_get_param (url, "filter"))
+ if (camel_url_get_param (url, "filter")) {
imap_store->parameters |= IMAP_PARAM_FILTER_INBOX;
+ store->flags |= CAMEL_STORE_FILTER_INBOX;
+ }
}
static void
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index 811a71ecbe..927ca105ae 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -213,10 +213,14 @@ camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store, con
folder->summary = (CamelFolderSummary *)CLOCALF_CLASS(lf)->create_summary(lf->summary_path, lf->folder_path, lf->index);
if (camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, ex) == -1) {
+ camel_exception_clear(ex);
+ }
+
+ if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {
camel_object_unref (CAMEL_OBJECT (folder));
return NULL;
}
-
+
fi = g_new0 (CamelFolderInfo, 1);
fi->full_name = g_strdup (full_name);
fi->name = g_strdup (name);
diff --git a/camel/providers/local/camel-local-provider.c b/camel/providers/local/camel-local-provider.c
index 8a4047699f..606416fc37 100644
--- a/camel/providers/local/camel-local-provider.c
+++ b/camel/providers/local/camel-local-provider.c
@@ -55,6 +55,12 @@ static CamelProvider mbox_provider = {
/* ... */
};
+static CamelProviderConfEntry local_conf_entries[] = {
+ { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
+ N_("Apply filters to new messages in INBOX"), "0" },
+ { CAMEL_PROVIDER_CONF_END }
+};
+
static CamelProvider maildir_provider = {
"maildir",
N_("Qmail maildir-format mail files"),
@@ -62,6 +68,7 @@ static CamelProvider maildir_provider = {
"mail",
CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE,
CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE,
+ local_conf_entries,
/* ... */
};
@@ -72,6 +79,7 @@ static CamelProvider spool_provider = {
"mail",
CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE,
CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE,
+ local_conf_entries,
/* ... */
};
diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c
index fe8f09a911..43437b551a 100644
--- a/camel/providers/local/camel-local-store.c
+++ b/camel/providers/local/camel-local-store.c
@@ -190,6 +190,9 @@ get_folder_info (CamelStore *store, const char *top,
/* FIXME: This is broken, but it corresponds to what was
* there before.
*/
+
+ printf("-- LOCAL STRE -- get folder info: %s\n", top);
+
return NULL;
}
diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c
index c925e6e36a..3202076520 100644
--- a/camel/providers/local/camel-local-summary.c
+++ b/camel/providers/local/camel-local-summary.c
@@ -148,18 +148,12 @@ camel_local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException
if (forceindex
|| stat(s->summary_path, &st) == -1
|| ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->load(cls, forceindex, ex) == -1) {
+ g_warning("Could not load summary: flags may be reset");
camel_folder_summary_clear((CamelFolderSummary *)cls);
+ return -1;
}
- if (camel_local_summary_check(cls, NULL, ex) == 0) {
- if (camel_folder_summary_save(s) == -1)
- g_warning("Could not save summary for %s: %s", cls->folder_path, strerror(errno));
- if (cls->index && ibex_save(cls->index) == -1)
- g_warning("Could not sync index for %s: %s", cls->folder_path, strerror(errno));
-
- return 0;
- }
- return -1;
+ return 0;
}
char *
@@ -261,6 +255,13 @@ camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changei
ret = ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->check(cls, changeinfo, ex);
+ if (ret != -1) {
+ if (camel_folder_summary_save((CamelFolderSummary *)cls) == -1)
+ g_warning("Could not save summary for %s: %s", cls->folder_path, strerror(errno));
+ if (cls->index && ibex_save(cls->index) == -1)
+ g_warning("Could not sync index for %s: %s", cls->folder_path, strerror(errno));
+ }
+
#ifdef DOSTATS
if (ret != -1) {
int i;
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index 159aa84620..1bd6417e1a 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -110,6 +110,11 @@ camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint3
d(printf("Creating maildir folder: %s\n", full_name));
folder = (CamelFolder *)camel_object_new(CAMEL_MAILDIR_FOLDER_TYPE);
+
+ if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
+ && strcmp(full_name, "") == 0)
+ folder->filter_recent = TRUE;
+
folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder,
parent_store, full_name, flags, ex);
diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c
index c200058c95..927c194089 100644
--- a/camel/providers/local/camel-maildir-store.c
+++ b/camel/providers/local/camel-maildir-store.c
@@ -313,8 +313,8 @@ static int scan_dir(GHashTable *visited, char *root, const char *path, guint32 f
closedir(dir);
return -1;
}
+ g_free(new);
}
- g_free(new);
}
g_free(tmp);
}
diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c
index 315e45ffd6..39726566bc 100644
--- a/camel/providers/local/camel-maildir-summary.c
+++ b/camel/providers/local/camel-maildir-summary.c
@@ -635,8 +635,10 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca
if (rename(src, dest) == 0) {
camel_maildir_summary_add(cls, destfilename, forceindex);
- if (changes)
+ if (changes) {
camel_folder_change_info_add_uid(changes, destname);
+ camel_folder_change_info_recent_uid(changes, destname);
+ }
} else {
/* else? we should probably care about failures, but wont */
g_warning("Failed to move new maildir message %s to cur %s", src, dest);
diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c
index be4ca31cf2..c5e9165917 100644
--- a/camel/providers/local/camel-spool-folder.c
+++ b/camel/providers/local/camel-spool-folder.c
@@ -200,7 +200,7 @@ camel_spool_folder_construct(CamelSpoolFolder *lf, CamelStore *parent_store, con
return NULL;
}
- camel_spool_summary_check((CamelSpoolSummary *)folder->summary, NULL, ex);
+ camel_spool_summary_check((CamelSpoolSummary *)folder->summary, lf->changes, ex);
camel_spool_folder_unlock(lf);
fi = g_malloc0(sizeof(*fi));
@@ -209,9 +209,8 @@ camel_spool_folder_construct(CamelSpoolFolder *lf, CamelStore *parent_store, con
fi->url = g_strdup(lf->folder_path);
fi->unread_message_count = camel_folder_get_unread_message_count(folder);
camel_object_trigger_event(CAMEL_OBJECT(parent_store), "folder_created", fi);
-
camel_folder_info_free (fi);
-
+
return lf;
}
@@ -223,6 +222,10 @@ camel_spool_folder_new(CamelStore *parent_store, const char *full_name, guint32
d(printf("Creating spool folder: %s in %s\n", full_name, camel_local_store_get_toplevel_dir((CamelLocalStore *)parent_store)));
folder = (CamelFolder *)camel_object_new(CAMEL_SPOOL_FOLDER_TYPE);
+
+ if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
+ && strcmp(full_name, "INBOX") == 0)
+ folder->filter_recent = TRUE;
folder = (CamelFolder *)camel_spool_folder_construct((CamelSpoolFolder *)folder,
parent_store, full_name, flags, ex);
diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c
index aa9d583d17..600ee8b2bc 100644
--- a/camel/providers/local/camel-spool-store.c
+++ b/camel/providers/local/camel-spool-store.c
@@ -148,8 +148,7 @@ static CamelFolder *
get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex)
{
char *path = ((CamelService *)store)->url->path;
- char *name;
- int len;
+ CamelFolder *folder;
printf("opening folder %s on path %s\n", folder_name, path);
@@ -161,12 +160,9 @@ get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelExce
return NULL;
}
- len = strlen(path);
- name = alloca(len+1);
- strcpy(name, path);
- name[len-1] = 0;
+ folder = camel_spool_folder_new(store, folder_name, flags, ex);
- return camel_spool_folder_new(store, name, flags, ex);
+ return folder;
}
static CamelFolder *
diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c
index 2aa0dcb8e4..651ce7b0e9 100644
--- a/camel/providers/local/camel-spool-summary.c
+++ b/camel/providers/local/camel-spool-summary.c
@@ -751,6 +751,11 @@ spool_summary_sync_full(CamelSpoolSummary *cls, gboolean expunge, CamelFolderCha
strerror(errno));
goto error;
}
+
+ /* mark this message as recent */
+ if (info->info.flags & CAMEL_MESSAGE_FOLDER_NOXEV)
+ camel_folder_change_info_recent_uid(changeinfo, camel_message_info_uid(info));
+
info->info.flags &= 0xffff;
g_free(xevnew);
xevnew = NULL;