** Merge in notzed-messageinfo-branch, fix some minor conflicts.
authorNot Zed <NotZed@Ximian.com>
Fri, 12 Nov 2004 05:53:12 +0000 (05:53 +0000)
committerMichael Zucci <zucchi@src.gnome.org>
Fri, 12 Nov 2004 05:53:12 +0000 (05:53 +0000)
2004-11-12  Not Zed  <NotZed@Ximian.com>

        ** Merge in notzed-messageinfo-branch, fix some minor conflicts.

62 files changed:
camel/ChangeLog
camel/Makefile.am
camel/camel-digest-folder.c
camel/camel-disco-folder.c
camel/camel-filter-driver.c
camel/camel-filter-search.c
camel/camel-folder-search.c
camel/camel-folder-summary.c
camel/camel-folder-summary.h
camel/camel-folder-thread.c
camel/camel-folder.c
camel/camel-folder.h
camel/camel-string-utils.c
camel/camel-string-utils.h
camel/camel-types.h
camel/camel-vee-folder.c
camel/camel-vee-folder.h
camel/camel-vee-store.c
camel/camel-vee-summary.c [new file with mode: 0644]
camel/camel-vee-summary.h [new file with mode: 0644]
camel/camel-vtrash-folder.c
camel/providers/Makefile.am
camel/providers/imap/camel-imap-folder.c
camel/providers/imap/camel-imap-message-cache.c
camel/providers/imap/camel-imap-store.c
camel/providers/imap/camel-imap-summary.c
camel/providers/imap/camel-imap-summary.h
camel/providers/imap/camel-imap-utils.c
camel/providers/imap4/camel-imap4-folder.c
camel/providers/imap4/camel-imap4-search.c
camel/providers/imap4/camel-imap4-store.c
camel/providers/imap4/camel-imap4-summary.c
camel/providers/imap4/camel-imap4-summary.h
camel/providers/imapp/ChangeLog
camel/providers/imapp/camel-imapp-driver.c
camel/providers/imapp/camel-imapp-folder.c
camel/providers/imapp/camel-imapp-store.c
camel/providers/imapp/camel-imapp-store.h
camel/providers/imapp/camel-imapp-summary.c
camel/providers/imapp/camel-imapp-summary.h
camel/providers/imapp/camel-imapp-utils.c
camel/providers/imapp/camel-imapp-utils.h
camel/providers/local/camel-local-summary.c
camel/providers/local/camel-local-summary.h
camel/providers/local/camel-maildir-folder.c
camel/providers/local/camel-maildir-store.c
camel/providers/local/camel-maildir-summary.c
camel/providers/local/camel-maildir-summary.h
camel/providers/local/camel-mbox-folder.c
camel/providers/local/camel-mbox-store.c
camel/providers/local/camel-mbox-summary.c
camel/providers/local/camel-mbox-summary.h
camel/providers/local/camel-mh-folder.c
camel/providers/local/camel-mh-store.c
camel/providers/local/camel-mh-summary.c
camel/providers/local/camel-mh-summary.h
camel/providers/local/camel-spool-folder.c
camel/providers/local/camel-spool-summary.c
camel/providers/local/camel-spool-summary.h
camel/providers/nntp/camel-nntp-folder.c
camel/providers/nntp/camel-nntp-summary.c
camel/providers/nntp/camel-nntp-summary.h

index 0ca4b09..6fe3ebb 100644 (file)
@@ -1,3 +1,7 @@
+2004-11-12  Not Zed  <NotZed@Ximian.com>
+
+        ** Merge in notzed-messageinfo-branch, fix some minor conflicts.
+
 2004-11-11  Jeffrey Stedfast  <fejj@novell.com>
 
        * providers/imap4/camel-imap4-store.c (imap4_reconnect): Free the
        (camel_imap4_store_summary_get_folder_info): Fixed the logic a
        bit.
 
+2004-11-11  Not Zed  <NotZed@Ximian.com>
+
+       * providers/imap4/*: Update for folder-summary api changes.
+
+       * providers/imap4/camel-imap4-store.c (imap4_build_folder_info):
+       clean up the logic for getting counts from the folder, we have
+       code to do this already.  Also always run it against the selected
+       folder, does'nt need to have FAST bit unset.
+
+       * camel-folder-summary.c (camel_folder_summary_info_new): removed.
+
+       * camel-string-utils.c (camel_pstring_strdup, camel_pstring_free):
+       pooled string allocators.  Oh so much easier than the poolv thing,
+       and these refcount too.
+
+       * camel-folder-summary.h: put message_id back into the summary.
+
+2004-11-08  Not Zed  <NotZed@Ximian.com>
+
+       * camel-folder.c (camel_folder_get_deleted_message_count): use
+       getv method to get the deleted count.
+       (get_deleted_message_count): removed.
+
+       * camel-vtrash-folder.c (vtrash_getv): override the unread count
+       to ignore junked or deleted.
+
+       * camel-folder.c (folder_getv): ignore junked and deleted in the
+       unread count.
+
+       * camel-vee-folder.c (camel_vee_folder_finalise): changed the
+       logic slightly not to call internal functions directly.
+       (vee_delete): implement, remove all our folders when we're
+       deleted, to give unmatched at least a snowflakes chance in hell of
+       working.
+
+       * camel-vtrash-folder.c (vtrash_search_by_expression)
+       (vtrash_search_by_uids, vtrash_folder_changed, vtrash_add_folder)
+       (vtrash_remove_folder, vtrash_rebuild_folder): implement
+       vtrash-optimised versions.  Much faster.
+
+       * camel-vee-folder.c (camel_vee_folder_set_folders): don't rebuild
+       the folder.
+       (camel_vee_folder_add_folder): track folders here, but invoke
+       virtual method to let subclasses know about it.
+       (camel_vee_folder_remove_folder): similar.
+       (vee_search_by_uids): free the folder_uids array with TRUE,
+       plugging memory leak.
+
+2004-11-06  Not Zed  <NotZed@Ximian.com>
+
+       * camel-vee-folder.c: Removed vname, use Folder->full_name
+       instead.  Make add_folder/remove_folder/set_expression/set_folders
+       virtual methods.
+       (vee_add_folder): virtual implementation.
+
+       * camel-vee-summary.c (camel_vee_summary_add): remove folder arg.
+
+2004-11-05  Not Zed  <NotZed@Ximian.com>
+
+       * camel-vee-summary.c (vee_info_set_flags): don't emit changed for
+       ourselves, let it filter through the changed handler, otherwise we
+       do it twice.
+       (vee_info_set_user_tag, vee_info_set_user_flag): same.
+
+       * camel-folder-summary.c (message_info_new_from_header): use the
+       string pool for allocations.
+       (message_info_load): same here.
+       (camel_pstring_strdup): noop for NULL or ""
+       (camel_pstring_free): same.
+       (summary_assign_uid): don't always assing the flagged bit, der.
+
+2004-11-02  Not Zed  <NotZed@Ximian.com>
+
+       * camel-folder-summary.c (camel_pstring_strdup)
+       (camel_pstring_free, message_info_free, message_info_clone):
+       'uniquify' the strings.
+
 2004-10-28  Jeffrey Stedfast  <fejj@ximian.com>
 
        * providers/imap4/camel-imap4-summary.c (envelope_decode_nstring):
index 51ec97c..f835bbf 100644 (file)
@@ -119,6 +119,7 @@ libcamel_la_SOURCES =                               \
        camel-utf8.c                            \
        camel-vee-folder.c                      \
        camel-vee-store.c                       \
+       camel-vee-summary.c                     \
        camel-vtrash-folder.c                   \
        camel.c
 
@@ -224,6 +225,7 @@ libcamelinclude_HEADERS =                   \
        camel-utf8.h                            \
        camel-vee-folder.h                      \
        camel-vee-store.h                       \
+       camel-vee-summary.h                     \
        camel-vtrash-folder.h                   \
        camel.h
 
index 1e814fd..6de3064 100644 (file)
@@ -196,9 +196,7 @@ digest_add_multipart (CamelFolder *folder, CamelMultipart *multipart, const char
                }
                
                info = camel_folder_summary_info_new_from_message (folder->summary, CAMEL_MIME_MESSAGE (wrapper));
-               
-               uid = g_strdup_printf ("%s%d", preuid, i);
-               camel_message_info_set_uid (info, uid);
+               info->uid = g_strdup_printf ("%s%d", preuid, i);
                camel_folder_summary_add (folder->summary, info);
        }
 }
index 7e4e653..af670a6 100644 (file)
@@ -345,9 +345,9 @@ disco_expunge (CamelFolder *folder, CamelException *ex)
        count = camel_folder_summary_count (folder->summary);
        for (i = 0; i < count; i++) {
                info = camel_folder_summary_index (folder->summary, i);
-               if (info->flags & CAMEL_MESSAGE_DELETED)
+               if (camel_message_info_flags(info) & CAMEL_MESSAGE_DELETED)
                        g_ptr_array_add (uids, g_strdup (camel_message_info_uid (info)));
-               camel_folder_summary_info_free (folder->summary, info);
+               camel_message_info_free(info);
        }
 
        disco_expunge_uids (folder, uids, ex);
index dfb88b8..e8b499d 100644 (file)
@@ -575,7 +575,7 @@ do_colour (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDr
                if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
                        camel_folder_set_message_user_tag (p->source, p->uid, "colour", argv[0]->value.string);
                else
-                       camel_tag_set (&p->info->user_tags, "colour", argv[0]->value.string);
+                       camel_message_info_set_user_tag(p->info, "colour", argv[0]->value.string);
                camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set colour to %s", argv[0]->value.string);
        }
        
@@ -595,7 +595,7 @@ do_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDri
                if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
                        camel_folder_set_message_user_tag (p->source, p->uid, "score", value);
                else
-                       camel_tag_set (&p->info->user_tags, "score", value);
+                       camel_message_info_set_user_tag(p->info, "score", value);
                camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set score to %d", argv[0]->value.number);
                g_free (value);
        }
@@ -615,7 +615,7 @@ set_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDri
                if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
                        camel_folder_set_message_flags (p->source, p->uid, flags, ~0);
                else
-                       p->info->flags |= flags | CAMEL_MESSAGE_FOLDER_FLAGGED;
+                       camel_message_info_set_flags(p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
                camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set %s flag", argv[0]->value.string);
        }
        
@@ -634,7 +634,7 @@ unset_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterD
                if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
                        camel_folder_set_message_flags (p->source, p->uid, flags, 0);
                else
-                       p->info->flags = (p->info->flags & ~flags) | CAMEL_MESSAGE_FOLDER_FLAGGED;
+                       camel_message_info_set_flags(p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, 0);
                camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Unset %s flag", argv[0]->value.string);
        }
        
@@ -1150,8 +1150,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const char *mbox, co
                        goto fail;
                }
                
-               info = camel_message_info_new_from_header(((CamelMimePart *)msg)->headers);
-               info->size = camel_mime_parser_tell(mp) - last;
+               info = camel_message_info_new_from_header(NULL, ((CamelMimePart *)msg)->headers);
+               ((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - last;
                last = camel_mime_parser_tell(mp);
                status = camel_filter_driver_filter_message (driver, msg, info, NULL, NULL, source_url, 
                                                             original_source_url ? original_source_url : source_url, ex);
@@ -1365,10 +1365,10 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage
                }
                
                h = CAMEL_MIME_PART (message)->headers;
-               info = camel_message_info_new_from_header (h);
+               info = camel_message_info_new_from_header (NULL, h);
                freeinfo = TRUE;
        } else {
-               if (info->flags & CAMEL_MESSAGE_DELETED)
+               if (camel_message_info_flags(info) & CAMEL_MESSAGE_DELETED)
                        return 0;
                
                uid = camel_message_info_uid (info);
@@ -1443,7 +1443,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage
                if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
                        camel_folder_set_message_flags(p->source, p->uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0);
                else
-                       info->flags |= CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED;
+                       camel_message_info_set_flags(info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
        }
        
        /* Logic: if !Moved and there exists a default folder... */
index 2d057ef..24578e4 100644 (file)
@@ -365,7 +365,7 @@ user_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessage
        /* performs an OR of all words */
        for (i = 0; i < argc && !truth; i++) {
                if (argv[i]->type == ESEXP_RES_STRING
-                   && camel_flag_get (&fms->info->user_flags, argv[i]->value.string)) {
+                   && camel_message_info_user_flag(fms->info, argv[i]->value.string)) {
                        truth = TRUE;
                        break;
                }
@@ -386,7 +386,7 @@ system_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessa
                e_sexp_fatal_error(f, _("Invalid arguments to (system-flag)"));
        
        r = e_sexp_result_new (f, ESEXP_RES_BOOL);
-       r->value.bool = camel_system_flag_get (fms->info->flags, argv[0]->value.string);
+       r->value.bool = camel_system_flag_get (camel_message_info_flags(fms->info), argv[0]->value.string);
        
        return r;
 }
@@ -400,7 +400,7 @@ user_tag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageS
        if (argc != 1 || argv[0]->type != ESEXP_RES_STRING)
                e_sexp_fatal_error(f, _("Invalid arguments to (user-tag)"));
        
-       tag = camel_tag_get (&fms->info->user_tags, argv[0]->value.string);
+       tag = camel_message_info_user_tag(fms->info, argv[0]->value.string);
        
        r = e_sexp_result_new (f, ESEXP_RES_STRING);
        r->value.string = g_strdup (tag ? tag : "");
@@ -491,7 +491,7 @@ get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageS
        ESExpResult *r;
        
        r = e_sexp_result_new(f, ESEXP_RES_INT);
-       r->value.number = fms->info->size / 1024;
+       r->value.number = camel_message_info_size(fms->info) / 1024;
 
        return r;
 }
index b7578ba..ff5dee6 100644 (file)
@@ -861,7 +861,7 @@ check_header(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolder
                        header = camel_message_info_subject(search->current);
                } else if (!strcasecmp(headername, "date")) {
                        /* FIXME: not a very useful form of the date */
-                       sprintf(strbuf, "%d", (int)search->current->date_sent);
+                       sprintf(strbuf, "%d", (int)camel_message_info_date_sent(search->current));
                        header = strbuf;
                } else if (!strcasecmp(headername, "from")) {
                        header = camel_message_info_from(search->current);
@@ -1247,7 +1247,7 @@ search_user_flag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFo
                /* performs an OR of all words */
                for (i=0;i<argc && !truth;i++) {
                        if (argv[i]->type == ESEXP_RES_STRING
-                           && camel_flag_get(&search->current->user_flags, argv[i]->value.string)) {
+                           && camel_message_info_user_flag(search->current, argv[i]->value.string)) {
                                truth = TRUE;
                                break;
                        }
@@ -1273,7 +1273,7 @@ search_system_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, Came
                gboolean truth = FALSE;
                
                if (argc == 1)
-                       truth = camel_system_flag_get (search->current->flags, argv[0]->value.string);
+                       truth = camel_system_flag_get (camel_message_info_flags(search->current), argv[0]->value.string);
                
                r = e_sexp_result_new(f, ESEXP_RES_BOOL);
                r->value.bool = truth;
@@ -1294,7 +1294,7 @@ search_user_tag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFol
        r(printf("executing user-tag\n"));
        
        if (argc == 1)
-               value = camel_tag_get (&search->current->user_tags, argv[0]->value.string);
+               value = camel_message_info_user_tag(search->current, argv[0]->value.string);
        
        r = e_sexp_result_new(f, ESEXP_RES_STRING);
        r->value.string = g_strdup (value ? value : "");
@@ -1313,7 +1313,7 @@ search_get_sent_date(struct _ESExp *f, int argc, struct _ESExpResult **argv, Cam
        if (s->current) {
                r = e_sexp_result_new(f, ESEXP_RES_INT);
 
-               r->value.number = s->current->date_sent;
+               r->value.number = camel_message_info_date_sent(s->current);
        } else {
                r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
                r->value.ptrarray = g_ptr_array_new ();
@@ -1333,7 +1333,7 @@ search_get_received_date(struct _ESExp *f, int argc, struct _ESExpResult **argv,
        if (s->current) {
                r = e_sexp_result_new(f, ESEXP_RES_INT);
 
-               r->value.number = s->current->date_received;
+               r->value.number = camel_message_info_date_received(s->current);
        } else {
                r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
                r->value.ptrarray = g_ptr_array_new ();
@@ -1364,7 +1364,7 @@ search_get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFo
        /* are we inside a match-all? */
        if (s->current) {
                r = e_sexp_result_new (f, ESEXP_RES_INT);
-               r->value.number = s->current->size / 1024;
+               r->value.number = camel_message_info_size(s->current) / 1024;
        } else {
                r = e_sexp_result_new (f, ESEXP_RES_ARRAY_PTR);
                r->value.ptrarray = g_ptr_array_new ();
index fdffcff..57bf271 100644 (file)
@@ -37,6 +37,9 @@
 
 #include "camel-folder-summary.h"
 
+/* for change events, perhaps we should just do them ourselves */
+#include "camel-folder.h"
+
 #include <camel/camel-file-utils.h>
 #include <camel/camel-mime-filter.h>
 #include <camel/camel-mime-filter-index.h>
@@ -90,14 +93,14 @@ static int my_list_size(struct _node **list);
 static int summary_header_load(CamelFolderSummary *, FILE *);
 static int summary_header_save(CamelFolderSummary *, FILE *);
 
-static CamelMessageInfo * message_info_new(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg);
 static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
 static int               message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *);
 static void              message_info_free(CamelFolderSummary *, CamelMessageInfo *);
 
-static CamelMessageContentInfo * content_info_new(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageContentInfo * content_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageContentInfo * content_info_new_from_message(CamelFolderSummary *s, CamelMimePart *mp);
 static CamelMessageContentInfo * content_info_load(CamelFolderSummary *, FILE *);
@@ -116,31 +119,6 @@ static void camel_folder_summary_finalize   (CamelObject *obj);
 static CamelObjectClass *camel_folder_summary_parent;
 
 static void
-camel_folder_summary_class_init (CamelFolderSummaryClass *klass)
-{
-       camel_folder_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ());
-
-       klass->summary_header_load = summary_header_load;
-       klass->summary_header_save = summary_header_save;
-
-       klass->message_info_new  = message_info_new;
-       klass->message_info_new_from_parser = message_info_new_from_parser;
-       klass->message_info_new_from_message = message_info_new_from_message;
-       klass->message_info_load = message_info_load;
-       klass->message_info_save = message_info_save;
-       klass->message_info_free = message_info_free;
-
-       klass->content_info_new  = content_info_new;
-       klass->content_info_new_from_parser = content_info_new_from_parser;
-       klass->content_info_new_from_message = content_info_new_from_message;
-       klass->content_info_load = content_info_load;
-       klass->content_info_save = content_info_save;
-       klass->content_info_free = content_info_free;
-
-       klass->next_uid_string = next_uid_string;
-}
-
-static void
 camel_folder_summary_init (CamelFolderSummary *s)
 {
        struct _CamelFolderSummaryPrivate *p;
@@ -149,7 +127,7 @@ camel_folder_summary_init (CamelFolderSummary *s)
 
        p->filter_charset = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
 
-       s->message_info_size = sizeof(CamelMessageInfo);
+       s->message_info_size = sizeof(CamelMessageInfoBase);
        s->content_info_size = sizeof(CamelMessageContentInfo);
 
        s->message_info_chunks = NULL;
@@ -249,17 +227,21 @@ camel_folder_summary_get_type (void)
 
 /**
  * camel_folder_summary_new:
+ * @folder: Parent folder.  It will hold a ref to us, not the other way around.
  *
  * Create a new CamelFolderSummary object.
  * 
  * Return value: A new CamelFolderSummary widget.
  **/
 CamelFolderSummary *
-camel_folder_summary_new (void)
+camel_folder_summary_new (struct _CamelFolder *folder)
 {
-       CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ()));  return new;
-}
+       CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ()));
 
+       new->folder = folder;
+
+       return new;
+}
 
 /**
  * camel_folder_summary_set_filename:
@@ -340,7 +322,6 @@ camel_folder_summary_count(CamelFolderSummary *s)
  * 
  * Return value: The summary item, or NULL if the index @i is out
  * of range.
- * It must be freed using camel_folder_summary_info_free().
  **/
 CamelMessageInfo *
 camel_folder_summary_index(CamelFolderSummary *s, int i)
@@ -406,8 +387,9 @@ camel_folder_summary_array_free(CamelFolderSummary *s, GPtrArray *array)
 {
        int i;
 
+       /* FIXME: do the locking around the whole lot to make it faster */
        for (i=0;i<array->len;i++)
-               camel_folder_summary_info_free(s, array->pdata[i]);
+               camel_message_info_free(array->pdata[i]);
 
        g_ptr_array_free(array, TRUE);
 }
@@ -424,7 +406,6 @@ camel_folder_summary_array_free(CamelFolderSummary *s, GPtrArray *array)
  * 
  * Return value: The summary item, or NULL if the uid @uid
  * is not available.
- * It must be freed using camel_folder_summary_info_free().
  **/
 CamelMessageInfo *
 camel_folder_summary_uid(CamelFolderSummary *s, const char *uid)
@@ -560,10 +541,11 @@ camel_folder_summary_load(CamelFolderSummary *s)
                if (mi == NULL)
                        goto error;
 
+               /* FIXME: this should be done differently, how i don't know */
                if (s->build_content) {
-                       mi->content = perform_content_info_load(s, in);
-                       if (mi->content == NULL) {
-                               camel_folder_summary_info_free(s, mi);
+                       ((CamelMessageInfoBase *)mi)->content = perform_content_info_load(s, in);
+                       if (((CamelMessageInfoBase *)mi)->content == NULL) {
+                               camel_message_info_free(mi);
                                goto error;
                        }
                }
@@ -631,6 +613,8 @@ camel_folder_summary_save(CamelFolderSummary *s)
        CamelMessageInfo *mi;
        char *path;
 
+       g_assert(s->message_info_size >= sizeof(CamelMessageInfoBase));
+
        if (s->summary_path == NULL
            || (s->flags & CAMEL_SUMMARY_DIRTY) == 0)
                return 0;
@@ -665,7 +649,7 @@ camel_folder_summary_save(CamelFolderSummary *s)
                        goto exception;
                
                if (s->build_content) {
-                       if (perform_content_info_save (s, out, mi->content) == -1)
+                       if (perform_content_info_save (s, out, ((CamelMessageInfoBase *)mi)->content) == -1)
                                goto exception;
                }
        }
@@ -740,8 +724,8 @@ summary_assign_uid(CamelFolderSummary *s, CamelMessageInfo *info)
 
        uid = camel_message_info_uid(info);
        if (uid == NULL || uid[0] == 0) {
-               camel_message_info_set_uid(info, camel_folder_summary_next_uid_string(s));
-               uid = camel_message_info_uid(info);
+               g_free(info->uid);
+               uid = info->uid = camel_folder_summary_next_uid_string(s);
        }
 
        CAMEL_SUMMARY_LOCK(s, summary_lock);
@@ -751,13 +735,14 @@ summary_assign_uid(CamelFolderSummary *s, CamelMessageInfo *info)
                if (mi == info)
                        return 0;
                d(printf ("Trying to insert message with clashing uid (%s).  new uid re-assigned", camel_message_info_uid(info)));
-               camel_message_info_set_uid(info, camel_folder_summary_next_uid_string(s));
-               uid = camel_message_info_uid(info);
-               info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+               g_free(info->uid);
+               uid = info->uid = camel_folder_summary_next_uid_string(s);
+               camel_message_info_set_flags(info, CAMEL_MESSAGE_FOLDER_FLAGGED, CAMEL_MESSAGE_FOLDER_FLAGGED);
                CAMEL_SUMMARY_LOCK(s, summary_lock);
        }
 
        CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+
        return 1;
 }
 
@@ -866,12 +851,11 @@ CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *s, C
  * 
  * Create a new info record from a header.
  * 
- * Return value: Guess?  This info record MUST be freed using
- * camel_folder_summary_info_free(), camel_message_info_free() will not work.
+ * Return value: Guess?  Free using camel_message_info_free().
  **/
 CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 {
-       return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s))) -> message_info_new(s, h);
+       return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s))) -> message_info_new_from_header(s, h);
 }
 
 /**
@@ -892,8 +876,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *
  * Once complete, the parser will be positioned at the end of
  * the message.
  *
- * Return value: Guess?  This info record MUST be freed using
- * camel_folder_summary_info_free(), camel_message_info_free() will not work.
+ * Return value: Guess?
  **/
 CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
 {
@@ -928,7 +911,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *
                }
 
                /* always scan the content info, even if we dont save it */
-               info->content = summary_build_content_info(s, info, mp);
+               ((CamelMessageInfoBase *)info)->content = summary_build_content_info(s, info, mp);
 
                if (name) {
                        camel_index_write_name(p->index, name);
@@ -938,7 +921,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *
 
                CAMEL_SUMMARY_UNLOCK(s, filter_lock);
 
-               info->size = camel_mime_parser_tell(mp) - start;
+               ((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - start;
        }
        return info;
 }
@@ -982,7 +965,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary
                }
        }
 
-       info->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg);
+       ((CamelMessageInfoBase *)info)->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg);
 
        if (name) {
                camel_index_write_name(p->index, name);
@@ -1017,58 +1000,6 @@ camel_folder_summary_content_info_free(CamelFolderSummary *s, CamelMessageConten
 }
 
 /**
- * camel_folder_summary_info_free:
- * @s: 
- * @mi: 
- * 
- * Unref and potentially free the message info @mi, and all associated memory.
- **/
-void camel_folder_summary_info_free(CamelFolderSummary *s, CamelMessageInfo *mi)
-{
-       CamelMessageContentInfo *ci;
-
-       g_assert(mi);
-       g_assert(s);
-
-       CAMEL_SUMMARY_LOCK(s, ref_lock);
-
-       g_assert(mi->refcount >= 1);
-
-       mi->refcount--;
-       if (mi->refcount > 0) {
-               CAMEL_SUMMARY_UNLOCK(s, ref_lock);
-               return;
-       }
-
-       CAMEL_SUMMARY_UNLOCK(s, ref_lock);
-
-       ci = mi->content;
-
-       ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_free(s, mi);             
-       if (s->build_content && ci) {
-               camel_folder_summary_content_info_free(s, ci);
-       }
-}
-
-/**
- * camel_folder_summary_info_ref:
- * @s: 
- * @mi: 
- * 
- * Add an extra reference to @mi.
- **/
-void camel_folder_summary_info_ref(CamelFolderSummary *s, CamelMessageInfo *mi)
-{
-       g_assert(mi);
-       g_assert(s);
-
-       CAMEL_SUMMARY_LOCK(s, ref_lock);
-       g_assert(mi->refcount >= 1);
-       mi->refcount++;
-       CAMEL_SUMMARY_UNLOCK(s, ref_lock);
-}
-
-/**
  * camel_folder_summary_touch:
  * @s: 
  * 
@@ -1100,7 +1031,7 @@ camel_folder_summary_clear(CamelFolderSummary *s)
        }
 
        for (i=0;i<s->messages->len;i++)
-               camel_folder_summary_info_free(s, s->messages->pdata[i]);
+               camel_message_info_free(s->messages->pdata[i]);
 
        g_ptr_array_set_size(s->messages, 0);
        g_hash_table_destroy(s->messages_uid);
@@ -1124,7 +1055,7 @@ void camel_folder_summary_remove(CamelFolderSummary *s, CamelMessageInfo *info)
        s->flags |= CAMEL_SUMMARY_DIRTY;
        CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 
-       camel_folder_summary_info_free(s, info);
+       camel_message_info_free(info);
 }
 
 /**
@@ -1147,7 +1078,7 @@ void camel_folder_summary_remove_uid(CamelFolderSummary *s, const char *uid)
                CAMEL_SUMMARY_UNLOCK(s, ref_lock);
                CAMEL_SUMMARY_UNLOCK(s, summary_lock);
                camel_folder_summary_remove(s, oldinfo);
-               camel_folder_summary_info_free(s, oldinfo);
+               camel_message_info_free(oldinfo);
         } else {
                CAMEL_SUMMARY_UNLOCK(s, ref_lock);
                CAMEL_SUMMARY_UNLOCK(s, summary_lock);
@@ -1172,7 +1103,7 @@ void camel_folder_summary_remove_index(CamelFolderSummary *s, int index)
                s->flags |= CAMEL_SUMMARY_DIRTY;
 
                CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-               camel_folder_summary_info_free(s, info);
+               camel_message_info_free(info);
        } else {
                CAMEL_SUMMARY_UNLOCK(s, summary_lock);
        }
@@ -1213,7 +1144,7 @@ void camel_folder_summary_remove_range(CamelFolderSummary *s, int start, int end
                CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 
                for (i=start;i<end;i++)
-                       camel_folder_summary_info_free(s, infos[i-start]);
+                       camel_message_info_free(infos[i-start]);
                g_free(infos);
        } else {
                CAMEL_SUMMARY_UNLOCK(s, summary_lock);
@@ -1459,18 +1390,20 @@ summary_header_save(CamelFolderSummary *s, FILE *out)
        count = camel_folder_summary_count(s);
        for (i=0; i<count; i++) {
                CamelMessageInfo *info = camel_folder_summary_index(s, i);
+               guint32 flags;
 
                if (info == NULL)
                        continue;
 
-               if ((info->flags & CAMEL_MESSAGE_SEEN) == 0)
+               flags = camel_message_info_flags(info);
+               if ((flags & CAMEL_MESSAGE_SEEN) == 0)
                        unread++;
-               if ((info->flags & CAMEL_MESSAGE_DELETED) != 0)
+               if ((flags & CAMEL_MESSAGE_DELETED) != 0)
                        deleted++;
-               if ((info->flags & CAMEL_MESSAGE_JUNK) != 0)
+               if ((flags & CAMEL_MESSAGE_JUNK) != 0)
                        junk++;
 
-               camel_folder_summary_info_free(s, info);
+               camel_message_info_free(info);
        }
 
        camel_file_util_encode_fixed_int32(out, count);
@@ -1491,7 +1424,7 @@ static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *s, Ca
        case CAMEL_MIME_PARSER_STATE_HEADER:
        case CAMEL_MIME_PARSER_STATE_MESSAGE:
        case CAMEL_MIME_PARSER_STATE_MULTIPART:
-               mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new(s, camel_mime_parser_headers_raw(mp));
+               mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, camel_mime_parser_headers_raw(mp));
                break;
        default:
                g_error("Invalid parser state");
@@ -1508,7 +1441,7 @@ static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary
        case CAMEL_MIME_PARSER_STATE_HEADER:
        case CAMEL_MIME_PARSER_STATE_MESSAGE:
        case CAMEL_MIME_PARSER_STATE_MULTIPART:
-               ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new(s, camel_mime_parser_headers_raw(mp));
+               ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, camel_mime_parser_headers_raw(mp));
                if (ci) {
                        ci->type = camel_mime_parser_content_type(mp);
                        camel_content_type_ref(ci->type);
@@ -1525,7 +1458,7 @@ static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, C
 {
        CamelMessageInfo *mi;
 
-       mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new(s, ((CamelMimePart *)msg)->headers);
+       mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
 
        return mi;
 }
@@ -1534,7 +1467,7 @@ static CamelMessageContentInfo * content_info_new_from_message(CamelFolderSummar
 {
        CamelMessageContentInfo *ci;
 
-       ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new(s, mp->headers);
+       ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, mp->headers);
 
        return ci;
 }
@@ -1574,37 +1507,6 @@ summary_format_string (struct _camel_header_raw *h, const char *name, const char
 }
 
 /**
- * camel_folder_summary_info_new:
- * @s: 
- * 
- * Allocate a new camel message info, suitable for adding
- * to this summary.
- * 
- * Return value: 
- **/
-CamelMessageInfo *
-camel_folder_summary_info_new(CamelFolderSummary *s)
-{
-       CamelMessageInfo *mi;
-
-       CAMEL_SUMMARY_LOCK(s, alloc_lock);
-       if (s->message_info_chunks == NULL)
-               s->message_info_chunks = e_memchunk_new(32, s->message_info_size);
-       mi = e_memchunk_alloc(s->message_info_chunks);
-       CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
-
-       memset(mi, 0, s->message_info_size);
-#ifdef DOEPOOLV
-       mi->strings = e_poolv_new (s->message_info_strings);
-#endif
-#ifdef DOESTRV
-       mi->strings = e_strv_new(s->message_info_strings);
-#endif
-       mi->refcount = 1;
-       return mi;
-}
-
-/**
  * camel_folder_summary_content_info_new:
  * @s: 
  * 
@@ -1629,9 +1531,9 @@ camel_folder_summary_content_info_new(CamelFolderSummary *s)
 }
 
 static CamelMessageInfo *
-message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 {
-       CamelMessageInfo *mi;
+       CamelMessageInfoBase *mi;
        const char *received;
        guchar digest[16];
        struct _camel_header_references *refs, *irt, *scan;
@@ -1641,12 +1543,12 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
        CamelContentType *ct = NULL;
        const char *content, *charset = NULL;
 
-       mi = camel_folder_summary_info_new(s);
+       mi = (CamelMessageInfoBase *)camel_message_info_new(s);
 
        if ((content = camel_header_raw_find(&h, "Content-Type", NULL))
             && (ct = camel_content_type_decode(content))
             && (charset = camel_content_type_param(ct, "charset"))
-            && (strcasecmp(charset, "us-ascii") == 0))
+            && (g_ascii_strcasecmp(charset, "us-ascii") == 0))
                charset = NULL;
        
        charset = charset ? e_iconv_charset_name (charset) : NULL;
@@ -1660,25 +1562,17 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
        if (ct)
                camel_content_type_unref(ct);
 
-#ifdef DOEPOOLV
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_FROM, from, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_TO, to, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_CC, cc, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist, TRUE);
-#elif defined (DOESTRV)
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_FROM, from);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_TO, to);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_CC, cc);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist);
-#else
-       mi->subject = subject;
-       mi->from = from;
-       mi->to = to;
-       mi->cc = cc;
-       mi->mlist = mlist;
-#endif
+       mi->subject = camel_pstring_strdup(subject);
+       mi->from = camel_pstring_strdup(from);
+       mi->to = camel_pstring_strdup(to);
+       mi->cc = camel_pstring_strdup(cc);
+       mi->mlist = camel_pstring_strdup(mlist);
+
+       g_free(subject);
+       g_free(from);
+       g_free(to);
+       g_free(cc);
+       g_free(mlist);
 
        mi->user_flags = NULL;
        mi->user_tags = NULL;
@@ -1727,19 +1621,18 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
                camel_header_references_list_clear(&refs);
        }
 
-       return mi;
+       return (CamelMessageInfo *)mi;
 }
 
-
 static CamelMessageInfo *
 message_info_load(CamelFolderSummary *s, FILE *in)
 {
-       CamelMessageInfo *mi;
+       CamelMessageInfoBase *mi;
        guint count;
        int i;
        char *subject, *from, *to, *cc, *mlist, *uid;;
 
-       mi = camel_folder_summary_info_new(s);
+       mi = (CamelMessageInfoBase *)camel_message_info_new(s);
 
        io(printf("Loading message info\n"));
 
@@ -1754,28 +1647,18 @@ message_info_load(CamelFolderSummary *s, FILE *in)
        camel_file_util_decode_string(in, &cc);
        camel_file_util_decode_string(in, &mlist);
 
-#ifdef DOEPOOLV
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_UID, uid, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_FROM, from, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_TO, to, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_CC, cc, TRUE);
-       e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist, TRUE);
-#elif defined (DOESTRV)
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_UID, uid);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_FROM, from);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_TO, to);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_CC, cc);
-       e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist);
-#else
        mi->uid = uid;
-       mi->subject = subject;
-       mi->from = from;
-       mi->to = to;
-       mi->cc = cc;
-       mi->mlist = mlist;
-#endif
+       mi->subject = camel_pstring_strdup(subject);
+       mi->from = camel_pstring_strdup(from);
+       mi->to = camel_pstring_strdup(to);
+       mi->cc = camel_pstring_strdup(cc);
+       mi->mlist = camel_pstring_strdup(mlist);
+
+       g_free(subject);
+       g_free(from);
+       g_free(to);
+       g_free(cc);
+       g_free(mlist);
 
        mi->content = NULL;
 
@@ -1819,21 +1702,22 @@ message_info_load(CamelFolderSummary *s, FILE *in)
        }
 
        if (!ferror(in))
-               return mi;
+               return (CamelMessageInfo *)mi;
 
 error:
-       camel_folder_summary_info_free(s, mi);
+       camel_message_info_free((CamelMessageInfo *)mi);
 
        return NULL;
 }
 
 static int
-message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
+message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
 {
        guint32 count;
        CamelFlag *flag;
        CamelTag *tag;
        int i;
+       CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
 
        io(printf("Saving message info\n"));
 
@@ -1882,28 +1766,27 @@ message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
 }
 
 static void
-message_info_free(CamelFolderSummary *s, CamelMessageInfo *mi)
+message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
 {
-#ifdef DOEPOOLV
-       e_poolv_destroy(mi->strings);
-#elif defined (DOESTRV)
-       e_strv_destroy(mi->strings);
-#else
+       CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+
        g_free(mi->uid);
-       g_free(mi->subject);
-       g_free(mi->from);
-       g_free(mi->to);
-       g_free(mi->cc);
-       g_free(mi->mlist);
-#endif
+       camel_pstring_free(mi->subject);
+       camel_pstring_free(mi->from);
+       camel_pstring_free(mi->to);
+       camel_pstring_free(mi->cc);
+       camel_pstring_free(mi->mlist);
        g_free(mi->references);
        camel_flag_list_free(&mi->user_flags);
        camel_tag_list_free(&mi->user_tags);
-       e_memchunk_free(s->message_info_chunks, mi);
+       if (s)
+               e_memchunk_free(s->message_info_chunks, mi);
+       else
+               g_free(mi);
 }
 
 static CamelMessageContentInfo *
-content_info_new (CamelFolderSummary *s, struct _camel_header_raw *h)
+content_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 {
        CamelMessageContentInfo *ci;
        const char *charset;
@@ -2056,7 +1939,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
                    || camel_content_type_is(ct, "application", "pkcs7-signature")
 #endif
                        )
-                       msginfo->flags |= CAMEL_MESSAGE_SECURE;
+                       camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
 
                if (p->index && camel_content_type_is(ct, "text", "*")) {
                        char *encoding;
@@ -2140,10 +2023,10 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
                /* update attachments flag as we go */
                ct = camel_mime_parser_content_type(mp);
                if (camel_content_type_is(ct, "multipart", "mixed"))
-                       msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS;
+                       camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
                if (camel_content_type_is(ct, "multipart", "signed")
                    || camel_content_type_is(ct, "multipart", "encrypted"))
-                       msginfo->flags |= CAMEL_MESSAGE_SECURE;
+                       camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
 
                while (camel_mime_parser_step(mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) {
                        camel_mime_parser_unstep(mp);
@@ -2157,7 +2040,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam
        case CAMEL_MIME_PARSER_STATE_MESSAGE:
                d(printf("Summarising message\n"));
                /* update attachments flag as we go */
-               msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS;
+               camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
 
                part = summary_build_content_info(s, msginfo, mp);
                if (part) {
@@ -2203,17 +2086,17 @@ summary_build_content_info_message(CamelFolderSummary *s, CamelMessageInfo *msgi
        ct = ((CamelDataWrapper *)containee)->mime_type;
        if (camel_content_type_is(ct, "multipart", "*")) {
                if (camel_content_type_is(ct, "multipart", "mixed"))
-                       msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS;
+                       camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS);
                if (camel_content_type_is(ct, "multipart", "signed")
                    || camel_content_type_is(ct, "multipart", "encrypted"))
-                       msginfo->flags |= CAMEL_MESSAGE_SECURE;
+                       camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
        } else if (camel_content_type_is(ct, "application", "pgp-signature")
 #ifdef ENABLE_SMIME
                    || camel_content_type_is(ct, "application", "x-pkcs7-signature")
                    || camel_content_type_is(ct, "application", "pkcs7-signature")
 #endif
                ) {
-               msginfo->flags |= CAMEL_MESSAGE_SECURE;
+               camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE);
        }
 
        /* using the object types is more accurate than using the mime/types */
@@ -2607,19 +2490,23 @@ camel_system_flag_get (guint32 flags, const char *name)
  *
  * Returns a new CamelMessageInfo structure.
  **/
-CamelMessageInfo *
-camel_message_info_new (void)
+void *
+camel_message_info_new (CamelFolderSummary *s)
 {
        CamelMessageInfo *info;
-       
-       info = g_malloc0(sizeof(*info));
-#ifdef DOEPOOLV
-       info->strings = e_poolv_new(CAMEL_MESSAGE_INFO_LAST);
-#endif
-#ifdef DOESTRV
-       info->strings = e_strv_new (CAMEL_MESSAGE_INFO_LAST);
-#endif
+
+       if (s) {
+               CAMEL_SUMMARY_LOCK(s, alloc_lock);
+               if (s->message_info_chunks == NULL)
+                       s->message_info_chunks = e_memchunk_new(32, s->message_info_size);
+               info = e_memchunk_alloc0(s->message_info_chunks);
+               CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
+       } else {
+               info = g_malloc0(sizeof(CamelMessageInfoBase));
+       }
+
        info->refcount = 1;
+       info->summary = s;
 
        return info;
 }
@@ -2629,14 +2516,22 @@ camel_message_info_new (void)
  * @info: 
  * 
  * Reference an info.
- *
- * NOTE: This interface is not MT-SAFE, like the others.
  **/
-void camel_message_info_ref(CamelMessageInfo *info)
+void camel_message_info_ref(void *o)
 {
-       GLOBAL_INFO_LOCK(info);
-       info->refcount++;
-       GLOBAL_INFO_UNLOCK(info);
+       CamelMessageInfo *mi = o;
+
+       if (mi->summary) {
+               CAMEL_SUMMARY_LOCK(mi->summary, ref_lock);
+               g_assert(mi->refcount >= 1);
+               mi->refcount++;
+               CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock);
+       } else {
+               GLOBAL_INFO_LOCK(info);
+               g_assert(mi->refcount >= 1);
+               mi->refcount++;
+               GLOBAL_INFO_UNLOCK(info);
+       }
 }
 
 /**
@@ -2646,108 +2541,89 @@ void camel_message_info_ref(CamelMessageInfo *info)
  * Returns a new CamelMessageInfo structure populated by the header.
  **/
 CamelMessageInfo *
-camel_message_info_new_from_header (struct _camel_header_raw *header)
+camel_message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *header)
 {
-       CamelMessageInfo *info;
-       char *subject, *from, *to, *cc, *mlist;
-       CamelContentType *ct = NULL;
-       const char *content, *date, *charset = NULL;
-       
-       if ((content = camel_header_raw_find(&header, "Content-Type", NULL))
-           && (ct = camel_content_type_decode(content))
-           && (charset = camel_content_type_param(ct, "charset"))
-           && (strcasecmp(charset, "us-ascii") == 0))
-               charset = NULL;
-       
-       charset = charset ? e_iconv_charset_name (charset) : NULL;
-       
-       subject = summary_format_string(header, "subject", charset);
-       from = summary_format_address(header, "from", charset);
-       to = summary_format_address(header, "to", charset);
-       cc = summary_format_address(header, "cc", charset);
-       date = camel_header_raw_find(&header, "date", NULL);
-       mlist = camel_header_raw_check_mailing_list(&header);
-
-       if (ct)
-               camel_content_type_unref(ct);
-
-       info = camel_message_info_new();
-
-       camel_message_info_set_subject(info, subject);
-       camel_message_info_set_from(info, from);
-       camel_message_info_set_to(info, to);
-       camel_message_info_set_cc(info, cc);
-       camel_message_info_set_mlist(info, mlist);
-       
-       if (date)
-               info->date_sent = camel_header_decode_date (date, NULL);
-       else
-               info->date_sent = time (NULL);
-       
-       date = camel_header_raw_find (&header, "received", NULL);
-       if (date && (date = strrchr (date, ';')))
-               date++;
-       
-       if (date)
-               info->date_received = camel_header_decode_date (date, NULL);
+       if (s)
+               return ((CamelFolderSummaryClass *)((CamelObject *)s)->klass)->message_info_new_from_header(s, header);
        else
-               info->date_received = time (NULL);
-       
-       return info;
+               return message_info_new_from_header(NULL, header);
 }
 
 /**
- * camel_message_info_dup_to:
- * @from: source message info
- * @to: destination message info
+ * camel_message_info_free:
+ * @mi: the message info
+ *
+ * Unref's and potentially frees a CamelMessageInfo and its contents.
  *
- * Duplicates the contents of one CamelMessageInfo structure into another.
- * (The destination is assumed to be empty: its contents are not freed.)
- * The slightly odd interface is to allow this to be used to initialize
- * "subclasses" of CamelMessageInfo.
  **/
 void
-camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to)
+camel_message_info_free(void *o)
+{
+       CamelMessageInfo *mi = o;
+
+       g_return_if_fail(mi != NULL);
+
+       if (mi->summary) {
+               CAMEL_SUMMARY_LOCK(mi->summary, ref_lock);
+
+               g_assert(mi->refcount >= 1);
+               mi->refcount--;
+               if (mi->refcount > 0) {
+                       CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock);
+                       return;
+               }
+
+               CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock);
+
+               /* FIXME: this is kinda busted, should really be handled by message info free */
+               if (mi->summary->build_content
+                   && ((CamelMessageInfoBase *)mi)->content) {
+                       camel_folder_summary_content_info_free(mi->summary, ((CamelMessageInfoBase *)mi)->content);
+               }
+
+               ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(mi->summary)))->message_info_free(mi->summary, mi);
+       } else {
+               GLOBAL_INFO_LOCK(info);
+               mi->refcount--;
+               if (mi->refcount > 0) {
+                       GLOBAL_INFO_UNLOCK(info);
+                       return;
+               }
+               GLOBAL_INFO_UNLOCK(info);
+
+               message_info_free(NULL, mi);
+       }
+}
+
+static CamelMessageInfo *
+message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
 {
+       CamelMessageInfoBase *to, *from = (CamelMessageInfoBase *)mi;
        CamelFlag *flag;
        CamelTag *tag;
 
-       /* Copy numbers */
+       to = (CamelMessageInfoBase *)camel_message_info_new(s);
+
        to->flags = from->flags;
        to->size = from->size;
        to->date_sent = from->date_sent;
        to->date_received = from->date_received;
        to->refcount = 1;
 
-       /* Copy strings */
-#ifdef DOEPOOLV
-       to->strings = e_poolv_cpy (to->strings, from->strings);
-#elif defined (DOESTRV)
-       /* to->strings = e_strv_new(CAMEL_MESSAGE_INFO_LAST); */
-       e_strv_set(to->strings, CAMEL_MESSAGE_INFO_SUBJECT, camel_message_info_subject(from));
-       e_strv_set(to->strings, CAMEL_MESSAGE_INFO_FROM, camel_message_info_from(from));
-       e_strv_set(to->strings, CAMEL_MESSAGE_INFO_TO, camel_message_info_to(from));
-       e_strv_set(to->strings, CAMEL_MESSAGE_INFO_CC, camel_message_info_cc(from));
-       e_strv_set(to->strings, CAMEL_MESSAGE_INFO_UID, camel_message_info_uid(from));
-       e_strv_set(to->strings, CAMEL_MESSAGE_INFO_UID, camel_message_info_mlist(from));
-#else
-       to->subject = g_strdup(from->subject);
-       to->from = g_strdup(from->from);
-       to->to = g_strdup(from->to);
-       to->cc = g_strdup(from->cc);
-       to->uid = g_strdup(from->uid);
-       to->mlist = g_strdup(from->mlist);
-#endif
-       memcpy(&to->message_id, &from->message_id, sizeof(from->message_id));
+       /* NB: We don't clone the uid */
+
+       to->subject = camel_pstring_strdup(from->subject);
+       to->from = camel_pstring_strdup(from->from);
+       to->to = camel_pstring_strdup(from->to);
+       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));
 
-       /* Copy structures */
        if (from->references) {
                int len = sizeof(*from->references) + ((from->references->size-1) * sizeof(from->references->references[0]));
 
                to->references = g_malloc(len);
                memcpy(to->references, from->references, len);
-       } else {
-               to->references = NULL;
        }
 
        flag = from->user_flags;
@@ -2762,83 +2638,226 @@ camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to)
                tag = tag->next;
        }
 
-       /* No, this is impossible without knowing the class of summary we came from */
-       /* FIXME some day */
-       to->content = NULL;
+       if (from->content) {
+               /* FIXME: copy content-infos */
+       }
+
+       return (CamelMessageInfo *)to;
 }
 
-/**
- * camel_message_info_free:
- * @mi: the message info
- *
- * Unref's and potentially frees a CamelMessageInfo and its contents.
- *
- * Can only be used to free CamelMessageInfo's created with
- * camel_message_info_dup_to.
- *
- * NOTE: This interface is not MT-SAFE, like the others.
- *
- **/
-void
-camel_message_info_free(CamelMessageInfo *mi)
+void *
+camel_message_info_clone(const void *o)
 {
-       g_return_if_fail(mi != NULL);
+       const CamelMessageInfo *mi = o;
 
-       GLOBAL_INFO_LOCK(info);
-       mi->refcount--;
-       if (mi->refcount > 0) {
-               GLOBAL_INFO_UNLOCK(info);
-               return;
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->message_info_clone(mi->summary, mi);
+       else
+               return message_info_clone(NULL, mi);
+}
+
+static const void *
+info_ptr(const CamelMessageInfo *mi, int id)
+{
+       switch (id) {
+       case CAMEL_MESSAGE_INFO_SUBJECT:
+               return ((const CamelMessageInfoBase *)mi)->subject;
+       case CAMEL_MESSAGE_INFO_FROM:
+               return ((const CamelMessageInfoBase *)mi)->from;
+       case CAMEL_MESSAGE_INFO_TO:
+               return ((const CamelMessageInfoBase *)mi)->to;
+       case CAMEL_MESSAGE_INFO_CC:
+               return ((const CamelMessageInfoBase *)mi)->cc;
+       case CAMEL_MESSAGE_INFO_MLIST:
+               return ((const CamelMessageInfoBase *)mi)->mlist;
+       case CAMEL_MESSAGE_INFO_MESSAGE_ID:
+               return &((const CamelMessageInfoBase *)mi)->message_id;
+       case CAMEL_MESSAGE_INFO_REFERENCES:
+               return ((const CamelMessageInfoBase *)mi)->references;
+       case CAMEL_MESSAGE_INFO_USER_FLAGS:
+               return ((const CamelMessageInfoBase *)mi)->user_flags;
+       case CAMEL_MESSAGE_INFO_USER_TAGS:
+               return ((const CamelMessageInfoBase *)mi)->user_tags;
+       default:
+               abort();
        }
-       GLOBAL_INFO_UNLOCK(info);
+}
 
-#ifdef DOEPOOLV
-       e_poolv_destroy(mi->strings);
-#elif defined (DOESTRV)
-       e_strv_destroy(mi->strings);
-#else
-       g_free(mi->uid);
-       g_free(mi->subject);
-       g_free(mi->from);
-       g_free(mi->to);
-       g_free(mi->cc);
-       g_free(mi->mlist);
-#endif
-       g_free(mi->references);
-       camel_flag_list_free(&mi->user_flags);
-       camel_tag_list_free(&mi->user_tags);
-       /* FIXME: content info? */
-       g_free(mi);
+static guint32
+info_uint32(const CamelMessageInfo *mi, int id)
+{
+       switch (id) {
+       case CAMEL_MESSAGE_INFO_FLAGS:
+               return ((const CamelMessageInfoBase *)mi)->flags;
+       case CAMEL_MESSAGE_INFO_SIZE:
+               return ((const CamelMessageInfoBase *)mi)->size;
+       default:
+               abort();
+       }
 }
 
-#if defined (DOEPOOLV) || defined (DOESTRV)
-const char *
-camel_message_info_string (const CamelMessageInfo *mi, int type)
+static time_t
+info_time(const CamelMessageInfo *mi, int id)
 {
-       g_assert (mi != NULL);
-       
-       if (mi->strings == NULL)
-               return "";
-#ifdef DOEPOOLV
-       return e_poolv_get (mi->strings, type);
-#else
-       return e_strv_get (mi->strings, type);
-#endif
+       switch (id) {
+       case CAMEL_MESSAGE_INFO_DATE_SENT:
+               return ((const CamelMessageInfoBase *)mi)->date_sent;
+       case CAMEL_MESSAGE_INFO_DATE_RECEIVED:
+               return ((const CamelMessageInfoBase *)mi)->date_received;
+       default:
+               abort();
+       }
 }
 
-void
-camel_message_info_set_string (CamelMessageInfo *mi, int type, char *str)
+static gboolean
+info_user_flag(const CamelMessageInfo *mi, const char *id)
 {
-       g_assert (mi != NULL);
-       g_assert (mi->strings != NULL);
-#ifdef DOEPOOLV
-       e_poolv_set (mi->strings, type, str, TRUE);
-#else
-       mi->strings = e_strv_set_ref_free (mi->strings, type, str);
-#endif
+       return camel_flag_get(&((CamelMessageInfoBase *)mi)->user_flags, id);
 }
-#endif
 
+static const char *
+info_user_tag(const CamelMessageInfo *mi, const char *id)
+{
+       return camel_tag_get(&((CamelMessageInfoBase *)mi)->user_tags, id);
+}
+
+const void *
+camel_message_info_ptr(const CamelMessageInfo *mi, int id)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_ptr(mi, id);
+       else
+               return info_ptr(mi, id);
+}
+
+guint32 camel_message_info_uint32(const CamelMessageInfo *mi, int id)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_uint32(mi, id);
+       else
+               return info_uint32(mi, id);
+}
+
+time_t camel_message_info_time(const CamelMessageInfo *mi, int id)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_time(mi, id);
+       else
+               return info_time(mi, id);
+}
+
+gboolean camel_message_info_user_flag(const CamelMessageInfo *mi, const char *id)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_flag(mi, id);
+       else
+               return info_user_flag(mi, id);
+}
+
+const char *camel_message_info_user_tag(const CamelMessageInfo *mi, const char *id)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_tag(mi, id);
+       else
+               return info_user_tag(mi, id);
+}
+
+static gboolean
+info_set_flags(CamelMessageInfo *info, guint32 flags, guint32 set)
+{
+       guint32 old;
+       CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+
+       /* TODO: locking? */
+
+       old = mi->flags;
+       mi->flags = (old & ~flags) | (set & flags);
+       if (old != mi->flags) {
+               mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+               if (mi->summary)
+                       camel_folder_summary_touch(mi->summary);
+       }
+
+       if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK))
+               return FALSE;
+
+       if (mi->summary && mi->summary->folder && mi->uid) {
+               CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+
+               camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
+               camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
+               camel_folder_change_info_free(changes);
+       }
+
+       return TRUE;
+}
+
+gboolean camel_message_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_flags(mi, flags, set);
+       else
+               return info_set_flags(mi, flags, set);
+}
+
+static gboolean
+info_set_user_flag(CamelMessageInfo *info, const char *name, gboolean value)
+{
+       CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+       int res;
+
+       res = camel_flag_set(&mi->user_flags, name, value);
+
+       /* TODO: check this item is still in the summary first */
+       if (mi->summary && res && mi->summary->folder && mi->uid) {
+               CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+
+               mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+               camel_folder_summary_touch(mi->summary);
+               camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
+               camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
+               camel_folder_change_info_free(changes);
+       }
+
+       return res;
+}
+
+gboolean camel_message_info_set_user_flag(CamelMessageInfo *mi, const char *id, gboolean state)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_flag(mi, id, state);
+       else
+               return info_set_user_flag(mi, id, state);
+}
+
+static gboolean
+info_set_user_tag(CamelMessageInfo *info, const char *name, const char *value)
+{
+       CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
+       int res;
+
+       res = camel_tag_set(&mi->user_tags, name, value);
+
+       if (mi->summary && res && mi->summary->folder && mi->uid) {
+               CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+
+               mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+               camel_folder_summary_touch(mi->summary);
+               camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
+               camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
+               camel_folder_change_info_free(changes);
+       }
+
+       return res;
+}
+
+gboolean camel_message_info_set_user_tag(CamelMessageInfo *mi, const char *id, const char *val)
+{
+       if (mi->summary)
+               return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_tag(mi, id, val);
+       else
+               return info_set_user_tag(mi, id, val);
+}
 
 void
 camel_content_info_dump (CamelMessageContentInfo *ci, int depth)
@@ -2883,6 +2902,50 @@ camel_message_info_dump (CamelMessageInfo *mi)
        printf("mailing list: %s\n", camel_message_info_mlist(mi));
        printf("From: %s\n", camel_message_info_from(mi));
        printf("UID: %s\n", camel_message_info_uid(mi));
-       printf("Flags: %04x\n", mi->flags & 0xffff);
-       camel_content_info_dump(mi->content, 0);
+       printf("Flags: %04x\n", camel_message_info_flags(mi));
+       /*camel_content_info_dump(mi->content, 0);*/
+}
+
+
+static void
+camel_folder_summary_class_init (CamelFolderSummaryClass *klass)
+{
+       camel_folder_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ());
+
+       klass->summary_header_load = summary_header_load;
+       klass->summary_header_save = summary_header_save;
+
+       klass->message_info_new_from_header  = message_info_new_from_header;
+       klass->message_info_new_from_parser = message_info_new_from_parser;
+       klass->message_info_new_from_message = message_info_new_from_message;
+       klass->message_info_load = message_info_load;
+       klass->message_info_save = message_info_save;
+       klass->message_info_free = message_info_free;
+       klass->message_info_clone = message_info_clone;
+
+       klass->content_info_new_from_header  = content_info_new_from_header;
+       klass->content_info_new_from_parser = content_info_new_from_parser;
+       klass->content_info_new_from_message = content_info_new_from_message;
+       klass->content_info_load = content_info_load;
+       klass->content_info_save = content_info_save;
+       klass->content_info_free = content_info_free;
+
+       klass->next_uid_string = next_uid_string;
+
+       klass->info_ptr = info_ptr;
+       klass->info_uint32 = info_uint32;
+       klass->info_time = info_time;
+       klass->info_user_flag = info_user_flag;
+       klass->info_user_tag = info_user_tag;
+
+#if 0
+       klass->info_set_string = info_set_string;
+       klass->info_set_uint32 = info_set_uint32;
+       klass->info_set_time = info_set_time;
+       klass->info_set_ptr = info_set_ptr;
+#endif
+       klass->info_set_user_flag = info_set_user_flag;
+       klass->info_set_user_tag = info_set_user_tag;
+
+       klass->info_set_flags = info_set_flags;
 }
index de56a6e..5f0b0d1 100644 (file)
@@ -33,6 +33,8 @@ extern "C" {
 #include <camel/camel-object.h>
 #include <camel/camel-index.h>
 
+struct _CamelFolder;
+
 #define CAMEL_FOLDER_SUMMARY_TYPE         camel_folder_summary_get_type ()
 #define CAMEL_FOLDER_SUMMARY(obj)         CAMEL_CHECK_CAST (obj, camel_folder_summary_get_type (), CamelFolderSummary)
 #define CAMEL_FOLDER_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_folder_summary_get_type (), CamelFolderSummaryClass)
@@ -41,6 +43,9 @@ extern "C" {
 /*typedef struct _CamelFolderSummary      CamelFolderSummary;*/
 typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass;
 
+typedef struct _CamelMessageInfo CamelMessageInfo;
+typedef struct _CamelMessageInfoBase CamelMessageInfoBase;
+
 /* A tree of message content info structures
    describe the content structure of the message (if it has any) */
 struct _CamelMessageContentInfo {
@@ -113,47 +118,58 @@ typedef struct _CamelSummaryReferences {
        CamelSummaryMessageID references[1];
 } CamelSummaryReferences;
 
-/* #define DOESTRV */
-#define DOEPOOLV
-
-#if defined (DOEPOOLV) || defined (DOESTRV)
-
-/* string array indices */
+/* accessor id's */
 enum {
-       CAMEL_MESSAGE_INFO_UID,
        CAMEL_MESSAGE_INFO_SUBJECT,
        CAMEL_MESSAGE_INFO_FROM,
        CAMEL_MESSAGE_INFO_TO,
        CAMEL_MESSAGE_INFO_CC,
        CAMEL_MESSAGE_INFO_MLIST,
-       CAMEL_MESSAGE_INFO_LAST,
+
+       CAMEL_MESSAGE_INFO_FLAGS,
+       CAMEL_MESSAGE_INFO_SIZE,
+
+       CAMEL_MESSAGE_INFO_DATE_SENT,
+       CAMEL_MESSAGE_INFO_DATE_RECEIVED,
+
+       CAMEL_MESSAGE_INFO_MESSAGE_ID,
+       CAMEL_MESSAGE_INFO_REFERENCES,
+       CAMEL_MESSAGE_INFO_USER_FLAGS,
+       CAMEL_MESSAGE_INFO_USER_TAGS,
+
+       CAMEL_MESSAGE_INFO_LAST
 };
-#endif
 
-/* information about a given object */
+/* information about a given message, use accessors */
 struct _CamelMessageInfo {
-       /* public fields */
-#ifdef DOEPOOLV
-       struct _EPoolv *strings;
-#elif defined (DOESTRV)
-       struct _EStrv *strings;         /* all strings packed into a single compact array */
-#else
-       char *subject;
-       char *from;
-       char *to;
-       char *cc;
-       char *mlist;
+       CamelFolderSummary *summary;
+
+       guint32 refcount;       /* ??? */
+       char *uid;
+};
 
+/* For classes wishing to do the provided i/o, or for anonymous users,
+ * they must subclass or use this messageinfo structure */
+/* Otherwise they can do their own thing entirely */
+struct _CamelMessageInfoBase {
+       CamelFolderSummary *summary;
+
+       guint32 refcount;       /* ??? */
        char *uid;
-#endif /* DOEPOOLV */
+
+       const char *subject;
+       const char *from;
+       const char *to;
+       const char *cc;
+       const char *mlist;
+
        guint32 flags;
        guint32 size;
-       guint32 refcount;
 
        time_t date_sent;
        time_t date_received;
 
-       CamelSummaryMessageID message_id;/* for this message */
+       CamelSummaryMessageID message_id;
        CamelSummaryReferences *references;/* from parent to root */
 
        struct _CamelFlag *user_flags;
@@ -163,6 +179,16 @@ struct _CamelMessageInfo {
        CamelMessageContentInfo *content;
 };
 
+/* probably do this as well, removing CamelFolderChangeInfo and interfaces 
+typedef struct _CamelChangeInfo CamelChangeInfo;
+struct _CamelChangeInfo {
+       GPtrArray *added;
+       GPtrArray *removed;
+       GPtrArray *changed;
+       GPtrArray *recent;
+};
+*/
+
 enum _CamelFolderSummaryFlags {
        CAMEL_SUMMARY_DIRTY = 1<<0,
 };
@@ -186,9 +212,6 @@ struct _CamelFolderSummary {
        guint32 message_info_size;
        guint32 content_info_size;
 
-#if defined (DOEPOOLV) || defined (DOESTRV)
-       guint32 message_info_strings;
-#endif 
        /* memory allocators (setup automatically) */
        struct _EMemChunk *message_info_chunks;
        struct _EMemChunk *content_info_chunks;
@@ -198,6 +221,8 @@ struct _CamelFolderSummary {
 
        GPtrArray *messages;    /* CamelMessageInfo's */
        GHashTable *messages_uid; /* CamelMessageInfo's by uid */
+
+       struct _CamelFolder *folder; /* parent folder, for events */
 };
 
 struct _CamelFolderSummaryClass {
@@ -208,15 +233,17 @@ struct _CamelFolderSummaryClass {
        int (*summary_header_save)(CamelFolderSummary *, FILE *);
 
        /* create/save/load an individual message info */
-       CamelMessageInfo * (*message_info_new)(CamelFolderSummary *, struct _camel_header_raw *);
+       CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
        CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
        CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *);
        CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *);
        int                (*message_info_save)(CamelFolderSummary *, FILE *, CamelMessageInfo *);
+
        void               (*message_info_free)(CamelFolderSummary *, CamelMessageInfo *);
+       CamelMessageInfo * (*message_info_clone)(CamelFolderSummary *, const CamelMessageInfo *);
 
        /* save/load individual content info's */
-       CamelMessageContentInfo * (*content_info_new)(CamelFolderSummary *, struct _camel_header_raw *);
+       CamelMessageContentInfo * (*content_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
        CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
        CamelMessageContentInfo * (*content_info_new_from_message)(CamelFolderSummary *, CamelMimePart *);
        CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *, FILE *);
@@ -225,10 +252,29 @@ struct _CamelFolderSummaryClass {
 
        /* get the next uid */
        char *(*next_uid_string)(CamelFolderSummary *);
+
+       /* virtual accessors on messageinfo's */
+       const void *(*info_ptr)(const CamelMessageInfo *mi, int id);
+       guint32     (*info_uint32)(const CamelMessageInfo *mi, int id);
+       time_t      (*info_time)(const CamelMessageInfo *mi, int id);
+
+       gboolean    (*info_user_flag)(const CamelMessageInfo *mi, const char *id);
+       const char *(*info_user_tag)(const CamelMessageInfo *mi, const char *id);
+
+       /* set accessors for the modifyable bits */
+#if 0
+       void (*info_set_ptr)(CamelMessageInfo *mi, int id, const void *val);
+       void (*info_set_uint32)(CamelMessageInfo *mi, int id, guint32 val);
+       void (*info_set_time)(CamelMessageInfo *mi, int id, time_t val);
+       void (*info_set_references)(CamelMessageInfo *mi, CamelSummaryReferences *);
+#endif
+       gboolean (*info_set_user_flag)(CamelMessageInfo *mi, const char *id, gboolean state);
+       gboolean (*info_set_user_tag)(CamelMessageInfo *mi, const char *id, const char *val);
+       gboolean (*info_set_flags)(CamelMessageInfo *mi, guint32 mask, guint32 set);
 };
 
 CamelType                       camel_folder_summary_get_type  (void);
-CamelFolderSummary      *camel_folder_summary_new      (void);
+CamelFolderSummary      *camel_folder_summary_new      (struct _CamelFolder *folder);
 
 void camel_folder_summary_set_filename(CamelFolderSummary *, const char *);
 void camel_folder_summary_set_index(CamelFolderSummary *, CamelIndex *);
@@ -257,14 +303,10 @@ CamelMessageInfo *camel_folder_summary_add_from_parser(CamelFolderSummary *, Cam
 CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *, CamelMimeMessage *);
 
 /* Just build raw summary items */
-CamelMessageInfo *camel_folder_summary_info_new(CamelFolderSummary *s);
 CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary *, CamelMimeMessage *);
 
-void camel_folder_summary_info_ref(CamelFolderSummary *, CamelMessageInfo *);
-void camel_folder_summary_info_free(CamelFolderSummary *, CamelMessageInfo *);
-
 CamelMessageContentInfo *camel_folder_summary_content_info_new(CamelFolderSummary *s);
 void camel_folder_summary_content_info_free(CamelFolderSummary *s, CamelMessageContentInfo *ci);
 
@@ -309,53 +351,46 @@ gboolean  camel_tag_list_copy(CamelTag **to, CamelTag **from);
 int            camel_tag_list_size(CamelTag **list);
 void           camel_tag_list_free(CamelTag **list);
 
-/* message info utils for working with pseudo-messageinfo structures
-   NOTE: These cannot be added to a real summary object, but suffice for all
-   other external interfaces that use message info's */
-CamelMessageInfo *camel_message_info_new(void);
-void camel_message_info_ref(CamelMessageInfo *info);
-CamelMessageInfo *camel_message_info_new_from_header(struct _camel_header_raw *header);
-void camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to);
-void camel_message_info_free(CamelMessageInfo *mi);
+/* Summary may be null */
+/* Use anonymous pointers to avoid tons of cast crap */
+void *camel_message_info_new(CamelFolderSummary *);
+void camel_message_info_ref(void *);
+CamelMessageInfo *camel_message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *header);
+void camel_message_info_free(void *);
+void *camel_message_info_clone(const void *);
 
 /* accessors */
-#if defined (DOEPOOLV) || defined (DOESTRV)
-const char *camel_message_info_string(const CamelMessageInfo *mi, int type);
-#define camel_message_info_subject(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_SUBJECT)
-#define camel_message_info_from(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_FROM)
-#define camel_message_info_to(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_TO)
-#define camel_message_info_cc(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_CC)
-#define camel_message_info_uid(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_UID)
-#define camel_message_info_mlist(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_MLIST)
-
-void camel_message_info_set_string(CamelMessageInfo *mi, int type, char *str);
-#define camel_message_info_set_subject(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_SUBJECT, s)
-#define camel_message_info_set_from(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_FROM, s)
-#define camel_message_info_set_to(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_TO, s)
-#define camel_message_info_set_cc(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_CC, s)
-#define camel_message_info_set_uid(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_UID, s)
-#define camel_message_info_set_mlist(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_MLIST, s)
-
-#else
-
-#define camel_message_info_subject(x) (((CamelMessageInfo *)(x))->subject?((CamelMessageInfo *)(x))->subject:"")
-#define camel_message_info_from(x) (((CamelMessageInfo *)(x))->from?((CamelMessageInfo *)(x))->from:"")
-#define camel_message_info_to(x) (((CamelMessageInfo *)(x))->to?((CamelMessageInfo *)(x))->to:"")
-#define camel_message_info_cc(x) (((CamelMessageInfo *)(x))->cc?((CamelMessageInfo *)(x))->cc:"")
-#define camel_message_info_uid(x) (((CamelMessageInfo *)(x))->uid?((CamelMessageInfo *)(x))->uid:"")
-#define camel_message_info_mlist(x) (((CamelMessageInfo *)(x))->mlist?((CamelMessageInfo *)(x))->mlist:"")
-
-#define camel_message_info_set_subject(x, s) (g_free(((CamelMessageInfo *)(x))->subject),((CamelMessageInfo *)(x))->subject = (s))
-#define camel_message_info_set_from(x, s) (g_free(((CamelMessageInfo *)(x))->from),((CamelMessageInfo *)(x))->from = (s))
-#define camel_message_info_set_to(x, s) (g_free(((CamelMessageInfo *)(x))->to),((CamelMessageInfo *)(x))->to = (s))
-#define camel_message_info_set_cc(x, s) (g_free(((CamelMessageInfo *)(x))->cc),((CamelMessageInfo *)(x))->cc = (s))
-#define camel_message_info_set_uid(x, s) (g_free(((CamelMessageInfo *)(x))->uid),((CamelMessageInfo *)(x))->uid = (s))
-#define camel_message_info_set_mlist(x, s) (g_free(((CamelMessageInfo *)(x))->mlist),((CamelMessageInfo *)(x))->mlist = (s))
-#endif
+const void *camel_message_info_ptr(const CamelMessageInfo *mi, int id);
+guint32 camel_message_info_uint32(const CamelMessageInfo *mi, int id);
+time_t camel_message_info_time(const CamelMessageInfo *mi, int id);
 
+#define camel_message_info_uid(mi) ((const char *)((const CamelMessageInfo *)mi)->uid)
 
-/* debugging functions */
+#define camel_message_info_subject(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SUBJECT))
+#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))
+#define camel_message_info_mlist(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MLIST))
+
+#define camel_message_info_flags(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FLAGS)
+#define camel_message_info_size(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SIZE)
+
+#define camel_message_info_date_sent(mi) camel_message_info_time((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_DATE_SENT)
+#define camel_message_info_date_received(mi) camel_message_info_time((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_DATE_RECEIVED)
 
+#define camel_message_info_message_id(mi) ((const CamelSummaryMessageID *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MESSAGE_ID))
+#define camel_message_info_references(mi) ((const CamelSummaryReferences *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_REFERENCES))
+#define camel_message_info_user_flags(mi) ((const CamelFlag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_FLAGS))
+#define camel_message_info_user_tags(mi) ((const CamelTag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_TAGS))
+
+gboolean camel_message_info_user_flag(const CamelMessageInfo *mi, const char *id);
+const char *camel_message_info_user_tag(const CamelMessageInfo *mi, const char *id);
+
+gboolean camel_message_info_set_flags(CamelMessageInfo *mi, guint32 mask, guint32 set);
+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);
+
+/* debugging functions */
 void camel_content_info_dump (CamelMessageContentInfo *ci, int depth);
 
 void camel_message_info_dump (CamelMessageInfo *mi);
index a110cdb..234b3f1 100644 (file)
@@ -333,7 +333,7 @@ dump_tree_rec(struct _tree_info *info, CamelFolderThreadNode *c, int depth)
                        g_hash_table_insert(info->visited, c, c);
                }
                if (c->message) {
-                       printf("%s %p Subject: %s <%.8s>\n", p, c, camel_message_info_subject(c->message), c->message->message_id.id.hash);
+                       printf("%s %p Subject: %s <%.8s>\n", p, c, camel_message_info_subject(c->message), camel_message_info_message_id(c->message)->id.hash);
                        count += 1;
                } else {
                        printf("%s %p <empty>\n", p, c);
@@ -446,9 +446,11 @@ thread_summary(CamelFolderThread *thread, GPtrArray *summary)
        no_id_table = g_hash_table_new(NULL, NULL);
        for (i=0;i<summary->len;i++) {
                CamelMessageInfo *mi = summary->pdata[i];
+               const CamelSummaryMessageID *mid = camel_message_info_message_id(mi);
+               const CamelSummaryReferences *references = camel_message_info_references(mi);
 
-               if (mi->message_id.id.id) {
-                       c = g_hash_table_lookup(id_table, &mi->message_id);
+               if (mid->id.id) {
+                       c = g_hash_table_lookup(id_table, mid);
                        /* check for duplicate messages */
                        if (c && c->order) {
                                /* if duplicate, just make out it is a no-id message,  but try and insert it
@@ -457,9 +459,9 @@ thread_summary(CamelFolderThread *thread, GPtrArray *summary)
                                c = e_memchunk_alloc0(thread->node_chunks);
                                g_hash_table_insert(no_id_table, (void *)mi, c);
                        } else if (!c) {
-                               d(printf("doing : %08x%08x (%s)\n", mi->message_id.id.part.hi, mi->message_id.id.part.lo, camel_message_info_subject(mi)));
+                               d(printf("doing : %08x%08x (%s)\n", mid->id.part.hi, mid->id.part.lo, camel_message_info_subject(mi)));
                                c = e_memchunk_alloc0(thread->node_chunks);
-                               g_hash_table_insert(id_table, (void *)&mi->message_id, c);
+                               g_hash_table_insert(id_table, (void *)mid, c);
                        }
                } else {
                        d(printf("doing : (no message id)\n"));
@@ -470,20 +472,20 @@ thread_summary(CamelFolderThread *thread, GPtrArray *summary)
                c->message = mi;
                c->order = i+1;
                child = c;
-               if (mi->references) {
+               if (references) {
                        int j;
 
                        d(printf("references:\n"));
-                       for (j=0;j<mi->references->size;j++) {
+                       for (j=0;j<references->size;j++) {
                                /* should never be empty, but just incase */
-                               if (mi->references->references[j].id.id == 0)
+                               if (references->references[j].id.id == 0)
                                        continue;
 
-                               c = g_hash_table_lookup(id_table, &mi->references->references[j]);
+                               c = g_hash_table_lookup(id_table, &references->references[j]);
                                if (c == NULL) {
                                        d(printf("not found\n"));
                                        c = e_memchunk_alloc0(thread->node_chunks);
-                                       g_hash_table_insert(id_table, &mi->references->references[j], c);
+                                       g_hash_table_insert(id_table, (void *)&references->references[j], c);
                                }
                                if (c!=child)
                                        container_parent_child(c, child);
index 30e5ab6..81884df 100644 (file)
@@ -71,8 +71,6 @@ static const char *get_message_user_tag(CamelFolder *folder, const char *uid, co
 static void set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
 
 static int get_message_count(CamelFolder *folder);
-static int get_unread_message_count(CamelFolder *folder);
-static int get_deleted_message_count(CamelFolder *folder);
 
 static void expunge             (CamelFolder *folder,
                                 CamelException *ex);
@@ -130,8 +128,6 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class)
        camel_folder_class->get_parent_store = get_parent_store;
        camel_folder_class->expunge = expunge;
        camel_folder_class->get_message_count = get_message_count;
-       camel_folder_class->get_unread_message_count = get_unread_message_count;
-       camel_folder_class->get_deleted_message_count = get_deleted_message_count;
        camel_folder_class->append_message = append_message;
        camel_folder_class->get_permanent_flags = get_permanent_flags;
        camel_folder_class->get_message_flags = get_message_flags;
@@ -356,15 +352,17 @@ folder_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
                                count = camel_folder_summary_count(folder->summary);
                                for (j=0; j<count; j++) {
                                        if ((info = camel_folder_summary_index(folder->summary, j))) {
-                                               if (!(info->flags & CAMEL_MESSAGE_SEEN))
+                                               guint32 flags = camel_message_info_flags(info);
+
+                                               if ((flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
                                                        unread++;
-                                               if (info->flags & CAMEL_MESSAGE_DELETED)
+                                               if (flags & CAMEL_MESSAGE_DELETED)
                                                        deleted++;
-                                               if (info->flags & CAMEL_MESSAGE_JUNK)
+                                               if (flags & CAMEL_MESSAGE_JUNK)
                                                        junked++;
-                                               if ((info->flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
+                                               if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
                                                        visible++;
-                                               camel_folder_summary_info_free(folder->summary, info);
+                                               camel_message_info_free(info);
                                        }
                                }
                        }
@@ -397,7 +395,7 @@ folder_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
                        for (j=0; j<count; j++) {
                                if ((info = camel_folder_summary_index(folder->summary, j))) {
                                        array->pdata[i] = g_strdup(camel_message_info_uid(info));
-                                       camel_folder_summary_info_free(folder->summary, info);
+                                       camel_message_info_free(info);
                                }
                        }
                        *arg->ca_ptr = array;
@@ -565,66 +563,24 @@ camel_folder_get_message_count (CamelFolder *folder)
        return ret;
 }
 
-static int
-get_unread_message_count(CamelFolder *folder)
-{
-       int i, count, unread=0;
-
-       g_return_val_if_fail(folder->summary != NULL, -1);
-
-       count = camel_folder_summary_count(folder->summary);
-       for (i=0; i<count; i++) {
-               CamelMessageInfo *info = camel_folder_summary_index(folder->summary, i);
-
-               if (info) {
-                       if (!(info->flags & CAMEL_MESSAGE_SEEN))
-                               unread++;
-                       camel_folder_summary_info_free(folder->summary, info);
-               }
-       }
-
-       return unread;
-}
-
 /**
  * camel_folder_unread_get_message_count:
  * @folder: A CamelFolder object
  *
+ * DEPRECATED, use camel_object_get instead.
+ *
  * Return value: the number of unread messages in the folder, or -1 if unknown.
  **/
 int
 camel_folder_get_unread_message_count (CamelFolder *folder)
 {
-       int ret;
+       int count = -1;
 
        g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
        
-       ret = CF_CLASS (folder)->get_unread_message_count (folder);
-
-       return ret;
-}
-
+       camel_object_get(folder, NULL, CAMEL_FOLDER_UNREAD, &count, 0);
 
-static int
-get_deleted_message_count (CamelFolder *folder)
-{
-       int i, count, deleted = 0;
-       CamelMessageInfo *info;
-       
-       g_return_val_if_fail (folder->summary != NULL, -1);
-       
-       count = camel_folder_summary_count (folder->summary);
-       for (i = 0; i < count; i++) {
-               if (!(info = camel_folder_summary_index (folder->summary, i)))
-                       continue;
-               
-               if ((info->flags & CAMEL_MESSAGE_DELETED))
-                       deleted++;
-               
-               camel_folder_summary_info_free (folder->summary, info);
-       }
-       
-       return deleted;
+       return count;
 }
 
 /**
@@ -636,11 +592,14 @@ get_deleted_message_count (CamelFolder *folder)
 int
 camel_folder_get_deleted_message_count (CamelFolder *folder)
 {
+       int count = -1;
+
        g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
-       
-       return CF_CLASS (folder)->get_deleted_message_count (folder);
-}
 
+       camel_object_get(folder, NULL, CAMEL_FOLDER_DELETED, &count, 0);
+
+       return count;
+}
 
 static void
 append_message (CamelFolder *folder, CamelMimeMessage *message,
@@ -720,8 +679,8 @@ get_message_flags(CamelFolder *folder, const char *uid)
        if (info == NULL)
                return 0;
 
-       flags = info->flags;
-       camel_folder_summary_info_free(folder->summary, info);
+       flags = camel_message_info_flags(info);
+       camel_message_info_free(info);
 
        return flags;
 }
@@ -731,6 +690,8 @@ get_message_flags(CamelFolder *folder, const char *uid)
  * @folder: a CamelFolder
  * @uid: the UID of a message in @folder
  *
+ * Deprecated: Use camel_folder_get_message_info instead.
+ *
  * Return value: the CamelMessageFlags that are set on the indicated
  * message.
  **/
@@ -750,8 +711,7 @@ static gboolean
 set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
 {
        CamelMessageInfo *info;
-       CamelFolderChangeInfo *changes;
-       guint32 old;
+       int res;
 
        g_return_val_if_fail(folder->summary != NULL, FALSE);
 
@@ -759,25 +719,10 @@ set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 s
        if (info == NULL)
                return FALSE;
 
-       old = info->flags;
-       info->flags = (old & ~flags) | (set & flags);
-       if (old != info->flags) {
-               info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
-               camel_folder_summary_touch(folder->summary);
-       }
-
-       camel_folder_summary_info_free(folder->summary, info);
-
-       /* app or vfolders don't need to be notified of system flag changes */
-       if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (info->flags & ~CAMEL_MESSAGE_SYSTEM_MASK))
-               return FALSE;
+       res = camel_message_info_set_flags(info, flags, set);
+       camel_message_info_free(info);
 
-       changes = camel_folder_change_info_new();
-       camel_folder_change_info_change_uid(changes, uid);
-       camel_object_trigger_event(folder, "folder_changed", changes);
-       camel_folder_change_info_free(changes);
-
-       return TRUE;
+       return res;
 }
 
 /**
@@ -794,6 +739,9 @@ set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 s
  * E.g. to set the deleted flag and clear the draft flag, use
  * set_message_flags(folder, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_DRAFT, CAMEL_MESSAGE_DELETED);
  *
+ * DEPRECATED: Use camel_message_info_set_flags on the message info directly
+ * (when it works)
+ *
  * Return Value: TRUE if the flags were changed, false otherwise.
  **/
 gboolean
@@ -821,8 +769,8 @@ get_message_user_flag(CamelFolder *folder, const char *uid, const char *name)
        if (info == NULL)
                return FALSE;
 
-       ret = camel_flag_get(&info->user_flags, name);
-       camel_folder_summary_info_free(folder->summary, info);
+       ret = camel_message_info_user_flag(info, name);
+       camel_message_info_free(info);
 
        return ret;
 }
@@ -833,7 +781,9 @@ get_message_user_flag(CamelFolder *folder, const char *uid, const char *name)
  * @uid: the UID of a message in @folder
  * @name: the name of a user flag
  *
- * Return value: whether or not the given user flag is set on the message.
+ * DEPRECATED: Use camel_message_info_get_user_flag on the message info directly
+ *
+ * * Return value: whether or not the given user flag is set on the message.
  **/
 gboolean
 camel_folder_get_message_user_flag (CamelFolder *folder, const char *uid,
@@ -859,16 +809,8 @@ set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gb
        if (info == NULL)
                return;
 
-       if (camel_flag_set(&info->user_flags, name, value)) {
-               CamelFolderChangeInfo *changes = camel_folder_change_info_new();
-
-               info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
-               camel_folder_summary_touch(folder->summary);
-               camel_folder_change_info_change_uid(changes, uid);
-               camel_object_trigger_event (folder, "folder_changed", changes);
-               camel_folder_change_info_free(changes);
-       }
-       camel_folder_summary_info_free(folder->summary, info);
+       camel_message_info_set_user_flag(info, name, value);
+       camel_message_info_free(info);
 }
 
 /**
@@ -878,6 +820,8 @@ set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gb
  * @name: the name of the user flag to set
  * @value: the value to set it to
  *
+ * DEPRECATED: Use camel_message_info_set_user_flag on the message info directly (when it works)
+ *
  * Sets the user flag specified by @name to the value specified by @value
  * on the indicated message. (This may or may not persist after the
  * folder or store is closed. See camel_folder_get_permanent_flags().)
@@ -903,10 +847,8 @@ get_message_user_tag(CamelFolder *folder, const char *uid, const char *name)
        if (info == NULL)
                return NULL;
 
-       /* FIXME: Need to duplicate tag string */
-
-       ret = camel_tag_get(&info->user_tags, name);
-       camel_folder_summary_info_free(folder->summary, info);
+       ret = camel_message_info_user_tag(info, name);
+       camel_message_info_free(info);
 
        return ret;
 }
@@ -917,6 +859,8 @@ get_message_user_tag(CamelFolder *folder, const char *uid, const char *name)
  * @uid: the UID of a message in @folder
  * @name: the name of a user tag
  *
+ * DEPRECATED: Use camel_message_info_get_user_tag on the messageinfo directly.
+ *
  * Return value: Returns the value of the user tag.
  **/
 const char *
@@ -943,16 +887,8 @@ set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, con
        if (info == NULL)
                return;
 
-       if (camel_tag_set(&info->user_tags, name, value)) {
-               CamelFolderChangeInfo *changes = camel_folder_change_info_new();
-
-               info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
-               camel_folder_summary_touch(folder->summary);
-               camel_folder_change_info_change_uid(changes, uid);
-               camel_object_trigger_event (folder, "folder_changed", changes);
-               camel_folder_change_info_free(changes);
-       }
-       camel_folder_summary_info_free(folder->summary, info);
+       camel_message_info_set_user_tag(info, name, value);
+       camel_message_info_free(info);
 }
 
 /**
@@ -962,6 +898,8 @@ set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, con
  * @name: the name of the user tag to set
  * @value: the value to set it to
  *
+ * DEPRECATED: Use camel_message_info_set_user_tag on the messageinfo directly (when it works).
+ *
  * Sets the user tag specified by @name to the value specified by @value
  * on the indicated message. (This may or may not persist after the
  * folder or store is closed. See camel_folder_get_permanent_flags().)
@@ -1011,7 +949,7 @@ free_message_info (CamelFolder *folder, CamelMessageInfo *info)
 {
        g_return_if_fail(folder->summary != NULL);
 
-       camel_folder_summary_info_free(folder->summary, info);
+       camel_message_info_free(info);
 }
 
 /**
@@ -1035,7 +973,7 @@ ref_message_info (CamelFolder *folder, CamelMessageInfo *info)
 {
        g_return_if_fail(folder->summary != NULL);
 
-       camel_folder_summary_info_ref(folder->summary, info);
+       camel_message_info_ref(info);
 }
 
 /**
@@ -1043,6 +981,8 @@ ref_message_info (CamelFolder *folder, CamelMessageInfo *info)
  * @folder: 
  * @info: 
  * 
+ * DEPRECATED: Use camel_message_info_ref directly.
+ *
  * Ref a CamelMessageInfo, previously obtained with get_message_info().
  **/
 void
@@ -1126,7 +1066,7 @@ get_uids(CamelFolder *folder)
                
                if (info) {
                        array->pdata[j++] = g_strdup (camel_message_info_uid (info));
-                       camel_folder_summary_info_free(folder->summary, info);
+                       camel_message_info_free(info);
                }
        }
        
@@ -1376,15 +1316,13 @@ transfer_message_to (CamelFolder *source, const char *uid, CamelFolder *dest,
        /* if its deleted we poke the flags, so we need to copy the messageinfo */
        if ((source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY)
            && (minfo = camel_folder_get_message_info(source, uid))) {
-               info = camel_message_info_new();
-               camel_message_info_dup_to(minfo, info);
+               info = camel_message_info_clone(minfo);
                camel_folder_free_message_info(source, minfo);
        } else
-               info = camel_message_info_new_from_header (((CamelMimePart *)msg)->headers);
+               info = camel_message_info_new_from_header(NULL, ((CamelMimePart *)msg)->headers);
        
        /* we don't want to retain the deleted flag */
-       if (info && info->flags & CAMEL_MESSAGE_DELETED)
-               info->flags = info->flags & ~CAMEL_MESSAGE_DELETED;
+       camel_message_info_set_flags(info, CAMEL_MESSAGE_DELETED, 0);
        
        camel_folder_append_message (dest, msg, info, transferred_uid, ex);
        camel_object_unref (msg);
index 78f8885..850a746 100644 (file)
@@ -130,8 +130,6 @@ typedef struct {
                          CamelException *ex);
 
        int   (*get_message_count)   (CamelFolder *folder);
-       int   (*get_unread_message_count) (CamelFolder *folder);
-       int   (*get_deleted_message_count) (CamelFolder *folder);
 
        void (*append_message)  (CamelFolder *folder, 
                                 CamelMimeMessage *message,
index 6949a9a..c169c8a 100644 (file)
 #endif
 
 #include <string.h>
+#include <pthread.h>
 
 #include "camel-string-utils.h"
 
-
 int
 camel_strcase_equal (gconstpointer a, gconstpointer b)
 {
@@ -141,3 +141,81 @@ char camel_toupper(char c)
        return c;
 }
 
+/* working stuff for pstrings */
+static pthread_mutex_t pstring_lock = PTHREAD_MUTEX_INITIALIZER;
+static GHashTable *pstring_table = NULL;
+
+/**
+ * camel_pstring_strdup:
+ * @s: String to copy.
+ * 
+ * Create a new pooled string entry for the string @s.  A pooled
+ * string is a table where common strings are uniquified to the same
+ * pointer value.  They are also refcounted, so freed when no longer
+ * in use.  In a thread-safe manner.
+ * 
+ * The NULL and empty strings are special cased to constant values.
+ *
+ * Return value: A pointer to an equivalent string of @s.  Use
+ * camel_pstring_free() when it is no longer needed.
+ **/
+const char *camel_pstring_strdup(const char *s)
+{
+       char *p;
+       void *pcount;
+       int count;
+
+       if (s == NULL)
+               return NULL;
+       if (s[0] == 0)
+               return "";
+
+       pthread_mutex_lock(&pstring_lock);
+       if (pstring_table == NULL)
+               pstring_table = g_hash_table_new(g_str_hash, g_str_equal);
+
+       if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) {
+               count = GPOINTER_TO_INT(pcount)+1;
+               g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count));
+       } else {
+               p = g_strdup(s);
+               g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(1));
+       }
+       pthread_mutex_unlock(&pstring_lock);
+
+       return p;
+}
+
+/**
+ * camel_pstring_free:
+ * @s: String to free.
+ * 
+ * De-ref a pooled string. If no more refs exist to this string, it will be deallocated.
+ *
+ * NULL and the empty string are special cased.
+ **/
+void camel_pstring_free(const char *s)
+{
+       char *p;
+       void *pcount;
+       int count;
+
+       if (pstring_table == NULL)
+               return;
+       if (s == NULL || s[0] == 0)
+               return;
+
+       pthread_mutex_lock(&pstring_lock);
+       if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) {
+               count = GPOINTER_TO_INT(pcount)-1;
+               if (count == 0) {
+                       g_hash_table_remove(pstring_table, p);
+                       g_free(p);
+               } else {
+                       g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count));
+               }
+       } else {
+               g_warning("Trying to free string not allocated from the pool '%s'", s);
+       }
+       pthread_mutex_unlock(&pstring_lock);
+}
index c655755..30745db 100644 (file)
@@ -42,6 +42,9 @@ const char *camel_strdown (char *str);
 char camel_tolower(char c);
 char camel_toupper(char c);
 
+const char *camel_pstring_strdup(const char *s);
+void camel_pstring_free(const char *s);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 8345bbf..5a69a6e 100644 (file)
@@ -41,7 +41,6 @@ typedef struct _CamelFolderSummary CamelFolderSummary;
 typedef struct _CamelInternetAddress CamelInternetAddress;
 typedef struct _CamelMedium CamelMedium;
 typedef struct _CamelMessageContentInfo CamelMessageContentInfo;
-typedef struct _CamelMessageInfo CamelMessageInfo;
 typedef struct _CamelMimeFilter CamelMimeFilter;
 typedef struct _CamelMimeFilterBasic CamelMimeFilterBasic;
 typedef struct _CamelMimeFilterBestenc CamelMimeFilterBestenc;
index 34211a4..7f8473e 100644 (file)
@@ -30,9 +30,9 @@
 #include "camel-exception.h"
 #include "camel-vee-folder.h"
 #include "camel-store.h"
-#include "camel-folder-summary.h"
 #include "camel-mime-message.h"
 #include "camel-folder-search.h"
+#include "camel-vee-summary.h"
 
 #include "camel-session.h"
 #include "camel-vee-store.h"   /* for open flags */
@@ -51,6 +51,7 @@
 
 #define _PRIVATE(o) (((CamelVeeFolder *)(o))->priv)
 
+#if 0
 static void vee_refresh_info(CamelFolder *folder, CamelException *ex);
 
 static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
@@ -66,21 +67,19 @@ static void vee_transfer_messages_to(CamelFolder *source, GPtrArray *uids, Camel
 static GPtrArray *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex);
 static GPtrArray *vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
 
-static gboolean vee_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
-static void vee_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value);
-static void vee_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
 static void vee_rename(CamelFolder *folder, const char *new);
+#endif
 
 static void camel_vee_folder_class_init (CamelVeeFolderClass *klass);
 static void camel_vee_folder_init       (CamelVeeFolder *obj);
 static void camel_vee_folder_finalise   (CamelObject *obj);
 
-static int vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex);
-static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun);
+static int vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex);
+static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source);
 
 static void folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf);
 static void subfolder_deleted(CamelFolder *f, void *event_data, CamelVeeFolder *vf);
-static void subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf);
+static void folder_renamed(CamelFolder *f, const char *old, CamelVeeFolder *vf);
 
 static void folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8], int keep, CamelVeeFolder *vf);
 
@@ -104,120 +103,21 @@ camel_vee_folder_get_type (void)
        return type;
 }
 
-static void
-camel_vee_folder_class_init (CamelVeeFolderClass *klass)
-{
-       CamelFolderClass *folder_class = (CamelFolderClass *) klass;
-
-       camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ()));
-
-       folder_class->refresh_info = vee_refresh_info;
-       folder_class->sync = vee_sync;
-       folder_class->expunge = vee_expunge;
-
-       folder_class->get_message = vee_get_message;
-       folder_class->append_message = vee_append_message;
-       folder_class->transfer_messages_to = vee_transfer_messages_to;
-
-       folder_class->search_by_expression = vee_search_by_expression;
-       folder_class->search_by_uids = vee_search_by_uids;
-
-       folder_class->set_message_flags = vee_set_message_flags;
-       folder_class->set_message_user_flag = vee_set_message_user_flag;
-       folder_class->set_message_user_tag = vee_set_message_user_tag;
-
-       folder_class->rename = vee_rename;
-
-       folder_class->freeze = vee_freeze;
-       folder_class->thaw = vee_thaw;
-}
-
-static void
-camel_vee_folder_init (CamelVeeFolder *obj)
-{
-       struct _CamelVeeFolderPrivate *p;
-       CamelFolder *folder = (CamelFolder *)obj;
-
-       p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
-
-       folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
-                                CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
-
-       /* FIXME: what to do about user flags if the subfolder doesn't support them? */
-       folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
-               CAMEL_MESSAGE_DELETED |
-               CAMEL_MESSAGE_DRAFT |
-               CAMEL_MESSAGE_FLAGGED |
-               CAMEL_MESSAGE_SEEN;
-
-       obj->changes = camel_folder_change_info_new();
-       obj->search = camel_folder_search_new();
-       
-       p->summary_lock = g_mutex_new();
-       p->subfolder_lock = g_mutex_new();
-       p->changed_lock = g_mutex_new();
-}
-
-static void
-camel_vee_folder_finalise (CamelObject *obj)
-{
-       CamelVeeFolder *vf = (CamelVeeFolder *)obj;
-       struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
-       GList *node;
-       CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
-
-       /* FIXME: check leaks */
-       node = p->folders;
-       while (node) {
-               CamelFolder *f = node->data;
-
-               if (vf != folder_unmatched) {
-                       camel_object_unhook_event((CamelObject *)f, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
-                       camel_object_unhook_event((CamelObject *)f, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
-                       camel_object_unhook_event((CamelObject *)f, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf);
-                       /* this updates the vfolder */
-                       if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0)
-                               vee_folder_remove_folder(vf, f, FALSE);
-               }
-               camel_object_unref((CamelObject *)f);
-
-               node = g_list_next(node);
-       }
-
-       g_free(vf->expression);
-       g_free(vf->vname);
-       
-       g_list_free(p->folders);
-       g_list_free(p->folders_changed);
-
-       camel_folder_change_info_free(vf->changes);
-       camel_object_unref((CamelObject *)vf->search);
-       
-       g_mutex_free(p->summary_lock);
-       g_mutex_free(p->subfolder_lock);
-       g_mutex_free(p->changed_lock);
-       
-       g_free(p);
-}
-
 void
 camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags)
 {
        CamelFolder *folder = (CamelFolder *)vf;
-       char *tmp;
+       const char *tmp;
 
        vf->flags = flags;
-       vf->vname = g_strdup(name);
-       tmp = strrchr(vf->vname, '/');
+       tmp = strrchr(name, '/');
        if (tmp)
                tmp++;
        else
-               tmp = vf->vname;
-       camel_folder_construct(folder, parent_store, vf->vname, tmp);
+               tmp = name;
+       camel_folder_construct(folder, parent_store, name, tmp);
 
-       /* should CamelVeeMessageInfo be subclassable ..? */
-       folder->summary = camel_folder_summary_new();
-       folder->summary->message_info_size = sizeof(CamelVeeMessageInfo);
+       folder->summary = camel_vee_summary_new(folder);
 
        if (CAMEL_IS_VEE_STORE(parent_store))
                vf->parent_vee_store = (CamelVeeStore *)parent_store;
@@ -262,38 +162,7 @@ camel_vee_folder_new(CamelStore *parent_store, const char *name, guint32 flags)
 void
 camel_vee_folder_set_expression(CamelVeeFolder *vf, const char *query)
 {
-       struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
-       GList *node;
-
-       CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
-
-       /* no change, do nothing */
-       if ((vf->expression && query && strcmp(vf->expression, query) == 0)
-           || (vf->expression == NULL && query == NULL)) {
-               CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
-               return;
-       }
-
-       g_free(vf->expression);
-       if (query)
-               vf->expression = g_strdup(query);
-
-       node = p->folders;
-       while (node) {
-               CamelFolder *f = node->data;
-
-               if (vee_folder_build_folder(vf, f, NULL) == -1)
-                       break;
-
-               node = node->next;
-       }
-
-       CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
-       g_list_free(p->folders_changed);
-       p->folders_changed = NULL;
-       CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
-
-       CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
+       ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->set_expression(vf, query);
 }
 
 /**
@@ -350,9 +219,9 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
 
        camel_object_hook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc)folder_changed, vf);
        camel_object_hook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc)subfolder_deleted, vf);
-       camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)subfolder_renamed, vf);
+       camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)folder_renamed, vf);
 
-       vee_folder_build_folder(vf, sub, NULL);
+       ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->add_folder(vf, sub);
 }
 
 /**
@@ -366,7 +235,6 @@ void
 camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
 {
        struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
-       int killun = FALSE;
        int i;
        CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
        
@@ -383,7 +251,7 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
        
        camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf);
        camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf);
-       camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf);
+       camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) folder_renamed, vf);
 
        p->folders = g_list_remove(p->folders, sub);
        
@@ -402,7 +270,6 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
                /* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
                if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
                        while (g_list_find(up->folders, sub)) {
-                               killun = TRUE;
                                up->folders = g_list_remove(up->folders, sub);
                                camel_object_unref((CamelObject *)sub);
                                
@@ -423,18 +290,29 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
                                        camel_folder_thaw(sub);
                                CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
                        }
-                       if (g_list_find(up->folders, sub) == NULL) {
-                               killun = TRUE;
-                       }
                }
                CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
        }
 
-       vee_folder_remove_folder(vf, sub, killun);
+       ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->remove_folder(vf, sub);
 
        camel_object_unref((CamelObject *)sub);
 }
 
+/**
+ * camel_vee_folder_rebuild_folder:
+ * @vf: Virtual Folder object
+ * @sub: source CamelFolder to add to @vf
+ * @ex: Exception.
+ *
+ * Rebuild the folder @sub, if it should be.
+ **/
+int
+camel_vee_folder_rebuild_folder(CamelVeeFolder *vf, CamelFolder *sub, CamelException *ex)
+{
+       return ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->rebuild_folder(vf, sub, ex);
+}
+
 static void
 remove_folders(CamelFolder *folder, CamelFolder *foldercopy, CamelVeeFolder *vf)
 {
@@ -456,7 +334,6 @@ camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders)
        GHashTable *remove = g_hash_table_new(NULL, NULL);
        GList *l;
        CamelFolder *folder;
-       int changed;
 
        /* setup a table of all folders we have currently */
        CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
@@ -474,15 +351,6 @@ camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders)
                if ((folder = g_hash_table_lookup(remove, l->data))) {
                        g_hash_table_remove(remove, folder);
                        camel_object_unref((CamelObject *)folder);
-
-                       /* if this was a changed folder, re-update it while we're here */
-                       CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
-                       changed = g_list_find(p->folders_changed, folder) != NULL;
-                       if (changed)
-                               p->folders_changed = g_list_remove(p->folders_changed, folder);
-                       CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
-                       if (changed)
-                               vee_folder_build_folder(vf, folder, NULL);
                } else {
                        camel_vee_folder_add_folder(vf, l->data);
                }
@@ -541,21 +409,25 @@ camel_vee_folder_hash_folder(CamelFolder *folder, char buffer[8])
 CamelFolder *
 camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid)
 {
+       CamelFolder *folder;
+
+       folder = vinfo->real->summary->folder;
+
        /* locking?  yes?  no?  although the vfolderinfo is valid when obtained
           the folder in it might not necessarily be so ...? */
-       if (CAMEL_IS_VEE_FOLDER(vinfo->folder)) {
-               CamelFolder *folder;
+       if (CAMEL_IS_VEE_FOLDER(folder)) {
+               CamelFolder *res;
                const CamelVeeMessageInfo *vfinfo;
 
-               vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(vinfo->folder, camel_message_info_uid(vinfo)+8);
-               folder = camel_vee_folder_get_location((CamelVeeFolder *)vinfo->folder, vfinfo, realuid);
-               camel_folder_free_message_info(vinfo->folder, (CamelMessageInfo *)vfinfo);
-               return folder;
+               vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(folder, camel_message_info_uid(vinfo)+8);
+               res = camel_vee_folder_get_location((CamelVeeFolder *)folder, vfinfo, realuid);
+               camel_folder_free_message_info(folder, (CamelMessageInfo *)vfinfo);
+               return res;
        } else {
                if (realuid)
                        *realuid = g_strdup(camel_message_info_uid(vinfo)+8);
 
-               return vinfo->folder;
+               return folder;
        }
 }
 
@@ -574,7 +446,7 @@ static void vee_refresh_info(CamelFolder *folder, CamelException *ex)
        while (node) {
                CamelFolder *f = node->data;
 
-               if (vee_folder_build_folder(vf, f, ex) == -1)
+               if (camel_vee_folder_rebuild_folder(vf, f, ex) == -1)
                        break;
 
                node = node->next;
@@ -607,7 +479,7 @@ vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex)
 
                /* auto update vfolders shouldn't need a rebuild */
                if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0
-                   && vee_folder_build_folder(vf, f, ex) == -1)
+                   && camel_vee_folder_rebuild_folder(vf, f, ex) == -1)
                        break;
 
                node = node->next;
@@ -639,8 +511,8 @@ vee_get_message(CamelFolder *folder, const char *uid, CamelException *ex)
 
        mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
        if (mi) {
-               msg =  camel_folder_get_message(mi->folder, camel_message_info_uid(mi)+8, ex);
-               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
+               msg =  camel_folder_get_message(mi->real->summary->folder, camel_message_info_uid(mi)+8, ex);
+               camel_message_info_free((CamelMessageInfo *)mi);
        } else {
                camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
                                     _("No such message %s in %s"), uid,
@@ -760,53 +632,11 @@ vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids,
        CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
 
        g_hash_table_destroy(searched);
-       g_ptr_array_free(folder_uids, 0);
+       g_ptr_array_free(folder_uids, TRUE);
 
        return result;
 }
 
-static gboolean
-vee_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
-       CamelVeeMessageInfo *mi;
-       int res = FALSE;
-
-       mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
-       if (mi) {
-               res = camel_folder_set_message_flags(mi->folder, camel_message_info_uid(mi) + 8, flags, set);
-               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
-               res = res || ((CamelFolderClass *)camel_vee_folder_parent)->set_message_flags(folder, uid, flags, set);
-       }
-
-       return res;
-}
-
-static void
-vee_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value)
-{
-       CamelVeeMessageInfo *mi;
-
-       mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
-       if (mi) {
-               camel_folder_set_message_user_flag(mi->folder, camel_message_info_uid(mi) + 8, name, value);
-               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
-               ((CamelFolderClass *)camel_vee_folder_parent)->set_message_user_flag(folder, uid, name, value);
-       }
-}
-
-static void
-vee_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value)
-{
-       CamelVeeMessageInfo *mi;
-
-       mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
-       if (mi) {
-               camel_folder_set_message_user_tag(mi->folder, camel_message_info_uid(mi) + 8, name, value);
-               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
-               ((CamelFolderClass *)camel_vee_folder_parent)->set_message_user_tag(folder, uid, name, value);
-       }
-}
-
 static void
 vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex)
 {
@@ -821,57 +651,36 @@ vee_transfer_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *des
 
 static void vee_rename(CamelFolder *folder, const char *new)
 {
-       CamelVeeFolder *vf = (CamelVeeFolder *)folder;
-
-       g_free(vf->vname);
-       vf->vname = g_strdup(new);
+       /*CamelVeeFolder *vf = (CamelVeeFolder *)folder;*/
 
        ((CamelFolderClass *)camel_vee_folder_parent)->rename(folder, new);
 }
 
-/* ********************************************************************** *
-   utility functions */
-
-/* must be called with summary_lock held */
-static CamelVeeMessageInfo *
-vee_folder_add_info(CamelVeeFolder *vf, CamelFolder *f, CamelMessageInfo *info, const char hash[8])
+static void vee_delete(CamelFolder *folder)
 {
-       CamelVeeMessageInfo *mi;
-       char *vuid;
-       const char *uid;
-       CamelFolder *folder = (CamelFolder *)vf;
-       CamelMessageInfo *dinfo;
+       struct _CamelVeeFolderPrivate *p = _PRIVATE(folder);
 
-       uid = camel_message_info_uid(info);
-       vuid = alloca(strlen(uid)+9);
-       memcpy(vuid, hash, 8);
-       strcpy(vuid+8, uid);
-       dinfo = camel_folder_summary_uid(folder->summary, vuid);
-       if (dinfo) {
-               d(printf("w:clash, we already have '%s' in summary\n", vuid));
-               camel_folder_summary_info_free(folder->summary, dinfo);
-               return NULL;
-       }
+       /* NB: this is never called on UNMTACHED */
 
-       d(printf("adding vuid %s to %s\n", vuid, vf->vname));
-
-       mi = (CamelVeeMessageInfo *)camel_folder_summary_info_new(folder->summary);
-       camel_message_info_dup_to(info, (CamelMessageInfo *)mi);
-#ifdef DOEPOOLV
-       mi->info.strings = e_poolv_set(mi->info.strings, CAMEL_MESSAGE_INFO_UID, vuid, FALSE);
-#elif defined (DOESTRV)
-       mi->info.strings = e_strv_set_ref(mi->info.strings, CAMEL_MESSAGE_INFO_UID, vuid);
-       mi->info.strings = e_strv_pack(mi->info.strings);
-#else  
-       g_free(mi->info.uid);
-       mi->info.uid = g_strdup(vuid);
-#endif
-       mi->folder = f;
-       camel_folder_summary_add(folder->summary, (CamelMessageInfo *)mi);
+       CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
+       while (p->folders) {
+               CamelFolder *f = p->folders->data;
 
-       return mi;
+               camel_object_ref(f);
+               CAMEL_VEE_FOLDER_UNLOCK(folder, subfolder_lock);
+
+               camel_vee_folder_remove_folder((CamelVeeFolder *)folder, f);
+               camel_object_unref(f);
+               CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
+       }
+       CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
+
+       ((CamelFolderClass *)camel_vee_folder_parent)->delete(folder);
 }
 
+/* ********************************************************************** *
+   utility functions */
+
 /* must be called with summary_lock held */
 static CamelVeeMessageInfo *
 vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const char hash[8])
@@ -881,14 +690,14 @@ vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const
 
        info = camel_folder_get_message_info(f, inuid);
        if (info) {
-               mi = vee_folder_add_info(vf, f, info, hash);
+               mi = camel_vee_summary_add((CamelVeeSummary *)((CamelFolder *)vf)->summary, info, hash);
                camel_folder_free_message_info(f, info);
        }
        return mi;
 }
 
 static void
-vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
+vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
 {
        int i, count, n, still = FALSE, start, last;
        char *oldkey;
@@ -899,10 +708,15 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
        void *oldval;
        CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
        GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
-       
+       CamelFolderSummary *ssummary = source->summary;
+       int killun = FALSE;
+
        if (vf == folder_unmatched)
                return;
 
+       if ((source->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED))
+               killun = TRUE;
+
        CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
 
        if (folder_unmatched != NULL) {
@@ -925,7 +739,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
                                CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
                                
                                if (mi) {
-                                       if (mi->folder == source) {
+                                       if (mi->real->summary == ssummary) {
                                                camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
                                                if (last == -1) {
                                                        last = start = i;
@@ -937,7 +751,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
                                                        start = last = i;
                                                }
                                        }
-                                       camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
+                                       camel_message_info_free((CamelMessageInfo *)mi);
                                }
                        }
                        if (last != -1)
@@ -951,7 +765,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
        for (i=0;i<count;i++) {
                CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i);
                if (mi) {
-                       if (mi->folder == source) {
+                       if (mi->real->summary == ssummary) {
                                const char *uid = camel_message_info_uid(mi);
 
                                camel_folder_change_info_remove_uid(vf->changes, uid);
@@ -986,7 +800,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
                                        }
                                }
                        }
-                       camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
+                       camel_message_info_free((CamelMessageInfo *)mi);
                }
        }
 
@@ -1046,7 +860,7 @@ unmatched_check_uid(char *uidin, void *value, struct _update_data *u)
                if (mi) {
                        camel_folder_summary_remove(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi);
                        camel_folder_change_info_remove_uid(u->folder_unmatched->changes, uid);
-                       camel_folder_summary_info_free(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi);
+                       camel_message_info_free((CamelMessageInfo *)mi);
                }
        }
 }
@@ -1075,7 +889,7 @@ folder_added_uid(char *uidin, void *value, struct _update_data *u)
 
 /* build query contents for a single folder */
 static int
-vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
+vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
 {
        GPtrArray *match, *all;
        GHashTable *allhash, *matchhash;
@@ -1086,6 +900,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
        CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
        CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
        GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
+       CamelFolderSummary *ssummary = source->summary;
 
        if (vf == folder_unmatched)
                return 0;
@@ -1130,7 +945,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
                CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i);
 
                if (mi) {
-                       if (mi->folder == source) {
+                       if (mi->real->summary == ssummary) {
                                char *uid = (char *)camel_message_info_uid(mi), *oldkey;
                                void *oldval;
                                
@@ -1160,7 +975,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
                                        g_hash_table_remove(matchhash, uid+8);
                                }
                        }
-                       camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
+                       camel_message_info_free((CamelMessageInfo *)mi);
                }
        }
        if (last != -1)
@@ -1176,7 +991,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
                        CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
 
                        if (mi) {
-                               if (mi->folder == source) {
+                               if (mi->real->summary == ssummary) {
                                        char *uid = (char *)camel_message_info_uid(mi);
 
                                        if (g_hash_table_lookup(allhash, uid+8) == NULL) {
@@ -1188,7 +1003,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
                                                g_hash_table_remove(allhash, uid+8);
                                        }
                                }
-                               camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
+                               camel_message_info_free((CamelMessageInfo *)mi);
                        }
                }
 
@@ -1295,7 +1110,7 @@ folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8],
        if (vinfo) {
                camel_folder_change_info_remove_uid(vf->changes, vuid);
                camel_folder_summary_remove(folder->summary, (CamelMessageInfo *)vinfo);
-               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
+               camel_message_info_free((CamelMessageInfo *)vinfo);
        }
 
        if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
@@ -1350,45 +1165,23 @@ folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8],
                info = camel_folder_get_message_info(sub, uid);
                if (info) {
                        if (vinfo) {
-                               int changed = FALSE;
-
-                               if (vinfo->info.flags != info->flags){
-                                       vinfo->info.flags = info->flags;
-                                       changed = TRUE;
-                               }
-                       
-                               changed |= camel_flag_list_copy(&vinfo->info.user_flags, &info->user_flags);
-                               changed |= camel_tag_list_copy(&vinfo->info.user_tags, &info->user_tags);
-                               if (changed)
-                                       camel_folder_change_info_change_uid(vf->changes, vuid);
-
-                               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
+                               camel_folder_change_info_change_uid(vf->changes, vuid);
+                               camel_message_info_free((CamelMessageInfo *)vinfo);
                        }
 
                        if (uinfo) {
-                               int changed = FALSE;
-
-                               if (uinfo->info.flags != info->flags){
-                                       uinfo->info.flags = info->flags;
-                                       changed = TRUE;
-                               }
-                       
-                               changed |= camel_flag_list_copy(&uinfo->info.user_flags, &info->user_flags);
-                               changed |= camel_tag_list_copy(&uinfo->info.user_tags, &info->user_tags);
-                               if (changed)
-                                       camel_folder_change_info_change_uid(folder_unmatched->changes, vuid);
-
-                               camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
+                               camel_folder_change_info_change_uid(folder_unmatched->changes, vuid);
+                               camel_message_info_free((CamelMessageInfo *)uinfo);
                        }
 
                        camel_folder_free_message_info(sub, info);
                } else {
                        if (vinfo) {
                                folder_changed_remove_uid(sub, uid, hash, FALSE, vf);
-                               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
+                               camel_message_info_free((CamelMessageInfo *)vinfo);
                        }
                        if (uinfo)
-                               camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo);
+                               camel_message_info_free((CamelMessageInfo *)uinfo);
                }
        }
 }
@@ -1464,7 +1257,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
                                        g_ptr_array_add(newchanged, (char *)uid);
                                } else {
                                        g_ptr_array_add(always_changed, (char *)uid);
-                                       camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
+                                       camel_message_info_free((CamelMessageInfo *)vinfo);
                                }
                        }
                        changed = newchanged;
@@ -1568,7 +1361,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
                                        dd(printf("  removing uid '%s' [did match]\n", uid));
                                        folder_changed_remove_uid(sub, uid, hash, TRUE, vf);
                                }
-                               camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
+                               camel_message_info_free((CamelMessageInfo *)vinfo);
                        }
                }
                g_hash_table_destroy(matches_hash);
@@ -1644,7 +1437,7 @@ static CamelSessionThreadOps folder_changed_ops = {
 };
 
 static void
-folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf)
+folder_changed_base(CamelVeeFolder *vf, CamelFolder *sub, CamelFolderChangeInfo *changes)
 {
        struct _folder_changed_msg *m;
        CamelSession *session = ((CamelService *)((CamelFolder *)vf)->parent_store)->session;
@@ -1659,6 +1452,12 @@ folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder
        camel_session_thread_queue(session, &m->msg, 0);
 }
 
+static void
+folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf)
+{
+       ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->folder_changed(vf, sub, changes);
+}
+
 /* track vanishing folders */
 static void
 subfolder_deleted(CamelFolder *f, void *event_data, CamelVeeFolder *vf)
@@ -1673,6 +1472,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
        CamelFolderChangeInfo *changes = NULL;
        CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
        GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
+       CamelFolderSummary *ssummary = sub->summary;
 
        CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
 
@@ -1684,7 +1484,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
                if (mi == NULL)
                        continue;
 
-               if (mi->folder == sub) {
+               if (mi->real->summary == ssummary) {
                        char *uid = (char *)camel_message_info_uid(mi);
                        char *oldkey;
                        void *oldval;
@@ -1709,7 +1509,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
                        }
                }
 
-               camel_folder_summary_info_free(((CamelFolder *)vf)->summary, (CamelMessageInfo *)mi);
+               camel_message_info_free((CamelMessageInfo *)mi);
        }
 
        if (camel_folder_change_info_changed(vf->changes)) {
@@ -1726,7 +1526,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
 }
 
 static void
-subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf)
+folder_renamed_base(CamelVeeFolder *vf, CamelFolder *f, const char *old)
 {
        char hash[8];
        CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
@@ -1744,6 +1544,12 @@ subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf)
 }
 
 static void
+folder_renamed(CamelFolder *sub, const char *old, CamelVeeFolder *vf)
+{
+       ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->folder_renamed(vf, sub, old);
+}
+
+static void
 vee_freeze (CamelFolder *folder)
 {
        CamelVeeFolder *vfolder = (CamelVeeFolder *)folder;
@@ -1788,3 +1594,148 @@ vee_thaw(CamelFolder *folder)
        /* call parent implementation */
        CAMEL_FOLDER_CLASS (camel_vee_folder_parent)->thaw(folder);
 }
+
+/* vfolder base implementaitons */
+static void
+vee_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
+{
+       vee_rebuild_folder(vf, sub, NULL);
+}
+
+static void
+vee_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
+{
+       vee_folder_remove_folder(vf, sub);
+}
+
+static void
+vee_set_expression(CamelVeeFolder *vf, const char *query)
+{
+       struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
+       GList *node;
+
+       CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
+
+       /* no change, do nothing */
+       if ((vf->expression && query && strcmp(vf->expression, query) == 0)
+           || (vf->expression == NULL && query == NULL)) {
+               CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
+               return;
+       }
+
+       g_free(vf->expression);
+       if (query)
+               vf->expression = g_strdup(query);
+
+       node = p->folders;
+       while (node) {
+               CamelFolder *f = node->data;
+
+               if (camel_vee_folder_rebuild_folder(vf, f, NULL) == -1)
+                       break;
+
+               node = node->next;
+       }
+
+       CAMEL_VEE_FOLDER_LOCK(vf, changed_lock);
+       g_list_free(p->folders_changed);
+       p->folders_changed = NULL;
+       CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock);
+
+       CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
+}
+
+static void
+camel_vee_folder_class_init (CamelVeeFolderClass *klass)
+{
+       CamelFolderClass *folder_class = (CamelFolderClass *) klass;
+
+       camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ()));
+
+       folder_class->refresh_info = vee_refresh_info;
+       folder_class->sync = vee_sync;
+       folder_class->expunge = vee_expunge;
+
+       folder_class->get_message = vee_get_message;
+       folder_class->append_message = vee_append_message;
+       folder_class->transfer_messages_to = vee_transfer_messages_to;
+
+       folder_class->search_by_expression = vee_search_by_expression;
+       folder_class->search_by_uids = vee_search_by_uids;
+
+       folder_class->rename = vee_rename;
+       folder_class->delete = vee_delete;
+
+       folder_class->freeze = vee_freeze;
+       folder_class->thaw = vee_thaw;
+
+       klass->set_expression = vee_set_expression;
+       klass->add_folder = vee_add_folder;
+       klass->remove_folder = vee_remove_folder;
+       klass->rebuild_folder = vee_rebuild_folder;
+       klass->folder_changed = folder_changed_base;
+       klass->folder_renamed = folder_renamed_base;
+}
+
+static void
+camel_vee_folder_init (CamelVeeFolder *obj)
+{
+       struct _CamelVeeFolderPrivate *p;
+       CamelFolder *folder = (CamelFolder *)obj;
+
+       p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
+
+       folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
+                                CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
+
+       /* FIXME: what to do about user flags if the subfolder doesn't support them? */
+       folder->permanent_flags = CAMEL_MESSAGE_ANSWERED |
+               CAMEL_MESSAGE_DELETED |
+               CAMEL_MESSAGE_DRAFT |
+               CAMEL_MESSAGE_FLAGGED |
+               CAMEL_MESSAGE_SEEN;
+
+       obj->changes = camel_folder_change_info_new();
+       obj->search = camel_folder_search_new();
+       
+       p->summary_lock = g_mutex_new();
+       p->subfolder_lock = g_mutex_new();
+       p->changed_lock = g_mutex_new();
+}
+
+static void
+camel_vee_folder_finalise (CamelObject *obj)
+{
+       CamelVeeFolder *vf = (CamelVeeFolder *)obj;
+       struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
+       CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+       GList *node;
+
+       /* TODO: there may be other leaks? */
+
+       /* This may invoke sub-classes with partially destroyed state, they must deal with this */
+       if (vf == folder_unmatched) {
+               for (node = p->folders;node;node = g_list_next(node))
+                       camel_object_unref(node->data);
+       } else {
+               while (p->folders) {
+                       CamelFolder *f = p->folders->data;
+
+                       camel_vee_folder_remove_folder(vf, f);
+               }
+       }
+
+       g_free(vf->expression);
+       
+       g_list_free(p->folders);
+       g_list_free(p->folders_changed);
+
+       camel_folder_change_info_free(vf->changes);
+       camel_object_unref((CamelObject *)vf->search);
+       
+       g_mutex_free(p->summary_lock);
+       g_mutex_free(p->subfolder_lock);
+       g_mutex_free(p->changed_lock);
+       
+       g_free(p);
+}
index 79f13a7..bccdf2c 100644 (file)
@@ -1,8 +1,8 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- *  Copyright (C) 2000 Ximian Inc.
+ * Copyright (C) 2000 Ximian Inc.
  *
- *  Authors: Michael Zucchi <notzed@ximian.com>
+ * Authors: Michael Zucchi <notzed@ximian.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -30,6 +30,7 @@ extern "C" {
 
 #include <glib.h>
 #include <camel/camel-folder.h>
+#include <camel/camel-vee-summary.h>
 
 #define CAMEL_VEE_FOLDER(obj)         CAMEL_CHECK_CAST (obj, camel_vee_folder_get_type (), CamelVeeFolder)
 #define CAMEL_VEE_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_folder_get_type (), CamelVeeFolderClass)
@@ -38,19 +39,12 @@ extern "C" {
 typedef struct _CamelVeeFolder      CamelVeeFolder;
 typedef struct _CamelVeeFolderClass CamelVeeFolderClass;
 
-/* our message info includes the parent folder */
-typedef struct _CamelVeeMessageInfo {
-       CamelMessageInfo info;
-       CamelFolder *folder;
-} CamelVeeMessageInfo;
-
 struct _CamelVeeFolder {
        CamelFolder parent;
 
        struct _CamelVeeFolderPrivate *priv;
 
        char *expression;       /* query expression */
-       char *vname;            /* local name */
 
        guint32 flags;          /* folder open flags */
 
@@ -64,6 +58,19 @@ struct _CamelVeeFolder {
 
 struct _CamelVeeFolderClass {
        CamelFolderClass parent_class;
+
+       /* TODO: Some of this may need some additional work/thinking through, it works for now*/
+
+       void (*add_folder)(CamelVeeFolder *, CamelFolder *);
+       void (*remove_folder)(CamelVeeFolder *, CamelFolder *);
+       int (*rebuild_folder)(CamelVeeFolder *, CamelFolder *, CamelException *);
+
+       void (*set_expression)(CamelVeeFolder *, const char *);
+
+       /* Called for a folder-changed event on a source folder */
+       void (*folder_changed)(CamelVeeFolder *, CamelFolder *sub, CamelFolderChangeInfo *changes);
+       /* Called for a folder-renamed event on a source folder */
+       void (*folder_renamed)(CamelVeeFolder *, CamelFolder *sub, const char *old);
 };
 
 #define CAMEL_UNMATCHED_NAME "UNMATCHED"
@@ -72,11 +79,12 @@ CamelType         camel_vee_folder_get_type         (void);
 CamelFolder  *camel_vee_folder_new             (CamelStore *parent_store, const char *name, guint32 flags);
 void         camel_vee_folder_construct                (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags);
 
-CamelFolder *camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid);
+CamelFolder *camel_vee_folder_get_location(CamelVeeFolder *vf, const struct _CamelVeeMessageInfo *vinfo, char **realuid);
 
 void         camel_vee_folder_add_folder        (CamelVeeFolder *vf, CamelFolder *sub);
 void         camel_vee_folder_remove_folder     (CamelVeeFolder *vf, CamelFolder *sub);
 void        camel_vee_folder_set_folders       (CamelVeeFolder *vf, GList *folders);
+int          camel_vee_folder_rebuild_folder(CamelVeeFolder *vf, CamelFolder *sub, CamelException *ex);
 void        camel_vee_folder_set_expression    (CamelVeeFolder *vf, const char *expr);
 
 void        camel_vee_folder_hash_folder       (CamelFolder *folder, char buffer[8]);
index 90c6ee1..8068339 100644 (file)
@@ -179,8 +179,8 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel
        vf = (CamelVeeFolder *)camel_vee_folder_new(store, folder_name, flags);
        if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
                /* Check that parents exist, if not, create dummy ones */
-               name = alloca(strlen(vf->vname)+1);
-               strcpy(name, vf->vname);
+               name = alloca(strlen(((CamelFolder *)vf)->full_name)+1);
+               strcpy(name, ((CamelFolder *)vf)->full_name);
                p = name;
                while ( (p = strchr(p, '/'))) {
                        *p = 0;
@@ -198,7 +198,7 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel
                        *p++='/';
                }
 
-               change_folder(store, vf->vname, CHANGE_ADD, camel_folder_get_message_count((CamelFolder *)vf));
+               change_folder(store, ((CamelFolder *)vf)->full_name, CHANGE_ADD, camel_folder_get_message_count((CamelFolder *)vf));
        }
 
        return (CamelFolder *)vf;
diff --git a/camel/camel-vee-summary.c b/camel/camel-vee-summary.c
new file mode 100644 (file)
index 0000000..6c44e0f
--- /dev/null
@@ -0,0 +1,227 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Copyright (C) 2000 Ximian Inc.
+ *
+ *  Authors: Michael Zucchi <notzed@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "camel-vee-summary.h"
+#include "camel-folder.h"
+
+#define d(x)
+
+static CamelFolderSummaryClass *camel_vee_summary_parent;
+
+static void
+vee_message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
+{
+       CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)info;
+
+       g_free(info->uid);
+       camel_message_info_free(mi->real);
+}
+
+static CamelMessageInfo *
+vee_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
+{
+       CamelVeeMessageInfo *to;
+       const CamelVeeMessageInfo *from = (const CamelVeeMessageInfo *)mi;
+
+       to = (CamelVeeMessageInfo *)camel_message_info_new(s);
+
+       to->real = camel_message_info_clone(from->real);
+       to->info.summary = s;
+
+       return (CamelMessageInfo *)to;
+}
+
+static const void *
+vee_info_ptr(const CamelMessageInfo *mi, int id)
+{
+       return camel_message_info_ptr(((CamelVeeMessageInfo *)mi)->real, id);
+}
+
+static guint32
+vee_info_uint32(const CamelMessageInfo *mi, int id)
+{
+       return camel_message_info_uint32(((CamelVeeMessageInfo *)mi)->real, id);
+}
+
+static time_t
+vee_info_time(const CamelMessageInfo *mi, int id)
+{
+       return camel_message_info_time(((CamelVeeMessageInfo *)mi)->real, id);
+}
+
+static gboolean
+vee_info_user_flag(const CamelMessageInfo *mi, const char *id)
+{
+       return camel_message_info_user_flag(((CamelVeeMessageInfo *)mi)->real, id);
+}
+
+static const char *
+vee_info_user_tag(const CamelMessageInfo *mi, const char *id)
+{
+       return camel_message_info_user_tag(((CamelVeeMessageInfo *)mi)->real, id);
+}
+
+static gboolean
+vee_info_set_user_flag(CamelMessageInfo *mi, const char *name, gboolean value)
+{
+       int res = FALSE;
+
+       if (mi->uid)
+               res = camel_message_info_set_user_flag(((CamelVeeMessageInfo *)mi)->real, name, value);
+
+       return res;
+}
+
+static gboolean
+vee_info_set_user_tag(CamelMessageInfo *mi, const char *name, const char *value)
+{
+       int res = FALSE;
+
+       if (mi->uid)
+               res = camel_message_info_set_user_tag(((CamelVeeMessageInfo *)mi)->real, name, value);
+
+       return res;
+}
+
+static gboolean
+vee_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
+{
+       int res = FALSE;
+
+       if (mi->uid)
+               res = camel_message_info_set_flags(((CamelVeeMessageInfo *)mi)->real, flags, set);
+
+       return res;
+}
+
+static void
+camel_vee_summary_class_init (CamelVeeSummaryClass *klass)
+{
+       ((CamelFolderSummaryClass *)klass)->message_info_clone = vee_message_info_clone;
+       ((CamelFolderSummaryClass *)klass)->message_info_free = vee_message_info_free;
+
+       ((CamelFolderSummaryClass *)klass)->info_ptr = vee_info_ptr;
+       ((CamelFolderSummaryClass *)klass)->info_uint32 = vee_info_uint32;
+       ((CamelFolderSummaryClass *)klass)->info_time = vee_info_time;
+       ((CamelFolderSummaryClass *)klass)->info_user_flag = vee_info_user_flag;
+       ((CamelFolderSummaryClass *)klass)->info_user_tag = vee_info_user_tag;
+
+#if 0
+       ((CamelFolderSummaryClass *)klass)->info_set_string = vee_info_set_string;
+       ((CamelFolderSummaryClass *)klass)->info_set_uint32 = vee_info_set_uint32;
+       ((CamelFolderSummaryClass *)klass)->info_set_time = vee_info_set_time;
+       ((CamelFolderSummaryClass *)klass)->info_set_references = vee_info_set_references;
+#endif
+       ((CamelFolderSummaryClass *)klass)->info_set_user_flag = vee_info_set_user_flag;
+       ((CamelFolderSummaryClass *)klass)->info_set_user_tag = vee_info_set_user_tag;
+
+       ((CamelFolderSummaryClass *)klass)->info_set_flags = vee_info_set_flags;
+}
+
+static void
+camel_vee_summary_init (CamelVeeSummary *obj)
+{
+       CamelFolderSummary *s = (CamelFolderSummary *)obj;
+
+       s->message_info_size = sizeof(CamelVeeMessageInfo);
+       s->content_info_size = 0;
+}
+
+CamelType
+camel_vee_summary_get_type (void)
+{
+       static CamelType type = CAMEL_INVALID_TYPE;
+
+       if (type == CAMEL_INVALID_TYPE) {
+               camel_vee_summary_parent = (CamelFolderSummaryClass *)camel_folder_summary_get_type();
+
+               type = camel_type_register(
+                       camel_folder_summary_get_type(), "CamelVeeSummary",
+                       sizeof (CamelVeeSummary),
+                       sizeof (CamelVeeSummaryClass),
+                       (CamelObjectClassInitFunc) camel_vee_summary_class_init,
+                       NULL,
+                       (CamelObjectInitFunc) camel_vee_summary_init,
+                       NULL);
+       }
+
+       return type;
+}
+
+/**
+ * camel_vee_summary_new:
+ * @parent: Folder its attached to.
+ *
+ * This will create a new CamelVeeSummary object and read in the
+ * summary data from disk, if it exists.
+ *
+ * Return value: A new CamelVeeSummary object.
+ **/
+CamelFolderSummary *
+camel_vee_summary_new(CamelFolder *parent)
+{
+       CamelVeeSummary *s;
+
+       s = (CamelVeeSummary *)camel_object_new(camel_vee_summary_get_type());
+       s->summary.folder = parent;
+
+       return &s->summary;
+}
+
+CamelVeeMessageInfo *
+camel_vee_summary_add(CamelVeeSummary *s, CamelMessageInfo *info, const char hash[8])
+{
+       CamelVeeMessageInfo *mi;
+       char *vuid;
+       const char *uid;
+
+       uid = camel_message_info_uid(info);
+       vuid = g_malloc(strlen(uid)+9);
+       memcpy(vuid, hash, 8);
+       strcpy(vuid+8, uid);
+       mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(&s->summary, vuid);
+       if (mi) {
+               d(printf("w:clash, we already have '%s' in summary\n", vuid));
+               camel_message_info_free((CamelMessageInfo *)mi);
+               g_free(vuid);
+               return NULL;
+       }
+
+       mi = (CamelVeeMessageInfo *)camel_message_info_new(&s->summary);
+       mi->real = info;
+       camel_message_info_ref(info);
+       mi->info.uid = vuid;
+
+       camel_folder_summary_add(&s->summary, (CamelMessageInfo *)mi);
+
+       return mi;
+}
diff --git a/camel/camel-vee-summary.h b/camel/camel-vee-summary.h
new file mode 100644 (file)
index 0000000..aa2683a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (C) 2000 Ximian Inc.
+ *
+ *  Authors:
+ *    Michael Zucchi <notzed@ximian.com>
+ *    Dan Winship <danw@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CAMEL_VEE_SUMMARY_H
+#define _CAMEL_VEE_SUMMARY_H
+
+#include <camel/camel-folder-summary.h>
+#include <camel/camel-exception.h>
+
+struct _CamelVeeFolder;
+struct _CamelFolder;
+
+#define CAMEL_VEE_SUMMARY(obj)         CAMEL_CHECK_CAST (obj, camel_vee_summary_get_type (), CamelVeeSummary)
+#define CAMEL_VEE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_summary_get_type (), CamelVeeSummaryClass)
+#define CAMEL_IS_VEE_SUMMARY(obj)      CAMEL_CHECK_TYPE (obj, camel_vee_summary_get_type ())
+
+typedef struct _CamelVeeSummary CamelVeeSummary;
+typedef struct _CamelVeeSummaryClass CamelVeeSummaryClass;
+
+typedef struct _CamelVeeMessageInfo CamelVeeMessageInfo;
+
+struct _CamelVeeMessageInfo {
+       CamelMessageInfo info;
+
+       CamelMessageInfo *real;
+};
+
+struct _CamelVeeSummary {
+       CamelFolderSummary summary;
+};
+
+struct _CamelVeeSummaryClass {
+       CamelFolderSummaryClass parent_class;
+
+};
+
+CamelType               camel_vee_summary_get_type     (void);
+CamelFolderSummary *camel_vee_summary_new(struct _CamelFolder *parent);
+
+CamelVeeMessageInfo * camel_vee_summary_add(CamelVeeSummary *s, CamelMessageInfo *info, const char hash[8]);
+
+#endif /* ! _CAMEL_VEE_SUMMARY_H */
+
index 91e4b8a..63656f4 100644 (file)
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  *  Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *          Michael Zucchi <notzed@ximian.com>
  *
  *  Copyright 2001 Ximian, Inc. (www.ximian.com)
  *
@@ -28,6 +29,7 @@
 #include "camel-vee-store.h"
 #include "camel-mime-message.h"
 #include "camel-i18n.h"
+#include "camel-private.h"
 
 #include <string.h>
 
@@ -49,23 +51,7 @@ static struct {
 
 static CamelVeeFolderClass *camel_vtrash_folder_parent;
 
-static void vtrash_append_message (CamelFolder *folder, CamelMimeMessage *message,
-                                  const CamelMessageInfo *info, char **appended_uid,
-                                  CamelException *ex);
-static void vtrash_transfer_messages_to (CamelFolder *folder, GPtrArray *uids,
-                                        CamelFolder *dest, GPtrArray **transferred_uids,
-                                        gboolean delete_originals, CamelException *ex);
-
-static void
-camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass)
-{
-       CamelFolderClass *folder_class = (CamelFolderClass *) klass;
-       
-       camel_vtrash_folder_parent = CAMEL_VEE_FOLDER_CLASS(camel_vee_folder_get_type());
-       
-       folder_class->append_message = vtrash_append_message;
-       folder_class->transfer_messages_to = vtrash_transfer_messages_to;
-}
+static void camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass);
 
 static void
 camel_vtrash_folder_init (CamelVTrashFolder *vtrash)
@@ -121,6 +107,77 @@ camel_vtrash_folder_new (CamelStore *parent_store, enum _camel_vtrash_folder_t t
        return (CamelFolder *)vtrash;
 }
 
+static int
+vtrash_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
+{
+       CamelFolder *folder = (CamelFolder *)object;
+       int i;
+       guint32 tag;
+       int unread = -1, deleted = 0, junked = 0, visible = 0, count = -1;
+
+       for (i=0;i<args->argc;i++) {
+               CamelArgGet *arg = &args->argv[i];
+
+               tag = arg->tag;
+
+               /* NB: this is a copy of camel-folder.c with the unread count logic altered.
+                  makes sure its still atomically calculated */
+               switch (tag & CAMEL_ARG_TAG) {
+               case CAMEL_FOLDER_ARG_UNREAD:
+               case CAMEL_FOLDER_ARG_DELETED:
+               case CAMEL_FOLDER_ARG_JUNKED:
+               case CAMEL_FOLDER_ARG_VISIBLE:
+                       /* This is so we can get the values atomically, and also so we can calculate them only once */
+                       if (unread == -1) {
+                               int j;
+                               CamelMessageInfo *info;
+
+                               unread = 0;
+                               count = camel_folder_summary_count(folder->summary);
+                               for (j=0; j<count; j++) {
+                                       if ((info = camel_folder_summary_index(folder->summary, j))) {
+                                               guint32 flags = camel_message_info_flags(info);
+
+                                               if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
+                                                       unread++;
+                                               if (flags & CAMEL_MESSAGE_DELETED)
+                                                       deleted++;
+                                               if (flags & CAMEL_MESSAGE_JUNK)
+                                                       junked++;
+                                               if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
+                                                       visible++;
+                                               camel_message_info_free(info);
+                                       }
+                               }
+                       }
+
+                       switch (tag & CAMEL_ARG_TAG) {
+                       case CAMEL_FOLDER_ARG_UNREAD:
+                               count = unread;
+                               break;
+                       case CAMEL_FOLDER_ARG_DELETED:
+                               count = deleted;
+                               break;
+                       case CAMEL_FOLDER_ARG_JUNKED:
+                               count = junked;
+                               break;
+                       case CAMEL_FOLDER_ARG_VISIBLE:
+                               count = visible;
+                               break;
+                       }
+
+                       *arg->ca_int = count;
+                       break;
+               default:
+                       continue;
+               }
+
+               arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
+       }
+
+       return ((CamelObjectClass *)camel_vtrash_folder_parent)->getv(object, ex, args);
+}
+
 static void
 vtrash_append_message (CamelFolder *folder, CamelMimeMessage *message,
                       const CamelMessageInfo *info, char **appended_uid,
@@ -199,20 +256,20 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
                        continue;
                }
                
-               if (dest == mi->folder) {
+               if (dest == mi->real->summary->folder) {
                        /* Just unset the flag on the original message */
                        camel_folder_set_message_flags (source, uids->pdata[i], sbit, 0);
                } else {
                        if (batch == NULL)
                                batch = g_hash_table_new(NULL, NULL);
-                       md = g_hash_table_lookup(batch, mi->folder);
+                       md = g_hash_table_lookup(batch, mi->real->summary->folder);
                        if (md == NULL) {
                                md = g_malloc0(sizeof(*md));
-                               md->folder = mi->folder;
+                               md->folder = mi->real->summary->folder;
                                camel_object_ref((CamelObject *)md->folder);
                                md->uids = g_ptr_array_new();
                                md->dest = dest;
-                               g_hash_table_insert(batch, mi->folder, md);
+                               g_hash_table_insert(batch, mi->real->summary->folder, md);
                        }
 
                        tuid = uids->pdata[i];
@@ -228,3 +285,322 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
                g_hash_table_destroy(batch);
        }
 }
+
+static GPtrArray *
+vtrash_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
+{
+       GList *node;
+       GPtrArray *matches, *result = g_ptr_array_new(), *uids = g_ptr_array_new();
+       struct _CamelVeeFolderPrivate *p = ((CamelVeeFolder *)folder)->priv;
+
+       /* we optimise the search by only searching for messages which we have anyway */
+       CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
+       node = p->folders;
+       while (node) {
+               CamelFolder *f = node->data;
+               int i;
+               char hash[8];
+               GPtrArray *infos = camel_folder_get_summary(f);
+
+               camel_vee_folder_hash_folder(f, hash);
+
+               for (i=0;i<infos->len;i++) {
+                       CamelMessageInfo *mi = infos->pdata[i];
+
+                       if (camel_message_info_flags(mi) & ((CamelVTrashFolder *)folder)->bit)
+                               g_ptr_array_add(uids, (void *)camel_message_info_uid(mi));
+               }
+
+               if (uids->len > 0
+                   && (matches = camel_folder_search_by_uids(f, expression, uids, NULL))) {
+                       for (i = 0; i < matches->len; i++) {
+                               char *uid = matches->pdata[i], *vuid;
+
+                               vuid = g_malloc(strlen(uid)+9);
+                               memcpy(vuid, hash, 8);
+                               strcpy(vuid+8, uid);
+                               g_ptr_array_add(result, vuid);
+                       }
+                       camel_folder_search_free(f, matches);
+               }
+               g_ptr_array_set_size(uids, 0);
+               camel_folder_free_summary(f, infos);
+
+               node = g_list_next(node);
+       }
+       CAMEL_VEE_FOLDER_UNLOCK(folder, subfolder_lock);
+
+       g_ptr_array_free(uids, TRUE);
+
+       return result;
+}
+
+static GPtrArray *
+vtrash_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex)
+{
+       GList *node;
+       GPtrArray *matches, *result = g_ptr_array_new(), *folder_uids = g_ptr_array_new();
+       struct _CamelVeeFolderPrivate *p = ((CamelVeeFolder *)folder)->priv;
+       
+       CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock);
+
+       node = p->folders;
+       while (node) {
+               CamelFolder *f = node->data;
+               int i;
+               char hash[8];
+               
+               camel_vee_folder_hash_folder(f, hash);
+
+               /* map the vfolder uid's to the source folder uid's first */
+               g_ptr_array_set_size(uids, 0);
+               for (i=0;i<uids->len;i++) {
+                       char *uid = uids->pdata[i];
+                       
+                       if (strlen(uid) >= 8 && strncmp(uid, hash, 8) == 0) {
+                               CamelMessageInfo *mi;
+
+                               mi = camel_folder_get_message_info(f, uid+8);
+                               if (mi) {
+                                       if(camel_message_info_flags(mi) & ((CamelVTrashFolder *)folder)->bit)
+                                               g_ptr_array_add(folder_uids, uid+8);
+                                       camel_folder_free_message_info(f, mi);
+                               }
+                       }
+               }
+
+               if (folder_uids->len > 0
+                   && (matches = camel_folder_search_by_uids(f, expression, folder_uids, ex))) {
+                       for (i = 0; i < matches->len; i++) {
+                               char *uid = matches->pdata[i], *vuid;
+                               
+                               vuid = g_malloc(strlen(uid)+9);
+                               memcpy(vuid, hash, 8);
+                               strcpy(vuid+8, uid);
+                               g_ptr_array_add(result, vuid);
+                       }
+                       camel_folder_search_free(f, matches);
+               }
+               node = g_list_next(node);
+       }
+
+       CAMEL_VEE_FOLDER_UNLOCK(folder, subfolder_lock);
+
+       g_ptr_array_free(folder_uids, TRUE);
+
+       return result;
+}
+
+static void
+vtrash_uid_removed(CamelVTrashFolder *vf, const char *uid, char hash[8])
+{
+       char *vuid;
+       CamelVeeMessageInfo *vinfo;
+
+       vuid = g_alloca(strlen(uid)+9);
+       memcpy(vuid, hash, 8);
+       strcpy(vuid+8, uid);
+       vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)vf)->summary, vuid);
+       if (vinfo) {
+               camel_folder_change_info_remove_uid(((CamelVeeFolder *)vf)->changes, vuid);
+               camel_folder_summary_remove(((CamelFolder *)vf)->summary, (CamelMessageInfo *)vinfo);
+               camel_message_info_free(vinfo);
+       }
+}
+
+static void
+vtrash_uid_added(CamelVTrashFolder *vf, const char *uid, CamelMessageInfo *info, char hash[8])
+{
+       char *vuid;
+       CamelVeeMessageInfo *vinfo;
+
+       vuid = g_alloca(strlen(uid)+9);
+       memcpy(vuid, hash, 8);
+       strcpy(vuid+8, uid);
+       vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)vf)->summary, vuid);
+       if (vinfo == NULL) {
+               camel_vee_summary_add((CamelVeeSummary *)((CamelFolder *)vf)->summary, info, hash);
+               camel_folder_change_info_add_uid(((CamelVeeFolder *)vf)->changes, vuid);
+       } else {
+               camel_folder_change_info_change_uid(((CamelVeeFolder *)vf)->changes, vuid);
+               camel_message_info_free(vinfo);
+       }
+}
+
+static void
+vtrash_folder_changed(CamelVeeFolder *vf, CamelFolder *sub, CamelFolderChangeInfo *changes)
+{
+       CamelMessageInfo *info;
+       char hash[8];
+       CamelFolderChangeInfo *vf_changes = NULL;
+       int i;
+
+       camel_vee_folder_hash_folder(sub, hash);
+
+       CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
+
+       /* remove any removed that we also have */
+       for (i=0;i<changes->uid_removed->len;i++)
+               vtrash_uid_removed((CamelVTrashFolder *)vf, (const char *)changes->uid_removed->pdata[i], hash);
+
+       /* check any changed still deleted/junked */
+       for (i=0;i<changes->uid_changed->len;i++) {
+               const char *uid = changes->uid_changed->pdata[i];
+
+               info = camel_folder_get_message_info(sub, uid);
+               if (info == NULL)
+                       continue;
+
+               if ((camel_message_info_flags(info) & ((CamelVTrashFolder *)vf)->bit) == 0)
+                       vtrash_uid_removed((CamelVTrashFolder *)vf, uid, hash);
+               else
+                       vtrash_uid_added((CamelVTrashFolder *)vf, uid, info, hash);
+
+               camel_message_info_free(info);
+       }
+
+       /* add any new ones which are already matching */
+       for (i=0;i<changes->uid_added->len;i++) {
+               const char *uid = changes->uid_added->pdata[i];
+
+               info = camel_folder_get_message_info(sub, uid);
+               if (info == NULL)
+                       continue;
+
+               if ((camel_message_info_flags(info) & ((CamelVTrashFolder *)vf)->bit) != 0)
+                       vtrash_uid_added((CamelVTrashFolder *)vf, uid, info, hash);
+
+               camel_message_info_free(info);
+       }
+
+       if (camel_folder_change_info_changed(((CamelVeeFolder *)vf)->changes)) {
+               vf_changes = ((CamelVeeFolder *)vf)->changes;
+               ((CamelVeeFolder *)vf)->changes = camel_folder_change_info_new();
+       }
+
+       CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
+       
+       if (vf_changes) {
+               camel_object_trigger_event(vf, "folder_changed", vf_changes);
+               camel_folder_change_info_free(vf_changes);
+       }
+}
+
+static void
+vtrash_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
+{
+       GPtrArray *infos;
+       int i;
+       char hash[8];
+       CamelFolderChangeInfo *vf_changes = NULL;
+
+       camel_vee_folder_hash_folder(sub, hash);
+
+       CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
+
+       infos = camel_folder_get_summary(sub);
+       for (i=0;i<infos->len;i++) {
+               CamelMessageInfo *info = infos->pdata[i];
+
+               if ((camel_message_info_flags(info) & ((CamelVTrashFolder *)vf)->bit))
+                       vtrash_uid_added((CamelVTrashFolder *)vf, camel_message_info_uid(info), info, hash);
+       }
+       camel_folder_free_summary(sub, infos);
+
+       if (camel_folder_change_info_changed(vf->changes)) {
+               vf_changes = vf->changes;
+               vf->changes = camel_folder_change_info_new();
+       }
+
+       CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
+
+       if (vf_changes) {
+               camel_object_trigger_event(vf, "folder_changed", vf_changes);
+               camel_folder_change_info_free(vf_changes);
+       }
+}
+
+static void
+vtrash_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
+{
+       GPtrArray *infos;
+       int i;
+       char hash[8];
+       CamelFolderChangeInfo *vf_changes = NULL;
+       CamelFolderSummary *ssummary = sub->summary;
+       int start, last;
+
+       camel_vee_folder_hash_folder(sub, hash);
+
+       CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
+
+       start = -1;
+       last = -1;
+       infos = camel_folder_get_summary(sub);
+       for (i=0;i<infos->len;i++) {
+               CamelVeeMessageInfo *mi = infos->pdata[i];
+
+               if (mi == NULL)
+                       continue;
+
+               if (mi->real->summary == ssummary) {
+                       const char *uid = camel_message_info_uid(mi);
+
+                       camel_folder_change_info_remove_uid(vf->changes, uid);
+
+                       if (last == -1) {
+                               last = start = i;
+                       } else if (last+1 == i) {
+                               last = i;
+                       } else {
+                               camel_folder_summary_remove_range(((CamelFolder *)vf)->summary, start, last);
+                               i -= (last-start)+1;
+                               start = last = i;
+                       }
+               }
+       }
+       camel_folder_free_summary(sub, infos);
+
+       if (last != -1)
+               camel_folder_summary_remove_range(((CamelFolder *)vf)->summary, start, last);
+
+       if (camel_folder_change_info_changed(vf->changes)) {
+               vf_changes = vf->changes;
+               vf->changes = camel_folder_change_info_new();
+       }
+
+       CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
+
+       if (vf_changes) {
+               camel_object_trigger_event(vf, "folder_changed", vf_changes);
+               camel_folder_change_info_free(vf_changes);
+       }
+}
+
+static int
+vtrash_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex)
+{
+       /* we should always be in sync */
+       return 0;
+}
+
+static void
+camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass)
+{
+       CamelFolderClass *folder_class = (CamelFolderClass *) klass;
+       
+       camel_vtrash_folder_parent = CAMEL_VEE_FOLDER_CLASS(camel_vee_folder_get_type());
+
+       ((CamelObjectClass *)klass)->getv = vtrash_getv;
+       
+       folder_class->append_message = vtrash_append_message;
+       folder_class->transfer_messages_to = vtrash_transfer_messages_to;
+       folder_class->search_by_expression = vtrash_search_by_expression;
+       folder_class->search_by_uids = vtrash_search_by_uids;
+
+       ((CamelVeeFolderClass *)klass)->add_folder = vtrash_add_folder;
+       ((CamelVeeFolderClass *)klass)->remove_folder = vtrash_remove_folder;
+       ((CamelVeeFolderClass *)klass)->rebuild_folder = vtrash_rebuild_folder;
+
+       ((CamelVeeFolderClass *)klass)->folder_changed = vtrash_folder_changed;
+}
index 22ea481..4ae70e9 100644 (file)
@@ -14,3 +14,4 @@ endif
 
 SUBDIRS = pop3 sendmail smtp imap $(NNTP_DIR) local $(IMAPP_DIR) $(IMAP4_DIR) groupwise
 
+
index 6d6908e..189844d 100644 (file)
@@ -237,7 +237,7 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name,
        camel_folder_construct (folder, parent, folder_name, short_name);
 
        summary_file = g_strdup_printf ("%s/summary", folder_dir);
-       folder->summary = camel_imap_summary_new (summary_file);
+       folder->summary = camel_imap_summary_new (folder, summary_file);
        g_free (summary_file);
        if (!folder->summary) {
                camel_object_unref (CAMEL_OBJECT (folder));
@@ -387,7 +387,7 @@ camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response,
                
                info = camel_folder_summary_index (folder->summary, count - 1);
                val = strtoul (camel_message_info_uid (info), NULL, 10);
-               camel_folder_summary_info_free (folder->summary, info);
+               camel_message_info_free(info);
                if (uid == 0 || uid != val)
                        imap_folder->need_rescan = TRUE;
        }
@@ -575,7 +575,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
        ok = camel_imap_command_start (store, folder, ex,
                                       "UID FETCH 1:%s (FLAGS)",
                                       camel_message_info_uid (info));
-       camel_folder_summary_info_free (folder->summary, info);
+       camel_message_info_free(info);
        if (!ok) {
                camel_operation_end (NULL);
                return;
@@ -632,7 +632,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
                iinfo = (CamelImapMessageInfo *)info;
                
                if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
-                       camel_folder_summary_info_free(folder->summary, info);
+                       camel_message_info_free(info);
                        seq = i + 1;
                        g_array_append_val (removed, seq);
                        i--;
@@ -646,8 +646,8 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
                        
                        server_set = new[i].flags & ~iinfo->server_flags;
                        server_cleared = iinfo->server_flags & ~new[i].flags;
-                       
-                       info->flags = (info->flags | server_set) & ~server_cleared;
+
+                       iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared;
                        iinfo->server_flags = new[i].flags;
 
                        if (changes == NULL)
@@ -655,7 +655,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
                        camel_folder_change_info_change_uid(changes, new[i].uid);
                }
                
-               camel_folder_summary_info_free (folder->summary, info);
+               camel_message_info_free(info);
                g_free (new[i].uid);
        }
 
@@ -697,7 +697,7 @@ static GPtrArray *
 get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
 {
        GPtrArray *matches;
-       CamelMessageInfo *info;
+       CamelImapMessageInfo *info;
        int i, max, range;
        GString *gset;
        
@@ -706,11 +706,11 @@ get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
        max = camel_folder_summary_count (folder->summary);
        range = -1;
        for (i = 0; i < max && !UID_SET_FULL (gset->len, UID_SET_LIMIT); i++) {
-               info = camel_folder_summary_index (folder->summary, i);
+               info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i);
                if (!info)
                        continue;
-               if ((info->flags & mask) != flags) {
-                       camel_folder_summary_info_free (folder->summary, info);
+               if ((info->info.flags & mask) != flags) {
+                       camel_message_info_free((CamelMessageInfo *)info);
                        if (range != -1) {
                                if (range != i - 1) {
                                        info = matches->pdata[matches->len - 1];
@@ -758,7 +758,7 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
 {
        CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
        CamelImapResponse *response = NULL;
-       CamelMessageInfo *info;
+       CamelImapMessageInfo *info;
        CamelException local_ex;
        GPtrArray *matches;
        char *set, *flaglist;
@@ -779,33 +779,33 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
         */
        max = camel_folder_summary_count (folder->summary);
        for (i = 0; i < max; i++) {
-               if (!(info = camel_folder_summary_index (folder->summary, i)))
+               if (!(info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i)))
                        continue;
                
-               if (!(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
-                       camel_folder_summary_info_free (folder->summary, info);
+               if (!(info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+                       camel_message_info_free((CamelMessageInfo *)info);
                        continue;
                }
                
                /* Note: Cyrus is broken and will not accept an
                   empty-set of flags so... if this is true then we
                   want to unset the previously set flags.*/
-               unset = !(info->flags & folder->permanent_flags);
+               unset = !(info->info.flags & folder->permanent_flags);
                
                /* Note: get_matching() uses UID_SET_LIMIT to limit
                   the size of the uid-set string. We don't have to
                   loop here to flush all the matching uids because
                   they will be scooped up later by our parent loop (I
                   think?). -- Jeff */
-               matches = get_matching (folder, info->flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
+               matches = get_matching (folder, info->info.flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
                                        folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED, &set);
-               camel_folder_summary_info_free (folder->summary, info);
+               camel_message_info_free(info);
                if (matches == NULL)
                        continue;
                
                /* FIXME: since we don't know the previously set flags,
                   if unset is TRUE then just unset all the flags? */
-               flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->flags & folder->permanent_flags);
+               flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->info.flags & folder->permanent_flags);
                
                /* Note: to `unset' flags, use -FLAGS.SILENT (<flag list>) */
                response = camel_imap_command (store, folder, &local_ex,
@@ -820,16 +820,15 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
                if (!camel_exception_is_set (&local_ex)) {
                        for (j = 0; j < matches->len; j++) {
                                info = matches->pdata[j];
-                               info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
-                               ((CamelImapMessageInfo *) info)->server_flags =
-                                       info->flags & CAMEL_IMAP_SERVER_FLAGS;
+                               info->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+                               ((CamelImapMessageInfo *) info)->server_flags = info->info.flags & CAMEL_IMAP_SERVER_FLAGS;
                        }
                        camel_folder_summary_touch (folder->summary);
                }
                
                for (j = 0; j < matches->len; j++) {
                        info = matches->pdata[j];
-                       camel_folder_summary_info_free (folder->summary, info);
+                       camel_message_info_free(&info->info);
                }
                g_ptr_array_free (matches, TRUE);
                
@@ -1167,10 +1166,11 @@ do_append (CamelFolder *folder, CamelMimeMessage *message,
        CamelStreamFilter *streamfilter;
        GByteArray *ba;
        char *flagstr, *end;
-       
-       /* create flag string param */
-       if (info && info->flags)
-               flagstr = imap_create_flag_list (info->flags);
+       guint32 flags;
+
+       flags = camel_message_info_flags(info);
+       if (flags)
+               flagstr = imap_create_flag_list (flags);
        else
                flagstr = NULL;
        
@@ -1357,7 +1357,7 @@ imap_transfer_offline (CamelFolder *source, GPtrArray *uids,
                        camel_imap_summary_add_offline_uncached (dest->summary, destuid, mi);
 
                camel_imap_message_cache_copy (sc, uid, dc, destuid, ex);
-               camel_folder_summary_info_free (source->summary, mi);
+               camel_message_info_free(mi);
 
                camel_folder_change_info_add_uid (changes, destuid);
                if (transferred_uids)
@@ -1968,12 +1968,12 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
 {
        CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
        CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
-       CamelMessageInfo *mi;
+       CamelImapMessageInfo *mi;
        CamelMimeMessage *msg = NULL;
        CamelStream *stream = NULL;
        int retry;
 
-       mi = camel_folder_summary_uid (folder->summary, uid);
+       mi = (CamelImapMessageInfo *)camel_folder_summary_uid (folder->summary, uid);
        if (mi == NULL) {
                camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
                                     _("Cannot get message: %s\n  %s"), uid, _("No such message"));
@@ -2001,11 +2001,11 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
                /* If the message is small or only 1 part, or server doesn't do 4v1 (properly) fetch it in one piece. */
                if (store->server_level < IMAP_LEVEL_IMAP4REV1
                    || store->braindamaged
-                   || mi->size < IMAP_SMALL_BODY_SIZE
-                   || (!content_info_incomplete(mi->content) && !mi->content->childs)) {
+                   || mi->info.size < IMAP_SMALL_BODY_SIZE
+                   || (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) {
                        msg = get_message_simple (imap_folder, uid, NULL, ex);
                } else {
-                       if (content_info_incomplete (mi->content)) {
+                       if (content_info_incomplete (mi->info.content)) {
                                /* For larger messages, fetch the structure and build a message
                                 * with offline parts. (We check mi->content->type rather than
                                 * mi->content because camel_folder_summary_info_new always creates
@@ -2038,7 +2038,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
                                        }
                                        
                                        if (body)
-                                               imap_parse_body ((const char **) &body, folder, mi->content);
+                                               imap_parse_body ((const char **) &body, folder, mi->info.content);
                                        
                                        if (fetch_data)
                                                g_datalist_clear (&fetch_data);
@@ -2049,7 +2049,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
 
                        if (camel_debug_start("imap:folder")) {
                                printf("Folder get message '%s' folder info ->\n", uid);
-                               camel_message_info_dump(mi);
+                               camel_message_info_dump((CamelMessageInfo *)mi);
                                camel_debug_end();
                        }
                        
@@ -2059,10 +2059,10 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
                         * fall back to fetching the entire thing and
                         * let the mailer's "bad MIME" code handle it.
                         */
-                       if (content_info_incomplete (mi->content))
+                       if (content_info_incomplete (mi->info.content))
                                msg = get_message_simple (imap_folder, uid, NULL, ex);
                        else
-                               msg = get_message (imap_folder, uid, mi->content, ex);
+                               msg = get_message (imap_folder, uid, mi->info.content, ex);
                }
        } while (msg == NULL
                 && retry < 2
@@ -2072,7 +2072,7 @@ done:     /* FIXME, this shouldn't be done this way. */
        if (msg)
                camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source", store->base_url);
 fail:
-       camel_folder_summary_info_free (folder->summary, mi);
+       camel_message_info_free(&mi->info);
        
        return msg;
 }
@@ -2201,7 +2201,7 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
 {
        CamelMimeMessage *msg;
        CamelStream *stream;
-       CamelMessageInfo *mi;
+       CamelImapMessageInfo *mi;
        const char *idate;
        int seq;
        
@@ -2221,14 +2221,14 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
                return;
        }
        
-       mi = camel_folder_summary_info_new_from_message (folder->summary, msg);
+       mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg);
        camel_object_unref (CAMEL_OBJECT (msg));
        
        if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
-               mi->date_received = decode_internaldate (idate);
+               mi->info.date_received = decode_internaldate (idate);
        
-       if (mi->date_received == -1)
-               mi->date_received = mi->date_sent;
+       if (mi->info.date_received == -1)
+               mi->info.date_received = mi->info.date_sent;
        
        messages->pdata[seq - first] = mi;
 }
@@ -2253,7 +2253,7 @@ imap_update_summary (CamelFolder *folder, int exists,
        int i, seq, first, size, got;
        CamelImapResponseType type;
        const char *header_spec;
-       CamelMessageInfo *mi, *info;
+       CamelImapMessageInfo *mi, *info;
        CamelStream *stream;
        char *uid, *resp;
        GData *data;
@@ -2272,9 +2272,9 @@ imap_update_summary (CamelFolder *folder, int exists,
        seq = camel_folder_summary_count (folder->summary);
        first = seq + 1;
        if (seq > 0) {
-               mi = camel_folder_summary_index (folder->summary, seq - 1);
+               mi = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, seq - 1);
                uidval = strtoul(camel_message_info_uid (mi), NULL, 10);
-               camel_folder_summary_info_free (folder->summary, mi);
+               camel_message_info_free(&mi->info);
        } else
                uidval = 0;
        
@@ -2433,24 +2433,23 @@ imap_update_summary (CamelFolder *folder, int exists,
                                continue;
                        }
                        
-                       mi = camel_message_info_new ();
-                       camel_message_info_dup_to (pmi, mi);
+                       mi = (CamelImapMessageInfo *)camel_message_info_clone(pmi);
                }
                
                uid = g_datalist_get_data (&data, "UID");
                if (uid)
-                       camel_message_info_set_uid (mi, g_strdup (uid));
+                       mi->info.uid = g_strdup (uid);
                flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS"));
                if (flags) {
                        ((CamelImapMessageInfo *)mi)->server_flags = flags;
                        /* "or" them in with the existing flags that may
                         * have been set by summary_info_new_from_message.
                         */
-                       mi->flags |= flags;
+                       mi->info.flags |= flags;
                }
                size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE"));
                if (size)
-                       mi->size = size;
+                       mi->info.size = size;
                
                g_datalist_clear (&data);
        }
@@ -2474,7 +2473,7 @@ imap_update_summary (CamelFolder *folder, int exists,
                                              i + first);
                        break;
                }
-               info = camel_folder_summary_uid(folder->summary, uid);
+               info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
                if (info) {
                        for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) {
                                if (folder->summary->messages->pdata[seq] == info)
@@ -2486,20 +2485,20 @@ imap_update_summary (CamelFolder *folder, int exists,
                                              _("Unexpected server response: Identical UIDs provided for messages %d and %d"),
                                              seq + 1, i + first);
                        
-                       camel_folder_summary_info_free(folder->summary, info);
+                       camel_message_info_free(&info->info);
                        break;
                }
                
-               camel_folder_summary_add (folder->summary, mi);
+               camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);
                camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
                
-               if ((mi->flags & CAMEL_IMAP_MESSAGE_RECENT))
+               if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT))
                        camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
        }
        
        for ( ; i < messages->len; i++) {
                if ((mi = messages->pdata[i]))
-                       camel_folder_summary_info_free(folder->summary, mi);
+                       camel_message_info_free(&mi->info);
        }
        
        g_ptr_array_free (messages, TRUE);
@@ -2517,7 +2516,7 @@ imap_update_summary (CamelFolder *folder, int exists,
        if (messages) {
                for (i = 0; i < messages->len; i++) {
                        if (messages->pdata[i])
-                               camel_folder_summary_info_free (folder->summary, messages->pdata[i]);
+                               camel_message_info_free(messages->pdata[i]);
                }
                g_ptr_array_free (messages, TRUE);
        }
@@ -2553,7 +2552,7 @@ camel_imap_folder_changed (CamelFolder *folder, int exists,
                        camel_imap_message_cache_remove (imap_folder->cache, camel_message_info_uid (info));
                        CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
                        camel_folder_summary_remove (folder->summary, info);
-                       camel_folder_summary_info_free(folder->summary, info);
+                       camel_message_info_free(info);
                }
        }
        
index 17fa9ca..3099602 100644 (file)
@@ -176,7 +176,7 @@ camel_imap_message_cache_new (const char *path, CamelFolderSummary *summary,
 
                info = camel_folder_summary_uid (summary, uid);
                if (info) {
-                       camel_folder_summary_info_free (summary, info);
+                       camel_message_info_free(info);
                        cache_put (cache, uid, d->d_name, NULL);
                } else
                        g_ptr_array_add (deletes, g_strdup_printf ("%s/%s", cache->path, d->d_name));
index b22743e..a2ecb71 100644 (file)
@@ -1047,7 +1047,7 @@ imap_forget_folder (CamelImapStore *imap_store, const char *folder_name, CamelEx
        }
        
        summary_file = g_strdup_printf ("%s/summary", folder_dir);
-       summary = camel_imap_summary_new (summary_file);
+       summary = camel_imap_summary_new (NULL, summary_file);
        if (!summary) {
                g_free (summary_file);
                g_free (folder_dir);
@@ -1597,14 +1597,17 @@ imap_disconnect_online (CamelService *service, gboolean clean, CamelException *e
 static gboolean
 imap_summary_is_dirty (CamelFolderSummary *summary)
 {
-       CamelMessageInfo *info;
+       CamelImapMessageInfo *info;
        int max, i;
-       
+       int found = FALSE;
+
        max = camel_folder_summary_count (summary);
-       for (i = 0; i < max; i++) {
-               info = camel_folder_summary_index (summary, i);
-               if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED))
-                       return TRUE;
+       for (i = 0; i < max && !found; i++) {
+               info = (CamelImapMessageInfo *)camel_folder_summary_index (summary, i);
+               if (info) {
+                       found = info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED;
+                       camel_message_info_free(info);
+               }
        }
        
        return FALSE;
index 6251f8b..3e1d024 100644 (file)
@@ -71,6 +71,21 @@ camel_imap_summary_get_type (void)
        return type;
 }
 
+static CamelMessageInfo *
+imap_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
+{
+       CamelImapMessageInfo *to;
+       const CamelImapMessageInfo *from = (const CamelImapMessageInfo *)mi;
+
+       to = (CamelImapMessageInfo *)camel_imap_summary_parent->message_info_clone(s, mi);
+       to->server_flags = from->server_flags;
+
+       /* FIXME: parent clone should do this */
+       to->info.content = camel_folder_summary_content_info_new(s);
+
+       return (CamelMessageInfo *)to;
+}
+
 static void
 camel_imap_summary_class_init (CamelImapSummaryClass *klass)
 {
@@ -78,6 +93,8 @@ camel_imap_summary_class_init (CamelImapSummaryClass *klass)
 
        camel_imap_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type()));
 
+       cfs_class->message_info_clone = imap_message_info_clone;
+
        cfs_class->summary_header_load = summary_header_load;
        cfs_class->summary_header_save = summary_header_save;
        cfs_class->message_info_load = message_info_load;
@@ -98,6 +115,7 @@ camel_imap_summary_init (CamelImapSummary *obj)
 
 /**
  * camel_imap_summary_new:
+ * @folder: Parent folder.
  * @filename: the file to store the summary in.
  *
  * This will create a new CamelImapSummary object and read in the
@@ -106,10 +124,11 @@ camel_imap_summary_init (CamelImapSummary *obj)
  * Return value: A new CamelImapSummary object.
  **/
 CamelFolderSummary *
-camel_imap_summary_new (const char *filename)
+camel_imap_summary_new (struct _CamelFolder *folder, const char *filename)
 {
-       CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (
-               camel_object_new (camel_imap_summary_get_type ()));
+       CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (camel_object_new (camel_imap_summary_get_type ()));
+
+       summary->folder = folder;
 
        camel_folder_summary_set_build_content (summary, TRUE);
        camel_folder_summary_set_filename (summary, filename);
@@ -177,7 +196,7 @@ message_info_load (CamelFolderSummary *s, FILE *in)
 
        return info;
 error:
-       camel_folder_summary_info_free (s, info);
+       camel_message_info_free(info);
        return NULL;
 }
 
@@ -218,52 +237,40 @@ camel_imap_summary_add_offline (CamelFolderSummary *summary, const char *uid,
                                CamelMimeMessage *message,
                                const CamelMessageInfo *info)
 {
-       CamelMessageInfo *mi;
-       CamelFlag *flag;
-       CamelTag *tag;
+       CamelImapMessageInfo *mi;
+       const CamelFlag *flag;
+       const CamelTag *tag;
 
        /* Create summary entry */
-       mi = camel_folder_summary_info_new_from_message (summary, message);
+       mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message);
 
        /* Copy flags 'n' tags */
-       mi->flags = info->flags;
-       flag = info->user_flags;
+       mi->info.flags = camel_message_info_flags(info);
+
+       flag = camel_message_info_user_flags(info);
        while (flag) {
-               camel_flag_set (&mi->user_flags, flag->name, TRUE);
+               camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
                flag = flag->next;
        }
-       tag = info->user_tags;
+       tag = camel_message_info_user_tags(info);
        while (tag) {
-               camel_tag_set (&mi->user_tags, tag->name, tag->value);
+               camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
                tag = tag->next;
        }
 
-       mi->size = info->size;
+       mi->info.size = camel_message_info_size(info);
+       mi->info.uid = g_strdup (uid);
 
-       /* Set uid and add to summary */
-       camel_message_info_set_uid (mi, g_strdup (uid));
-       camel_folder_summary_add (summary, mi);
+       camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
 }
 
 void
 camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, const char *uid,
                                         const CamelMessageInfo *info)
 {
-       CamelMessageInfo *mi;
-       CamelMessageContentInfo *ci;
-
-       /* Create summary entry */
-       mi = camel_folder_summary_info_new (summary);
-       ci = camel_folder_summary_content_info_new (summary);
-
-       camel_message_info_dup_to (info, mi);
-       mi->content = ci;
-
-       /* copy our private fields */
-       ((CamelImapMessageInfo *)mi)->server_flags = 
-               ((CamelImapMessageInfo *)info)->server_flags;
+       CamelImapMessageInfo *mi;
 
-       /* Set uid and add to summary */
-       camel_message_info_set_uid (mi, g_strdup (uid));
-       camel_folder_summary_add (summary, mi);
+       mi = camel_message_info_clone(info);
+       mi->info.uid = g_strdup(uid);
+       camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
 }
index e7402aa..04fb9b8 100644 (file)
@@ -47,7 +47,7 @@ typedef struct _CamelImapMessageContentInfo {
 } CamelImapMessageContentInfo;
 
 typedef struct _CamelImapMessageInfo {
-       CamelMessageInfo info;
+       CamelMessageInfoBase info;
 
        guint32 server_flags;
 } CamelImapMessageInfo;
@@ -65,7 +65,7 @@ struct _CamelImapSummaryClass {
 };
 
 CamelType               camel_imap_summary_get_type     (void);
-CamelFolderSummary *camel_imap_summary_new          (const char *filename);
+CamelFolderSummary *camel_imap_summary_new          (struct _CamelFolder *folder, const char *filename);
 
 void camel_imap_summary_add_offline (CamelFolderSummary *summary,
                                     const char *uid,
index ca94c18..a557f7f 100644 (file)
@@ -1061,7 +1061,7 @@ get_summary_uid_numeric (CamelFolderSummary *summary, int index)
        
        info = camel_folder_summary_index (summary, index);
        uid = strtoul (camel_message_info_uid (info), NULL, 10);
-       camel_folder_summary_info_free (summary, info);
+       camel_message_info_free(info);
        return uid;
 }
 
index 7ee109a..921d7aa 100644 (file)
@@ -459,7 +459,7 @@ imap4_sync_changes (CamelFolder *folder, GPtrArray *sync, CamelException *ex)
                
                for (j = 0; j < sync->len; j++) {
                        iinfo = (CamelIMAP4MessageInfo *) (info = sync->pdata[j]);
-                       camel_imap4_flags_diff (&diff, iinfo->server_flags, info->flags);
+                       camel_imap4_flags_diff (&diff, iinfo->server_flags, iinfo->info.flags);
                        if (diff.changed & imap4_flags[i].flag) {
                                if (diff.bits & imap4_flags[i].flag) {
                                        g_ptr_array_add (on_set, info);
@@ -492,8 +492,8 @@ imap4_sync_changes (CamelFolder *folder, GPtrArray *sync, CamelException *ex)
        
        for (i = 0; i < sync->len; i++) {
                iinfo = (CamelIMAP4MessageInfo *) (info = sync->pdata[i]);
-               info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
-               iinfo->server_flags = info->flags & folder->permanent_flags;
+               iinfo->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+               iinfo->server_flags = iinfo->info.flags & folder->permanent_flags;
        }
        
        return 0;
@@ -522,17 +522,17 @@ imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
        max = camel_folder_summary_count (folder->summary);
        for (i = 0; i < max; i++) {
                iinfo = (CamelIMAP4MessageInfo *) (info = camel_folder_summary_index (folder->summary, i));
-               if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
-                       camel_imap4_flags_diff (&diff, iinfo->server_flags, info->flags);
+               if (iinfo->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
+                       camel_imap4_flags_diff (&diff, iinfo->server_flags, iinfo->info.flags);
                        diff.changed &= folder->permanent_flags;
                        
                        /* weed out flag changes that we can't sync to the server */
                        if (!diff.changed)
-                               camel_folder_summary_info_free (folder->summary, info);
+                               camel_message_info_free(info);
                        else
                                g_ptr_array_add (sync, info);
                } else {
-                       camel_folder_summary_info_free (folder->summary, info);
+                       camel_message_info_free(info);
                }
        }
        
@@ -540,7 +540,7 @@ imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
                retval = imap4_sync_changes (folder, sync, ex);
                
                for (i = 0; i < sync->len; i++)
-                       camel_folder_summary_info_free (folder->summary, sync->pdata[i]);
+                       camel_message_info_free(sync->pdata[i]);
                
                g_ptr_array_free (sync, TRUE);
                
@@ -695,7 +695,7 @@ untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index,
                        
                        if ((info = camel_folder_summary_index (summary, index - 1))) {
                                iinfo = (CamelIMAP4MessageInfo *) info;
-                               info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, flags);
+                               iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, flags);
                                iinfo->server_flags = flags;
                                
                                changes = camel_folder_change_info_new ();
@@ -703,7 +703,7 @@ untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index,
                                camel_object_trigger_event (engine->folder, "folder_changed", changes);
                                camel_folder_change_info_free (changes);
                                
-                               camel_folder_summary_info_free (summary, info);
+                               camel_message_info_free(info);
                        }
                } else {
                        /* wtf? */
@@ -856,6 +856,7 @@ imap4_append_message (CamelFolder *folder, CamelMimeMessage *message,
        CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine;
        CamelSession *session = ((CamelService *) folder->parent_store)->session;
        CamelIMAP4Summary *summary = (CamelIMAP4Summary *) folder->summary;
+       const CamelIMAP4MessageInfo *iinfo = (const CamelIMAP4MessageInfo *)info;
        CamelIMAP4RespCode *resp;
        CamelIMAP4Command *ic;
        CamelFolderInfo *fi;
@@ -873,11 +874,11 @@ imap4_append_message (CamelFolder *folder, CamelMimeMessage *message,
        CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock);
        
        /* construct the option flags list */
-       if (info->flags & folder->permanent_flags) {
+       if (iinfo->info.flags & folder->permanent_flags) {
                p = g_stpcpy (flags, " (");
                
                for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) {
-                       if ((info->flags & imap4_flags[i].flag) & folder->permanent_flags) {
+                       if ((iinfo->info.flags & imap4_flags[i].flag) & folder->permanent_flags) {
                                p = g_stpcpy (p, imap4_flags[i].name);
                                *p++ = ' ';
                        }
@@ -890,13 +891,13 @@ imap4_append_message (CamelFolder *folder, CamelMimeMessage *message,
        }
        
        /* construct the optional date_time string */
-       if (info->date_received != (time_t) -1) {
+       if (iinfo->info.date_received != (time_t) -1) {
                int tzone;
                
 #ifdef HAVE_LOCALTIME_R
                localtime_r (&info->date_received, &tm);
 #else
-               memcpy (&tm, localtime (&info->date_received), sizeof (tm));
+               memcpy (&tm, localtime (&iinfo->info.date_received), sizeof (tm));
 #endif
                
 #if defined (HAVE_TM_GMTOFF)
@@ -1118,7 +1119,7 @@ imap4_transfer_messages_to (CamelFolder *src, GPtrArray *uids, CamelFolder *dest
  done:
        
        for (i = 0; i < infos->len; i++)
-               camel_folder_summary_info_free (src->summary, infos->pdata[i]);
+               camel_message_info_free(infos->pdata[i]);
        g_ptr_array_free (infos, TRUE);
        
        CAMEL_SERVICE_LOCK (src->parent_store, connect_lock);
index f7cb5ac..7102e2f 100644 (file)
@@ -123,7 +123,7 @@ untagged_search (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index,
                sprintf (uid, "%u", token->v.number);
                if ((info = camel_folder_summary_uid (summary, uid))) {
                        g_ptr_array_add (matches, (char *) camel_message_info_uid (info));
-                       camel_folder_summary_info_free (summary, info);
+                       camel_message_info_free(info);
                }
        }
        
index 4d2395b..c8832b5 100644 (file)
@@ -1112,28 +1112,12 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
                fi->flags = list->flags;
                fi->unread = -1;
                fi->total = -1;
-               
-               if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
-                       if (folder && !strcmp (folder->full_name, fi->full_name)) {
-                               /* can't STATUS this folder since it is SELECTED, besides - it would be wasteful */
-                               CamelMessageInfo *info;
-                               int index;
-                               
-                               fi->total = camel_folder_summary_count (folder->summary);
-                               
-                               fi->unread = 0;
-                               for (index = 0; index < fi->total; index++) {
-                                       if (!(info = camel_folder_summary_index (folder->summary, index)))
-                                               continue;
-                                       
-                                       if ((info->flags & CAMEL_MESSAGE_SEEN) == 0)
-                                               fi->unread++;
-                                       
-                                       camel_folder_summary_info_free (folder->summary, info);
-                               }
-                       } else {
-                               imap4_status (store, fi);
-                       }
+
+               /* SELECTED folder, just get it from the folder */
+               if (folder && !strcmp (folder->full_name, fi->full_name)) {
+                       camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &fi->total, CAMEL_FOLDER_UNREAD, &fi->unread, 0);
+               } else if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
+                       imap4_status (store, fi);
                }
                
                g_free (list->name);
index ef3e7e3..ce31d87 100644 (file)
@@ -36,6 +36,7 @@
 #include <e-util/md5-utils.h>
 
 #include <camel/camel-file-utils.h>
+#include <camel/camel-string-utils.h>
 #include <camel/camel-i18n.h>
 
 #include "camel-imap4-store.h"
@@ -57,7 +58,7 @@ static void camel_imap4_summary_finalize (CamelObject *object);
 
 static int imap4_header_load (CamelFolderSummary *summary, FILE *fin);
 static int imap4_header_save (CamelFolderSummary *summary, FILE *fout);
-static CamelMessageInfo *imap4_message_info_new (CamelFolderSummary *summary, struct _camel_header_raw *header);
+static CamelMessageInfo *imap4_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header);
 static CamelMessageInfo *imap4_message_info_load (CamelFolderSummary *summary, FILE *fin);
 static int imap4_message_info_save (CamelFolderSummary *summary, FILE *fout, CamelMessageInfo *info);
 
@@ -94,7 +95,7 @@ camel_imap4_summary_class_init (CamelIMAP4SummaryClass *klass)
        
        summary_class->summary_header_load = imap4_header_load;
        summary_class->summary_header_save = imap4_header_save;
-       summary_class->message_info_new = imap4_message_info_new;
+       summary_class->message_info_new_from_header = imap4_message_info_new_from_header;
        summary_class->message_info_load = imap4_message_info_load;
        summary_class->message_info_save = imap4_message_info_save;
 }
@@ -430,7 +431,8 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t
 {
        unsigned char md5sum[16];
        char *nstring;
-       
+       CamelIMAP4MessageInfo *iinfo = (CamelIMAP4MessageInfo *)info;
+
        if (camel_imap4_engine_next_token (engine, token, ex) == -1)
                return -1;
        
@@ -439,18 +441,20 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t
                return -1;
        }
        
-       if (envelope_decode_date (engine, &info->date_sent, ex) == -1)
+       if (envelope_decode_date (engine, &iinfo->info.date_sent, ex) == -1)
                goto exception;
        
        /* subject */
        if (envelope_decode_nstring (engine, &nstring, TRUE, ex) == -1)
                goto exception;
-       camel_message_info_set_subject (info, nstring);
+       iinfo->info.subject = camel_pstring_strdup(nstring);
+       g_free(nstring);
        
        /* from */
        if (envelope_decode_addresses (engine, &nstring, ex) == -1)
                goto exception;
-       camel_message_info_set_from (info, nstring);
+       iinfo->info.from = camel_pstring_strdup(nstring);
+       g_free(nstring);
        
        /* sender */
        if (envelope_decode_addresses (engine, &nstring, ex) == -1)
@@ -465,12 +469,14 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t
        /* to */
        if (envelope_decode_addresses (engine, &nstring, ex) == -1)
                goto exception;
-       camel_message_info_set_to (info, nstring);
+       iinfo->info.to = camel_pstring_strdup(nstring);
+       g_free(nstring);
        
        /* cc */
        if (envelope_decode_addresses (engine, &nstring, ex) == -1)
                goto exception;
-       camel_message_info_set_cc (info, nstring);
+       iinfo->info.cc = camel_pstring_strdup(nstring);
+       g_free(nstring);
        
        /* bcc */
        if (envelope_decode_addresses (engine, &nstring, ex) == -1)
@@ -482,7 +488,7 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t
                goto exception;
        
        if (nstring != NULL) {
-               info->references = decode_references (nstring);
+               iinfo->info.references = decode_references (nstring);
                g_free (nstring);
        }
        
@@ -492,7 +498,7 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t
        
        if (nstring != NULL) {
                md5_get_digest (nstring, strlen (nstring), md5sum);
-               memcpy (info->message_id.id.hash, md5sum, sizeof (info->message_id.id.hash));
+               memcpy (iinfo->info.message_id.id.hash, md5sum, sizeof (iinfo->info.message_id.id.hash));
                g_free (nstring);
        }
        
@@ -666,7 +672,7 @@ imap4_fetch_all_free (struct imap4_fetch_all_t *fetch)
                if (!(envelope = fetch->added->pdata[i]))
                        continue;
                
-               camel_folder_summary_info_free (fetch->summary, envelope->info);
+               camel_message_info_free(envelope->info);
                g_free (envelope);
        }
        
@@ -714,13 +720,13 @@ imap4_fetch_all_add (struct imap4_fetch_all_t *fetch)
                
                if (envelope->changed != IMAP4_FETCH_ALL) {
                        d(fprintf (stderr, "Hmmm, IMAP4 server didn't give us everything for message %d\n", i + 1));
-                       camel_folder_summary_info_free (fetch->summary, envelope->info);
+                       camel_message_info_free(envelope->info);
                        g_free (envelope);
                        continue;
                }
                
                if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (envelope->info)))) {
-                       camel_folder_summary_info_free (fetch->summary, envelope->info);
+                       camel_message_info_free(envelope->info);
                        g_free (envelope);
                        continue;
                }
@@ -769,14 +775,14 @@ imap4_fetch_all_update (struct imap4_fetch_all_t *fetch)
                        new_iinfo = (CamelIMAP4MessageInfo *) envelope->info;
                        iinfo = (CamelIMAP4MessageInfo *) info;
                        
-                       flags = info->flags;
-                       info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, new_iinfo->server_flags);
+                       flags = iinfo->info.flags;
+                       iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, new_iinfo->server_flags);
                        iinfo->server_flags = new_iinfo->server_flags;
-                       if (info->flags != flags)
+                       if (iinfo->info.flags != flags)
                                camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
                }
                
-               camel_folder_summary_info_free (fetch->summary, info);
+               camel_message_info_free(info);
        }
        
        for (i = 0; i < fetch->added->len; i++) {
@@ -788,13 +794,13 @@ imap4_fetch_all_update (struct imap4_fetch_all_t *fetch)
                info = envelope->info;
                if (!first && camel_message_info_uid (info)) {
                        if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (info)))) {
-                               camel_folder_summary_info_free (fetch->summary, info);
+                               camel_message_info_free(info);
                        } else {
                                first = i + fetch->first;
                        }
                }
                
-               camel_folder_summary_info_free (fetch->summary, envelope->info);
+               camel_message_info_free(envelope->info);
                g_free (envelope);
        }
        
@@ -835,7 +841,7 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind
                        g_ptr_array_set_size (added, index - fetch->first + 1);
                
                if (!(envelope = added->pdata[index - fetch->first])) {
-                       iinfo = (CamelIMAP4MessageInfo *) (info = camel_folder_summary_info_new (summary));
+                       iinfo = (CamelIMAP4MessageInfo *) (info = camel_message_info_new (summary));
                        envelope = g_new (struct imap4_envelope_t, 1);
                        added->pdata[index - fetch->first] = envelope;
                        envelope->info = info;
@@ -876,9 +882,9 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind
                                
                                g_warning ("Hmmm, server is sending us ENVELOPE data for a message we didn't ask for (message %u)\n",
                                           index);
-                               tmp = camel_folder_summary_info_new (summary);
+                               tmp = camel_message_info_new (summary);
                                rv = decode_envelope (engine, tmp, token, ex);
-                               camel_folder_summary_info_free (summary, tmp);
+                               camel_message_info_free(tmp);
                                
                                if (rv == -1)
                                        goto exception;
@@ -889,7 +895,7 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind
                        if (camel_imap4_parse_flags_list (engine, &server_flags, ex) == -1)
                                return -1;
                        
-                       info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, server_flags);
+                       iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, server_flags);
                        iinfo->server_flags = server_flags;
                        
                        changed |= IMAP4_FETCH_FLAGS;
@@ -899,11 +905,11 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind
                        
                        switch (token->token) {
                        case CAMEL_IMAP4_TOKEN_NIL:
-                               info->date_received = (time_t) -1;
+                               iinfo->info.date_received = (time_t) -1;
                                break;
                        case CAMEL_IMAP4_TOKEN_ATOM:
                        case CAMEL_IMAP4_TOKEN_QSTRING:
-                               info->date_received = decode_internaldate (token->v.qstring);
+                               iinfo->info.date_received = decode_internaldate (token->v.qstring);
                                break;
                        default:
                                goto unexpected;
@@ -917,7 +923,7 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind
                        if (token->token != CAMEL_IMAP4_TOKEN_NUMBER)
                                goto unexpected;
                        
-                       info->size = token->v.number;
+                       iinfo->info.size = token->v.number;
                        
                        changed |= IMAP4_FETCH_RFC822SIZE;
                } else if (!strcmp (token->v.atom, "UID")) {
@@ -935,7 +941,8 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind
                                        g_assert_not_reached ();
                                }
                        } else {
-                               camel_message_info_set_uid (info, g_strdup (uid));
+                               g_free(info->uid);
+                               info->uid = g_strdup (uid);
                                g_hash_table_insert (fetch->uid_hash, (void *) camel_message_info_uid (info), envelope);
                                changed |= IMAP4_FETCH_UID;
                        }
@@ -1071,11 +1078,11 @@ imap4_build_summary (CamelFolderSummary *summary, guint32 first, guint32 last)
 #endif
 
 static CamelMessageInfo *
-imap4_message_info_new (CamelFolderSummary *summary, struct _camel_header_raw *header)
+imap4_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header)
 {
        CamelMessageInfo *info;
        
-       info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new (summary, header);
+       info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header (summary, header);
        
        ((CamelIMAP4MessageInfo *) info)->server_flags = 0;
        
@@ -1100,7 +1107,7 @@ imap4_message_info_load (CamelFolderSummary *summary, FILE *fin)
        
  exception:
        
-       camel_folder_summary_info_free (summary, info);
+       camel_message_info_free(info);
        
        return NULL;
 }
@@ -1178,7 +1185,7 @@ camel_imap4_summary_set_uidvalidity (CamelFolderSummary *summary, guint32 uidval
                        continue;
                
                camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
-               camel_folder_summary_info_free (summary, info);
+               camel_message_info_free(info);
        }
        
        camel_folder_summary_clear (summary);
@@ -1215,7 +1222,7 @@ camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid)
        changes = camel_folder_change_info_new ();
        camel_folder_change_info_remove_uid (changes, uid);
        
-       camel_folder_summary_info_free (summary, info);
+       camel_message_info_free(info);
        camel_folder_summary_remove_index (summary, seqid);
        
        camel_object_trigger_event (imap4_summary->folder, "folder_changed", changes);
index 7de05a5..9af9621 100644 (file)
@@ -45,7 +45,7 @@ typedef struct _CamelIMAP4SummaryClass CamelIMAP4SummaryClass;
 #define CAMEL_IMAP4_MESSAGE_RECENT (1 << 17)
 
 struct _CamelIMAP4MessageInfo {
-       CamelMessageInfo parent_info;
+       CamelMessageInfoBase info;
        
        guint32 server_flags;
 };
index 9c70d8d..63b46ae 100644 (file)
@@ -1,3 +1,7 @@
+2004-11-11  Not Zed  <NotZed@Ximian.com>
+
+       * updates for camel folder summary api changes.
+
 2004-09-30  Not Zed  <NotZed@Ximian.com>
 
        * camel-imapp-engine.c: make the build again, warnings, doesn't
index aa1f2a2..c9a9e45 100644 (file)
@@ -332,7 +332,7 @@ imapp_write_flags(CamelIMAPPDriver *id, guint32 orset, gboolean on, CamelFolderS
                                                ic = camel_imapp_engine_command_new(id->engine, "STORE", NULL, "UID STORE ");
                                        flush = imapp_uidset_add(&ss, ic, camel_message_info_uid(info));                                
                                }
-                               camel_folder_summary_info_free(summary, (CamelMessageInfo *)info);
+                               camel_message_info_free((CamelMessageInfo *)info);
                        }
 
                        if (i == count-1 && ic != NULL)
@@ -391,7 +391,7 @@ camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, CamelIMAPPFolder
                        off_orset |= ( flags ^ sflags ) & ~flags;
                        on_orset |= (flags ^ sflags) & flags;
                }
-               camel_folder_summary_info_free(summary, (CamelMessageInfo *)info);
+               camel_message_info_free((CamelMessageInfo *)info);
        }
 
        if (on_orset || off_orset) {
@@ -407,7 +407,7 @@ camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, CamelIMAPPFolder
                        if (info == NULL)
                                continue;
                        info->server_flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS;
-                       camel_folder_summary_info_free(summary, (CamelMessageInfo *)info);
+                       camel_message_info_free((CamelMessageInfo *)info);
                }
                camel_folder_summary_touch(summary);
                /* could save summary here, incase of failure? */
@@ -656,7 +656,7 @@ driver_resp_expunge(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
                if (info) {
                        printf("expunging msg %d\n", id);
                        camel_folder_summary_remove(summary, info);
-                       camel_folder_summary_info_free(summary, info);
+                       camel_message_info_free(info);
                        camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info));
                } else {
                        printf("can not find msg %u from expunge\n", id);
@@ -670,7 +670,7 @@ static int
 driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
 {
        struct _fetch_info *finfo = NULL;
-       CamelMessageInfo *info, *uinfo;
+       CamelIMAPPMessageInfo *info, *uinfo;
        unsigned int i;
        CamelFolderSummary *summary;
 
@@ -684,36 +684,36 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
        finfo = imap_parse_fetch(ie->stream);
        imap_dump_fetch(finfo);
 
-       info = camel_folder_summary_index(summary, id-1);
+       info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, id-1);
        if (info == NULL) {
                if (finfo->uid == NULL) {
                        printf("got fetch response for currently unknown message %u\n", id);
                        goto done;
                }
-               uinfo = camel_folder_summary_uid(summary, finfo->uid);
+               uinfo = (CamelIMAPPMessageInfo *)camel_folder_summary_uid(summary, finfo->uid);
                if (uinfo) {
                        /* we have a problem ... index mismatch */
                        printf("index mismatch, uid '%s' not at index '%u'\n",
                               finfo->uid, id);
-                       camel_folder_summary_info_free(summary, uinfo);
+                       camel_message_info_free(uinfo);
                }
                /* pad out the summary till we have enough indexes */
                for (i=camel_folder_summary_count(summary);i<id;i++) {
-                       info = camel_folder_summary_info_new(summary);
+                       info = camel_message_info_new(summary);
                        if (i == id-1) {
                                printf("inserting new info @ %u\n", i);
-                               camel_message_info_set_uid(info, g_strdup(finfo->uid));
+                               info->info.uid = g_strdup(finfo->uid);
                        } else {
                                char uidtmp[32];
 
                                sprintf(uidtmp, "blank-%u", i);
-                               camel_message_info_set_uid(info, g_strdup(uidtmp));
+                               info->info.uid = g_strdup(uidtmp);
                                printf("inserting empty uid %s\n", uidtmp);
                        }
                
-                       camel_folder_summary_add(summary, info);
+                       camel_folder_summary_add(summary, (CamelMessageInfo *)info);
                }
-               info = camel_folder_summary_index(summary, id-1);
+               info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, id-1);
                g_assert(info != NULL);
        } else {
                if (finfo->uid) {
@@ -723,9 +723,9 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
                                       finfo->uid, id, camel_message_info_uid(info));
 
                                camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info));
-                               camel_folder_summary_remove(summary, info);
-                               camel_folder_summary_info_free(summary, info);
-                               info = camel_folder_summary_index(summary, id-1);
+                               camel_folder_summary_remove(summary, (CamelMessageInfo *)info);
+                               camel_message_info_free(info);
+                               info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, id-1);
                        }
                } else {
                        printf("got info for unknown message %u\n", id);
@@ -735,19 +735,19 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
        if (info) {
                if (finfo->got & FETCH_MINFO) {
                        /* if we only use ENVELOPE? */
-                       camel_message_info_set_subject(info, g_strdup(camel_message_info_subject(finfo->minfo)));
-                       camel_message_info_set_from(info, g_strdup(camel_message_info_from(finfo->minfo)));
-                       camel_message_info_set_to(info, g_strdup(camel_message_info_to(finfo->minfo)));
-                       camel_message_info_set_cc(info, g_strdup(camel_message_info_cc(finfo->minfo)));
-                       info->date_sent = finfo->minfo->date_sent;
+                       info->info.subject = g_strdup(camel_message_info_subject(finfo->minfo));
+                       info->info.from = g_strdup(camel_message_info_from(finfo->minfo));
+                       info->info.to = g_strdup(camel_message_info_to(finfo->minfo));
+                       info->info.cc = g_strdup(camel_message_info_cc(finfo->minfo));
+                       info->info.date_sent = camel_message_info_date_sent(finfo->minfo);
                        camel_folder_change_info_add_uid(sdata->folder->changes, camel_message_info_uid(info));
                        printf("adding change info uid '%s'\n", camel_message_info_uid(info));
                }
 
                if (finfo->got & FETCH_FLAGS) {
-                       if ((info->flags & CAMEL_IMAPP_SERVER_FLAGS) != (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS)) {
+                       if ((info->info.flags & CAMEL_IMAPP_SERVER_FLAGS) != (camel_message_info_flags(finfo) & CAMEL_IMAPP_SERVER_FLAGS)) {
                                camel_folder_change_info_change_uid(sdata->folder->changes, camel_message_info_uid(info));
-                               info->flags = (info->flags & ~(CAMEL_IMAPP_SERVER_FLAGS)) | (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS);
+                               info->info.flags = (info->info.flags & ~(CAMEL_IMAPP_SERVER_FLAGS)) | (camel_message_info_flags(finfo) & CAMEL_IMAPP_SERVER_FLAGS);
                                camel_folder_summary_touch(summary);
                        }
                        ((CamelIMAPPMessageInfo *)info)->server_flags = finfo->flags & CAMEL_IMAPP_SERVER_FLAGS;
@@ -770,7 +770,7 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata)
                        }
                }
 
-               camel_folder_summary_info_free(summary, info);
+               camel_message_info_free(info);
        } else {
                printf("dont know what to do with message\n");
        }
index aed7534..e85048d 100644 (file)
@@ -68,7 +68,6 @@ imap_folder_class_init (CamelIMAPPFolderClass *camel_imapp_folder_class)
        camel_folder_class->sync = imap_sync;
        
        camel_folder_class->get_message = imap_get_message;
-       /*camel_folder_class->set_message_flags = imap_set_message_flags;*/
 }
 
 static void
index 23b6d3c..60d2816 100644 (file)
@@ -810,7 +810,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
                                if (strcmp(finfo->uid, camel_message_info_uid(info)) != 0) {
                                        printf("summary at index %d has uid %s expected %s\n", id, camel_message_info_uid(info), finfo->uid);
                                        /* uid mismatch???  try do it based on uid instead? try to reorder?  i dont know? */
-                                       camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
+                                       camel_message_info_free(info);
                                        info = camel_folder_summary_uid(((CamelFolder *)istore->selected)->summary, finfo->uid);
                                }
                        }
@@ -859,7 +859,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
                                        CamelMimeParser *mp;
 
                                        if (pending == NULL)
-                                               camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
+                                               camel_message_info_free(info);
                                        mp = camel_mime_parser_new();
                                        camel_mime_parser_init_with_stream(mp, finfo->header);
                                        info = camel_folder_summary_info_new_from_parser(((CamelFolder *)istore->selected)->summary, mp);
@@ -872,7 +872,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
                                                /* FIXME: use a dlist */
                                                e_dlist_remove((EDListNode *)pending);
                                                g_hash_table_remove(istore->pending_fetch_table, camel_message_info_uid(pending->info));
-                                               camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, pending->info);
+                                               camel_message_info_free(pending->info);
                                                /*e_memchunk_free(istore->pending_fetch_chunks, pending);*/
                                        }
                                } else if (finfo->got & FETCH_FLAGS) {
@@ -884,7 +884,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
                                        }
                                } else {
                                        if (pending == NULL)
-                                               camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
+                                               camel_message_info_free(info);
                                        printf("got unexpected fetch response?\n");
                                        imap_dump_fetch(finfo);
                                }
@@ -974,7 +974,7 @@ camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *fold
                        if (info) {
                                printf("message info [%d] =\n", i);
                                camel_message_info_dump(info);
-                               camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
+                               camel_message_info_free(info);
                        }
                }
        } CAMEL_CATCH (e) {
index 97b7afd..ace5288 100644 (file)
@@ -44,7 +44,7 @@ struct _pending_fetch {
        struct _pending_fetch *next;
        struct _pending_fetch *prev;
 
-       CamelMessageInfo *info;
+       struct _CamelMessageInfo *info;
 };
 
 typedef struct {
index 05f0ec5..1b5a2c7 100644 (file)
@@ -168,7 +168,7 @@ message_info_load(CamelFolderSummary *s, FILE *in)
 
        return info;
 error:
-       camel_folder_summary_info_free(s, info);
+       camel_message_info_free(info);
        return NULL;
 }
 
index 215ad24..1189bac 100644 (file)
@@ -42,7 +42,7 @@ typedef struct _CamelIMAPPSummaryClass CamelIMAPPSummaryClass;
 typedef struct _CamelIMAPPSummary CamelIMAPPSummary;
 
 typedef struct _CamelIMAPPMessageInfo {
-       CamelMessageInfo info;
+       CamelMessageInfoBase info;
 
        guint32 server_flags;
 } CamelIMAPPMessageInfo;
index 19bdb3b..51e0fe1 100644 (file)
@@ -6,6 +6,7 @@
 #include <camel/camel-folder-summary.h>
 #include <camel/camel-store.h>
 #include <camel/camel-utf8.h>
+#include <camel/camel-string-utils.h>
 
 #include "camel-imapp-folder.h"
 #include "camel-imapp-stream.h"
@@ -585,7 +586,7 @@ imap_parse_envelope(CamelIMAPPStream *is)
        unsigned char *token;
        struct _camel_header_address *addr, *addr_from;
        char *addrstr;
-       struct _CamelMessageInfo *minfo;
+       struct _CamelMessageInfoBase *minfo;
 
        /* envelope        ::= "(" env_date SPACE env_subject SPACE env_from
           SPACE env_sender SPACE env_reply_to SPACE env_to
@@ -594,7 +595,7 @@ imap_parse_envelope(CamelIMAPPStream *is)
 
        p(printf("envelope\n"));
 
-       minfo = camel_message_info_new();
+       minfo = (CamelMessageInfoBase *)camel_message_info_new(NULL);
 
        CAMEL_TRY {
                tok = camel_imapp_stream_token(is, &token, &len);
@@ -607,8 +608,7 @@ imap_parse_envelope(CamelIMAPPStream *is)
 
                /* env_subject     ::= nstring */
                tok = camel_imapp_stream_nstring(is, &token);
-               /* DUH: this free's it!: camel_message_info_set_subject(minfo, token); */
-               e_poolv_set(minfo->strings, CAMEL_MESSAGE_INFO_SUBJECT, token, FALSE);
+               minfo->subject = camel_pstring_strdup(token);
 
                /* we merge from/sender into from, append should probably merge more smartly? */
 
@@ -630,7 +630,8 @@ imap_parse_envelope(CamelIMAPPStream *is)
 
                if (addr_from) {
                        addrstr = camel_header_address_list_format(addr_from);
-                       camel_message_info_set_from(minfo, addrstr);
+                       minfo->from = camel_pstring_strdup(addrstr);
+                       g_free(addrstr);
                        camel_header_address_list_clear(&addr_from);
                }
 
@@ -644,7 +645,8 @@ imap_parse_envelope(CamelIMAPPStream *is)
                addr = imap_parse_address_list(is);
                if (addr) {
                        addrstr = camel_header_address_list_format(addr);
-                       camel_message_info_set_to(minfo, addrstr);
+                       minfo->to = camel_pstring_strdup(addrstr);
+                       g_free(addrstr);
                        camel_header_address_list_clear(&addr);
                }
 
@@ -652,7 +654,8 @@ imap_parse_envelope(CamelIMAPPStream *is)
                addr = imap_parse_address_list(is);
                if (addr) {
                        addrstr = camel_header_address_list_format(addr);
-                       camel_message_info_set_cc(minfo, addrstr);
+                       minfo->cc = camel_pstring_strdup(addrstr);
+                       g_free(addrstr);
                        camel_header_address_list_clear(&addr);
                }
 
@@ -680,7 +683,7 @@ imap_parse_envelope(CamelIMAPPStream *is)
                camel_exception_throw_ex(ex);
        } CAMEL_DONE;
 
-       return minfo;
+       return (CamelMessageInfo *)minfo;
 }
        
 struct _CamelMessageContentInfo *
@@ -771,7 +774,7 @@ imap_parse_body(CamelIMAPPStream *is)
                                /* what do we do with the envelope?? */
                                minfo = imap_parse_envelope(is);
                                /* what do we do with the message content info?? */
-                               minfo->content = imap_parse_body(is);
+                               ((CamelMessageInfoBase *)minfo)->content = imap_parse_body(is);
                                camel_message_info_free(minfo);
                                minfo = NULL;
                                d(printf("Scanned envelope - what do i do with it?\n"));
index e0974bd..2734cd0 100644 (file)
@@ -65,8 +65,8 @@ struct _fetch_info {
        CamelStream *body;      /* BODY[.*](<.*>)? */
        CamelStream *text;      /* RFC822.TEXT */
        CamelStream *header;    /* RFC822.HEADER */
-       CamelMessageInfo *minfo; /* ENVELOPE */
-       CamelMessageContentInfo *cinfo; /* BODYSTRUCTURE,BODY */
+       struct _CamelMessageInfo *minfo; /* ENVELOPE */
+       struct _CamelMessageContentInfo *cinfo; /* BODYSTRUCTURE,BODY */
        guint32 size;           /* RFC822.SIZE */
        guint32 offset;         /* start offset of a BODY[]<offset.length> request */
        guint32 flags;          /* FLAGS */
index e515dd5..0a4f96b 100644 (file)
 static int summary_header_load (CamelFolderSummary *, FILE *);
 static int summary_header_save (CamelFolderSummary *, FILE *);
 
-static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
 
-static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi);
-static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi);
+static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi);
+static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi);
 
 static int local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex);
 static int local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
@@ -89,7 +89,7 @@ camel_local_summary_class_init(CamelLocalSummaryClass *klass)
        sklass->summary_header_load = summary_header_load;
        sklass->summary_header_save = summary_header_save;
 
-       sklass->message_info_new  = message_info_new;
+       sklass->message_info_new_from_header  = message_info_new_from_header;
 
        klass->load = local_summary_load;
        klass->check = local_summary_check;
@@ -106,7 +106,7 @@ camel_local_summary_init(CamelLocalSummary *obj)
        struct _CamelFolderSummary *s = (CamelFolderSummary *)obj;
 
        /* subclasses need to set the right instance data sizes */
-       s->message_info_size = sizeof(CamelMessageInfo);
+       s->message_info_size = sizeof(CamelLocalMessageInfo);
        s->content_info_size = sizeof(CamelMessageContentInfo);
 
        /* and a unique file version */
@@ -166,13 +166,13 @@ void camel_local_summary_check_force(CamelLocalSummary *cls)
 }
 
 char *
-camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info)
+camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *info)
 {
        return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->encode_x_evolution(cls, info);
 }
 
 int
-camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info)
+camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *info)
 {
        return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->decode_x_evolution(cls, xev, info);
 }
@@ -273,7 +273,7 @@ camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changei
                for (i=0;i<camel_folder_summary_count(s);i++) {
                        CamelMessageInfo *info = camel_folder_summary_index(s, i);
                        do_stat_mi(cls, &stats, info);
-                       camel_folder_summary_info_free(s, info);
+                       camel_message_info_free(info);
                }
 
                printf("\nMemory used by summary:\n\n");
@@ -418,43 +418,42 @@ local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn
 static CamelMessageInfo *
 local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex)
 {
-       CamelMessageInfo *mi;
+       CamelLocalMessageInfo *mi;
        char *xev;
 
        d(printf("Adding message to summary\n"));
        
-       mi = camel_folder_summary_add_from_message((CamelFolderSummary *)cls, msg);
+       mi = (CamelLocalMessageInfo *)camel_folder_summary_add_from_message((CamelFolderSummary *)cls, msg);
        if (mi) {
                d(printf("Added, uid = %s\n", mi->uid));
                if (info) {
-                       CamelTag *tag = info->user_tags;
-                       CamelFlag *flag = info->user_flags;
+                       const CamelTag *tag = camel_message_info_user_tags(info);
+                       const CamelFlag *flag = camel_message_info_user_flags(info);
 
                        while (flag) {
-                               camel_flag_set(&mi->user_flags, flag->name, TRUE);
+                               camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
                                flag = flag->next;
                        }
                        
                        while (tag) {
-                               camel_tag_set(&mi->user_tags, tag->name, tag->value);
+                               camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
                                tag = tag->next;
                        }
 
-                       mi->flags = mi->flags | (info->flags & 0xffff);
-                       if (info->size)
-                               mi->size = info->size;
+                       mi->info.flags |= (camel_message_info_flags(info) & 0xffff);
+                       mi->info.size = camel_message_info_size(info);
                }
 
                /* we need to calculate the size ourselves */
-               if (mi->size == 0) {
+               if (mi->info.size == 0) {
                        CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new();
 
                        camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, (CamelStream *)sn);
-                       mi->size = sn->written;
+                       mi->info.size = sn->written;
                        camel_object_unref((CamelObject *)sn);
                }
 
-               mi->flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED);
+               mi->info.flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED);
                xev = camel_local_summary_encode_x_evolution(cls, mi);
                camel_medium_set_header((CamelMedium *)msg, "X-Evolution", xev);
                g_free(xev);
@@ -464,17 +463,17 @@ local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMess
                camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
                                     _("Unable to add message to summary: unknown reason"));
        }
-       return mi;
+       return (CamelMessageInfo *)mi;
 }
 
 static char *
-local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi)
+local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi)
 {
        GString *out = g_string_new("");
        struct _camel_header_param *params = NULL;
        GString *val = g_string_new("");
-       CamelFlag *flag = mi->user_flags;
-       CamelTag *tag = mi->user_tags;
+       CamelFlag *flag = mi->info.user_flags;
+       CamelTag *tag = mi->info.user_tags;
        char *ret;
        const char *p, *uidstr;
        guint32 uid;
@@ -485,9 +484,9 @@ local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo
        while (*p && isdigit(*p))
                p++;
        if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) {
-               g_string_printf (out, "%08x-%04x", uid, mi->flags & 0xffff);
+               g_string_printf (out, "%08x-%04x", uid, mi->info.flags & 0xffff);
        } else {
-               g_string_printf (out, "%s-%04x", uidstr, mi->flags & 0xffff);
+               g_string_printf (out, "%s-%04x", uidstr, mi->info.flags & 0xffff);
        }
 
        if (flag || tag) {
@@ -525,23 +524,22 @@ local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo
 }
 
 static int
-local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi)
+local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi)
 {
        struct _camel_header_param *params, *scan;
        guint32 uid, flags;
        char *header;
        int i;
+       char uidstr[20];
+
+       uidstr[0] = 0;
 
        /* check for uid/flags */
        header = camel_header_token_decode(xev);
        if (header && strlen(header) == strlen("00000000-0000")
            && sscanf(header, "%08x-%04x", &uid, &flags) == 2) {
-               char uidstr[20];
-               if (mi) {
+               if (mi)
                        sprintf(uidstr, "%u", uid);
-                       camel_message_info_set_uid(mi, g_strdup(uidstr));
-                       mi->flags = flags;
-               }
        } else {
                g_free(header);
                return -1;
@@ -560,9 +558,8 @@ local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelM
                        if (!strcasecmp(scan->name, "flags")) {
                                char **flagv = g_strsplit(scan->value, ",", 1000);
 
-                               for (i=0;flagv[i];i++) {
-                                       camel_flag_set(&mi->user_flags, flagv[i], TRUE);
-                               }
+                               for (i=0;flagv[i];i++)
+                                       camel_message_info_set_user_flag((CamelMessageInfo *)mi, flagv[i], TRUE);
                                g_strfreev(flagv);
                        } else if (!strcasecmp(scan->name, "tags")) {
                                char **tagv = g_strsplit(scan->value, ",", 10000);
@@ -572,7 +569,7 @@ local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelM
                                        val = strchr(tagv[i], '=');
                                        if (val) {
                                                *val++ = 0;
-                                               camel_tag_set(&mi->user_tags, tagv[i], val);
+                                               camel_message_info_set_user_tag((CamelMessageInfo *)mi, tagv[i], val);
                                                val[-1]='=';
                                        }
                                }
@@ -582,6 +579,10 @@ local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelM
                }
                camel_header_param_list_free(params);
        }
+
+       mi->info.uid = g_strdup(uidstr);
+       mi->info.flags = flags;
+
        return 0;
 }
 
@@ -615,12 +616,12 @@ summary_header_save(CamelFolderSummary *s, FILE *out)
 }
 
 static CamelMessageInfo *
-message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 {
-       CamelMessageInfo *mi;
+       CamelLocalMessageInfo *mi;
        CamelLocalSummary *cls = (CamelLocalSummary *)s;
 
-       mi = ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new(s, h);
+       mi = (CamelLocalMessageInfo *)((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new_from_header(s, h);
        if (mi) {
                const char *xev;
                int doindex = FALSE;
@@ -628,8 +629,8 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
                xev = camel_header_raw_find(&h, "X-Evolution", NULL);
                if (xev==NULL || camel_local_summary_decode_x_evolution(cls, xev, mi) == -1) {
                        /* to indicate it has no xev header */
-                       mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
-                       camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s));
+                       mi->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
+                       mi->info.uid = camel_folder_summary_next_uid_string(s);
 
                        /* shortcut, no need to look it up in the index library */
                        doindex = TRUE;
@@ -647,5 +648,5 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
                }
        }
        
-       return mi;
+       return (CamelMessageInfo *)mi;
 }
index 99a520f..cc7dc3e 100644 (file)
@@ -40,6 +40,12 @@ enum {
        CAMEL_MESSAGE_FOLDER_NOTSEEN = 1<<19, /* have we seen this in processing this loop? */
 };
 
+typedef struct _CamelLocalMessageInfo CamelLocalMessageInfo;
+
+struct _CamelLocalMessageInfo {
+       CamelMessageInfoBase info;
+};
+
 struct _CamelLocalSummary {
        CamelFolderSummary parent;
 
@@ -60,8 +66,8 @@ struct _CamelLocalSummaryClass {
        int (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
        CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
 
-       char *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelMessageInfo *info);
-       int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info);
+       char *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelLocalMessageInfo *info);
+       int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *info);
 };
 
 CamelType      camel_local_summary_get_type    (void);
@@ -80,8 +86,8 @@ CamelMessageInfo *camel_local_summary_add(CamelLocalSummary *cls, CamelMimeMessa
 void camel_local_summary_check_force(CamelLocalSummary *cls);
 
 /* generate an X-Evolution header line */
-char *camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info);
-int camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info);
+char *camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *info);
+int camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *info);
 
 /* utility functions - write headers to a file with optional X-Evolution header and/or status header */
 int camel_local_summary_write_headers(int fd, struct _camel_header_raw *header, const char *xevline, const char *status, const char *xstatus);
index 669e636..b74f6e5 100644 (file)
@@ -153,7 +153,7 @@ camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint3
 
 static CamelLocalSummary *maildir_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
 {
-       return (CamelLocalSummary *)camel_maildir_summary_new(path, folder, index);
+       return (CamelLocalSummary *)camel_maildir_summary_new((CamelFolder *)lf, path, folder, index);
 }
 
 static void
@@ -251,7 +251,7 @@ static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar *
        /* what do we do if the message flags (and :info data) changes?  filename mismatch - need to recheck I guess */
        name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
 
-       camel_folder_summary_info_free(folder->summary, info);
+       camel_message_info_free(info);
 
        if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
                camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
index 9c4097a..eac22d2 100644 (file)
@@ -283,7 +283,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
                root = camel_local_store_get_toplevel_dir((CamelLocalStore *)store);
                path = g_strdup_printf("%s/%s.ev-summary", root, fi->full_name);
                folderpath = g_strdup_printf("%s/%s", root, fi->full_name);
-               s = (CamelFolderSummary *)camel_maildir_summary_new(path, folderpath, NULL);
+               s = (CamelFolderSummary *)camel_maildir_summary_new(NULL, path, folderpath, NULL);
                if (camel_folder_summary_header_load(s) != -1) {
                        fi->unread = s->unread_count;
                        fi->total = s->saved_count;
index 8b15c2b..07183d2 100644 (file)
@@ -49,7 +49,7 @@
 #define CAMEL_MAILDIR_SUMMARY_VERSION (0x2000)
 
 static CamelMessageInfo *message_info_load(CamelFolderSummary *s, FILE *in);
-static CamelMessageInfo *message_info_new(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo *message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static void message_info_free(CamelFolderSummary *, CamelMessageInfo *mi);
 
 static int maildir_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex);
@@ -58,8 +58,8 @@ static int maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelF
 static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);
 
 static char *maildir_summary_next_uid_string(CamelFolderSummary *s);
-static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi);
-static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi);
+static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi);
+static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi);
 
 static void camel_maildir_summary_class_init   (CamelMaildirSummaryClass *class);
 static void camel_maildir_summary_init (CamelMaildirSummary *gspaper);
@@ -104,7 +104,7 @@ camel_maildir_summary_class_init (CamelMaildirSummaryClass *class)
 
        /* override methods */
        sklass->message_info_load = message_info_load;
-       sklass->message_info_new = message_info_new;
+       sklass->message_info_new_from_header = message_info_new_from_header;
        sklass->message_info_free = message_info_free;
        sklass->next_uid_string = maildir_summary_next_uid_string;
 
@@ -151,15 +151,20 @@ camel_maildir_summary_finalise(CamelObject *obj)
 
 /**
  * camel_maildir_summary_new:
+ * @folder: parent folder.
+ * @filename: Path to root of this maildir directory (containing new/tmp/cur directories).
+ * @index: Index if one is reqiured.
  *
  * Create a new CamelMaildirSummary object.
  * 
  * Return value: A new #CamelMaildirSummary object.
  **/
-CamelMaildirSummary    *camel_maildir_summary_new      (const char *filename, const char *maildirdir, CamelIndex *index)
+CamelMaildirSummary    *camel_maildir_summary_new(struct _CamelFolder *folder, const char *filename, const char *maildirdir, CamelIndex *index)
 {
        CamelMaildirSummary *o = (CamelMaildirSummary *)camel_object_new(camel_maildir_summary_get_type ());
 
+       ((CamelFolderSummary *)o)->folder = folder;
+
        camel_local_summary_construct((CamelLocalSummary *)o, filename, maildirdir, index);
        return o;
 }
@@ -178,17 +183,17 @@ static struct {
 };
 
 /* convert the uid + flags into a unique:info maildir format */
-char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info)
+char *camel_maildir_summary_info_to_name(const CamelMaildirMessageInfo *info)
 {
        const char *uid;
        char *p, *buf;
        int i;
-       
+
        uid = camel_message_info_uid (info);
        buf = g_alloca (strlen (uid) + strlen (":2,") +  (sizeof (flagbits) / sizeof (flagbits[0])) + 1);
        p = buf + sprintf (buf, "%s:2,", uid);
        for (i = 0; i < sizeof (flagbits) / sizeof (flagbits[0]); i++) {
-               if (info->flags & flagbits[i].flagbit)
+               if (info->info.info.flags & flagbits[i].flagbit)
                        *p++ = flagbits[i].flag;
        }
        *p = 0;
@@ -197,7 +202,7 @@ char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info)
 }
 
 /* returns 0 if the info matches (or there was none), otherwise we changed it */
-int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name)
+int camel_maildir_summary_name_to_info(CamelMaildirMessageInfo *info, const char *name)
 {
        char *p, c;
        guint32 set = 0;        /* what we set */
@@ -210,7 +215,7 @@ int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name)
                while ((c = *p++)) {
                        /* we could assume that the flags are in order, but its just as easy not to require */
                        for (i=0;i<sizeof(flagbits)/sizeof(flagbits[0]);i++) {
-                               if (flagbits[i].flag == c && (info->flags & flagbits[i].flagbit) == 0) {
+                               if (flagbits[i].flag == c && (info->info.info.flags & flagbits[i].flagbit) == 0) {
                                        set |= flagbits[i].flagbit;
                                }
                                /*all |= flagbits[i].flagbit;*/
@@ -219,10 +224,10 @@ int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name)
 
                /* changed? */
                /*if ((info->flags & all) != set) {*/
-               if ((info->flags & set) != set) {
+               if ((info->info.info.flags & set) != set) {
                        /* ok, they did change, only add the new flags ('merge flags'?) */
                        /*info->flags &= all;  if we wanted to set only the new flags, which we probably dont */
-                       info->flags |= set;
+                       info->info.info.flags |= set;
                        return 1;
                }
        }
@@ -231,12 +236,12 @@ int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name)
 }
 
 /* for maildir, x-evolution isn't used, so dont try and get anything out of it */
-static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi)
+static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi)
 {
        return -1;
 }
 
-static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi)
+static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi)
 {
        return NULL;
 }
@@ -246,9 +251,9 @@ static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const Ca
 */
 static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *changes, CamelException *ex)
 {
-       CamelMessageInfo *mi;
+       CamelMaildirMessageInfo *mi;
 
-       mi = ((CamelLocalSummaryClass *) parent_class)->add(cls, msg, info, changes, ex);
+       mi = (CamelMaildirMessageInfo *)((CamelLocalSummaryClass *) parent_class)->add(cls, msg, info, changes, ex);
        if (mi) {
                if (info) {
                        camel_maildir_info_set_filename(mi, camel_maildir_summary_info_to_name(mi));
@@ -256,35 +261,35 @@ static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMe
                }
        }
 
-       return mi;
+       return (CamelMessageInfo *)mi;
 }
 
-static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_header_raw *h)
+static CamelMessageInfo *message_info_new_from_header(CamelFolderSummary * s, struct _camel_header_raw *h)
 {
        CamelMessageInfo *mi, *info;
        CamelMaildirSummary *mds = (CamelMaildirSummary *)s;
        CamelMaildirMessageInfo *mdi;
        const char *uid;
 
-       mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new(s, h);
+       mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new_from_header(s, h);
        /* assign the uid and new filename */
        if (mi) {
                mdi = (CamelMaildirMessageInfo *)mi;
 
                uid = camel_message_info_uid(mi);
                if (uid==NULL || uid[0] == 0)
-                       camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s));
+                       mdi->info.info.uid = camel_folder_summary_next_uid_string(s);
 
                /* handle 'duplicates' */
                info = camel_folder_summary_uid(s, uid);
                if (info) {
                        d(printf("already seen uid '%s', just summarising instead\n", uid));
-                       camel_folder_summary_info_free(s, mi);
+                       camel_message_info_free(mi);
                        mdi = (CamelMaildirMessageInfo *)(mi = info);
                }
 
                /* with maildir we know the real received date, from the filename */
-               mi->date_received = strtoul(camel_message_info_uid(mi), NULL, 10);
+               mdi->info.info.date_received = strtoul(camel_message_info_uid(mi), NULL, 10);
 
                if (mds->priv->current_file) {
 #if 0
@@ -293,7 +298,7 @@ static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_
 #endif
                        /* if setting from a file, grab the flags from it */
                        camel_maildir_info_set_filename(mi, g_strdup(mds->priv->current_file));
-                       camel_maildir_summary_name_to_info(mi, mds->priv->current_file);
+                       camel_maildir_summary_name_to_info(mdi, mds->priv->current_file);
 
 #if 0
                        /* Actually, I dont think all this effort is worth it at all ... */
@@ -313,7 +318,7 @@ static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_
 #endif
                } else {
                        /* if creating a file, set its name from the flags we have */
-                       camel_maildir_info_set_filename(mdi, camel_maildir_summary_info_to_name(mi));
+                       camel_maildir_info_set_filename(mdi, camel_maildir_summary_info_to_name(mdi));
                        d(printf("Setting filename to %s\n", camel_maildir_info_filename(mi)));
                }
        }
@@ -393,7 +398,7 @@ message_info_load(CamelFolderSummary *s, FILE *in)
                    && (name = g_hash_table_lookup(mds->priv->load_map, camel_message_info_uid(mi)))) {
                        d(printf("Setting filename of %s to %s\n", camel_message_info_uid(mi), name));
                        camel_maildir_info_set_filename(mi, g_strdup(name));
-                       camel_maildir_summary_name_to_info(mi, name);
+                       camel_maildir_summary_name_to_info((CamelMaildirMessageInfo *)mi, name);
                }
        }
 
@@ -502,19 +507,19 @@ remove_summary(char *key, CamelMessageInfo *info, struct _remove_data *rd)
        if (rd->changes)
                camel_folder_change_info_remove_uid(rd->changes, key);
        camel_folder_summary_remove((CamelFolderSummary *)rd->cls, info);
-       camel_folder_summary_info_free((CamelFolderSummary *)rd->cls, info);
+       camel_message_info_free(info);
 }
 
 static int
 sort_receive_cmp(const void *ap, const void *bp)
 {
-       const CamelMessageInfo
-               *a = *((CamelMessageInfo **)ap),
-               *b = *((CamelMessageInfo **)bp);
+       const CamelMaildirMessageInfo
+               *a = *((CamelMaildirMessageInfo **)ap),
+               *b = *((CamelMaildirMessageInfo **)bp);
 
-       if (a->date_received < b->date_received)
+       if (a->info.info.date_received < b->info.info.date_received)
                return -1;
-       else if (a->date_received > b->date_received)
+       else if (a->info.info.date_received > b->info.info.date_received)
                return 1;
 
        return 0;
@@ -594,7 +599,7 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca
                
                info = g_hash_table_lookup(left, uid);
                if (info) {
-                       camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+                       camel_message_info_free(info);
                        g_hash_table_remove(left, uid);
                }
 
@@ -634,7 +639,7 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca
 # endif
 #endif
                        }
-                       camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+                       camel_message_info_free(info);
                }
                g_free(uid);
        }
@@ -669,7 +674,7 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca
 
                        /* already in summary?  shouldn't happen, but just incase ... */
                        if ((info = camel_folder_summary_uid((CamelFolderSummary *)cls, name))) {
-                               camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+                               camel_message_info_free(info);
                                newname = destname = camel_folder_summary_next_uid_string(s);
                        } else {
                                newname = NULL;
@@ -741,7 +746,7 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange
 
                info = camel_folder_summary_index((CamelFolderSummary *)cls, i);
                mdi = (CamelMaildirMessageInfo *)info;
-               if (info && (info->flags & CAMEL_MESSAGE_DELETED) && expunge) {
+               if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_DELETED) && expunge) {
                        name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi));
                        d(printf("deleting %s\n", name));
                        if (unlink(name) == 0 || errno==ENOENT) {
@@ -754,8 +759,8 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange
                                camel_folder_summary_remove((CamelFolderSummary *)cls, info);
                        }
                        g_free(name);
-               } else if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
-                       char *newname = camel_maildir_summary_info_to_name(info);
+               } else if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+                       char *newname = camel_maildir_summary_info_to_name(mdi);
                        char *dest;
 
                        /* do we care about additional metainfo stored inside the message? */
@@ -798,9 +803,9 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange
                        }
 
                        /* strip FOLDER_MESSAGE_FLAGED, etc */
-                       info->flags &= 0xffff;
+                       mdi->info.info.flags &= 0xffff;
                }
-               camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+               camel_message_info_free(info);
        }
 
        camel_operation_end(NULL);
index 0cae785..4ecaf36 100644 (file)
@@ -37,19 +37,15 @@ typedef struct _CamelMaildirMessageContentInfo {
        CamelMessageContentInfo info;
 } CamelMaildirMessageContentInfo;
 
-#if defined (DOEPOOLV) || defined (DOESTRV)
 enum {
        CAMEL_MAILDIR_INFO_FILENAME = CAMEL_MESSAGE_INFO_LAST,
        CAMEL_MAILDIR_INFO_LAST,
 };
-#endif
 
 typedef struct _CamelMaildirMessageInfo {
-       CamelMessageInfo info;
+       CamelLocalMessageInfo info;
 
-#if !defined (DOEPOOLV) && !defined (DOESTRV)
        char *filename;         /* maildir has this annoying status shit on the end of the filename, use this to get the real message id */
-#endif
 } CamelMaildirMessageInfo;
 
 struct _CamelMaildirSummary {
@@ -66,19 +62,15 @@ struct _CamelMaildirSummaryClass {
 };
 
 CamelType       camel_maildir_summary_get_type (void);
-CamelMaildirSummary    *camel_maildir_summary_new      (const char *filename, const char *maildirdir, CamelIndex *index);
+CamelMaildirSummary    *camel_maildir_summary_new      (struct _CamelFolder *folder, const char *filename, const char *maildirdir, CamelIndex *index);
 
 /* convert some info->flags to/from the messageinfo */
-char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info);
-int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name);
+char *camel_maildir_summary_info_to_name(const CamelMaildirMessageInfo *info);
+int camel_maildir_summary_name_to_info(CamelMaildirMessageInfo *info, const char *name);
 
-#if defined (DOEPOOLV) || defined (DOESTRV)
-#define camel_maildir_info_filename(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME)
-#define camel_maildir_info_set_filename(x, s) camel_message_info_set_string((CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME, s)
-#else
+/* TODO: could proably use get_string stuff */
 #define camel_maildir_info_filename(x) (((CamelMaildirMessageInfo *)x)->filename)
 #define camel_maildir_info_set_filename(x, s) (g_free(((CamelMaildirMessageInfo *)x)->filename),((CamelMaildirMessageInfo *)x)->filename = s)
-#endif
 
 #endif /* ! _CAMEL_MAILDIR_SUMMARY_H */
 
index b4926b9..d213b44 100644 (file)
@@ -56,13 +56,6 @@ static CamelLocalFolderClass *parent_class = NULL;
 static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
 static void mbox_unlock(CamelLocalFolder *lf);
 
-#ifdef STATUS_PINE
-static gboolean mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
-#endif
-
-static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value);
-static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
-
 static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info,        char **appended_uid, CamelException *ex);
 static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
 static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index);
@@ -83,12 +76,6 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class)
        camel_folder_class->append_message = mbox_append_message;
        camel_folder_class->get_message = mbox_get_message;
 
-#ifdef STATUS_PINE
-       camel_folder_class->set_message_flags = mbox_set_message_flags;
-#endif
-       camel_folder_class->set_message_user_flag = mbox_set_message_user_flag;
-       camel_folder_class->set_message_user_tag = mbox_set_message_user_tag;
-       
        lclass->get_full_path = camel_mbox_folder_get_full_path;
        lclass->get_meta_path = camel_mbox_folder_get_meta_path;
        lclass->create_summary = mbox_create_summary;
@@ -207,7 +194,7 @@ camel_mbox_folder_get_meta_path (CamelLocalFolder *lf, const char *toplevel_dir,
 
 static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
 {
-       return (CamelLocalSummary *)camel_mbox_summary_new(path, folder, index);
+       return (CamelLocalSummary *)camel_mbox_summary_new((CamelFolder *)lf, path, folder, index);
 }
 
 static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex)
@@ -421,7 +408,7 @@ retry:
        g_assert(info->frompos != -1);
 
        frompos = info->frompos;
-       camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info);
+       camel_message_info_free((CamelMessageInfo *)info);
        
        /* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache
           the whole message in memory if the stream is non-seekable (which it is when built from a parser
@@ -493,66 +480,3 @@ fail:
        
        return message;
 }
-
-#ifdef STATUS_PINE
-static gboolean
-mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
-{
-       /* Basically, if anything could change the Status line, presume it does */
-       if (((CamelMboxSummary *)folder->summary)->xstatus
-           && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) {
-               flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
-               set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
-       }
-
-       return ((CamelFolderClass *)parent_class)->set_message_flags(folder, uid, flags, set);
-}
-#endif
-
-static void
-mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value)
-{
-       CamelMessageInfo *info;
-
-       g_return_if_fail(folder->summary != NULL);
-
-       info = camel_folder_summary_uid(folder->summary, uid);
-       if (info == NULL)
-               return;
-
-       if (camel_flag_set(&info->user_flags, name, value)) {
-               CamelFolderChangeInfo *changes = camel_folder_change_info_new();
-
-               info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
-               camel_folder_summary_touch(folder->summary);
-
-               camel_folder_change_info_change_uid(changes, uid);
-               camel_object_trigger_event(folder, "folder_changed", changes);
-               camel_folder_change_info_free(changes);
-       }
-       camel_folder_summary_info_free(folder->summary, info);
-}
-
-static void
-mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value)
-{
-       CamelMessageInfo *info;
-
-       g_return_if_fail(folder->summary != NULL);
-
-       info = camel_folder_summary_uid(folder->summary, uid);
-       if (info == NULL)
-               return;
-
-       if (camel_tag_set(&info->user_tags, name, value)) {
-               CamelFolderChangeInfo *changes = camel_folder_change_info_new();
-
-               info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
-               camel_folder_summary_touch(folder->summary);
-
-               camel_folder_change_info_change_uid(changes, uid);
-               camel_object_trigger_event (folder, "folder_changed", changes);
-               camel_folder_change_info_free(changes);
-       }
-       camel_folder_summary_info_free(folder->summary, info);
-}
index f98c87a..a9e581c 100644 (file)
@@ -618,7 +618,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
                path = camel_mbox_folder_get_meta_path(NULL, root, fi->full_name, ".ev-summary");
                folderpath = camel_mbox_folder_get_full_path(NULL, root, fi->full_name);
                
-               mbs = (CamelMboxSummary *)camel_mbox_summary_new(path, folderpath, NULL);
+               mbs = (CamelMboxSummary *)camel_mbox_summary_new(NULL, path, folderpath, NULL);
                if (camel_folder_summary_header_load((CamelFolderSummary *)mbs) != -1) {
                        fi->unread = ((CamelFolderSummary *)mbs)->unread_count;
                        fi->total = ((CamelFolderSummary *)mbs)->saved_count;
index 60dcf34..9dcee0a 100644 (file)
 static int summary_header_load (CamelFolderSummary *, FILE *);
 static int summary_header_save (CamelFolderSummary *, FILE *);
 
-static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
-static CamelMessageInfo * message_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *);
+static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_load (CamelFolderSummary *, FILE *);
 static int               message_info_save (CamelFolderSummary *, FILE *, CamelMessageInfo *);
 /*static void            message_info_free (CamelFolderSummary *, CamelMessageInfo *);*/
 
-static char *mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelMessageInfo *mi);
+static char *mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi);
 
 static int mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex);
 static int mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex);
@@ -100,6 +100,44 @@ camel_mbox_summary_get_type(void)
        
        return type;
 }
+static gboolean
+mbox_info_set_user_flag(CamelMessageInfo *mi, const char *name, gboolean value)
+{
+       int res;
+
+       res = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_user_flag(mi, name, value);
+       if (res)
+               ((CamelLocalMessageInfo *)mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
+
+       return res;
+}
+
+static gboolean
+mbox_info_set_user_tag(CamelMessageInfo *mi, const char *name, const char *value)
+{
+       int res;
+
+       res = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_user_tag(mi, name, value);
+       if (res)
+               ((CamelLocalMessageInfo *)mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
+
+       return res;
+}
+
+#ifdef STATUS_PINE
+static gboolean
+mbox_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set)
+{
+       /* Basically, if anything could change the Status line, presume it does */
+       if (((CamelMboxSummary *)mi->summary)->xstatus
+           && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) {
+               flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
+               set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
+       }
+
+       return ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_flags(mi, flags, set);
+}
+#endif
 
 static void
 camel_mbox_summary_class_init(CamelMboxSummaryClass *klass)
@@ -112,11 +150,17 @@ camel_mbox_summary_class_init(CamelMboxSummaryClass *klass)
        sklass->summary_header_load = summary_header_load;
        sklass->summary_header_save = summary_header_save;
 
-       sklass->message_info_new  = message_info_new;
+       sklass->message_info_new_from_header  = message_info_new_from_header;
        sklass->message_info_new_from_parser = message_info_new_from_parser;
        sklass->message_info_load = message_info_load;
        sklass->message_info_save = message_info_save;
        /*sklass->message_info_free = message_info_free;*/
+
+       sklass->info_set_user_flag = mbox_info_set_user_flag;
+       sklass->info_set_user_tag = mbox_info_set_user_tag;
+#ifdef STATUS_PINE
+       sklass->info_set_flags = mbox_info_set_flags;
+#endif
        
        lklass->encode_x_evolution = mbox_summary_encode_x_evolution;
        lklass->check = mbox_summary_check;
@@ -156,10 +200,12 @@ camel_mbox_summary_finalise(CamelObject *obj)
  * Return value: A new CamelMboxSummary widget.
  **/
 CamelMboxSummary *
-camel_mbox_summary_new(const char *filename, const char *mbox_name, CamelIndex *index)
+camel_mbox_summary_new(struct _CamelFolder *folder, const char *filename, const char *mbox_name, CamelIndex *index)
 {
        CamelMboxSummary *new = (CamelMboxSummary *)camel_object_new(camel_mbox_summary_get_type());
 
+       ((CamelFolderSummary *)new)->folder = folder;
+
        camel_local_summary_construct((CamelLocalSummary *)new, filename, mbox_name, index);
        return new;
 }
@@ -170,19 +216,20 @@ void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state)
 }
 
 static char *
-mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelMessageInfo *mi)
+mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi)
 {
        const char *p, *uidstr;
        guint32 uid;
-       
-       p = uidstr = camel_message_info_uid (mi);
-       while (*p && isdigit (*p))
+
+       /* This is busted, it is supposed to encode ALL DATA */
+       p = uidstr = camel_message_info_uid(mi);
+       while (*p && isdigit(*p))
                p++;
        
-       if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) {
-               return g_strdup_printf ("%08x-%04x", uid, mi->flags & 0xffff);
+       if (*p == 0 && sscanf(uidstr, "%u", &uid) == 1) {
+               return g_strdup_printf("%08x-%04x", uid, mi->info.flags & 0xffff);
        } else {
-               return g_strdup_printf ("%s-%04x", uidstr, mi->flags & 0xffff);
+               return g_strdup_printf("%s-%04x", uidstr, mi->info.flags & 0xffff);
        }
 }
 
@@ -220,16 +267,15 @@ summary_header_save(CamelFolderSummary *s, FILE *out)
 }
 
 static CamelMessageInfo *
-message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 {
-       CamelMessageInfo *mi;
+       CamelMboxMessageInfo *mi;
        CamelMboxSummary *mbs = (CamelMboxSummary *)s;
 
-       mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new(s, h);
+       mi = (CamelMboxMessageInfo *)((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new_from_header(s, h);
        if (mi) {
-               CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
                const char *xev, *uid;
-               CamelMessageInfo *info = NULL;
+               CamelMboxMessageInfo *info = NULL;
                int add = 0;    /* bitmask of things to add, 1 assign uid, 2, just add as new, 4 = recent */
 #ifdef STATUS_PINE
                const char *status = NULL, *xstatus = NULL;
@@ -248,19 +294,19 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
                /* if we have an xev header, use it, else assign a new one */
                xev = camel_header_raw_find(&h, "X-Evolution", NULL);
                if (xev != NULL
-                   && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, mi) == 0) {
+                   && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, &mi->info) == 0) {
                        uid = camel_message_info_uid(mi);
                        d(printf("found valid x-evolution: %s\n", uid));
-                       info = camel_folder_summary_uid(s, uid);
+                       info = (CamelMboxMessageInfo *)camel_folder_summary_uid(s, uid);
                        if (info) {
-                               if ((info->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
-                                       info->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
-                                       camel_folder_summary_info_free(s, mi);
-                                       mbi = (CamelMboxMessageInfo *)(mi = info);
+                               if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
+                                       info->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
+                                       camel_message_info_free(mi);
+                                       mi = info;
                                } else {
                                        add = 7;
                                        d(printf("seen '%s' before, adding anew\n", uid));
-                                       camel_folder_summary_info_free(s, info);
+                                       camel_message_info_free(info);
                                }
                        } else {
                                add = 2;
@@ -272,8 +318,8 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
                }
 
                if (add&1) {
-                       mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
-                       camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s));
+                       mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
+                       mi->info.info.uid = camel_folder_summary_next_uid_string(s);
                } else {
                        camel_folder_summary_set_uid(s, strtoul(camel_message_info_uid(mi), NULL, 10));
                }
@@ -281,9 +327,9 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
                if (mbs->xstatus && add&2) {
                        /* use the status as the flags when we read it the first time */
                        if (status)
-                               mi->flags = (mi->flags & ~(STATUS_STATUS)) | (flags & STATUS_STATUS);
+                               mi->info.info.flags = (mi->info.info.flags & ~(STATUS_STATUS)) | (flags & STATUS_STATUS);
                        if (xstatus)
-                               mi->flags = (mi->flags & ~(STATUS_XSTATUS)) | (flags & STATUS_XSTATUS);
+                               mi->info.info.flags = (mi->info.info.flags & ~(STATUS_XSTATUS)) | (flags & STATUS_XSTATUS);
                }
 #endif
                if (mbs->changes) {
@@ -293,10 +339,10 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
                                camel_folder_change_info_recent_uid(mbs->changes, camel_message_info_uid(mi));
                }
 
-               mbi->frompos = -1;
+               mi->frompos = -1;
        }
        
-       return mi;
+       return (CamelMessageInfo *)mi;
 }
 
 static CamelMessageInfo *
@@ -331,7 +377,7 @@ message_info_load(CamelFolderSummary *s, FILE *in)
        
        return mi;
 error:
-       camel_folder_summary_info_free(s, mi);
+       camel_message_info_free(mi);
        return NULL;
 }
 
@@ -357,7 +403,7 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan
        CamelFolderSummary *s = (CamelFolderSummary *)cls;
        CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
        CamelMimeParser *mp;
-       CamelMessageInfo *mi;
+       CamelMboxMessageInfo *mi;
        int fd;
        int ok = 0;
        struct stat st;
@@ -404,12 +450,12 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan
           from the old end, so everything must be treated as new */
        count = camel_folder_summary_count(s);
        for (i=0;i<count;i++) {
-               mi = camel_folder_summary_index(s, i);
+               mi = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
                if (offset == 0)
-                       mi->flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN;
+                       mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN;
                else
-                       mi->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
-               camel_folder_summary_info_free(s, mi);
+                       mi->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
+               camel_message_info_free(mi);
        }
        mbs->changes = changeinfo;
 
@@ -434,17 +480,17 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan
 
        count = camel_folder_summary_count(s);
        for (i=0;i<count;i++) {
-               mi = camel_folder_summary_index(s, i);
+               mi = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
                /* must've dissapeared from the file? */
-               if (mi->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
+               if (mi->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
                        d(printf("uid '%s' vanished, removing", camel_message_info_uid(mi)));
                        if (changeinfo)
                                camel_folder_change_info_remove_uid(changeinfo, camel_message_info_uid(mi));
-                       camel_folder_summary_remove(s, mi);
+                       camel_folder_summary_remove(s, (CamelMessageInfo *)mi);
                        count--;
                        i--;
                }
-               camel_folder_summary_info_free(s, mi);
+               camel_message_info_free(mi);
        }
        mbs->changes = NULL;
        
@@ -495,7 +541,7 @@ mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Camel
 
                        if (info) {
                                camel_folder_change_info_remove_uid(changes, camel_message_info_uid(info));
-                               camel_folder_summary_info_free(s, info);
+                               camel_message_info_free(info);
                        }
                }
                camel_folder_summary_clear(s);
@@ -661,8 +707,8 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 
                d(printf("Checking message %s %08x\n", camel_message_info_uid(info), info->info.flags));
 
-               if ((info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
-                       camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+               if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
+                       camel_message_info_free((CamelMessageInfo *)info);
                        info = NULL;
                        continue;
                }
@@ -696,7 +742,7 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
                        g_warning("We're supposed to have a valid x-ev header, but we dont");
                        goto error;
                }
-               xevnew = camel_local_summary_encode_x_evolution(cls, (CamelMessageInfo *)info);
+               xevnew = camel_local_summary_encode_x_evolution(cls, &info->info);
                /* SIGH: encode_param_list is about the only function which folds headers by itself.
                   This should be fixed somehow differently (either parser doesn't fold headers,
                   or param_list doesn't, or something */
@@ -725,8 +771,8 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
                camel_mime_parser_drop_step(mp);
                camel_mime_parser_drop_step(mp);
 
-               info->info.flags &= 0xffff;
-               camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+               info->info.info.flags &= 0xffff;
+               camel_message_info_free((CamelMessageInfo *)info);
        }
 
        d(printf("Closing folders\n"));
@@ -751,7 +797,7 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
        if (mp)
                camel_object_unref((CamelObject *)mp);
        if (info)
-               camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+               camel_message_info_free((CamelMessageInfo *)info);
 
        camel_operation_end(NULL);
 
@@ -778,14 +824,15 @@ mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInf
 
        /* check what work we have to do, if any */
        for (i=0;quick && i<count; i++) {
-               CamelMessageInfo *info = camel_folder_summary_index(s, i);
+               CamelMboxMessageInfo *info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
+
                g_assert(info);
-               if ((expunge && (info->flags & CAMEL_MESSAGE_DELETED)) ||
-                   (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_XEVCHANGE)))
+               if ((expunge && (info->info.info.flags & CAMEL_MESSAGE_DELETED)) ||
+                   (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_XEVCHANGE)))
                        quick = FALSE;
                else
-                       work |= (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
-               camel_folder_summary_info_free(s, info);
+                       work |= (info->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
+               camel_message_info_free(info);
        }
 
        /* yuck i hate this logic, but its to simplify the 'all ok, update summary' and failover cases */
@@ -888,7 +935,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
                }
 
                lastdel = FALSE;
-               if ((flags&1) && info->info.flags & CAMEL_MESSAGE_DELETED) {
+               if ((flags&1) && info->info.info.flags & CAMEL_MESSAGE_DELETED) {
                        const char *uid = camel_message_info_uid(info);
 
                        d(printf("Deleting %s\n", uid));
@@ -899,7 +946,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
                        /* remove it from the change list */
                        camel_folder_change_info_remove_uid(changeinfo, uid);
                        camel_folder_summary_remove(s, (CamelMessageInfo *)info);
-                       camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+                       camel_message_info_free((CamelMessageInfo *)info);
                        count--;
                        i--;
                        info = NULL;
@@ -915,7 +962,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
                        write(fdout, fromline, strlen(fromline));
                }
 
-               if (info && info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+               if (info && info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) {
                        d(printf("Updating header for %s flags = %08x\n", camel_message_info_uid(info), info->info.flags));
 
                        if (camel_mime_parser_step(mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM_END) {
@@ -923,11 +970,11 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
                                goto error;
                        }
 
-                       xevnew = camel_local_summary_encode_x_evolution((CamelLocalSummary *)cls, (CamelMessageInfo *)info);
+                       xevnew = camel_local_summary_encode_x_evolution((CamelLocalSummary *)cls, &info->info);
 #ifdef STATUS_PINE
                        if (mbs->xstatus) {
-                               encode_status(((CamelMessageInfo *)info)->flags & STATUS_STATUS, statnew);
-                               encode_status(((CamelMessageInfo *)info)->flags & STATUS_XSTATUS, xstatnew);
+                               encode_status(info->info.info.flags & STATUS_STATUS, statnew);
+                               encode_status(info->info.info.flags & STATUS_XSTATUS, xstatnew);
                                len = camel_local_summary_write_headers(fdout, camel_mime_parser_headers_raw(mp), xevnew, statnew, xstatnew);
                        } else {
 #endif
@@ -942,7 +989,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
                                                      g_strerror (errno));
                                goto error;
                        }
-                       info->info.flags &= 0xffff;
+                       info->info.info.flags &= 0xffff;
                        g_free(xevnew);
                        xevnew = NULL;
                        camel_mime_parser_drop_step(mp);
@@ -972,7 +1019,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
                        d(printf("we are now at %d, from = %d\n", (int)camel_mime_parser_tell(mp),
                                 (int)camel_mime_parser_tell_start_from(mp)));
                        camel_mime_parser_unstep(mp);
-                       camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+                       camel_message_info_free((CamelMessageInfo *)info);
                        info = NULL;
                }
        }
@@ -992,7 +1039,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
        if (mp)
                camel_object_unref((CamelObject *)mp);
        if (info)
-               camel_folder_summary_info_free(s, (CamelMessageInfo *)info);
+               camel_message_info_free((CamelMessageInfo *)info);
 
        return -1;
 }
@@ -1001,20 +1048,20 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
 static CamelMessageInfo *
 mbox_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex)
 {
-       CamelMessageInfo *mi;
+       CamelMboxMessageInfo *mi;
 
-       mi = ((CamelLocalSummaryClass *)camel_mbox_summary_parent)->add(cls, msg, info, ci, ex);
+       mi = (CamelMboxMessageInfo *)((CamelLocalSummaryClass *)camel_mbox_summary_parent)->add(cls, msg, info, ci, ex);
        if (mi && ((CamelMboxSummary *)cls)->xstatus) {
                char status[8];
 
                /* we snoop and add status/x-status headers to suit */
-               encode_status(mi->flags & STATUS_STATUS, status);
+               encode_status(mi->info.info.flags & STATUS_STATUS, status);
                camel_medium_set_header((CamelMedium *)msg, "Status", status);
-               encode_status(mi->flags & STATUS_XSTATUS, status);
+               encode_status(mi->info.info.flags & STATUS_XSTATUS, status);
                camel_medium_set_header((CamelMedium *)msg, "X-Status", status);
        }
 
-       return mi;
+       return (CamelMessageInfo *)mi;
 }
 
 static struct {
index 34402ad..9089fe7 100644 (file)
@@ -38,7 +38,7 @@ typedef struct _CamelMboxMessageContentInfo {
 } CamelMboxMessageContentInfo;
 
 typedef struct _CamelMboxMessageInfo {
-       CamelMessageInfo info;
+       CamelLocalMessageInfo info;
 
        off_t frompos;
 } CamelMboxMessageInfo;
@@ -64,7 +64,7 @@ struct _CamelMboxSummaryClass {
 };
 
 CamelType              camel_mbox_summary_get_type     (void);
-CamelMboxSummary      *camel_mbox_summary_new  (const char *filename, const char *mbox_name, CamelIndex *index);
+CamelMboxSummary      *camel_mbox_summary_new  (struct _CamelFolder *, const char *filename, const char *mbox_name, CamelIndex *index);
 
 /* do we honour/use xstatus headers, etc */
 void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state);
index fd05493..1b054a4 100644 (file)
@@ -117,7 +117,7 @@ camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 fla
 
 static CamelLocalSummary *mh_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
 {
-       return (CamelLocalSummary *)camel_mh_summary_new(path, folder, index);
+       return (CamelLocalSummary *)camel_mh_summary_new((CamelFolder *)lf, path, folder, index);
 }
 
 static void
@@ -205,7 +205,7 @@ static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid,
        }
 
        /* we only need it to check the message exists */
-       camel_folder_summary_info_free(folder->summary, info);
+       camel_message_info_free(info);
 
        name = g_strdup_printf("%s/%s", lf->folder_path, uid);
        if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
index cc2f3ce..03b6db9 100644 (file)
@@ -324,7 +324,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
                root = camel_local_store_get_toplevel_dir((CamelLocalStore *)store);
                path = g_strdup_printf("%s/%s.ev-summary", root, fi->full_name);
                folderpath = g_strdup_printf("%s/%s", root, fi->full_name);
-               s = (CamelFolderSummary *)camel_mh_summary_new(path, folderpath, NULL);
+               s = (CamelFolderSummary *)camel_mh_summary_new(NULL, path, folderpath, NULL);
                if (camel_folder_summary_header_load(s) != -1) {
                        fi->unread = s->unread_count;
                        fi->total = s->saved_count;
index d51bf7a..fe0201e 100644 (file)
@@ -123,10 +123,12 @@ camel_mh_summary_finalise(CamelObject *obj)
  * 
  * Return value: A new #CamelMhSummary object.
  **/
-CamelMhSummary *camel_mh_summary_new   (const char *filename, const char *mhdir, CamelIndex *index)
+CamelMhSummary *camel_mh_summary_new(struct _CamelFolder *folder, const char *filename, const char *mhdir, CamelIndex *index)
 {
        CamelMhSummary *o = (CamelMhSummary *)camel_object_new(camel_mh_summary_get_type ());
 
+       ((CamelFolderSummary *)o)->folder = folder;
+
        camel_local_summary_construct((CamelLocalSummary *)o, filename, mhdir, index);
        return o;
 }
@@ -204,7 +206,7 @@ remove_summary(char *key, CamelMessageInfo *info, CamelLocalSummary *cls)
        if (cls->index)
                camel_index_delete_name(cls->index, camel_message_info_uid(info));
        camel_folder_summary_remove((CamelFolderSummary *)cls, info);
-       camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+       camel_message_info_free(info);
 }
 
 static int
@@ -272,7 +274,7 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came
                                if (info != NULL) {
                                        g_hash_table_remove(left, camel_message_info_uid(info));
                                        camel_folder_summary_remove((CamelFolderSummary *)cls, info);
-                                       camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+                                       camel_message_info_free(info);
                                }
                                camel_mh_summary_add(cls, d->d_name, forceindex);
                        } else {
@@ -280,10 +282,10 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came
                                CamelMessageInfo *old = g_hash_table_lookup(left, uid);
 
                                if (old) {
-                                       camel_folder_summary_info_free((CamelFolderSummary *)cls, old);
+                                       camel_message_info_free(old);
                                        g_hash_table_remove(left, uid);
                                }
-                               camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+                               camel_message_info_free(info);
                        }
                }
        }
@@ -300,7 +302,7 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came
 }
 
 static int
-mh_summary_sync_message(CamelLocalSummary *cls, CamelMessageInfo *info, CamelException *ex)
+mh_summary_sync_message(CamelLocalSummary *cls, CamelLocalMessageInfo *info, CamelException *ex)
 {
        CamelMimeParser *mp;
        const char *xev, *buffer;
@@ -378,7 +380,7 @@ static int
 mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, CamelException *ex)
 {
        int count, i;
-       CamelMessageInfo *info;
+       CamelLocalMessageInfo *info;
        char *name;
        const char *uid;
 
@@ -391,9 +393,9 @@ mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo
 
        count = camel_folder_summary_count((CamelFolderSummary *)cls);
        for (i=count-1;i>=0;i--) {
-               info = camel_folder_summary_index((CamelFolderSummary *)cls, i);
+               info = (CamelLocalMessageInfo *)camel_folder_summary_index((CamelFolderSummary *)cls, i);
                g_assert(info);
-               if (expunge && (info->flags & CAMEL_MESSAGE_DELETED)) {
+               if (expunge && (info->info.flags & CAMEL_MESSAGE_DELETED)) {
                        uid = camel_message_info_uid(info);
                        name = g_strdup_printf("%s/%s", cls->folder_path, uid);
                        d(printf("deleting %s\n", name));
@@ -404,17 +406,17 @@ mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo
                                        camel_index_delete_name(cls->index, (char *)uid);
                                
                                camel_folder_change_info_remove_uid(changes, uid);
-                               camel_folder_summary_remove((CamelFolderSummary *)cls, info);
+                               camel_folder_summary_remove((CamelFolderSummary *)cls, (CamelMessageInfo *)info);
                        }
                        g_free(name);
-               } else if (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+               } else if (info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED)) {
                        if (mh_summary_sync_message(cls, info, ex) != -1) {
-                               info->flags &= 0xffff;
+                               info->info.flags &= 0xffff;
                        } else {
                                g_warning("Problem occured when trying to expunge, ignored");
                        }
                }
-               camel_folder_summary_info_free((CamelFolderSummary *)cls, info);
+               camel_message_info_free(info);
        }
 
        return ((CamelLocalSummaryClass *)parent_class)->sync(cls, expunge, changes, ex);
index 4ee30df..d2fdcd1 100644 (file)
@@ -47,7 +47,7 @@ struct _CamelMhSummaryClass {
 };
 
 CamelType       camel_mh_summary_get_type      (void);
-CamelMhSummary *camel_mh_summary_new   (const char *filename, const char *mhdir, CamelIndex *index);
+CamelMhSummary *camel_mh_summary_new(struct _CamelFolder *, const char *filename, const char *mhdir, CamelIndex *index);
 
 #endif /* ! _CAMEL_MH_SUMMARY_H */
 
index b9cb643..c4c7da9 100644 (file)
@@ -160,7 +160,7 @@ spool_get_meta_path(CamelLocalFolder *lf, const char *toplevel_dir, const char *
 static CamelLocalSummary *
 spool_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
 {
-       return (CamelLocalSummary *)camel_spool_summary_new(folder);
+       return (CamelLocalSummary *)camel_spool_summary_new((CamelFolder *)lf, folder);
 }
 
 static int
index 3e4fb53..c8e074a 100644 (file)
@@ -106,10 +106,12 @@ camel_spool_summary_finalise(CamelObject *obj)
 }
 
 CamelSpoolSummary *
-camel_spool_summary_new(const char *mbox_name)
+camel_spool_summary_new(struct _CamelFolder *folder, const char *mbox_name)
 {
        CamelSpoolSummary *new = (CamelSpoolSummary *)camel_object_new(camel_spool_summary_get_type());
 
+       ((CamelFolderSummary *)new)->folder = folder;
+
        camel_local_summary_construct((CamelLocalSummary *)new, NULL, mbox_name, NULL);
        return new;
 }
@@ -318,10 +320,10 @@ spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, C
        work = FALSE;
        count = camel_folder_summary_count(s);
        for (i=0;!work && i<count; i++) {
-               CamelMessageInfo *info = camel_folder_summary_index(s, i);
+               CamelMboxMessageInfo *info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
                g_assert(info);
-               work = (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
-               camel_folder_summary_info_free(s, info);
+               work = (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
+               camel_message_info_free((CamelMessageInfo *)info);
        }
 
        /* if we do, then write out the headers using sync_full, etc */
index b72aeda..2849c8c 100644 (file)
@@ -47,7 +47,7 @@ CamelType     camel_spool_summary_get_type    (void);
 void   camel_spool_summary_construct   (CamelSpoolSummary *new, const char *filename, const char *spool_name, CamelIndex *index);
 
 /* create the summary, in-memory only */
-CamelSpoolSummary *camel_spool_summary_new(const char *filename);
+CamelSpoolSummary *camel_spool_summary_new(struct _CamelFolder *, const char *filename);
 
 /* load/check the summary */
 int camel_spool_summary_load(CamelSpoolSummary *cls, int forceindex, CamelException *ex);
index 7f06555..de0f4cd 100644 (file)
@@ -511,7 +511,7 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti
        g_free(root);
 
        root = g_strdup_printf("%s.ev-summary", nntp_folder->storage_path);
-       folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (root);
+       folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (folder, root);
        g_free(root);
        camel_folder_summary_load (folder->summary);
        
index bb2dda8..213c6f9 100644 (file)
@@ -60,7 +60,7 @@ struct _CamelNNTPSummaryPrivate {
 
 #define _PRIVATE(o) (((CamelNNTPSummary *)(o))->priv)
 
-static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
 static int summary_header_load(CamelFolderSummary *, FILE *);
 static int summary_header_save(CamelFolderSummary *, FILE *);
 
@@ -94,7 +94,7 @@ camel_nntp_summary_class_init(CamelNNTPSummaryClass *klass)
        
        camel_nntp_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type()));
 
-       sklass->message_info_new  = message_info_new;
+       sklass->message_info_new_from_header  = message_info_new_from_header;
        sklass->summary_header_load = summary_header_load;
        sklass->summary_header_save = summary_header_save;
 }
@@ -108,7 +108,7 @@ camel_nntp_summary_init(CamelNNTPSummary *obj)
        p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
 
        /* subclasses need to set the right instance data sizes */
-       s->message_info_size = sizeof(CamelMessageInfo);
+       s->message_info_size = sizeof(CamelMessageInfoBase);
        s->content_info_size = sizeof(CamelMessageContentInfo);
 
        /* and a unique file version */
@@ -124,10 +124,12 @@ camel_nntp_summary_finalise(CamelObject *obj)
 }
 
 CamelNNTPSummary *
-camel_nntp_summary_new(const char *path)
+camel_nntp_summary_new(struct _CamelFolder *folder, const char *path)
 {
        CamelNNTPSummary *cns = (CamelNNTPSummary *)camel_object_new(camel_nntp_summary_get_type());
 
+       ((CamelFolderSummary *)cns)->folder = folder;
+
        camel_folder_summary_set_filename((CamelFolderSummary *)cns, path);
        camel_folder_summary_set_build_content((CamelFolderSummary *)cns, FALSE);
        
@@ -135,9 +137,9 @@ camel_nntp_summary_new(const char *path)
 }
 
 static CamelMessageInfo *
-message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
 {
-       CamelMessageInfo *mi;
+       CamelMessageInfoBase *mi;
        CamelNNTPSummary *cns = (CamelNNTPSummary *)s;
 
        /* error to call without this setup */
@@ -147,13 +149,13 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
        /* we shouldn't be here if we already have this uid */
        g_assert(camel_folder_summary_uid(s, cns->priv->uid) == NULL);
 
-       mi = ((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new(s, h);
+       mi = (CamelMessageInfoBase *)((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new_from_header(s, h);
        if (mi) {
-               camel_message_info_set_uid(mi, cns->priv->uid);
+               mi->uid = g_strdup(cns->priv->uid);
                cns->priv->uid = NULL;
        }
        
-       return mi;
+       return (CamelMessageInfo *)mi;
 }
 
 static int
@@ -207,7 +209,7 @@ static int
 add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex)
 {
        CamelFolderSummary *s;
-       CamelMessageInfo *mi;
+       CamelMessageInfoBase *mi;
        struct _camel_header_raw *headers = NULL;
        char *line, *tab;
        int len, ret;
@@ -271,16 +273,16 @@ add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high,
 
                /* truncated line? ignore? */
                if (xover == NULL) {
-                       mi = camel_folder_summary_uid(s, cns->priv->uid);
+                       mi = (CamelMessageInfoBase *)camel_folder_summary_uid(s, cns->priv->uid);
                        if (mi == NULL) {
-                               mi = camel_folder_summary_add_from_header(s, headers);
+                               mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header(s, headers);
                                if (mi) {
                                        mi->size = size;
                                        cns->high = n;
                                        camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
                                }
                        } else {
-                               camel_folder_summary_info_free(s, mi);
+                               camel_message_info_free(mi);
                        }
                }
 
@@ -352,7 +354,7 @@ add_range_head(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high,
                                camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
                        } else {
                                /* already have, ignore */
-                               camel_folder_summary_info_free(s, mi);
+                               camel_message_info_free(mi);
                        }
                        if (cns->priv->uid) {
                                g_free(cns->priv->uid);
@@ -445,7 +447,7 @@ camel_nntp_summary_check(CamelNNTPSummary *cns, CamelNNTPStore *store, char *lin
                                        i--;
                                }
                                
-                               camel_folder_summary_info_free(s, mi);
+                               camel_message_info_free(mi);
                        }
                }
                cns->low = f;
@@ -473,12 +475,12 @@ update:
 
                count = camel_folder_summary_count(s);
                for (i = 0; i < count; i++) {
-                       CamelMessageInfo *mi = camel_folder_summary_index(s, i);
+                       CamelMessageInfoBase *mi = (CamelMessageInfoBase *)camel_folder_summary_index(s, i);
 
                        if (mi) {
                                if ((mi->flags & CAMEL_MESSAGE_SEEN) == 0)
                                        unread++;
-                               camel_folder_summary_info_free(s, mi);
+                               camel_message_info_free(mi);
                        }
                }
                
index fb58cea..2aff431 100644 (file)
@@ -48,7 +48,7 @@ struct _CamelNNTPSummaryClass {
 };
 
 CamelType      camel_nntp_summary_get_type     (void);
-CamelNNTPSummary *camel_nntp_summary_new(const char *path);
+CamelNNTPSummary *camel_nntp_summary_new(struct _CamelFolder *folder, const char *path);
 
 int camel_nntp_summary_check(CamelNNTPSummary *cns, struct _CamelNNTPStore *store, char *line, struct _CamelFolderChangeInfo *changes, struct _CamelException *ex);