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. svn path=/trunk/; revision=3598
This commit is contained in:
@ -1,3 +1,63 @@
|
||||
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):
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user