[anjal] Patches for evo/eds of 2.27.x for Anjal
- From: Srinivasa Ragavan <sragavan src gnome org>
- To: svn-commits-list gnome org
- Subject: [anjal] Patches for evo/eds of 2.27.x for Anjal
- Date: Tue, 5 May 2009 05:02:27 -0400 (EDT)
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]