diff --git a/camel/camel-db.c b/camel/camel-db.c index 8cc23d1..f074879 100644 --- a/camel/camel-db.c +++ b/camel/camel-db.c @@ -1060,6 +1060,60 @@ camel_db_get_folder_deleted_uids (CamelDB *db, char *folder_name, CamelException } static int +read_preview_callback (void *ref, int ncol, char ** cols, char ** name) +{ + GHashTable *hash = (GHashTable *)ref; + const char *uid=NULL; + char *msg=NULL; + int i; + + for (i = 0; i < ncol; ++i) { + if (!strcmp (name [i], "uid")) + uid = camel_pstring_strdup(cols [i]); + else if (!strcmp (name [i], "preview")) + msg = g_strdup(cols[i]); + } + + g_hash_table_insert(hash, (char *)uid, msg); + + return 0; +} + +GHashTable * +camel_db_get_folder_preview (CamelDB *db, char *folder_name, CamelException *ex) +{ + char *sel_query; + int ret; + GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); + + sel_query = sqlite3_mprintf("SELECT uid, preview FROM '%s_preview'", folder_name); + + ret = camel_db_select (db, sel_query, read_preview_callback, hash, ex); + sqlite3_free (sel_query); + + if (!g_hash_table_size (hash) || ret != 0) { + g_hash_table_destroy (hash); + hash = NULL; + } + + return hash; +} + +int +camel_db_write_preview_record (CamelDB *db, char *folder_name, const char *uid, const char *msg, CamelException *ex) +{ + char *query; + int ret; + + query = sqlite3_mprintf("INSERT OR REPLACE INTO '%s_preview' VALUES(%Q,%Q)", folder_name, uid, msg); + + ret = camel_db_add_to_transaction (db, query, ex); + sqlite3_free (query); + + return ret; +} + +static int read_vuids_callback (void *ref, int ncol, char ** cols, char ** name) { GPtrArray *array = (GPtrArray *)ref; @@ -1160,6 +1214,11 @@ camel_db_create_message_info_table (CamelDB *cdb, const char *folder_name, Camel ret = camel_db_add_to_transaction (cdb, table_creation_query, ex); sqlite3_free (table_creation_query); + /* Create message preview table. */ + table_creation_query = sqlite3_mprintf ("CREATE TABLE IF NOT EXISTS '%s_preview' ( uid TEXT PRIMARY KEY , preview TEXT)", folder_name); + ret = camel_db_add_to_transaction (cdb, table_creation_query, ex); + sqlite3_free (table_creation_query); + /* FIXME: sqlize folder_name before you create the index */ safe_index = g_strdup_printf("SINDEX-%s", folder_name); table_creation_query = sqlite3_mprintf ("CREATE INDEX IF NOT EXISTS %Q ON %Q (uid, flags, size, dsent, dreceived, subject, mail_from, mail_to, mail_cc, mlist, part, labels, usertags, cinfo, bdata)", safe_index, folder_name); @@ -1167,6 +1226,13 @@ camel_db_create_message_info_table (CamelDB *cdb, const char *folder_name, Camel g_free (safe_index); sqlite3_free (table_creation_query); + /* INDEX on preview */ + safe_index = g_strdup_printf("SINDEX-%s-preview", folder_name); + table_creation_query = sqlite3_mprintf ("CREATE INDEX IF NOT EXISTS %Q ON '%s_preview' (uid, preview)", safe_index, folder_name); + ret = camel_db_add_to_transaction (cdb, table_creation_query, ex); + g_free (safe_index); + sqlite3_free (table_creation_query); + /* Index on deleted*/ safe_index = g_strdup_printf("DELINDEX-%s", folder_name); table_creation_query = sqlite3_mprintf ("CREATE INDEX IF NOT EXISTS %Q ON %Q (deleted)", safe_index, folder_name); diff --git a/camel/camel-db.h b/camel/camel-db.h index 3eaeeb1..7451b90 100644 --- a/camel/camel-db.h +++ b/camel/camel-db.h @@ -179,5 +179,8 @@ int camel_db_migrate_vfolders_to_14(CamelDB *cdb, const char *folder, CamelExcep int camel_db_start_in_memory_transactions (CamelDB *cdb, CamelException *ex); int camel_db_flush_in_memory_transactions (CamelDB *cdb, const char * folder_name, CamelException *ex); +GHashTable * +camel_db_get_folder_preview (CamelDB *db, char *folder_name, CamelException *ex); +int camel_db_write_preview_record (CamelDB *db, char *folder_name, const char *uid, const char *msg, CamelException *ex); #endif diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index f448f84..3375e03 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -61,6 +61,7 @@ #include "camel-string-utils.h" #include "camel-store.h" #include "camel-vee-folder.h" +#include "camel-mime-part-utils.h" /* To switch between e-memchunk and g-alloc */ #define ALWAYS_ALLOC 1 @@ -159,7 +160,8 @@ camel_folder_summary_init (CamelFolderSummary *s) s->message_info_chunks = NULL; s->content_info_chunks = NULL; - + p->need_preview = FALSE; + p->preview_updates = g_hash_table_new (g_str_hash, g_str_equal); #if defined (DOESTRV) || defined (DOEPOOLV) s->message_info_strings = CAMEL_MESSAGE_INFO_LAST; #endif @@ -895,6 +897,97 @@ camel_folder_summary_cache_size (CamelFolderSummary *s) return s->uids->len; } +/* Update preview of cached messages */ + +struct _preview_update_msg { + CamelSessionThreadMsg msg; + + CamelFolder *folder; + CamelException ex; +}; + +static void +msg_update_preview (const char *uid, gpointer value, CamelFolder *folder) +{ + CamelMessageInfoBase *info = (CamelMessageInfoBase *)camel_folder_summary_uid (folder->summary, uid); + CamelMimeMessage *msg; + CamelException ex; + + camel_exception_init(&ex); + msg = camel_folder_get_message (folder, uid, &ex); + if (camel_exception_is_set(&ex)) + g_warning ("Error fetching message: %s", camel_exception_get_description(&ex)); + else { + if (camel_mime_message_build_preview ((CamelMimePart *)msg, (CamelMessageInfo *)info) && info->preview) + camel_db_write_preview_record (folder->parent_store->cdb_w, folder->full_name, info->uid, info->preview, NULL); + } + camel_exception_clear(&ex); + camel_message_info_free(info); +} + +static void +pick_uids (const char *uid, CamelMessageInfoBase *mi, GPtrArray *array) +{ + if (mi->preview) + g_ptr_array_add (array, (char *)camel_pstring_strdup(uid)); +} + +static gboolean +fill_mi (const char *uid, const char *msg, CamelFolder *folder) +{ + CamelMessageInfoBase *info; + + info = g_hash_table_lookup (folder->summary->loaded_infos, uid); + if (info) /* We re assign the memory of msg */ + info->preview = (char *)msg; + camel_pstring_free (uid); /* unref the uid */ + + return TRUE; +} + +static void +preview_update_exec (CamelSession *session, CamelSessionThreadMsg *msg) +{ + struct _preview_update_msg *m = (struct _preview_update_msg *)msg; + /* FIXME: Either lock & use or copy & use.*/ + GPtrArray *uids_uncached= camel_folder_get_uncached_uids (m->folder, m->folder->summary->uids, NULL); + GHashTable *hash = camel_folder_summary_get_hashtable (m->folder->summary); + GHashTable *preview_data; + int i; + + preview_data = camel_db_get_folder_preview (m->folder->parent_store->cdb_r, m->folder->full_name, NULL); + if (preview_data) { + g_hash_table_foreach_remove (preview_data, (GHRFunc)fill_mi, m->folder); + g_hash_table_destroy (preview_data); + } + + CAMEL_SUMMARY_LOCK (m->folder->summary, summary_lock); + g_hash_table_foreach (m->folder->summary->loaded_infos, (GHFunc)pick_uids, uids_uncached); + CAMEL_SUMMARY_UNLOCK (m->folder->summary, summary_lock); + + for (i=0; i < uids_uncached->len; i++) { + g_hash_table_remove (hash, uids_uncached->pdata[i]); + camel_pstring_free (uids_uncached->pdata[i]); /* unref the hash table key */ + } + + camel_db_begin_transaction (m->folder->parent_store->cdb_w, NULL); + g_hash_table_foreach (hash, (GHFunc)msg_update_preview, m->folder); + camel_db_end_transaction (m->folder->parent_store->cdb_w, NULL); + camel_folder_free_uids(m->folder, uids_uncached); + camel_folder_summary_free_hashtable (hash); +} + +static void +preview_update_free (CamelSession *session, CamelSessionThreadMsg *msg) +{ + struct _preview_update_msg *m = (struct _preview_update_msg *)msg; +} +static CamelSessionThreadOps preview_update_ops = { + preview_update_exec, + preview_update_free, +}; + +/* end */ int camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex) { @@ -921,9 +1014,26 @@ camel_folder_summary_reload_from_db (CamelFolderSummary *s, CamelException *ex) if (!g_getenv("CAMEL_FREE_INFOS") && !s->timeout_handle) s->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s); + if (_PRIVATE(s)->need_preview) { + struct _preview_update_msg *m; + + m = camel_session_thread_msg_new(((CamelService *)s->folder->parent_store)->session, &preview_update_ops, sizeof(*m)); + m->folder = s->folder; + camel_exception_init(&m->ex); + camel_session_thread_queue(((CamelService *)s->folder->parent_store)->session, &m->msg, 0); + } + return ret == 0 ? 0 : -1; } +void +camel_folder_summary_add_preview (CamelFolderSummary *s, CamelMessageInfo *info) +{ + CAMEL_SUMMARY_LOCK(s, summary_lock); + g_hash_table_insert (_PRIVATE(s)->preview_updates, info->uid, ((CamelMessageInfoBase *)info)->preview); + CAMEL_SUMMARY_UNLOCK(s, summary_lock); +} + static void camel_folder_summary_dump (CamelFolderSummary *s) { @@ -1403,6 +1513,12 @@ save_message_infos_to_db (CamelFolderSummary *s, gboolean fresh_mirs, CamelExcep return 0; } +static void +msg_save_preview (const char *uid, gpointer value, CamelFolder *folder) +{ + camel_db_write_preview_record (folder->parent_store->cdb_w, folder->full_name, uid, (char *)value, NULL); +} + int camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex) { @@ -1411,6 +1527,14 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s, CamelException *ex) int ret, count; d(printf ("\ncamel_folder_summary_save_to_db called \n")); + if (_PRIVATE(s)->need_preview && g_hash_table_size(_PRIVATE(s)->preview_updates)) { + camel_db_begin_transaction (s->folder->parent_store->cdb_w, NULL); + CAMEL_SUMMARY_LOCK(s, summary_lock); + g_hash_table_foreach (_PRIVATE(s)->preview_updates, (GHFunc)msg_save_preview, s->folder); + g_hash_table_remove_all (_PRIVATE(s)->preview_updates); + CAMEL_SUMMARY_UNLOCK(s, summary_lock); + camel_db_end_transaction (s->folder->parent_store->cdb_w, NULL); + } if (!(s->flags & CAMEL_SUMMARY_DIRTY)) return 0; @@ -3369,6 +3493,7 @@ message_info_free(CamelFolderSummary *s, CamelMessageInfo *info) camel_pstring_free(mi->cc); camel_pstring_free(mi->mlist); g_free(mi->references); + g_free (mi->preview); camel_flag_list_free(&mi->user_flags); camel_tag_list_free(&mi->user_tags); if (mi->headers) @@ -4432,7 +4557,7 @@ message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi) to->cc = camel_pstring_strdup(from->cc); to->mlist = camel_pstring_strdup(from->mlist); memcpy(&to->message_id, &from->message_id, sizeof(to->message_id)); - + to->preview = g_strdup (from->preview); if (from->references) { int len = sizeof(*from->references) + ((from->references->size-1) * sizeof(from->references->references[0])); @@ -4503,6 +4628,9 @@ info_ptr(const CamelMessageInfo *mi, int id) return ((const CamelMessageInfoBase *)mi)->user_tags; case CAMEL_MESSAGE_INFO_HEADERS: return ((const CamelMessageInfoBase *)mi)->headers; + case CAMEL_MESSAGE_INFO_PREVIEW: + return ((const CamelMessageInfoBase *)mi)->preview; + default: abort(); } @@ -4916,3 +5044,18 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *klass) klass->info_set_flags = info_set_flags; } + +/* Utils */ +void +camel_folder_summary_set_need_preview (CamelFolderSummary *summary, gboolean preview) +{ + _PRIVATE(summary)->need_preview = preview; +} + +gboolean +camel_folder_summary_get_need_preview (CamelFolderSummary *summary) +{ + return _PRIVATE(summary)->need_preview; +} + + diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index c553971..d3308c1 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -141,7 +141,7 @@ enum { CAMEL_MESSAGE_INFO_USER_TAGS, CAMEL_MESSAGE_INFO_HEADERS, - + CAMEL_MESSAGE_INFO_PREVIEW, CAMEL_MESSAGE_INFO_LAST }; @@ -187,7 +187,7 @@ struct _CamelMessageInfoBase { /* tree of content description - NULL if it is not available */ CamelMessageContentInfo *content; struct _camel_header_param *headers; - + char *preview; }; @@ -447,6 +447,7 @@ time_t camel_message_info_time(const CamelMessageInfo *mi, int id); #define camel_message_info_uid(mi) ((const char *)((const CamelMessageInfo *)mi)->uid) #define camel_message_info_subject(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SUBJECT)) +#define camel_message_info_preview(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_PREVIEW)) #define camel_message_info_from(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FROM)) #define camel_message_info_to(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_TO)) #define camel_message_info_cc(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_CC)) @@ -472,6 +473,10 @@ gboolean camel_message_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint gboolean camel_message_info_set_user_flag(CamelMessageInfo *mi, const char *id, gboolean state); gboolean camel_message_info_set_user_tag(CamelMessageInfo *mi, const char *id, const char *val); +void camel_folder_summary_set_need_preview (CamelFolderSummary *summary, gboolean preview); +void camel_folder_summary_add_preview (CamelFolderSummary *s, CamelMessageInfo *info); +gboolean camel_folder_summary_get_need_preview (CamelFolderSummary *summary); + /* debugging functions */ void camel_content_info_dump (CamelMessageContentInfo *ci, int depth); diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c index 1946e7d..5396800 100644 --- a/camel/camel-mime-part-utils.c +++ b/camel/camel-mime-part-utils.c @@ -47,6 +47,7 @@ #include "camel-stream-filter.h" #include "camel-stream-fs.h" #include "camel-stream-mem.h" +#include "camel-stream-buffer.h" #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x)) #include */ @@ -136,3 +137,81 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw, CamelMimeParse g_free (encoding); } + +gboolean +camel_mime_message_build_preview (CamelMimePart *msg, CamelMessageInfo *info) +{ + char *mime_type; + CamelDataWrapper *dw; + gboolean got_plain = FALSE; + + dw = camel_medium_get_content_object((CamelMedium *)msg); + mime_type = camel_data_wrapper_get_mime_type(dw); + if (camel_content_type_is (dw->mime_type, "multipart", "*")) { + int i, nparts; + CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)msg); + + if (!CAMEL_IS_MULTIPART(mp)) + g_assert (0); + nparts = camel_multipart_get_number(mp); + for (i = 0; i < nparts && !got_plain; i++) { + CamelMimePart *part = camel_multipart_get_part(mp, i); + got_plain = camel_mime_message_build_preview (part, info); + } + + } else if (camel_content_type_is (dw->mime_type, "text", "*") && + // !camel_content_type_is (dw->mime_type, "text", "html") && + !camel_content_type_is (dw->mime_type, "text", "calendar")) { + CamelStream *mstream, *bstream; + mstream = camel_stream_mem_new(); + if (camel_data_wrapper_decode_to_stream (dw, mstream) > 0) { + char *line = NULL; + gboolean stop = FALSE; + GString *str = g_string_new (NULL); + + camel_stream_reset (mstream); + bstream = camel_stream_buffer_new (mstream, CAMEL_STREAM_BUFFER_READ|CAMEL_STREAM_BUFFER_BUFFER); + + /* We should fetch just 200 unquoted lines. */ + while ((line = camel_stream_buffer_read_line((CamelStreamBuffer *)bstream)) && !stop && str->len < 200) { + gpointer *tmp = line; + if (!line) + continue; + + if (*line == '>' || strstr(line, "wrote:")) { + g_free(tmp); + continue; + } + if (line [0]== '-' && line[1] == '-') { + g_free(tmp); + stop = TRUE; + line = NULL; + break; + } + while (*line && ((*line == ' ') || *line == '\t')) + line++; + if (*line == '\0' || *line == '\n') { + g_free(tmp); + continue; + } + + g_string_append (str, " "); + g_string_append (str, line); + g_free(tmp); + line = NULL; + } + if (str->len > 100) { + g_string_insert (str, 100, "\n"); + } + /* We don't mark dirty, as we don't store these */ + ((CamelMessageInfoBase *) info)->preview = str->str; + g_string_free(str, FALSE); + + camel_object_unref (bstream); + } + camel_object_unref (mstream); + return TRUE; + } + + return got_plain; +} diff --git a/camel/camel-mime-part-utils.h b/camel/camel-mime-part-utils.h index 8f09799..958d33c 100644 --- a/camel/camel-mime-part-utils.h +++ b/camel/camel-mime-part-utils.h @@ -28,10 +28,12 @@ #define CAMEL_MIME_PART_UTILS_H 1 #include +#include G_BEGIN_DECLS void camel_mime_part_construct_content_from_parser(CamelMimePart *, CamelMimeParser *mp); +gboolean camel_mime_message_build_preview (CamelMimePart *msg, CamelMessageInfo *info); G_END_DECLS diff --git a/camel/camel-private.h b/camel/camel-private.h index 9d9e701..98c403f 100644 --- a/camel/camel-private.h +++ b/camel/camel-private.h @@ -129,6 +129,9 @@ struct _CamelFolderSummaryPrivate { GMutex *alloc_lock; /* for setting up and using allocators */ GMutex *ref_lock; /* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */ GHashTable *flag_cache; + + gboolean need_preview; + GHashTable *preview_updates; }; #define CAMEL_SUMMARY_LOCK(f, l) \ diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index cc36ffa..97cb53c 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -2912,7 +2912,14 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) || store->braindamaged || mi->info.size < IMAP_SMALL_BODY_SIZE || (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) { + CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid); msg = get_message_simple (imap_folder, uid, NULL, ex); + if (info && !info->preview && msg && camel_folder_summary_get_need_preview(folder->summary)) { + if (camel_mime_message_build_preview (msg, info) && info->preview) + camel_folder_summary_add_preview (folder->summary, info); + } + + camel_message_info_free (info); } else { if (content_info_incomplete (mi->info.content)) { /* For larger messages, fetch the structure and build a message @@ -2982,6 +2989,15 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) msg = get_message_simple (imap_folder, uid, NULL, ex); else msg = get_message (imap_folder, uid, mi->info.content, ex); + if (msg && camel_folder_summary_get_need_preview(folder->summary)) { + CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid); + if (info && !info->preview) { + if (camel_mime_message_build_preview (msg, info) && info->preview) + camel_folder_summary_add_preview (folder->summary, info); + } + camel_message_info_free (info); + } + } } while (msg == NULL && retry < 2 diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c index a1ba108..d95bffd 100644 --- a/camel/providers/local/camel-local-folder.c +++ b/camel/providers/local/camel-local-folder.c @@ -84,6 +84,7 @@ static GPtrArray *local_search_by_expression(CamelFolder *folder, const char *ex static guint32 local_count_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); static GPtrArray *local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex); static void local_search_free(CamelFolder *folder, GPtrArray * result); +static GPtrArray * local_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex); static void local_delete(CamelFolder *folder); static void local_rename(CamelFolder *folder, const char *newname); @@ -105,6 +106,7 @@ camel_local_folder_class_init(CamelLocalFolderClass * camel_local_folder_class) camel_folder_class->refresh_info = local_refresh_info; camel_folder_class->sync = local_sync; camel_folder_class->expunge = local_expunge; + camel_folder_class->get_uncached_uids = local_get_uncached_uids; camel_folder_class->search_by_expression = local_search_by_expression; camel_folder_class->count_by_expression = local_count_by_expression; @@ -501,6 +503,14 @@ local_refresh_info(CamelFolder *folder, CamelException *ex) } +static GPtrArray * +local_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, CamelException *ex) +{ + GPtrArray *result = g_ptr_array_new (); + /* By default, we would have everything local. No need to fetch from anywhere. */ + return result; +} + static void local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) { diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c index 2eb31a5..38f6591 100644 --- a/camel/providers/local/camel-mbox-folder.c +++ b/camel/providers/local/camel-mbox-folder.c @@ -44,6 +44,9 @@ #include "camel/camel-private.h" #include "camel/camel-stream-filter.h" #include "camel/camel-stream-fs.h" +#include +#include +#include #include "camel-mbox-folder.h" #include "camel-mbox-store.h" @@ -136,7 +139,7 @@ camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 f folder = (CamelFolder *)camel_object_new(CAMEL_MBOX_FOLDER_TYPE); folder = (CamelFolder *)camel_local_folder_construct((CamelLocalFolder *)folder, parent_store, full_name, flags, ex); - + return folder; } @@ -254,6 +257,11 @@ mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const Camel camel_object_unref (filter_stream); camel_object_unref (output_stream); g_free(fromline); + + if (!((CamelMessageInfoBase *)mi)->preview && camel_folder_summary_get_need_preview(folder->summary)) { + if (camel_mime_message_build_preview (message, mi) && ((CamelMessageInfoBase *)mi)->preview) + camel_folder_summary_add_preview (folder->summary, mi); + } /* now we 'fudge' the summary to tell it its uptodate, because its idea of uptodate has just changed */ /* the stat really shouldn't fail, we just wrote to it */ @@ -461,8 +469,9 @@ retry: message = NULL; goto fail; } - + camel_medium_remove_header((CamelMedium *)message, "X-Evolution"); + fail: /* and unlock now we're finished with it */ camel_local_folder_unlock(lf);