[anjal] Patches for evo/eds of 2.27.x for Anjal



commit 765e2a7cceb88db16994ced05917fad8b4b643c9
Author: Srinivasa Ragavan <sragavan novell com>
Date:   Tue May 5 14:30:26 2009 +0530

    Patches for evo/eds of 2.27.x for Anjal
---
 eds-anjal-2-27.patch |  607 ++++++++++++++++++++++
 evo-anjal-2-27.patch | 1369 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1976 insertions(+), 0 deletions(-)

diff --git a/eds-anjal-2-27.patch b/eds-anjal-2-27.patch
new file mode 100644
index 0000000..73de5ef
--- /dev/null
+++ b/eds-anjal-2-27.patch
@@ -0,0 +1,607 @@
+diff --git a/camel/camel-db.c b/camel/camel-db.c
+index 4d38fce..71f871d 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 23be990..668f195 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);
++}
++
+ /**
+  * camel_folder_summary_ensure_infos_loaded:
+  * @s: #CamelFolderSummary object
+@@ -1427,6 +1537,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 +1551,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 +3517,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 +4581,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 +4652,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 +5067,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..be5198d 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 <stdio.h>*/
+@@ -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 <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 f219be4..225e42c 100644
+--- a/camel/providers/imap/camel-imap-folder.c
++++ b/camel/providers/imap/camel-imap-folder.c
+@@ -2913,7 +2913,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
+@@ -2983,6 +2990,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 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..4ce0012 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 <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 +143,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 +264,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 */
+@@ -468,8 +476,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);
diff --git a/evo-anjal-2-27.patch b/evo-anjal-2-27.patch
new file mode 100644
index 0000000..64894f0
--- /dev/null
+++ b/evo-anjal-2-27.patch
@@ -0,0 +1,1369 @@
+diff --git a/composer/Makefile.am b/composer/Makefile.am
+index 578805c..97debe5 100644
+--- a/composer/Makefile.am
++++ b/composer/Makefile.am
+@@ -5,6 +5,19 @@ errordir = $(privdatadir)/errors
+ @EVO_PLUGIN_RULE@
+ 
+ noinst_LTLIBRARIES = libcomposer.la
++libcomposerincludedir = $(privincludedir)/composer
++libcomposerinclude_HEADERS = 			\
++	e-composer-header.h			\
++	e-composer-header-table.h		\
++	e-composer-from-header.h		\
++	e-composer-name-header.h		\
++	e-composer-post-header.h		\
++	e-composer-private.h			\
++	e-composer-text-header.h		\
++	e-composer-common.h			\
++	e-composer-actions.h			\
++	e-composer-autosave.h			\
++	e-msg-composer.h
+ 
+ INCLUDES =								\
+ 	-I$(top_srcdir)							\
+@@ -27,27 +40,18 @@ INCLUDES =								\
+ libcomposer_la_SOURCES = 			\
+ 	$(IDL_GENERATED)			\
+ 	$(HTML_EDITOR_GENERATED)		\
++	$(libcomposerinclude_HEADERS)		\
+ 	e-composer-actions.c			\
+-	e-composer-actions.h			\
+ 	e-composer-autosave.c			\
+-	e-composer-autosave.h			\
+-	e-composer-common.h			\
+ 	e-composer-header.c			\
+-	e-composer-header.h			\
+ 	e-composer-header-table.c		\
+-	e-composer-header-table.h		\
+ 	e-composer-from-header.c		\
+-	e-composer-from-header.h		\
+ 	e-composer-name-header.c		\
+-	e-composer-name-header.h		\
+ 	e-composer-post-header.c		\
+-	e-composer-post-header.h		\
+ 	e-composer-private.c			\
+-	e-composer-private.h			\
+ 	e-composer-text-header.c		\
+-	e-composer-text-header.h		\
+-	e-msg-composer.c			\
+-	e-msg-composer.h
++	e-msg-composer.c
++
+ 
+ uidir = $(evolutionuidir)
+ ui_DATA = evolution-composer.ui
+diff --git a/composer/e-composer-from-header.h b/composer/e-composer-from-header.h
+index 74fda9a..f8c6dc6 100644
+--- a/composer/e-composer-from-header.h
++++ b/composer/e-composer-from-header.h
+@@ -26,7 +26,7 @@
+ #include <libedataserver/e-account.h>
+ #include <libedataserver/e-account-list.h>
+ 
+-#include "e-account-combo-box.h"
++#include <misc/e-account-combo-box.h>
+ #include "e-composer-header.h"
+ 
+ /* Standard GObject macros */
+diff --git a/composer/e-composer-header-table.c b/composer/e-composer-header-table.c
+index 461c11e..618adbf 100644
+--- a/composer/e-composer-header-table.c
++++ b/composer/e-composer-header-table.c
+@@ -649,7 +649,7 @@ composer_header_table_init (EComposerHeaderTable *table)
+ 		composer_header_table_from_changed_cb), table);
+ 	table->priv->headers[E_COMPOSER_HEADER_FROM] = header;
+ 
+-	header = e_composer_text_header_new_label (_("_Reply-To:"));
++	header = e_composer_text_header_new_label (_("_Reply-To:"), NULL);
+ 	composer_header_table_bind_header ("reply-to", "changed", header);
+ 	table->priv->headers[E_COMPOSER_HEADER_REPLY_TO] = header;
+ 
+@@ -672,7 +672,7 @@ composer_header_table_init (EComposerHeaderTable *table)
+ 	composer_header_table_bind_header ("post-to", "changed", header);
+ 	table->priv->headers[E_COMPOSER_HEADER_POST_TO] = header;
+ 
+-	header = e_composer_text_header_new_label (_("S_ubject:"));
++	header = e_composer_text_header_new_label (_("S_ubject:"), NULL);
+ 	composer_header_table_bind_header ("subject", "changed", header);
+ 	table->priv->headers[E_COMPOSER_HEADER_SUBJECT] = header;
+ 
+diff --git a/composer/e-composer-header.c b/composer/e-composer-header.c
+index 8cbcf64..1ed21b6 100644
+--- a/composer/e-composer-header.c
++++ b/composer/e-composer-header.c
+@@ -1,3 +1,7 @@
++/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
++
++/*Modified for Anjal - Johnny Jacob <jjohnny novell com>*/
++
+ /*
+  *
+  * This program is free software; you can redistribute it and/or
+@@ -28,6 +32,8 @@ enum {
+ 	PROP_0,
+ 	PROP_BUTTON,
+ 	PROP_LABEL,
++	PROP_ADDACTION,
++	PROP_ADDACTION_TEXT,
+ 	PROP_SENSITIVE,
+ 	PROP_VISIBLE
+ };
+@@ -40,7 +46,9 @@ enum {
+ 
+ struct _EComposerHeaderPrivate {
+ 	gchar *label;
++	gchar *addaction_text;
+ 	gboolean button;
++	gboolean addaction; /*For Add button.*/
+ };
+ 
+ static gpointer parent_class;
+@@ -54,6 +62,14 @@ composer_header_button_clicked_cb (GtkButton *button,
+ 	g_signal_emit (header, signal_ids[CLICKED], 0);
+ }
+ 
++static void
++composer_header_addaction_clicked_cb (GtkButton *button,
++				      EComposerHeader *header)
++{
++	gtk_widget_hide (button);
++	e_composer_header_set_visible (header, TRUE);
++}
++
+ static GObject *
+ composer_header_constructor (GType type,
+                              guint n_construct_properties,
+@@ -81,6 +97,20 @@ composer_header_constructor (GType type,
+ 		gtk_label_set_mnemonic_widget (
+ 			GTK_LABEL (widget), header->input_widget);
+ 	}
++
++	if (header->priv->addaction) {
++		header->action_widget = gtk_link_button_new_with_label (header->priv->label, 
++									header->priv->addaction_text);
++		g_signal_connect (
++			header->action_widget, "clicked",
++			G_CALLBACK (composer_header_addaction_clicked_cb),
++			header);
++
++		/*TODO : Add + icon*/
++		/* widget = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU); */
++		/* gtk_button_set_image (header->action_widget, widget); */
++	}
++
+ 	header->title_widget = g_object_ref_sink (widget);
+ 
+ 	g_free (header->priv->label);
+@@ -104,6 +134,14 @@ composer_header_set_property (GObject *object,
+ 			priv->button = g_value_get_boolean (value);
+ 			return;
+ 
++		case PROP_ADDACTION:	/* construct only */
++			priv->addaction = g_value_get_boolean (value);
++			return;
++
++		case PROP_ADDACTION_TEXT:/* construct only */
++			priv->addaction_text = g_value_dup_string (value);
++			return;
++
+ 		case PROP_LABEL:	/* construct only */
+ 			priv->label = g_value_dup_string (value);
+ 			return;
+@@ -124,6 +162,15 @@ composer_header_set_property (GObject *object,
+ 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+ 
++void
++e_composer_header_set_property (GObject *object,
++                              guint property_id,
++                              const GValue *value,
++                              GParamSpec *pspec)
++{
++	composer_header_set_property (object, property_id, value, pspec);
++}
++
+ static void
+ composer_header_get_property (GObject *object,
+                               guint property_id,
+@@ -139,6 +186,15 @@ composer_header_get_property (GObject *object,
+ 			g_value_set_boolean (value, priv->button);
+ 			return;
+ 
++		case PROP_ADDACTION:	/* construct only */
++			g_value_set_boolean (value, priv->button);
++			return;
++
++		case PROP_ADDACTION_TEXT:	/* construct only */
++			g_value_take_string (
++				value, priv->addaction_text);
++			return;
++
+ 		case PROP_LABEL:	/* construct only */
+ 			g_value_take_string (
+ 				value, e_composer_header_get_label (
+@@ -207,6 +263,28 @@ composer_header_class_init (EComposerHeaderClass *class)
+ 
+ 	g_object_class_install_property (
+ 		object_class,
++		PROP_ADDACTION,
++		g_param_spec_boolean (
++			"addaction",
++			NULL,
++			NULL,
++			FALSE,
++			G_PARAM_READWRITE |
++			G_PARAM_CONSTRUCT_ONLY));
++
++	g_object_class_install_property (
++		object_class,
++		PROP_ADDACTION_TEXT,
++		g_param_spec_string (
++			"addaction_text",
++			NULL,
++			NULL,
++			NULL,
++			G_PARAM_READWRITE |
++			G_PARAM_CONSTRUCT_ONLY));
++
++	g_object_class_install_property (
++		object_class,
+ 		PROP_LABEL,
+ 		g_param_spec_string (
+ 			"label",
+diff --git a/composer/e-composer-header.h b/composer/e-composer-header.h
+index d1edd11..2b8f802 100644
+--- a/composer/e-composer-header.h
++++ b/composer/e-composer-header.h
+@@ -49,6 +49,7 @@ struct _EComposerHeader {
+ 	GObject parent;
+ 	GtkWidget *title_widget;
+ 	GtkWidget *input_widget;
++        GtkWidget *action_widget;
+ 	EComposerHeaderPrivate *priv;
+ };
+ 
+@@ -64,6 +65,8 @@ void		e_composer_header_set_sensitive (EComposerHeader *header,
+ gboolean	e_composer_header_get_visible	(EComposerHeader *header);
+ void		e_composer_header_set_visible	(EComposerHeader *header,
+ 						 gboolean visible);
++void		e_composer_header_set_property 	(GObject *object, guint property_id, 
++						const GValue *value, GParamSpec *pspec);
+ void		e_composer_header_set_title_tooltip
+ 						(EComposerHeader *header,
+ 						 const gchar *tooltip);
+diff --git a/composer/e-composer-name-header.c b/composer/e-composer-name-header.c
+index 70a126b..ed96312 100644
+--- a/composer/e-composer-name-header.c
++++ b/composer/e-composer-name-header.c
+@@ -23,8 +23,8 @@
+ #include <glib/gi18n.h>
+ 
+ /* XXX Temporary kludge */
+-#include "addressbook/gui/contact-editor/e-contact-editor.h"
+-#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
++/* #include "addressbook/gui/contact-editor/e-contact-editor.h" */
++/* #include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" */
+ 
+ #define E_COMPOSER_NAME_HEADER_GET_PRIVATE(obj) \
+ 	(G_TYPE_INSTANCE_GET_PRIVATE \
+@@ -117,10 +117,7 @@ composer_name_header_constructor (GType type,
+ 	entry = E_NAME_SELECTOR_ENTRY (
+ 		e_name_selector_peek_section_list (
+ 		priv->name_selector, label));
+-	e_name_selector_entry_set_contact_editor_func (
+-		entry, e_contact_editor_new);
+-	e_name_selector_entry_set_contact_list_editor_func (
+-		entry, e_contact_list_editor_new);
++
+ 	g_signal_connect (
+ 		entry, "changed",
+ 		G_CALLBACK (composer_name_header_entry_changed_cb), object);
+@@ -261,6 +258,32 @@ e_composer_name_header_new (const gchar *label,
+ 		"button", TRUE, "name-selector", name_selector, NULL);
+ }
+ 
++EComposerHeader *
++e_composer_name_header_new_with_label (const gchar *label,
++				  ENameSelector *name_selector)
++{
++	return g_object_new (
++		E_TYPE_COMPOSER_NAME_HEADER, "label", label,
++		"button", FALSE,  "name-selector", name_selector,
++		"addaction", FALSE, "visible", TRUE,
++		NULL);
++}
++
++EComposerHeader *
++e_composer_name_header_new_with_action (const gchar *label,
++					const gchar *action_label,
++					ENameSelector *name_selector)
++{
++	g_return_val_if_fail (E_IS_NAME_SELECTOR (name_selector), NULL);
++
++	return g_object_new (
++		E_TYPE_COMPOSER_NAME_HEADER, "label", label,
++		"button", FALSE, "name-selector", name_selector, 
++		"addaction_text", action_label,
++		"addaction", action_label != NULL,
++		NULL);
++}
++
+ ENameSelector *
+ e_composer_name_header_get_name_selector (EComposerNameHeader *header)
+ {
+diff --git a/composer/e-composer-name-header.h b/composer/e-composer-name-header.h
+index 04f7100..92a379b 100644
+--- a/composer/e-composer-name-header.h
++++ b/composer/e-composer-name-header.h
+@@ -62,6 +62,15 @@ struct _EComposerNameHeaderClass {
+ GType		e_composer_name_header_get_type	(void);
+ EComposerHeader * e_composer_name_header_new	(const gchar *label,
+ 						 ENameSelector *name_selector);
++/*No button. Just a label.*/
++EComposerHeader * e_composer_name_header_new_with_label	(const gchar *label,
++							 ENameSelector *name_selector);
++
++/*No button. Label with a Link button for show/hide.*/
++EComposerHeader * e_composer_name_header_new_with_action (const gchar *label,
++							  const gchar *action,
++							  ENameSelector *name_selector);
++
+ ENameSelector *	e_composer_name_header_get_name_selector
+ 						(EComposerNameHeader *header);
+ EDestination **	e_composer_name_header_get_destinations
+diff --git a/composer/e-composer-text-header.c b/composer/e-composer-text-header.c
+index 2945720..bfb3237 100644
+--- a/composer/e-composer-text-header.c
++++ b/composer/e-composer-text-header.c
+@@ -1,3 +1,7 @@
++/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
++
++/*Modified for Anjal - Johnny Jacob <jjohnny novell com>*/
++
+ /*
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+@@ -21,6 +25,11 @@
+ #define E_COMPOSER_TEXT_HEADER_GET_ENTRY(header) \
+ 	(GTK_ENTRY (E_COMPOSER_HEADER (header)->input_widget))
+ 
++struct _EComposerTextHeaderPrivate {
++	GtkLinkButton *linkbtn;
++	guint destination_index;
++};
++
+ static gpointer parent_class;
+ 
+ static void
+@@ -99,19 +108,23 @@ e_composer_text_header_get_type (void)
+ }
+ 
+ EComposerHeader *
+-e_composer_text_header_new_label (const gchar *label)
++e_composer_text_header_new_label (const gchar *label, const gchar *action_label)
+ {
+ 	return g_object_new (
+ 		E_TYPE_COMPOSER_TEXT_HEADER, "label", label,
+-		"button", FALSE, NULL);
++		"button", FALSE, "addaction", action_label != NULL,
++		"addaction_text", action_label,
++		"visible", action_label == NULL, NULL);
+ }
+ 
+ EComposerHeader *
+-e_composer_text_header_new_button (const gchar *label)
++e_composer_text_header_new_button (const gchar *label, const gchar *action_label)
+ {
+ 	return g_object_new (
+ 		E_TYPE_COMPOSER_TEXT_HEADER, "label", label,
+-		"button", TRUE, NULL);
++		"button", TRUE, "addaction", action_label != NULL, 
++		"addaction_text", action_label,
++		"visible", action_label == NULL, NULL);
+ }
+ 
+ const gchar *
+diff --git a/composer/e-composer-text-header.h b/composer/e-composer-text-header.h
+index c0c4708..79e972d 100644
+--- a/composer/e-composer-text-header.h
++++ b/composer/e-composer-text-header.h
+@@ -57,10 +57,13 @@ struct _EComposerTextHeaderClass {
+ };
+ 
+ GType		e_composer_text_header_get_type	(void);
+-EComposerHeader * e_composer_text_header_new_label
+-						(const gchar *label);
+-EComposerHeader * e_composer_text_header_new_button
+-						(const gchar *label);
++
++EComposerHeader *
++e_composer_text_header_new_label (const gchar *label, const gchar *action_label);
++
++EComposerHeader *
++e_composer_text_header_new_button (const gchar *label, const gchar *action_label);
++
+ const gchar *	e_composer_text_header_get_text	(EComposerTextHeader *header);
+ void		e_composer_text_header_set_text (EComposerTextHeader *header,
+ 						 const gchar *text);
+diff --git a/e-util/e-config.c b/e-util/e-config.c
+index 1da54b5..a2d68e1 100644
+--- a/e-util/e-config.c
++++ b/e-util/e-config.c
+@@ -532,11 +532,13 @@ ec_rebuild(EConfig *emp)
+ 					gnome_druid_page_edge_set_title((GnomeDruidPageEdge *)page, translated_label);
+ 					gnome_druid_insert_page((GnomeDruid *)druid, pagenode?(GnomeDruidPage *)pagenode->frame:NULL, (GnomeDruidPage *)page);
+ 				}
+-				if (item->type == E_CONFIG_PAGE_FINISH) {
+-					g_signal_connect(page, "back", G_CALLBACK(ec_druid_prev), wn);
+-					g_signal_connect(page, "finish", G_CALLBACK(ec_druid_finish), wn);
+-				} else
+-					g_signal_connect(page, "next", G_CALLBACK(ec_druid_next), wn);
++				if (page) {
++					if (item->type == E_CONFIG_PAGE_FINISH) {
++						g_signal_connect(page, "back", G_CALLBACK(ec_druid_prev), wn);
++						g_signal_connect(page, "finish", G_CALLBACK(ec_druid_finish), wn);
++					} else
++						g_signal_connect(page, "next", G_CALLBACK(ec_druid_next), wn);
++				}
+ 				wn->frame = page;
+ 				wn->widget = page;
+ 			}
+@@ -567,10 +569,11 @@ ec_rebuild(EConfig *emp)
+ 				page = item->factory(emp, item, root, wn->frame, wn->context->data);
+ 				if (emp->type == E_CONFIG_DRUID) {
+ 					if (page) {
+-						g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD(page));
+-						connect = wn->frame != page;
+-						wn->frame = page;
+-						page = ((GnomeDruidPageStandard *)page)->vbox;
++						if (GNOME_IS_DRUID_PAGE_STANDARD(page)) {
++							connect = wn->frame != page;
++							wn->frame = page;
++							page = ((GnomeDruidPageStandard *)page)->vbox;
++						}
+ 					} else
+ 						wn->frame = page;
+ 				} else {
+diff --git a/filter/Makefile.am b/filter/Makefile.am
+index 8eee6bd..b58b4b2 100644
+--- a/filter/Makefile.am
++++ b/filter/Makefile.am
+@@ -12,6 +12,22 @@ INCLUDES = 					\
+ privsolib_LTLIBRARIES =				\
+ 	libfilter.la
+ 
++filterincludedir = $(privincludedir)/filter
++
++filterinclude_HEADERS = 			\
++	filter-code.h				\
++	filter-colour.h				\
++	filter-datespec.h			\
++	filter-element.h			\
++	filter-file.h				\
++	filter-input.h				\
++	filter-int.h				\
++	filter-option.h				\
++	filter-part.h				\
++	filter-rule.h				\
++	rule-context.h				\
++	rule-editor.h
++
+ libfilter_la_SOURCES =				\
+ 	filter-code.c				\
+ 	filter-code.h				\
+diff --git a/mail/Makefile.am b/mail/Makefile.am
+index 96ed893..74aefef 100644
+--- a/mail/Makefile.am
++++ b/mail/Makefile.am
+@@ -31,7 +31,9 @@ INCLUDES =						\
+ 	-DPREFIX=\""$(prefix)"\"			\
+ 	-DG_LOG_DOMAIN=\"evolution-mail\"
+ 
+-component_LTLIBRARIES = libevolution-mail.la
++component_LTLIBRARIES = libevolution-mail-shared.la \
++			libevolution-mail.la
++
+ 
+ # Mail.idl
+ MAIL_IDL = Evolution-Mail.idl
+@@ -55,9 +57,16 @@ idl_DATA = $(MAIL_IDL)
+ mailinclude_HEADERS =				\
+ 	$(MAIL_IDL_GENERATED_H)			\
+ 	e-mail-attachment-bar.h			\
++ 	e-searching-tokenizer.h			\
++ 	em-account-editor.h			\	
+ 	em-composer-utils.h			\
+ 	em-config.h				\
+ 	em-event.h				\
++ 	em-filter-context.h			\
++ 	em-filter-editor.h			\
++ 	em-filter-folder-element.h		\
++ 	em-filter-rule.h			\
++ 	em-filter-source-element.h	        \	
+ 	em-folder-browser.h			\
+ 	em-folder-tree-model.h			\
+ 	em-folder-tree.h			\
+@@ -76,14 +85,17 @@ mailinclude_HEADERS =				\
+ 	em-menu.h				\
+ 	em-message-browser.h			\
+ 	em-popup.h				\
++	em-search-context.h			\
+ 	em-stripsig-filter.h			\
+ 	em-sync-stream.h			\
+ 	em-utils.h				\
+ 	mail-autofilter.h			\
+ 	mail-component.h			\
+ 	mail-config.h				\
++	mail-folder-cache.h			\
+ 	mail-mt.h				\
+ 	mail-ops.h				\
++	mail-send-recv.h			\
+ 	mail-session.h				\
+ 	mail-tools.h				\
+ 	message-list.h				\
+@@ -98,16 +110,77 @@ libevolution_mail_la_SOURCES =			\
+ 	e-attachment-handler-mail.h		\
+ 	e-mail-attachment-bar.c			\
+ 	e-searching-tokenizer.c			\
+-	e-searching-tokenizer.h			\
+-	em-account-editor.c			\
+-	em-account-editor.h			\
+ 	em-account-prefs.c			\
+ 	em-account-prefs.h			\
+ 	em-composer-prefs.c			\
+ 	em-composer-prefs.h			\
+-	em-composer-utils.c			\
+-	em-config.c				\
++	em-folder-browser.c			\
++	em-folder-view.c			\
++	em-format-hook.c			\
++	em-format-html-display.c		\
++	em-format-html-print.c			\
++	em-format-html.c			\
++	em-html-stream.c			\
++	em-junk-hook.c				\
++	em-mailer-prefs.c			\
++	em-mailer-prefs.h			\
++	em-menu.c				\
++	em-message-browser.c			\
++	em-migrate.c				\
++	em-migrate.h				\
++	em-network-prefs.c			\
++	em-network-prefs.h			\
++	em-subscribe-editor.c			\
++	em-subscribe-editor.h			\
++	mail-component-factory.c		\
++	mail-component.c			\
++	mail-config-factory.c			\
++	mail-config-factory.h			\
++	mail-signature-editor.c			\
++	mail-signature-editor.h			\
++	mail-types.h				\
++	message-list.c				
++if ENABLE_SMIME
++SMIME_LIBS = 				\
++	$(top_builddir)/smime/lib/libessmime.la		\
++	$(top_builddir)/smime/gui/libevolution-smime.la
++endif
++
++
++libevolution_mail_la_LIBADD =					\
++	$(top_builddir)/mail/libevolution-mail-shared.la	\								
++	$(top_builddir)/e-util/libeutil.la			\
++	$(top_builddir)/shell/libeshell.la			\
++	$(top_builddir)/widgets/table/libetable.la		\
++	$(top_builddir)/widgets/text/libetext.la		\
++	$(top_builddir)/widgets/misc/libemiscwidgets.la		\
++	$(top_builddir)/widgets/misc/libefilterbar.la		\
++	$(top_builddir)/filter/libfilter.la			\
++	$(top_builddir)/widgets/menus/libmenus.la		\
++	$(top_builddir)/addressbook/util/libeabutil.la		\
++	$(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
++	$(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
++	$(top_builddir)/mail/importers/libevolution-mail-importers.la	\
++	$(SMIME_LIBS)						\
++	$(EVOLUTION_MAIL_LIBS)					\
++	$(GTKHTML_LIBS)						\
++	$(REGEX_LIBS)						\
++	$(THREADS_LIBS)
++
++libevolution_mail_la_LDFLAGS = 			\
++	-avoid-version -module $(NO_UNDEFINED)
++
++libevolution_mail_la_DEPENDENCIES = em-filter-i18n.h
++
++# .server files
++
++libevolution_mail_shared_la_SOURCES =			\
++	em-account-editor.c			\
++	em-account-editor.h			\
+ 	em-event.c				\
++	em-config.c				\
++	em-composer-utils.c			\
++	em-composer-utils.h			\	
+ 	em-filter-context.c			\
+ 	em-filter-context.h			\
+ 	em-filter-editor.c			\
+@@ -118,7 +191,8 @@ libevolution_mail_la_SOURCES =			\
+ 	em-filter-rule.h			\
+ 	em-filter-source-element.c		\
+ 	em-filter-source-element.h		\
+-	em-folder-browser.c			\
++	em-folder-tree-model.c			\
++	em-folder-tree.c			\
+ 	em-folder-properties.c			\
+ 	em-folder-properties.h			\
+ 	em-folder-selection-button.c		\
+@@ -127,34 +201,15 @@ libevolution_mail_la_SOURCES =			\
+ 	em-folder-selection.h			\
+ 	em-folder-selector.c			\
+ 	em-folder-selector.h			\
+-	em-folder-tree-model.c			\
+-	em-folder-tree.c			\
+ 	em-folder-utils.c			\
+-	em-folder-view.c			\
+-	em-format-hook.c			\
+-	em-format-html-display.c		\
+-	em-format-html-print.c			\
+-	em-format-html.c			\
+ 	em-format-quote.c			\
+ 	em-format.c				\
+-	em-html-stream.c			\
+ 	em-icon-stream.c			\
+ 	em-inline-filter.c			\
+-	em-junk-hook.c				\
+-	em-mailer-prefs.c			\
+-	em-mailer-prefs.h			\
+-	em-menu.c				\
+-	em-message-browser.c			\
+-	em-migrate.c				\
+-	em-migrate.h				\
+-	em-network-prefs.c			\
+-	em-network-prefs.h			\
+ 	em-popup.c				\
+ 	em-search-context.c			\
+ 	em-search-context.h			\
+ 	em-stripsig-filter.c			\
+-	em-subscribe-editor.c			\
+-	em-subscribe-editor.h			\
+ 	em-sync-stream.c			\
+ 	em-utils.c				\
+ 	em-vfolder-context.c			\
+@@ -164,63 +219,41 @@ libevolution_mail_la_SOURCES =			\
+ 	em-vfolder-rule.c			\
+ 	em-vfolder-rule.h			\
+ 	mail-autofilter.c			\
+-	mail-component-factory.c		\
+-	mail-component.c			\
+-	mail-config-factory.c			\
+-	mail-config-factory.h			\
+ 	mail-config.c				\
+ 	mail-crypto.c				\
+ 	mail-crypto.h				\
+ 	mail-folder-cache.c			\
+ 	mail-folder-cache.h			\
+-	mail-mt.c				\
+ 	mail-ops.c				\
++	mail-mt.c				\
+ 	mail-send-recv.c			\
+ 	mail-send-recv.h			\
+ 	mail-session.c				\
+-	mail-signature-editor.c			\
+-	mail-signature-editor.h			\
+ 	mail-tools.c				\
+-	mail-types.h				\
+ 	mail-vfolder.c				\
+-	message-list.c				\
+ 	message-tag-editor.c			\
+ 	message-tag-editor.h			\
+ 	message-tag-followup.c			\
+ 	message-tag-followup.h
+ 
+-if ENABLE_SMIME
+-SMIME_LIBS = 				\
+-	$(top_builddir)/smime/lib/libessmime.la		\
+-	$(top_builddir)/smime/gui/libevolution-smime.la
+-endif
+ 
+-libevolution_mail_la_LIBADD =					\
++
++
++
++
++libevolution_mail_shared_la_LIBADD =					\
+ 	$(top_builddir)/e-util/libeutil.la			\
+-	$(top_builddir)/shell/libeshell.la			\
+-	$(top_builddir)/composer/libcomposer.la			\
+-	$(top_builddir)/widgets/table/libetable.la		\
+-	$(top_builddir)/widgets/text/libetext.la		\
+ 	$(top_builddir)/widgets/misc/libemiscwidgets.la		\
+-	$(top_builddir)/widgets/misc/libefilterbar.la		\
++	$(top_builddir)/composer/libcomposer.la			\
+ 	$(top_builddir)/filter/libfilter.la			\
+ 	$(top_builddir)/widgets/menus/libmenus.la		\
+-	$(top_builddir)/addressbook/util/libeabutil.la		\
+-	$(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+-	$(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
+-	$(top_builddir)/mail/importers/libevolution-mail-importers.la	\
+ 	$(SMIME_LIBS)						\
+-	$(EVOLUTION_MAIL_LIBS)					\
+-	$(GTKHTML_LIBS)						\
+-	$(REGEX_LIBS)						\
+ 	$(THREADS_LIBS)
+ 
+-libevolution_mail_la_LDFLAGS = 			\
++libevolution_mail_shared_la_LDFLAGS = 			\
+ 	-avoid-version -module $(NO_UNDEFINED)
+ 
+-libevolution_mail_la_DEPENDENCIES = em-filter-i18n.h
+ 
+-# .server files
+ 
+ server_in_files = GNOME_Evolution_Mail.server.in.in
+ server_DATA = $(server_in_files:.server.in.in=.server)
+diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
+index b9850bd..42a6fa0 100644
+--- a/mail/em-account-editor.c
++++ b/mail/em-account-editor.c
+@@ -276,6 +276,26 @@ EMAccountEditor *em_account_editor_new(EAccount *account, em_account_editor_t ty
+ 	return emae;
+ }
+ 
++/**
++ * em_account_editor_new_for_pages:
++ * @account:
++ * @type:
++ *
++ * Create a new account editor.  If @account is NULL then this is to
++ * create a new account, else @account is copied to a working
++ * structure and is for editing an existing account.
++ *
++ * Return value:
++ **/
++EMAccountEditor *em_account_editor_new_for_pages(EAccount *account, em_account_editor_t type, char *id, GtkWidget **pages)
++{
++	EMAccountEditor *emae = g_object_new(em_account_editor_get_type(), NULL);
++	emae->pages = pages;
++	em_account_editor_construct(emae, account, type, id);
++
++	return emae;
++}
++
+ /* ********************************************************************** */
+ 
+ static struct {
+@@ -401,7 +421,7 @@ emae_display_license(EMAccountEditor *emae, CamelProvider *prov)
+ 		gtk_text_view_set_editable((GtkTextView *)w, FALSE);
+ 		response = gtk_dialog_run((GtkDialog *)dialog);
+ 	} else {
+-		e_error_run((GtkWindow *)gtk_widget_get_toplevel(emae->editor),
++		e_error_run(emae->editor ? (GtkWindow *)gtk_widget_get_toplevel(emae->editor) : NULL,
+ 			    "mail:no-load-license", prov->license_file, NULL);
+ 	}
+ 
+@@ -1018,7 +1038,8 @@ emae_url_set_hostport(CamelURL *url, const char *txt)
+ 	}
+ 
+ 	g_strstrip(host);
+-	camel_url_set_host(url, host);
++	if (txt && *txt)
++		camel_url_set_host(url, host);
+ 
+ 	g_free(host);
+ }
+@@ -1381,7 +1402,8 @@ emae_refresh_providers(EMAccountEditor *emae, EMAccountEditorService *service)
+ 	int active = 0, i;
+ 	struct _service_info *info = &emae_service_info[service->type];
+ 	const char *uri = e_account_get_string(account, info->account_uri_key);
+-	char *current = NULL;
++	char *current = NULL, *tmp;
++	CamelURL *url;
+ 
+ 	dropdown = service->providers;
+ 	gtk_widget_show((GtkWidget *)dropdown);
+@@ -1396,8 +1418,10 @@ emae_refresh_providers(EMAccountEditor *emae, EMAccountEditorService *service)
+ 			memcpy(current, uri, len);
+ 			current[len] = 0;
+ 		}
++	} else {
++		current = g_strdup("imap");
+ 	}
+-
++	
+ 	store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
+ 
+ 	i = 0;
+@@ -1423,7 +1447,7 @@ emae_refresh_providers(EMAccountEditor *emae, EMAccountEditorService *service)
+ 
+ 		gtk_list_store_append(store, &iter);
+ 		gtk_list_store_set(store, &iter, 0, provider->name, 1, provider, -1);
+-
++		
+ 		/* find the displayed and set default */
+ 		if (i == 0 || (current && strcmp(provider->protocol, current) == 0)) {
+ 			service->provider = provider;
+@@ -1441,13 +1465,30 @@ emae_refresh_providers(EMAccountEditor *emae, EMAccountEditorService *service)
+ 		i++;
+ 	}
+ 
++
++	gtk_cell_layout_clear((GtkCellLayout *)dropdown);
+ 	gtk_combo_box_set_model(dropdown, (GtkTreeModel *)store);
+ 	gtk_cell_layout_pack_start((GtkCellLayout *)dropdown, cell, TRUE);
+ 	gtk_cell_layout_set_attributes((GtkCellLayout *)dropdown, cell, "text", 0, NULL);
+ 
++	g_signal_handlers_disconnect_by_func(dropdown, emae_provider_changed, service);
+ 	gtk_combo_box_set_active(dropdown, -1);	/* needed for gtkcombo bug(?) */
+ 	gtk_combo_box_set_active(dropdown, active);
+ 	g_signal_connect(dropdown, "changed", G_CALLBACK(emae_provider_changed), service);
++
++	if (!uri  || (url = camel_url_new(uri, NULL)) == NULL) {
++		return;
++	}
++	
++	tmp = camel_url_get_param(url, "use_ssl");
++	if (tmp == NULL)
++		tmp = "never";	
++	for (i=0;i<num_ssl_options;i++) {
++		if (!strcmp(ssl_options[i].value, tmp)) {
++			gtk_combo_box_set_active(service->use_ssl, i);
++			break;
++		}
++	}
+ }
+ 
+ static void
+@@ -1603,11 +1644,12 @@ static void emae_check_authtype(GtkWidget *w, EMAccountEditorService *service)
+ 	uri = e_account_get_string(emae->account, emae_service_info[service->type].account_uri_key);
+ 	g_object_ref(emae);
+ 
+-	service->check_dialog = e_error_new((GtkWindow *)gtk_widget_get_toplevel(emae->editor),
++	service->check_dialog = e_error_new(emae->editor ? (GtkWindow *)gtk_widget_get_toplevel(emae->editor) : NULL,
+ 					    "mail:checking-service", NULL);
+ 	g_signal_connect(service->check_dialog, "response", G_CALLBACK(emae_check_authtype_response), service);
+ 	gtk_widget_show(service->check_dialog);
+-	gtk_widget_set_sensitive(emae->editor, FALSE);
++	if (emae->editor)
++		gtk_widget_set_sensitive(emae->editor, FALSE);
+ 	service->check_id = mail_check_service(uri, service->type, emae_check_authtype_done, service);
+ }
+ 
+@@ -1621,7 +1663,6 @@ emae_setup_service(EMAccountEditor *emae, EMAccountEditorService *service, Glade
+ 	int i;
+ 
+ 	service->provider = uri?camel_provider_get(uri, NULL):NULL;
+-
+ 	service->frame = glade_xml_get_widget(xml, info->frame);
+ 	service->container = glade_xml_get_widget(xml, info->container);
+ 	service->description = GTK_LABEL (glade_xml_get_widget (xml, info->description));
+@@ -1650,8 +1691,9 @@ emae_setup_service(EMAccountEditor *emae, EMAccountEditorService *service, Glade
+ 		} else
+ 			gtk_entry_set_text(service->hostname, url->host);
+ 	}
+-	if (url->user)
++	if (url->user && *url->user) {
+ 		gtk_entry_set_text(service->username, url->user);
++	}
+ 	if (service->pathentry) {
+ 		GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
+ 
+@@ -1789,7 +1831,9 @@ emae_identity_page(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, st
+ 	}
+ 
+ 	w = glade_xml_get_widget(xml, item->label);
+-	if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
++	if (emae->type == EMAE_PAGES) {
++		gtk_box_pack_start (emae->pages[0], w, TRUE, TRUE, 0);
++	} else if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
+ 		GladeXML *druidxml;
+ 		GtkWidget *page;
+ 
+@@ -1838,7 +1882,9 @@ emae_receive_page(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, str
+ 	emae_setup_service(emae, &gui->source, xml);
+ 
+ 	w = glade_xml_get_widget(xml, item->label);
+-	if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
++	if (emae->type == EMAE_PAGES) {
++		gtk_box_pack_start (emae->pages[1], w, TRUE, TRUE, 0);
++	} else if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
+ 		GladeXML *druidxml;
+ 		GtkWidget *page;
+ 
+@@ -2306,7 +2352,9 @@ emae_send_page(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct
+ 	emae_setup_service(emae, &gui->transport, xml);
+ 
+ 	w = glade_xml_get_widget(xml, item->label);
+-	if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
++	if (emae->type == EMAE_PAGES) {
++		gtk_box_pack_start (emae->pages[2], w, TRUE, TRUE, 0);
++	} else if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
+ 		GladeXML *druidxml;
+ 		GtkWidget *page;
+ 
+@@ -2321,7 +2369,7 @@ emae_send_page(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct
+ 		gtk_box_pack_start((GtkBox*)((GnomeDruidPageStandard *)page)->vbox, w, TRUE, TRUE, 0);
+ 		w = page;
+ 		g_object_unref(druidxml);
+-		gnome_druid_append_page((GnomeDruid *)parent, (GnomeDruidPage *)page);
++		gnome_druid_append_page((GnomeDruid *)parent, (GnomeDruidPage *)page);	
+ 	} else {
+ 		gtk_notebook_append_page((GtkNotebook *)parent, w, gtk_label_new(_("Sending Email")));
+ 	}
+@@ -2542,6 +2590,10 @@ emae_widget_druid_glade(EConfig *ec, EConfigItem *item, struct _GtkWidget *paren
+ 	GladeXML *druidxml;
+ 	GtkWidget *w;
+ 	char *gladefile;
++	EMAccountEditor *emae = (EMAccountEditor *)data;
++
++	if (emae->type == EMAE_PAGES)
++		return NULL;
+ 
+ 	gladefile = g_build_filename (EVOLUTION_GLADEDIR,
+ 				      "mail-config.glade",
+@@ -2631,10 +2683,12 @@ emae_service_complete(EMAccountEditor *emae, EMAccountEditorService *service)
+ 	if (uri == NULL || (url = camel_url_new(uri, NULL)) == NULL)
+ 		return FALSE;
+ 
+-	if (CAMEL_PROVIDER_NEEDS(service->provider, CAMEL_URL_PART_HOST)
+-	    && (url->host == NULL || url->host[0] == 0))
+-		ok = FALSE;
+-
++	if (CAMEL_PROVIDER_NEEDS(service->provider, CAMEL_URL_PART_HOST)) {
++		if (url->host == NULL || url->host[0] == 0)
++			ok = FALSE;
++		else 
++			gtk_entry_set_text(service->hostname, url->host);
++	}
+ 	/* We only need the user if the service needs auth as well, i think */
+ 	if (ok
+ 	    && (service->needs_auth == NULL
+@@ -2654,6 +2708,37 @@ emae_service_complete(EMAccountEditor *emae, EMAccountEditorService *service)
+ 	return ok;
+ }
+ 
++enum {
++	GMAIL = 0,
++	YAHOO,
++	AOL
++};
++struct _server_prefill {
++	char *key;
++	char *recv;
++	char *send;
++	char *proto;
++	char *ssl;
++} mail_servers [] = {
++	{"gmail", "imap.gmail.com", "smtp.gmail.com", "imap", "always"},
++	{"yahoo", "pop3.yahoo.com", "smtp.yahoo.com", "pop", "never"},
++	{"aol", "imap.aol.com", "smtp.aol.com", "pop", "never"},
++	{"msn", "pop3.email.msn.com", "smtp.email.msn.com", "pop", "never"}
++};
++
++static int
++check_servers (char *server)
++{
++	int len = G_N_ELEMENTS(mail_servers), i;
++
++	for (i=0; i<len; i++) {
++		if (strstr(server, mail_servers[i].key) != NULL)
++			return i;
++	}
++
++	return -1;
++}
++
+ static gboolean
+ emae_check_complete(EConfig *ec, const char *pageid, void *data)
+ {
+@@ -2661,6 +2746,7 @@ emae_check_complete(EConfig *ec, const char *pageid, void *data)
+ 	int ok = TRUE;
+ 	const char *tmp;
+ 	EAccount *ea;
++	gboolean refresh = FALSE;
+ 
+ 	/* We use the page-check of various pages to 'prepare' or
+ 	   pre-load their values, only in the druid */
+@@ -2684,6 +2770,9 @@ emae_check_complete(EConfig *ec, const char *pageid, void *data)
+ 		} else if (!strcmp(pageid, "10.receive")) {
+ 			if (!emae->priv->receive_set) {
+ 				char *user, *at;
++				int index;
++				char *uri = e_account_get_string(emae->account, E_ACCOUNT_SOURCE_URL);
++				CamelURL *url;
+ 
+ 				emae->priv->receive_set = 1;
+ 				tmp = e_account_get_string(emae->account, E_ACCOUNT_ID_ADDRESS);
+@@ -2691,9 +2780,58 @@ emae_check_complete(EConfig *ec, const char *pageid, void *data)
+ 				user = g_alloca(at-tmp+1);
+ 				memcpy(user, tmp, at-tmp);
+ 				user[at-tmp] = 0;
++				at++;
++
++				index = check_servers(at);
+ 				gtk_entry_set_text(emae->priv->source.username, user);
+ 				gtk_entry_set_text(emae->priv->transport.username, user);
++				if (uri && (url = camel_url_new(uri, NULL)) != NULL) {
++					refresh = TRUE;
++					camel_url_set_protocol(url, mail_servers[index].proto);
++					camel_url_set_param(url, "use_ssl", mail_servers[index].ssl);
++					camel_url_set_host (url, mail_servers[index].recv);
++					camel_url_set_user (url, user);
++					gtk_entry_set_text(emae->priv->source.hostname, mail_servers[index].recv);
++					gtk_entry_set_text(emae->priv->transport.hostname, mail_servers[index].send);
++					uri = camel_url_to_string(url, 0);
++					e_account_set_string(emae->account, E_ACCOUNT_SOURCE_URL, uri);
++
++					g_free(uri);
++					camel_url_free(url);
++				} else {
++					g_warning("buz1\n");
++				}
++				
+ 			}
++		} else if (!strcmp(pageid, "30.send")) {
++				CamelURL *url;
++				char *at, *user;
++				int index;
++				char *uri = e_account_get_string(emae->account, E_ACCOUNT_TRANSPORT_URL);
++				
++				tmp = e_account_get_string(emae->account, E_ACCOUNT_ID_ADDRESS);
++				at = strchr(tmp, '@');
++				user = g_alloca(at-tmp+1);
++				memcpy(user, tmp, at-tmp);
++				user[at-tmp] = 0;
++				at++;
++
++				index = check_servers(at);
++				if (uri  && (url = camel_url_new(uri, NULL)) != NULL) {
++					refresh = TRUE;
++					camel_url_set_protocol (url, "smtp");
++					camel_url_set_param(url, "use_ssl", mail_servers[index].ssl);
++					camel_url_set_host (url, mail_servers[index].send);
++					camel_url_set_user (url, user);
++					uri = camel_url_to_string(url, 0);
++					e_account_set_string(emae->account, E_ACCOUNT_TRANSPORT_URL, uri);
++					g_free(uri);
++					camel_url_free(url);
++				} else {
++					g_warning("buz2\n");
++				}
++				
++		
+ 		} else if (!strcmp(pageid, "20.receive_options")) {
+ 			if (emae->priv->source.provider
+ 			    && emae->priv->extra_provider != emae->priv->source.provider) {
+@@ -2740,12 +2878,18 @@ emae_check_complete(EConfig *ec, const char *pageid, void *data)
+ 	}
+ 
+ 	if (ok && (pageid == NULL || !strcmp(pageid, "10.receive"))) {
++		if (emae->type == EMAE_PAGES && refresh) {
++			emae_refresh_providers(emae, &emae->priv->source);
++		}
+ 		ok = emae_service_complete(emae, &emae->priv->source);
+ 		if (!ok)
+ 			d(printf("receive page incomplete\n"));
+ 	}
+ 
+ 	if (ok && (pageid == NULL || !strcmp(pageid, "30.send"))) {
++		if (emae->type == EMAE_PAGES && refresh) {
++			emae_refresh_providers(emae, &emae->priv->transport);
++		}
+ 		ok = emae_service_complete(emae, &emae->priv->transport);
+ 		if (!ok)
+ 			d(printf("send page incomplete\n"));
+@@ -2763,6 +2907,12 @@ emae_check_complete(EConfig *ec, const char *pageid, void *data)
+ 	return ok;
+ }
+ 
++void
++em_account_editor_check (EMAccountEditor *emae, const char *page)
++{
++	emae_check_complete(emae->config, page, emae);
++}
++
+ /* HACK: FIXME: the component should listen to the account object directly */
+ static void
+ add_new_store (char *uri, CamelStore *store, void *user_data)
+@@ -2809,6 +2959,12 @@ emae_commit(EConfig *ec, GSList *items, void *data)
+ 	e_account_list_save(accounts);
+ }
+ 
++void
++em_account_editor_commit (EMAccountEditor *emae)
++{
++	emae_commit (emae->config, NULL, emae);
++}
++
+ static void
+ emae_editor_destroyed(GtkWidget *dialog, EMAccountEditor *emae)
+ {
+@@ -2928,7 +3084,11 @@ em_account_editor_construct(EMAccountEditor *emae, EAccount *account, em_account
+ 
+ 	target = em_config_target_new_account(ec, emae->account);
+ 	e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
+-	emae->editor = e_config_create_window((EConfig *)ec, NULL, type==EMAE_NOTEBOOK?_("Account Editor"):_("Evolution Account Assistant"));
+ 
+-	g_signal_connect(emae->editor, "destroy", G_CALLBACK(emae_editor_destroyed), emae);
++	if (type != EMAE_PAGES) {
++		emae->editor = e_config_create_window((EConfig *)ec, NULL, type==EMAE_NOTEBOOK?_("Account Editor"):_("Evolution Account Assistant"));
++		g_signal_connect(emae->editor, "destroy", G_CALLBACK(emae_editor_destroyed), emae);
++	} else {
++		e_config_create_widget((EConfig *)ec);
++	} 
+ }
+diff --git a/mail/em-account-editor.h b/mail/em-account-editor.h
+index 9a5b09a..42421c2 100644
+--- a/mail/em-account-editor.h
++++ b/mail/em-account-editor.h
+@@ -39,6 +39,7 @@ typedef struct _EMAccountEditorClass EMAccountEditorClass;
+ typedef enum {
+ 	EMAE_NOTEBOOK,
+ 	EMAE_DRUID,
++	EMAE_PAGES,
+ } em_account_editor_t;
+ 
+ struct _EMAccountEditor {
+@@ -54,6 +55,8 @@ struct _EMAccountEditor {
+ 	struct _EAccount *account; /* working account, must instant apply to this */
+ 	struct _EAccount *original; /* original account, not changed unless commit is invoked */
+ 
++	GtkWidget **pages; /* Pages for Anjal's page type editor */
++
+ 	guint do_signature:1;	/* allow editing signature */
+ };
+ 
+@@ -64,6 +67,9 @@ struct _EMAccountEditorClass {
+ GType em_account_editor_get_type(void);
+ 
+ EMAccountEditor *em_account_editor_new(struct _EAccount *account, em_account_editor_t type, char *id);
++EMAccountEditor *em_account_editor_new_for_pages(struct _EAccount *account, em_account_editor_t type, char *id, struct _GtkWidget **pages);
++void em_account_editor_commit (EMAccountEditor *emae);
++void em_account_editor_check (EMAccountEditor *emae, const char *page);
+ 
+ gboolean em_account_editor_save (EMAccountEditor *gui);
+ void em_account_editor_destroy (EMAccountEditor *gui);
+diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
+index 38f35d1..d884154 100644
+--- a/mail/em-composer-utils.c
++++ b/mail/em-composer-utils.c
+@@ -1713,7 +1713,7 @@ generate_account_hash (void)
+ 	return account_hash;
+ }
+ 
+-static EDestination **
++EDestination **
+ em_utils_camel_address_to_destination (CamelInternetAddress *iaddr)
+ {
+ 	EDestination *dest, **destv;
+@@ -1915,6 +1915,12 @@ get_reply_sender (CamelMimeMessage *message, CamelInternetAddress *to, CamelNNTP
+ 	}
+ }
+ 
++void
++em_utils_get_reply_sender (CamelMimeMessage *message, CamelInternetAddress *to, CamelNNTPAddress *postto)
++{
++	get_reply_sender (message, to, postto);
++}
++
+ static gboolean
+ get_reply_list (CamelMimeMessage *message, CamelInternetAddress *to)
+ {
+@@ -2028,6 +2034,13 @@ get_reply_all (CamelMimeMessage *message, CamelInternetAddress *to, CamelInterne
+ 	g_hash_table_destroy (rcpt_hash);
+ }
+ 
++void
++em_utils_get_reply_all (CamelMimeMessage *message, CamelInternetAddress *to, CamelInternetAddress *cc, CamelNNTPAddress *postto)
++{
++	get_reply_all (message, to, cc, postto);
++}
++
++
+ enum {
+ 	ATTRIB_UNKNOWN,
+ 	ATTRIB_CUSTOM,
+@@ -2285,6 +2298,21 @@ struct _reply_data {
+ 	int mode;
+ };
+ 
++char *
++em_utils_construct_composer_text (CamelMimeMessage *message, EMFormat *source)
++{
++	char *text, *credits;
++	ssize_t len = 0;
++	gboolean start_bottom = 0;
++	
++	credits = attribution_format (ATTRIBUTION, message);
++	text = em_utils_message_to_html (message, credits, EM_FORMAT_QUOTE_CITE, &len, source, start_bottom ? "<BR>" : NULL);
++
++	g_free (credits);
++	return text;
++}
++
++
+ static void
+ reply_to_message(CamelFolder *folder, const char *uid, CamelMimeMessage *message, void *user_data)
+ {
+diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h
+index d17a98c..8b5d279 100644
+--- a/mail/em-composer-utils.h
++++ b/mail/em-composer-utils.h
+@@ -34,9 +34,12 @@ extern "C" {
+ struct _CamelFolder;
+ struct _CamelMimeMessage;
+ struct _CamelException;
++struct _CamelInternetAddress;
++struct _CamelNNTPAddress;
+ struct _EMsgComposer;
+ struct _EMFormat;
+ struct _EAccount;
++struct _EDestination;
+ 
+ void em_composer_utils_setup_callbacks (struct _EMsgComposer *composer, struct _CamelFolder *folder, const char *uid,
+ 					guint32 flags, guint32 set, struct _CamelFolder *drafts, const char *drafts_uid);
+@@ -77,9 +80,15 @@ enum {
+ 	REPLY_MODE_LIST
+ };
+ 
++char *em_utils_construct_composer_text (struct _CamelMimeMessage *message, struct _EMFormat *source);
++void em_utils_get_reply_sender (struct _CamelMimeMessage *message, struct _CamelInternetAddress *to, struct _CamelNNTPAddress *postto);
++void em_utils_get_reply_all (struct _CamelMimeMessage *message, struct _CamelInternetAddress *to, struct _CamelInternetAddress *cc, struct _CamelNNTPAddress *postto);
++
++
+ void em_utils_reply_to_message (struct _CamelFolder *, const char *uid, struct _CamelMimeMessage *message, int mode, struct _EMFormat *source);
+ 
+ void em_utils_post_reply_to_message_by_uid (struct _CamelFolder *folder, const char *uid);
++struct _EDestination ** em_utils_camel_address_to_destination (struct _CamelInternetAddress *iaddr);
+ 
+ #ifdef __cplusplus
+ }
+diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
+index e7063e9..de40377 100644
+--- a/mail/em-folder-tree.c
++++ b/mail/em-folder-tree.c
+@@ -109,6 +109,7 @@ struct _EMFolderTreePrivate {
+ 	guint loaded_row_id;
+ 
+ 	GtkTreeRowReference *drag_row;
++	gboolean skip_double_click;
+ };
+ 
+ enum {
+@@ -436,6 +437,7 @@ em_folder_tree_init (EMFolderTree *emft)
+ 	priv->treeview = NULL;
+ 	priv->model = NULL;
+ 	priv->drag_row = NULL;
++	priv->skip_double_click = FALSE;
+ 
+ 	emft->priv = priv;
+ }
+@@ -2291,6 +2293,9 @@ emft_tree_button_press (GtkTreeView *treeview, GdkEventButton *event, EMFolderTr
+ 	gtk_tree_view_set_cursor (treeview, tree_path, NULL, FALSE);
+ 
+ 	if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
++		if (emft->priv->skip_double_click) {
++			return FALSE;
++		}
+ 		emft_tree_row_activated (treeview, tree_path, NULL, emft);
+ 		gtk_tree_path_free (tree_path);
+ 		return TRUE;
+@@ -2643,3 +2648,15 @@ emft_queue_save_state (EMFolderTree *emft)
+ 
+ 	priv->save_state_id = g_timeout_add_seconds (1, (GSourceFunc) emft_save_state, emft);
+ }
++
++GtkWidget *
++em_folder_tree_get_tree_view (EMFolderTree *emft)
++{
++	return emft->priv->treeview;
++}
++
++void
++em_folder_tree_set_skip_double_click (EMFolderTree *emft, gboolean skip)
++{
++	emft->priv->skip_double_click = skip;
++}
+diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h
+index e89be47..b02a4d8 100644
+--- a/mail/em-folder-tree.h
++++ b/mail/em-folder-tree.h
+@@ -94,6 +94,8 @@ EMFolderTreeModel *em_folder_tree_get_model (EMFolderTree *emft);
+ EMFolderTreeModelStoreInfo *em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store);
+ 
+ gboolean em_folder_tree_create_folder (EMFolderTree *emft, const char *full_name, const char *uri);
++GtkWidget * em_folder_tree_get_tree_view (EMFolderTree *emft);
++void em_folder_tree_set_skip_double_click (EMFolderTree *emft, gboolean skip);
+ 
+ #ifdef __cplusplus
+ }
+diff --git a/mail/mail-component.c b/mail/mail-component.c
+index 556715d..7d7547c 100644
+--- a/mail/mail-component.c
++++ b/mail/mail-component.c
+@@ -106,7 +106,7 @@ static void view_changed_timeout_remove (EComponentView *component_view);
+ 
+ #define PARENT_TYPE evolution_component_get_type ()
+ static BonoboObjectClass *parent_class = NULL;
+-
++const char *x_mailer = "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT;
+ #define OFFLINE 0
+ #define ONLINE 1
+ 
+diff --git a/mail/mail-ops.c b/mail/mail-ops.c
+index a8aa14d..42d778a 100644
+--- a/mail/mail-ops.c
++++ b/mail/mail-ops.c
+@@ -73,6 +73,8 @@
+ #define w(x)
+ #define d(x)
+ 
++extern const char *x_mailer;
++
+ /* used for both just filtering a folder + uid's, and for filtering a whole folder */
+ /* used both for fetching mail, and for filtering mail */
+ struct _filter_mail_msg {
+@@ -462,7 +464,7 @@ mail_send_message(CamelFolder *queue, const char *uid, const char *destination,
+ 	if (!message)
+ 		return;
+ 
+-	camel_medium_set_header (CAMEL_MEDIUM (message), "X-Mailer", "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT);
++	camel_medium_set_header (CAMEL_MEDIUM (message), "X-Mailer", x_mailer);
+ 
+ 	err = g_string_new("");
+ 	xev = mail_tool_remove_xevolution_headers (message);
+@@ -919,8 +921,7 @@ mail_append_mail (CamelFolder *folder, CamelMimeMessage *message, CamelMessageIn
+ 	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+ 
+ 	if (!camel_medium_get_header (CAMEL_MEDIUM (message), "X-Mailer"))
+-		camel_medium_set_header (CAMEL_MEDIUM (message), "X-Mailer",
+-					 "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT);
++		camel_medium_set_header (CAMEL_MEDIUM (message), "X-Mailer", x_mailer);
+ 
+ 	m = mail_msg_new (&append_mail_info);
+ 	m->folder = folder;
+diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
+index 124c736..b0486ab 100644
+--- a/widgets/misc/Makefile.am
++++ b/widgets/misc/Makefile.am
+@@ -19,6 +19,7 @@ privsolib_LTLIBRARIES =		\
+ 	libefilterbar.la
+ 
+ widgetsincludedir = $(privincludedir)/misc
++filterbarincludedir = $(privincludedir)/misc
+ 
+ if ENABLE_PILOT_CONDUITS
+ pilot_sources = e-pilot-settings.c
+@@ -155,9 +156,11 @@ libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la		\
+ 	$(EVOLUTON_MAIL_LIBS)						\
+ 	$(ICONV_LIBS)
+ 
++filterbarinclude_HEADERS = e-filter-bar.h
++
+ libefilterbar_la_SOURCES =	\
+ 	e-filter-bar.c		\
+-	e-filter-bar.h
++	$(filterbarinclude_HEADERS)
+ 
+ libefilterbar_la_LDFLAGS = $(NO_UNDEFINED)
+ 



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