[evolution-data-server] Commit custom patches of Anjal to EDS. Almost all of the code is



commit 903fbd6964ea4b26aa062063ee88b60b3d47d6d3
Author: Srinivasa Ragavan <sragavan novell com>
Date:   Fri May 22 16:01:05 2009 +0530

    Commit custom patches of Anjal to EDS. Almost all of the code is
    conditional and won't be run in Evolution's normal usage.
---
 camel/camel-db.c                           |   66 ++++++++++++
 camel/camel-db.h                           |    3 +
 camel/camel-folder-summary.c               |  149 +++++++++++++++++++++++++++-
 camel/camel-folder-summary.h               |    9 ++-
 camel/camel-mime-part-utils.c              |   80 +++++++++++++++
 camel/camel-mime-part-utils.h              |    2 +
 camel/camel-private.h                      |    3 +
 camel/providers/imap/camel-imap-folder.c   |   17 +++
 camel/providers/local/camel-local-folder.c |   10 ++
 camel/providers/local/camel-mbox-folder.c  |   14 +++-
 10 files changed, 347 insertions(+), 6 deletions(-)

diff --git a/camel/camel-db.c b/camel/camel-db.c
index 5636270..94c46c7 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -1000,6 +1000,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;
@@ -1100,6 +1154,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);
@@ -1107,6 +1166,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 577713d..ca7eb8a 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 6726cc3..ff9fd29 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,99 @@ 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;
+
+	m=m;
+}
+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 +1016,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, (char *)info->uid, ((CamelMessageInfoBase *)info)->preview);
+	CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+}
+
 /**
  * camel_folder_summary_ensure_infos_loaded:
  * @s: #CamelFolderSummary object
@@ -1427,6 +1539,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)
 {
@@ -1435,6 +1553,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;
@@ -3393,6 +3519,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)
@@ -4456,7 +4583,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]));
 
@@ -4527,6 +4654,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();
 	}
@@ -4939,3 +5069,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 2a97067..e9a6f4d 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;
 
 };
 
@@ -446,6 +446,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))
@@ -471,6 +472,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 d24bb19..a57ea65 100644
--- a/camel/camel-mime-part-utils.c
+++ b/camel/camel-mime-part-utils.c
@@ -47,6 +47,8 @@
 #include "camel-stream-filter.h"
 #include "camel-stream-fs.h"
 #include "camel-stream-mem.h"
+#include "camel-stream-buffer.h"
+#include "camel-utf8.h"
 
 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))
 	       #include <stdio.h>*/
@@ -136,3 +138,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) {
+				char *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 = camel_utf8_make_valid(str->str);
+			g_string_free(str, TRUE);
+		
+			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 <camel/camel-mime-part.h>
+#include <camel/camel-folder-summary.h>
 
 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 b6c0f1e..aa6b41e 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -49,6 +49,7 @@
 #include "camel-mime-filter-from.h"
 #include "camel-mime-message.h"
 #include "camel-mime-utils.h"
+#include "camel-mime-part-utils.h"
 #include "camel-multipart-encrypted.h"
 #include "camel-multipart-signed.h"
 #include "camel-multipart.h"
@@ -2913,7 +2914,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 ((CamelMimePart *)msg, (CamelMessageInfo *)info) && info->preview)
+					camel_folder_summary_add_preview (folder->summary, (CamelMessageInfo *)info);
+			}
+				
+			camel_message_info_free (info);	
 		} else {
 			if (content_info_incomplete (mi->info.content)) {
 				/* For larger messages, fetch the structure and build a message
@@ -2983,6 +2991,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 ((CamelMimePart *)msg, (CamelMessageInfo *)info) && info->preview)
+						camel_folder_summary_add_preview (folder->summary, (CamelMessageInfo *)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 3363b0a..b09e7b9 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 efd19b4..3558669 100644
--- a/camel/providers/local/camel-mbox-folder.c
+++ b/camel/providers/local/camel-mbox-folder.c
@@ -41,9 +41,13 @@
 #include "camel/camel-exception.h"
 #include "camel/camel-mime-filter-from.h"
 #include "camel/camel-mime-message.h"
+#include "camel/camel-mime-part-utils.h"
 #include "camel/camel-private.h"
 #include "camel/camel-stream-filter.h"
 #include "camel/camel-stream-fs.h"
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-stream-buffer.h>
+#include <camel/camel-multipart.h>
 
 #include "camel-mbox-folder.h"
 #include "camel-mbox-store.h"
@@ -140,7 +144,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;
 }
 
@@ -261,6 +265,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 ((CamelMimePart *)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 */
@@ -468,8 +477,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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]