aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog60
-rw-r--r--camel/camel-folder-summary.c71
-rw-r--r--camel/camel-folder-summary.h25
-rw-r--r--camel/camel-folder.c151
-rw-r--r--camel/camel-folder.h40
-rw-r--r--camel/camel-mime-message.c168
-rw-r--r--camel/camel-mime-message.h51
-rw-r--r--camel/providers/imap/camel-imap-folder.c37
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c127
-rw-r--r--camel/providers/vee/camel-vee-folder.c164
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.