From 14bc1cbfc8a8c492e4a280655238159e004c53b3 Mon Sep 17 00:00:00 2001 From: NotZed Date: Wed, 17 May 2000 19:24:24 +0000 Subject: All this basically to support user flags in the summary. They are not yet All this basically to support user flags in the summary. They are not yet saved to the message headers (complicates things a bit). 2000-05-17 NotZed * providers/mbox/camel-mbox-folder.c (message_changed): Snoop changes to user flags on the message into the summary as well. * providers/mbox/camel-mbox-summary.c (camel_mbox_summary_init): Changed version init to include the parent class version info (i.e. add it not overwrite it). * camel-folder-summary.c (message_info_new): Initialise user_flags to empty. (message_info_load): And load user flags. (message_info_save): And save user flags. (message_info_free): And free them. (CAMEL_FOLDER_SUMMARY_VERSION): Bumped file revision. * camel-folder-summary.h: Added user-flags to summary. * camel-mime-message.c (camel_mime_message_set_user_flag): Dont use a hashtable for user flags. (camel_mime_message_get_user_flag): And changed here too. (camel_flag_get): New interface to get a flag from a flag list. Flag lists are easier to work with than hash tables, and save memory too. (camel_flag_set): And set. (camel_flag_list_free): And free. (free_key_only): Discard. (finalize): Remove the flag list. svn path=/trunk/; revision=3107 --- camel/ChangeLog | 29 +++++++++ camel/camel-folder-summary.c | 28 ++++++++- camel/camel-folder-summary.h | 2 + camel/camel-mime-message.c | 98 +++++++++++++++++++++++-------- camel/camel-mime-message.h | 13 +++- camel/providers/mbox/camel-mbox-folder.c | 7 +++ camel/providers/mbox/camel-mbox-summary.c | 2 +- 7 files changed, 152 insertions(+), 27 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 287ee7aab6..6ea9f7d363 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,32 @@ +2000-05-17 NotZed + + * providers/mbox/camel-mbox-folder.c (message_changed): Snoop + changes to user flags on the message into the summary as well. + + * providers/mbox/camel-mbox-summary.c (camel_mbox_summary_init): + Changed version init to include the parent class version info + (i.e. add it not overwrite it). + + * camel-folder-summary.c (message_info_new): Initialise user_flags + to empty. + (message_info_load): And load user flags. + (message_info_save): And save user flags. + (message_info_free): And free them. + (CAMEL_FOLDER_SUMMARY_VERSION): Bumped file revision. + + * camel-folder-summary.h: Added user-flags to summary. + + * camel-mime-message.c (camel_mime_message_set_user_flag): Dont + use a hashtable for user flags. + (camel_mime_message_get_user_flag): And changed here too. + (camel_flag_get): New interface to get a flag from a flag + list. Flag lists are easier to work with than hash tables, and + save memory too. + (camel_flag_set): And set. + (camel_flag_list_free): And free. + (free_key_only): Discard. + (finalize): Remove the flag list. + 2000-05-17 Jeffrey Stedfast * providers/smtp/camel-smtp-transport.c: (smtp_helo): Error diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index 6f80a62325..01403a5cad 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -45,7 +45,7 @@ extern int strdup_count, malloc_count, free_count; #endif -#define CAMEL_FOLDER_SUMMARY_VERSION (3) +#define CAMEL_FOLDER_SUMMARY_VERSION (4) struct _CamelFolderSummaryPrivate { GHashTable *filter_charset; /* CamelMimeFilterCharset's indexed by source charset */ @@ -963,6 +963,7 @@ message_info_new(CamelFolderSummary *s, struct _header_raw *h) mi->subject = summary_format_string(h, "subject"); mi->from = summary_format_address(h, "from"); mi->to = summary_format_address(h, "to"); + mi->user_flags = NULL; mi->date_sent = header_decode_date(header_raw_find(&h, "date", NULL), NULL); mi->date_received = 0; @@ -974,6 +975,8 @@ static CamelMessageInfo * message_info_load(CamelFolderSummary *s, FILE *in) { CamelMessageInfo *mi; + guint count; + int i; mi = g_malloc0(s->message_info_size); @@ -989,12 +992,24 @@ message_info_load(CamelFolderSummary *s, FILE *in) camel_folder_summary_decode_string(in, &mi->to); mi->content = NULL; + camel_folder_summary_decode_uint32(in, &count); + for (i=0;iuser_flags, name); + g_free(name); + } + return mi; } static int message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi) { + guint32 count; + int i; + CamelFlag *flag; + io(printf("Saving message info\n")); camel_folder_summary_encode_string(out, mi->uid); @@ -1004,7 +1019,15 @@ message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi) /* camel_folder_summary_encode_uint32(out, ms->xev_offset);*/ camel_folder_summary_encode_string(out, mi->subject); camel_folder_summary_encode_string(out, mi->from); - return camel_folder_summary_encode_string(out, mi->to); + camel_folder_summary_encode_string(out, mi->to); + + count = camel_flag_list_size(&mi->user_flags); + camel_folder_summary_encode_uint32(out, count); + flag = mi->user_flags; + while (flag) { + camel_folder_summary_encode_string(out, flag->name); + flag = flag->next; + } } static void @@ -1014,6 +1037,7 @@ message_info_free(CamelFolderSummary *s, CamelMessageInfo *mi) g_free(mi->subject); g_free(mi->from); g_free(mi->to); + camel_flag_list_free(&mi->user_flags); g_free(mi); } diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index 76cecffb31..a22172c41b 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -79,6 +79,8 @@ typedef struct { time_t date_sent; time_t date_received; + struct _CamelFlag *user_flags; + /* tree of content description - NULL if it is not available */ CamelMessageContentInfo *content; } CamelMessageInfo; diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index 7c28949856..f65691909f 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -136,7 +136,7 @@ camel_mime_message_init (gpointer object, gpointer klass) g_hash_table_insert(mime_message->recipients, recipient_names[i], camel_internet_address_new()); } - mime_message->user_flags = g_hash_table_new (g_strcase_hash, g_strcase_equal); + mime_message->user_flags = NULL; mime_message->flags = 0; mime_message->subject = NULL; @@ -179,11 +179,6 @@ static void g_lib_is_uber_crappy_shit(gpointer whocares, gpointer getlost, gpoin gtk_object_unref((GtkObject *)getlost); } -static void free_key_only(gpointer whocares, gpointer getlost, gpointer blah) -{ - g_free(whocares); -} - static void finalize (GtkObject *object) { @@ -199,9 +194,7 @@ finalize (GtkObject *object) g_hash_table_foreach (message->recipients, g_lib_is_uber_crappy_shit, NULL); g_hash_table_destroy(message->recipients); - if (message->user_flags) - g_hash_table_foreach (message->user_flags, free_key_only, NULL); - g_hash_table_destroy(message->user_flags); + camel_flag_list_free(&message->user_flags); if (message->folder) gtk_object_unref (GTK_OBJECT (message->folder)); @@ -454,29 +447,88 @@ camel_mime_message_set_flags (CamelMimeMessage *m, guint32 flags, guint32 set) gtk_signal_emit((GtkObject *)m, signals[MESSAGE_CHANGED], MESSAGE_FLAGS_CHANGED); } +gboolean +camel_flag_get(CamelFlag **list, const char *name) +{ + CamelFlag *flag; + flag = *list; + while (flag) { + if (!strcmp(flag->name, name)) + return TRUE; + flag = flag->next; + } + return FALSE; +} + +void +camel_flag_set(CamelFlag **list, const char *name, gboolean value) +{ + CamelFlag *flag, *tmp; + + /* this 'trick' works because flag->next is the first element */ + flag = (CamelFlag *)list; + while (flag->next) { + tmp = flag->next; + if (!strcmp(flag->next->name, name)) { + if (!value) { + flag->next = tmp->next; + g_free(tmp); + } + return; + } + flag = tmp; + } + + if (value) { + tmp = g_malloc(sizeof(*tmp) + strlen(name)); + strcpy(tmp->name, name); + tmp->next = 0; + flag->next = tmp; + } +} + +int +camel_flag_list_size(CamelFlag **list) +{ + int count=0; + CamelFlag *flag; + + flag = *list; + while (flag) { + count++; + flag = flag->next; + } + return count; +} + +void +camel_flag_list_free(CamelFlag **list) +{ + CamelFlag *flag, *tmp; + flag = *list; + while (flag) { + tmp = flag->next; + g_free(flag); + flag = tmp; + } + *list = NULL; +} + gboolean camel_mime_message_get_user_flag (CamelMimeMessage *m, const char *name) { - return (gboolean)g_hash_table_lookup(m->user_flags, name); + g_return_val_if_fail(m->flags & CAMEL_MESSAGE_USER, FALSE); + + return camel_flag_get(&m->user_flags, name); } void camel_mime_message_set_user_flag (CamelMimeMessage *m, const char *name, gboolean value) { - gboolean there; - char *oldname; - gboolean oldvalue; - - there = g_hash_table_lookup_extended(m->user_flags, name, (void *)&oldname, (void *)&oldvalue); + g_return_if_fail(m->flags & CAMEL_MESSAGE_USER); - if (value && !there) { - g_hash_table_insert(m->user_flags, g_strdup(name), (void *)TRUE); - gtk_signal_emit((GtkObject *)m, signals[MESSAGE_CHANGED], MESSAGE_FLAGS_CHANGED); - } else if (there) { - g_hash_table_remove(m->user_flags, name); - g_free(oldname); - gtk_signal_emit((GtkObject *)m, signals[MESSAGE_CHANGED], MESSAGE_FLAGS_CHANGED); - } + camel_flag_set(&m->user_flags, name, value); + gtk_signal_emit((GtkObject *)m, signals[MESSAGE_CHANGED], MESSAGE_FLAGS_CHANGED); } diff --git a/camel/camel-mime-message.h b/camel/camel-mime-message.h index f1e254da51..40a170e244 100644 --- a/camel/camel-mime-message.h +++ b/camel/camel-mime-message.h @@ -62,6 +62,11 @@ enum _CamelMessageFlags { CAMEL_MESSAGE_USER = 1<<31 /* supports user flags */ }; +typedef struct _CamelFlag { + struct _CamelFlag *next; + char name[1]; +} CamelFlag; + struct _CamelMimeMessage { CamelMimePart parent_object; @@ -80,7 +85,7 @@ struct _CamelMimeMessage /* other fields */ guint32 flags; /* system flags */ - GHashTable *user_flags; /* if present, then true */ + struct _CamelFlag *user_flags; gboolean expunged; guint message_number; /* set by folder object when retrieving message */ @@ -151,6 +156,12 @@ void camel_mime_message_set_user_flag (CamelMimeMessage *m, const char *name, guint camel_mime_message_get_message_number (CamelMimeMessage *mime_message); +/* message flag operations */ +gboolean camel_flag_get(CamelFlag **list, const char *name); +void camel_flag_set(CamelFlag **list, const char *name, gboolean state); +int camel_flag_list_size(CamelFlag **list); +void camel_flag_list_free(CamelFlag **list); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index 9d405bd1db..460b970ca7 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -842,6 +842,7 @@ static void message_changed(CamelMimeMessage *m, int type, CamelMboxFolder *mf) { CamelMessageInfo *info; + CamelFlag *flag; printf("Message changed: %s: %d\n", m->message_uid, type); switch (type) { @@ -849,6 +850,12 @@ message_changed(CamelMimeMessage *m, int type, CamelMboxFolder *mf) info = camel_folder_summary_uid((CamelFolderSummary *)mf->summary, m->message_uid); if (info) { info->flags = m->flags | CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_flag_list_free(&info->user_flags); + flag = m->user_flags; + while (flag) { + camel_flag_set(&info->user_flags, flag->name, TRUE); + flag = flag->next; + } camel_folder_summary_touch((CamelFolderSummary *)mf->summary); } else g_warning("Message changed event on message not in summary: %s", m->message_uid); diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c index dac2694f4c..46b180e999 100644 --- a/camel/providers/mbox/camel-mbox-summary.c +++ b/camel/providers/mbox/camel-mbox-summary.c @@ -117,7 +117,7 @@ camel_mbox_summary_init (CamelMboxSummary *obj) s->content_info_size = sizeof(CamelMboxMessageContentInfo); /* and a unique file version */ - s->version = CAMEL_MBOX_SUMMARY_VERSION; + s->version += CAMEL_MBOX_SUMMARY_VERSION; } static void -- cgit v1.2.3