diff options
-rw-r--r-- | camel/ChangeLog | 60 | ||||
-rw-r--r-- | camel/camel-folder-summary.c | 71 | ||||
-rw-r--r-- | camel/camel-folder-summary.h | 25 | ||||
-rw-r--r-- | camel/camel-folder.c | 151 | ||||
-rw-r--r-- | camel/camel-folder.h | 40 | ||||
-rw-r--r-- | camel/camel-mime-message.c | 168 | ||||
-rw-r--r-- | camel/camel-mime-message.h | 51 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.c | 37 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 127 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-folder.c | 164 |
10 files changed, 543 insertions, 351 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index e8ae2fbfa9..1073fd812a 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,65 @@ 2000-06-16 Dan Winship <danw@helixcode.com> + Move flag handling from CamelMimeMessage to CamelFolder. This + simplifies several flag-handling pieces of code in the mailer, and + lets you change a message's flags without having to fetch the + message body. It also means that fully-constructed + CamelMimeMessages are now essentially constant, which will help + simplify locking issues later since it means two threads + interested in the same message can just work with separate copies + of it. + + * camel-mime-message.h (struct _CamelMimeMessage): Removed flags + and user_flags (moved to summary). Removed expunged and + message_number which were unused. Removed message_uid and folder + which are no longer needed in the new scheme. + (struct CamelMimeMessageClass): Removed message_changed signal and + get/set_message_number methods. + + * camel-mime-message.c: Updates for CamelMimeMessage changes. + (camel_mime_message_get/set_flags, + camel_mime_message_get/set_user_flag): Replaced with methods in + CamelFolder. + (camel_flag_get, camel_flag_set, camel_flag_list_size, + camel_flag_list_free): Moved verbatim to camel-folder-summary.c + + * camel-folder.c (camel_folder_get/set_message_flags, + camel_folder_get/set_message_user_flag): New methods (and + corresponding useless default implementations) + (camel_folder_class_init): add a message_changed signal + + * camel-folder-summary.c (camel_flag_get, camel_flag_set, + camel_flag_list_size, camel_flag_list_free): Moved here from + camel-mime-message.c + + * providers/mbox/camel-mbox-folder.c (message_changed): Removed. + (mbox_get_message_flags, mbox_set_message_flags, + mbox_get_message_user_flag, mbox_set_message_user_flag): Tweak + summary bits as appropriate. (Functionality moved here from + message_changed.) + (mbox_get_message_by_uid): Update for CamelMimeMessage changes + (less stuff to initialize). + + * providers/imap/camel-imap-folder.c (message_changed): Remove + this. It was just copied from the mbox provider and doesn't deal + with the real IMAP flag stuff anyway. (So there's currently no + flag support in the IMAP provider.) + (imap_get_message_by_uid): Update for CamelMimeMessage changes. + + * providers/vee/camel-vee-folder.c: (message_changed): Remove old + one. Add a new one to listen for message_changed on each folder + and re-emit message_changed signals that correspond to messages in + the vfolder. + (vee_get/set_message_flags, vee_get/set_message_user_flag): Proxy + flag setting to the underlying real messages. + (vee_append_message): Removed for now; there's no way to translate + this into the new CamelMimeMessage/CamelFolder scheme, but (a) + there's also no code which would ever call it and (b) we're + probably going want a better interface than append_message for + message drag and drop to work anyway. To be revisited. + +2000-06-16 Dan Winship <danw@helixcode.com> + * camel-mime-utils.c (rfc2047_decode_word): * camel-mime-part-utils.c (simple_data_wrapper_construct_from_parser): * camel-folder-summary.c (summary_build_content_info): diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index 26b7f2e413..d13d9da333 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -1300,6 +1300,75 @@ summary_build_content_info(CamelFolderSummary *s, CamelMimeParser *mp) return info; } +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; +} + + +#if 0 static void content_info_dump(CamelMessageContentInfo *ci, int depth) { @@ -1341,8 +1410,6 @@ message_info_dump(CamelMessageInfo *mi) content_info_dump(mi->content, 0); } - -#if 0 int main(int argc, char **argv) { CamelMimeParser *mp; diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index 1281415368..46ae856ee6 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -65,6 +65,23 @@ typedef struct _CamelMessageContentInfo { off_t endpos; } CamelMessageContentInfo; +/* system flag bits */ +enum _CamelMessageFlags { + CAMEL_MESSAGE_ANSWERED = 1<<0, + CAMEL_MESSAGE_DELETED = 1<<1, + CAMEL_MESSAGE_DRAFT = 1<<2, + CAMEL_MESSAGE_FLAGGED = 1<<3, + CAMEL_MESSAGE_SEEN = 1<<4, + /* following flags are for the folder, and are not really permanent flags */ + CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder implementation */ + CAMEL_MESSAGE_USER = 1<<31 /* supports user flags */ +}; + +typedef struct _CamelFlag { + struct _CamelFlag *next; + char name[1]; +} CamelFlag; + /* information about a given object */ typedef struct { /* public fields */ @@ -173,8 +190,6 @@ int camel_folder_summary_count(CamelFolderSummary *); CamelMessageInfo *camel_folder_summary_index(CamelFolderSummary *, int); CamelMessageInfo *camel_folder_summary_uid(CamelFolderSummary *, const char *uid); -/* utility functions */ -void camel_folder_summary_set_flags_by_uid(CamelFolderSummary *s, const char *uid, guint32 flags); /* shift content ... */ void camel_folder_summary_offset_content(CamelMessageContentInfo *content, off_t offset); @@ -192,4 +207,10 @@ int camel_folder_summary_decode_string(FILE *, char **); int camel_folder_summary_encode_token(FILE *, char *); int camel_folder_summary_decode_token(FILE *, char **); +/* 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); + #endif /* ! _CAMEL_FOLDER_SUMMARY_H */ diff --git a/camel/camel-folder.c b/camel/camel-folder.c index a5ccc24070..f3cea51af2 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -39,6 +39,7 @@ static CamelObjectClass *parent_class = NULL; enum SIGNALS { FOLDER_CHANGED, + MESSAGE_CHANGED, LAST_SIGNAL }; @@ -63,6 +64,15 @@ static const gchar *get_full_name (CamelFolder *folder); static gboolean can_hold_folders (CamelFolder *folder); static gboolean can_hold_messages (CamelFolder *folder); static guint32 get_permanent_flags (CamelFolder *folder, CamelException *ex); +static guint32 get_message_flags (CamelFolder *folder, const char *uid, + CamelException *ex); +static void set_message_flags (CamelFolder *folder, const char *uid, + guint32 flags, guint32 set, CamelException *ex); +static gboolean get_message_user_flag (CamelFolder *folder, const char *uid, + const char *name, CamelException *ex); +static void set_message_user_flag (CamelFolder *folder, const char *uid, + const char *name, gboolean value, + CamelException *ex); static GPtrArray *get_subfolder_names (CamelFolder *folder, @@ -136,6 +146,10 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->get_message_count = get_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; + camel_folder_class->set_message_flags = set_message_flags; + camel_folder_class->get_message_user_flag = get_message_user_flag; + camel_folder_class->set_message_user_flag = set_message_user_flag; camel_folder_class->get_message_uid = get_message_uid; camel_folder_class->get_message_by_uid = get_message_by_uid; camel_folder_class->delete_message_by_uid = delete_message_by_uid; @@ -158,6 +172,15 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); + signals[MESSAGE_CHANGED] = + gtk_signal_new ("message_changed", + GTK_RUN_LAST, + gtk_object_class->type, + GTK_SIGNAL_OFFSET (CamelFolderClass, + message_changed), + gtk_marshal_NONE__STRING, + GTK_TYPE_NONE, 1, GTK_TYPE_STRING); + gtk_object_class_add_signals (gtk_object_class, signals, LAST_SIGNAL); } @@ -571,6 +594,15 @@ get_permanent_flags (CamelFolder *folder, CamelException *ex) return folder->permanent_flags; } +/** + * camel_folder_get_permanent_flags: + * @folder: a CamelFolder + * @ex: a CamelException + * + * Return value: the set of CamelMessageFlags that can be permanently + * stored on a message between sessions. If it includes %CAMEL_FLAG_USER, + * then user-defined flags will be remembered. + **/ guint32 camel_folder_get_permanent_flags (CamelFolder *folder, CamelException *ex) { @@ -580,6 +612,125 @@ camel_folder_get_permanent_flags (CamelFolder *folder, CamelException *ex) } +static guint32 +get_message_flags (CamelFolder *folder, const char *uid, CamelException *ex) +{ + g_warning ("CamelFolder::get_message_flags not implemented for `%s'", + gtk_type_name (GTK_OBJECT_TYPE (folder))); + return 0; +} + +/** + * camel_folder_get_message_flags: + * @folder: a CamelFolder + * @uid: the UID of a message in @folder + * @ex: a CamelException + * + * Return value: the CamelMessageFlags that are set on the indicated + * message. + **/ +guint32 +camel_folder_get_message_flags (CamelFolder *folder, const char *uid, + CamelException *ex) +{ + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0); + + return CF_CLASS (folder)->get_message_flags (folder, uid, ex); +} + + +static void +set_message_flags (CamelFolder *folder, const char *uid, + guint32 flags, guint32 set, CamelException *ex) +{ + g_warning ("CamelFolder::set_message_flags not implemented for `%s'", + gtk_type_name (GTK_OBJECT_TYPE (folder))); +} + +/** + * camel_folder_set_message_flags: + * @folder: a CamelFolder + * @uid: the UID of a message in @folder + * @flags: a set of CamelMessageFlag values to set + * @set: the mask of values in @flags to use. + * @ex: a CamelException + * + * Sets those flags specified by @set to the values specified by @flags + * on the indicated message. (This may or may not persist after the + * folder or store is closed. See camel_folder_get_permanent_flags().) + **/ +void +camel_folder_set_message_flags (CamelFolder *folder, const char *uid, + guint32 flags, guint32 set, + CamelException *ex) +{ + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + + CF_CLASS (folder)->set_message_flags (folder, uid, flags, set, ex); +} + + +static gboolean +get_message_user_flag (CamelFolder *folder, const char *uid, + const char *name, CamelException *ex) +{ + g_warning ("CamelFolder::get_message_user_flag not implemented " + "for `%s'", gtk_type_name (GTK_OBJECT_TYPE (folder))); + return FALSE; +} + +/** + * camel_folder_get_message_user_flag: + * @folder: a CamelFolder + * @uid: the UID of a message in @folder + * @name: the name of a user flag + * @ex: a CamelException + * + * 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, + const char *name, CamelException *ex) +{ + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), 0); + + return CF_CLASS (folder)->get_message_user_flag (folder, uid, + name, ex); +} + + +static void +set_message_user_flag (CamelFolder *folder, const char *uid, + const char *name, gboolean value, CamelException *ex) +{ + g_warning ("CamelFolder::set_message_user_flag not implemented " + "for `%s'", gtk_type_name (GTK_OBJECT_TYPE (folder))); +} + +/** + * camel_folder_set_message_user_flag: + * @folder: a CamelFolder + * @uid: the UID of a message in @folder + * @name: the name of the user flag to set + * @value: the value to set it to + * @ex: a CamelException + * + * 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().) + **/ +void +camel_folder_set_message_user_flag (CamelFolder *folder, const char *uid, + const char *name, gboolean value, + CamelException *ex) +{ + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + + CF_CLASS (folder)->set_message_user_flag (folder, uid, name, + value, ex); +} + + static const CamelMessageInfo * summary_get_by_uid (CamelFolder *folder, const char *uid) { diff --git a/camel/camel-folder.h b/camel/camel-folder.h index 2412f8da2c..9e9acc6afd 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -65,6 +65,8 @@ typedef struct { /* signals */ void (*folder_changed) (CamelFolder *, int type); + void (*message_changed) (CamelFolder *, + const char *uid); /* Virtual methods */ void (*init) (CamelFolder *folder, CamelStore *parent_store, @@ -106,6 +108,23 @@ typedef struct { guint32 (*get_permanent_flags) (CamelFolder *folder, CamelException *ex); + guint32 (*get_message_flags) (CamelFolder *folder, + const char *uid, + CamelException *ex); + void (*set_message_flags) (CamelFolder *folder, + const char *uid, + guint32 flags, guint32 set, + CamelException *ex); + + gboolean (*get_message_user_flag) (CamelFolder *folder, + const char *uid, + const char *name, + CamelException *ex); + void (*set_message_user_flag) (CamelFolder *folder, + const char *uid, + const char *name, + gboolean value, + CamelException *ex); const gchar * (*get_message_uid) (CamelFolder *folder, CamelMimeMessage *message, @@ -182,6 +201,27 @@ const gchar * camel_folder_get_full_name (CamelFolder *folder); guint32 camel_folder_get_permanent_flags (CamelFolder *folder, CamelException *ex); +guint32 camel_folder_get_message_flags (CamelFolder *folder, + const char *uid, + CamelException *ex); + +void camel_folder_set_message_flags (CamelFolder *folder, + const char *uid, + guint32 flags, + guint32 set, + CamelException *ex); + +gboolean camel_folder_get_message_user_flag (CamelFolder *folder, + const char *uid, + const char *name, + CamelException *ex); + +void camel_folder_set_message_user_flag (CamelFolder *folder, + const char *uid, + const char *name, + gboolean value, + CamelException *ex); + /* message manipulation */ diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index 5959e59933..0e78ca6912 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- */ -/* camelMimeMessage.c : class for a mime_message */ +/* camel-mime-message.c : class for a mime_message */ /* * Authors: Bertrand Guiheneuf <bertrand@helixcode.com> @@ -57,15 +57,6 @@ static char *recipient_names[] = { "To", "Cc", "Bcc", NULL }; -enum SIGNALS { - MESSAGE_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static void set_message_number (CamelMimeMessage *mime_message, guint number); -static guint get_message_number (CamelMimeMessage *mime_message); static int write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); static void finalize (GtkObject *object); static void add_header (CamelMedium *medium, const char *header_name, const void *header_value); @@ -93,10 +84,6 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) for (i=0;header_names[i];i++) g_hash_table_insert (header_name_table, header_names[i], (gpointer)i+1); - /* virtual method definition */ - camel_mime_message_class->set_message_number = set_message_number; - camel_mime_message_class->get_message_number = get_message_number; - /* virtual method overload */ camel_data_wrapper_class->write_to_stream = write_to_stream; @@ -106,16 +93,6 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) camel_mime_part_class->construct_from_parser = construct_from_parser; - signals[MESSAGE_CHANGED] = - gtk_signal_new ("message_changed", - GTK_RUN_LAST, - gtk_object_class->type, - GTK_SIGNAL_OFFSET (CamelMimeMessageClass, message_changed), - gtk_marshal_NONE__INT, - GTK_TYPE_NONE, 1, GTK_TYPE_INT); - - gtk_object_class_add_signals (gtk_object_class, signals, LAST_SIGNAL); - gtk_object_class->finalize = finalize; } @@ -135,13 +112,9 @@ 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 = NULL; - mime_message->flags = 0; - mime_message->subject = NULL; mime_message->reply_to = NULL; mime_message->from = NULL; - mime_message->folder = NULL; mime_message->date = CAMEL_MESSAGE_DATE_CURRENT; mime_message->date_offset = 0; mime_message->date_str = NULL; @@ -188,16 +161,9 @@ finalize (GtkObject *object) g_free (message->reply_to); g_free (message->from); - g_free (message->message_uid); - g_hash_table_foreach (message->recipients, g_lib_is_uber_crappy_shit, NULL); g_hash_table_destroy(message->recipients); - camel_flag_list_free(&message->user_flags); - - if (message->folder) - gtk_object_unref (GTK_OBJECT (message->folder)); - GTK_OBJECT_CLASS (parent_class)->finalize (object); } @@ -421,138 +387,6 @@ camel_mime_message_get_recipients (CamelMimeMessage *mime_message, -/* **** */ - - -guint32 -camel_mime_message_get_flags (CamelMimeMessage *m) -{ - return m->flags; -} - -void -camel_mime_message_set_flags (CamelMimeMessage *m, guint32 flags, guint32 set) -{ - guint32 old; - - printf("%p setting flags %x mask %x\n", m, flags, set); - - old = m->flags; - m->flags = (m->flags & ~flags) | (set & flags); - - printf("old = %x new = %x\n", old, m->flags); - - if (old != m->flags) - 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) -{ - 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) -{ - g_return_if_fail(m->flags & CAMEL_MESSAGE_USER); - - camel_flag_set(&m->user_flags, name, value); - gtk_signal_emit((GtkObject *)m, signals[MESSAGE_CHANGED], MESSAGE_FLAGS_CHANGED); -} - - - -/* FIXME: to be removed??? */ -static void -set_message_number (CamelMimeMessage *mime_message, guint number) -{ - mime_message->message_number = number; -} - -static guint -get_message_number (CamelMimeMessage *mime_message) -{ - return mime_message->message_number; -} - - - -guint -camel_mime_message_get_message_number (CamelMimeMessage *mime_message) -{ - return CMM_CLASS (mime_message)->get_message_number (mime_message); -} - /* mime_message */ static int construct_from_parser(CamelMimePart *dw, CamelMimeParser *mp) diff --git a/camel/camel-mime-message.h b/camel/camel-mime-message.h index 40a170e244..b52da923a9 100644 --- a/camel/camel-mime-message.h +++ b/camel/camel-mime-message.h @@ -50,23 +50,6 @@ extern "C" { /* specify local time */ #define CAMEL_MESSAGE_DATE_CURRENT (~0) -/* system flag bits */ -enum _CamelMessageFlags { - CAMEL_MESSAGE_ANSWERED = 1<<0, - CAMEL_MESSAGE_DELETED = 1<<1, - CAMEL_MESSAGE_DRAFT = 1<<2, - CAMEL_MESSAGE_FLAGGED = 1<<3, - CAMEL_MESSAGE_SEEN = 1<<4, - /* following flags are for the folder, and are not really permanent flags */ - CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder implementation */ - CAMEL_MESSAGE_USER = 1<<31 /* supports user flags */ -}; - -typedef struct _CamelFlag { - struct _CamelFlag *next; - char name[1]; -} CamelFlag; - struct _CamelMimeMessage { CamelMimePart parent_object; @@ -82,33 +65,12 @@ struct _CamelMimeMessage gchar *from; GHashTable *recipients; /* hash table of CamelInternetAddress's */ - - /* other fields */ - guint32 flags; /* system flags */ - struct _CamelFlag *user_flags; - gboolean expunged; - - guint message_number; /* set by folder object when retrieving message */ - gchar *message_uid; - - CamelFolder *folder; -}; - -enum _MessageChangeType { - MESSAGE_FLAGS_CHANGED, - MESSAGE_ENVELOPE_CHANGED, }; typedef struct { CamelMimePartClass parent_class; - /* signals */ - void (*message_changed) (CamelMimeMessage *, enum _MessageChangeType type); - /* Virtual methods */ - void (*set_message_number) (CamelMimeMessage *mime_message, - guint number); - guint (*get_message_number) (CamelMimeMessage *mime_message); } CamelMimeMessageClass; @@ -149,19 +111,6 @@ void camel_mime_message_remove_recipient_name (CamelMimeMessage *mime_message, const CamelInternetAddress *camel_mime_message_get_recipients (CamelMimeMessage *mime_message, const char *type); -guint32 camel_mime_message_get_flags (CamelMimeMessage *m); -void camel_mime_message_set_flags (CamelMimeMessage *m, guint32 flags, guint32 set); -gboolean camel_mime_message_get_user_flag (CamelMimeMessage *m, const char *name); -void camel_mime_message_set_user_flag (CamelMimeMessage *m, const char *name, gboolean value); - -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/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 33e4980d24..c38ff8a18c 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -555,35 +555,6 @@ imap_delete_message_by_uid (CamelFolder *folder, const gchar *uid, CamelExceptio return; } -/* track flag changes in the summary */ -static void -message_changed (CamelMimeMessage *m, int type, CamelImapFolder *mf) -{ - CamelMessageInfo *info; - CamelFlag *flag; - - printf("Message changed: %s: %d\n", m->message_uid, type); - switch (type) { - case MESSAGE_FLAGS_CHANGED: - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY (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(CAMEL_FOLDER_SUMMARY (mf->summary)); - } else - g_warning("Message changed event on message not in summary: %s", m->message_uid); - break; - default: - printf("Unhandled message change event: %d\n", type); - break; - } -} - static CamelMimeMessage * imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) { @@ -702,14 +673,6 @@ imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException * g_warning("Construction failed"); goto fail; } - - /* we're constructed, finish setup and clean up */ - message->folder = folder; - gtk_object_ref(GTK_OBJECT (folder)); - message->message_uid = g_strdup(uid); - message->flags = info->info.flags; - gtk_signal_connect(GTK_OBJECT (message), "message_changed", message_changed, folder); - gtk_object_unref(GTK_OBJECT (parser)); return message; diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index 3c8de8dfcf..97ba44180a 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -82,6 +82,12 @@ static const CamelMessageInfo *mbox_summary_get_by_uid(CamelFolder *f, const cha static GList *mbox_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); +static guint32 mbox_get_message_flags (CamelFolder *folder, const char *uid, CamelException *ex); +static void mbox_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set, CamelException *ex); +static gboolean mbox_get_message_user_flag (CamelFolder *folder, const char *uid, const char *name, CamelException *ex); +static void mbox_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value, CamelException *ex); + + static void mbox_finalize (GtkObject *object); static void @@ -112,6 +118,11 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class) camel_folder_class->summary_get_by_uid = mbox_summary_get_by_uid; + camel_folder_class->get_message_flags = mbox_get_message_flags; + camel_folder_class->set_message_flags = mbox_set_message_flags; + camel_folder_class->get_message_user_flag = mbox_get_message_user_flag; + camel_folder_class->set_message_user_flag = mbox_set_message_user_flag; + gtk_object_class->finalize = mbox_finalize; } @@ -182,6 +193,7 @@ mbox_init (CamelFolder *folder, CamelStore *parent_store, CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_USER; + /* FIXME: we don't actually preserve user flags right now. */ mbox_folder->summary = NULL; mbox_folder->search = NULL; @@ -309,7 +321,7 @@ mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept /* assign a new x-evolution header/uid */ camel_medium_remove_header((CamelMedium *)message, "X-Evolution"); uid = camel_folder_summary_next_uid((CamelFolderSummary *)mbox_folder->summary); - xev = g_strdup_printf("%08x-%04x", uid, message->flags & 0xffff); + xev = g_strdup_printf("%08x-0000", uid); camel_medium_add_header((CamelMedium *)message, "X-Evolution", xev); g_free(xev); @@ -404,35 +416,6 @@ mbox_delete_message_by_uid(CamelFolder *folder, const gchar *uid, CamelException } } -/* track flag changes in the summary */ -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) { - case MESSAGE_FLAGS_CHANGED: - 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); - break; - default: - printf("Unhandled message change event: %d\n", type); - break; - } -} - static CamelMimeMessage * mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) { @@ -486,14 +469,6 @@ mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException * g_warning("Construction failed"); goto fail; } - - /* we're constructed, finish setup and clean up */ - message->folder = folder; - gtk_object_ref((GtkObject *)folder); - message->message_uid = g_strdup(uid); - message->flags = info->info.flags; - gtk_signal_connect((GtkObject *)message, "message_changed", message_changed, folder); - gtk_object_unref((GtkObject *)parser); return message; @@ -551,3 +526,79 @@ mbox_search_by_expression(CamelFolder *folder, const char *expression, CamelExce return camel_folder_search_execute_expression(mbox_folder->search, expression, ex); } + +static guint32 +mbox_get_message_flags (CamelFolder *folder, const char *uid, + CamelException *ex) +{ + CamelMessageInfo *info; + CamelMboxFolder *mf = (CamelMboxFolder *)folder; + + info = camel_folder_summary_uid((CamelFolderSummary *)mf->summary, uid); + if (info) + return info->flags; + else { + camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, + "No such message %s in %s.", uid, + folder->name); + return 0; + } +} + +static void +mbox_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, + guint32 set, CamelException *ex) +{ + CamelMessageInfo *info; + CamelMboxFolder *mf = (CamelMboxFolder *)folder; + + info = camel_folder_summary_uid((CamelFolderSummary *)mf->summary, uid); + if (info) { + info->flags = (info->flags & ~flags) | (set & flags) | + CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_folder_summary_touch((CamelFolderSummary *)mf->summary); + gtk_signal_emit_by_name((GtkObject *)folder, "message_changed", uid); + } else { + camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, + "No such message %s in %s.", uid, + folder->name); + } +} + +static gboolean +mbox_get_message_user_flag (CamelFolder *folder, const char *uid, + const char *name, CamelException *ex) +{ + CamelMessageInfo *info; + CamelMboxFolder *mf = (CamelMboxFolder *)folder; + + info = camel_folder_summary_uid((CamelFolderSummary *)mf->summary, uid); + if (info) + return camel_flag_get(&info->user_flags, name); + else { + camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, + "No such message %s in %s.", uid, + folder->name); + return FALSE; + } +} + +static void mbox_set_message_user_flag (CamelFolder *folder, const char *uid, + const char *name, gboolean value, + CamelException *ex) +{ + CamelMessageInfo *info; + CamelMboxFolder *mf = (CamelMboxFolder *)folder; + + info = camel_folder_summary_uid((CamelFolderSummary *)mf->summary, uid); + if (info) { + camel_flag_set(&info->user_flags, name, value); + info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_folder_summary_touch((CamelFolderSummary *)mf->summary); + gtk_signal_emit_by_name((GtkObject *)folder, "message_changed", uid); + } else { + camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, + "No such message %s in %s.", uid, + folder->name); + } +} diff --git a/camel/providers/vee/camel-vee-folder.c b/camel/providers/vee/camel-vee-folder.c index 0b7b02d2e2..9d0d33b475 100644 --- a/camel/providers/vee/camel-vee-folder.c +++ b/camel/providers/vee/camel-vee-folder.c @@ -50,11 +50,14 @@ void vee_free_summary (CamelFolder *folder, GPtrArray *array); static gint vee_get_message_count (CamelFolder *folder, CamelException *ex); static CamelMimeMessage *vee_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex); -static void vee_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex); - static const CamelMessageInfo *vee_summary_get_by_uid(CamelFolder *f, const char *uid); static GList *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); +static guint32 vee_get_message_flags (CamelFolder *folder, const char *uid, CamelException *ex); +static void vee_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set, CamelException *ex); +static gboolean vee_get_message_user_flag (CamelFolder *folder, const char *uid, const char *name, CamelException *ex); +static void vee_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value, CamelException *ex); + static void camel_vee_folder_class_init (CamelVeeFolderClass *klass); static void camel_vee_folder_init (CamelVeeFolder *obj); @@ -109,13 +112,17 @@ camel_vee_folder_class_init (CamelVeeFolderClass *klass) folder_class->get_summary = vee_get_summary; folder_class->free_summary = vee_free_summary; folder_class->get_message_by_uid = vee_get_message_by_uid; - folder_class->append_message = vee_append_message; folder_class->summary_get_by_uid = vee_summary_get_by_uid; folder_class->get_message_count = vee_get_message_count; folder_class->search_by_expression = vee_search_by_expression; + folder_class->get_message_flags = vee_get_message_flags; + folder_class->set_message_flags = vee_set_message_flags; + folder_class->get_message_user_flag = vee_get_message_user_flag; + folder_class->set_message_user_flag = vee_set_message_user_flag; + object_class->finalize = camel_vee_folder_finalise; gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); @@ -176,6 +183,33 @@ folder_changed(CamelFolder *sub, int type, CamelVeeFolder *vf) gtk_signal_emit_by_name((GtkObject *)vf, "folder_changed", 0); } +/* track flag changes in the summary */ +static void +message_changed(CamelFolder *f, const char *uid, CamelVeeFolder *mf) +{ + const CamelMessageInfo *info; + CamelMessageInfo *vinfo; + CamelFlag *flag; + char *vuid; + + printf("VMessage changed: %s\n", uid); + info = camel_folder_summary_get_by_uid(f, uid); + + vuid = g_strdup_printf("%p:%s", f, uid); + vinfo = (CamelMessageInfo *)vee_summary_get_by_uid((CamelFolder *)mf, vuid); + if (info && vinfo) { + vinfo->flags = info->flags; + camel_flag_list_free(&vinfo->user_flags); + flag = info->user_flags; + while (flag) { + camel_flag_set(&vinfo->user_flags, flag->name, TRUE); + flag = flag->next; + } + gtk_signal_emit_by_name((GtkObject *)mf, "message_changed", vinfo->uid); + } + g_free(vuid); +} + void camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub) { @@ -186,6 +220,7 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub) p->folders = g_list_append(p->folders, sub); gtk_signal_connect((GtkObject *)sub, "folder_changed", folder_changed, vf); + gtk_signal_connect((GtkObject *)sub, "message_changed", message_changed, vf); ex = camel_exception_new(); vee_folder_build_folder(vf, sub, ex); @@ -242,19 +277,6 @@ static void vee_init (CamelFolder *folder, CamelStore *parent_store, vee_folder_build(vf, ex); } -static void vee_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex) -{ - CamelVeeFolder *vf = (CamelVeeFolder *)folder; - - if (message->folder && message->folder->permanent_flags & CAMEL_MESSAGE_USER) { - /* set the flag on the message ... */ - camel_mime_message_set_user_flag(message, vf->vname, TRUE); - } else { - /* FIXME: error code */ - camel_exception_setv(ex, 1, "Cannot append this message to virtual folder"); - } -} - static gint vee_get_message_count (CamelFolder *folder, CamelException *ex) { CamelVeeFolder *vf = (CamelVeeFolder *)folder; @@ -262,54 +284,35 @@ static gint vee_get_message_count (CamelFolder *folder, CamelException *ex) return vf->messages->len; } -/* track flag changes in the summary */ -static void -message_changed(CamelMimeMessage *m, int type, CamelVeeFolder *mf) +static gboolean +get_real_message (CamelFolder *folder, const char *uid, + CamelFolder **out_folder, const char **out_uid, + CamelException *ex) { - CamelMessageInfo *info; - CamelFlag *flag; - char *uid; + CamelVeeMessageInfo *mi; - printf("VMessage changed: %s: %d\n", m->message_uid, type); - switch (type) { - case MESSAGE_FLAGS_CHANGED: - uid = g_strdup_printf("%p:%s", m->folder, m->message_uid); - info = (CamelMessageInfo *)vee_summary_get_by_uid((CamelFolder *)mf, uid); - if (info) { - info->flags = m->flags; - 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; - } - } else { - g_warning("Message changed event on message not in summary: %s", uid); - } - g_free(uid); - break; - default: - printf("Unhandled message change event: %d\n", type); - break; + mi = (CamelVeeMessageInfo *)vee_summary_get_by_uid(folder, uid); + if (mi == NULL) { + camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, + "No such message %s in %s", uid, + folder->name); + return FALSE; } + + *out_folder = mi->folder; + *out_uid = strchr(mi->info.uid, ':')+1; + return TRUE; } static CamelMimeMessage *vee_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) { - CamelVeeMessageInfo *mi; - CamelMimeMessage *mm; + const char *real_uid; + CamelFolder *real_folder; - mi = (CamelVeeMessageInfo *)vee_summary_get_by_uid(folder, uid); - if (mi == NULL) { - camel_exception_setv(ex, 1, "Failed"); + if (!get_real_message (folder, uid, &real_folder, &real_uid, ex)) return NULL; - } - mm = camel_folder_get_message_by_uid(mi->folder, strchr(mi->info.uid, ':')+1, ex); - if (mm) { - gtk_signal_connect((GtkObject *)mm, "message_changed", message_changed, folder); - } - return mm; + return camel_folder_get_message_by_uid(real_folder, real_uid, ex); } GPtrArray *vee_get_summary (CamelFolder *folder, CamelException *ex) @@ -373,6 +376,59 @@ vee_search_by_expression(CamelFolder *folder, const char *expression, CamelExcep return result; } +static guint32 +vee_get_message_flags(CamelFolder *folder, const char *uid, CamelException *ex) +{ + const char *real_uid; + CamelFolder *real_folder; + + if (!get_real_message (folder, uid, &real_folder, &real_uid, ex)) + return 0; + + return camel_folder_get_message_flags(real_folder, real_uid, ex); +} + +static void +vee_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, + guint32 set, CamelException *ex) +{ + const char *real_uid; + CamelFolder *real_folder; + + if (!get_real_message (folder, uid, &real_folder, &real_uid, ex)) + return; + + camel_folder_set_message_flags(real_folder, real_uid, flags, set, ex); +} + +static gboolean +vee_get_message_user_flag(CamelFolder *folder, const char *uid, + const char *name, CamelException *ex) +{ + const char *real_uid; + CamelFolder *real_folder; + + if (!get_real_message (folder, uid, &real_folder, &real_uid, ex)) + return FALSE; + + return camel_folder_get_message_user_flag(real_folder, real_uid, name, ex); +} + +static void +vee_set_message_user_flag(CamelFolder *folder, const char *uid, + const char *name, gboolean value, + CamelException *ex) +{ + const char *real_uid; + CamelFolder *real_folder; + + if (!get_real_message (folder, uid, &real_folder, &real_uid, ex)) + return; + + return camel_folder_set_message_user_flag(real_folder, real_uid, name, value, ex); +} + + /* need incremental update, based on folder. Need to watch folders for changes and update accordingly. |