From f4f3ede9d32822a9398992e1e80bfb18a3eae635 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Thu, 4 Jan 2001 07:34:26 +0000 Subject: Removed old implementation. 2001-01-04 Not Zed * mail-ops.c (mail_do_send_mail): Removed old implementation. * folder-browser.c (do_message_selected): If we haven't got a real uid, then clear the display instead. * message-list.c (message_list_drag_data_get): Use new save message function, and also wait for it to finish before continuing. (folder_changed): (message_changed): Use mail_proxy_event instead of mail_do_forward. (mail_regen_list): New iplementation to replace the old. : remove from headers. Dont define timeit by default. (main_folder_changed): (message_list_set_folder): (message_list_set_threaded): (message_list_set_search): (message_list_hide_add): (message_list_hide_uids): (message_list_hide_clear): Use mail_regen_list instead of mail_do_regenerate_messagelist. (mail_do_regenerate_messagelist): Removed the old stuff. No functionality changed yet, just using different thread stuff. * mail-callbacks.c (save_msg_ok): Use new save message function. * component-factory.c (create_view): (add_storage): Use mail_scan_subfolders to build the folder info. (create_folder): Use new implementation with our own callback. (owner_set_cb): Changed b ack to use mail_get_folder, but now wait for it to finish. This will let any gui still run, but also gives us the required synchronous operation. (got_folder): Callback for when the folder has been opened. * mail-ops.c (mail_get_folderinfo): New function to just get the folder info in another thread. (mail_scan_subfolders): New scan subfolder implementation that uses mail_get_folderinfo. (mail_do_scan_subfolders): Removed old implementation. (mail_create_folder): Nerw implementation to create a folder, only. (mail_do_create_folder): Removed old implementation. (mail_save_messages): New implementation, fixes a couple of minor problems, and now provides a return so it can be waited on. Also check that the writes worked, etc. (mail_do_save_messages): Remove previous implementation. (mail_do_flag_messages): Removed, nothing uses it. (mail_do_flag_messages): Removed, nothing uses it anymore. (mail_get_folder): REturn the operation id, so callers can wait for it. (sync_folder_desc): (expunge_folder_desc): Add describe functions so we know what its doing. (mail_send_mail): More generic implementation of sending mail. * mail-mt.c (mail_msg_new): Lock around seq increment. And insert each new message into a hash table of active messages. (mail_msg_init): Init the active message table. (mail_msg_free): Remove the message from the active message table. (mail_msg_wait): New function, waits for a message to be processed, by id. (mail_msg_check_error): Dont display the error if it is a user-cancelled operation. (mail_proxy_event): new implementation of mail_op_forward_event. Only real difference is it uses the new thread stuff, and you can wait for it to finish if you want. (mail_proxy_event): If we're already in the main thread, just call the function. svn path=/trunk/; revision=7246 --- mail/ChangeLog | 70 ++++ mail/component-factory.c | 46 ++- mail/folder-browser.c | 13 +- mail/mail-callbacks.c | 43 ++- mail/mail-mt.c | 112 +++++- mail/mail-mt.h | 5 + mail/mail-ops.c | 967 +++++++++++++++-------------------------------- mail/mail-ops.h | 24 +- mail/message-list.c | 249 ++++++------ 9 files changed, 705 insertions(+), 824 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 58068d8061..3ff21a0ac4 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,73 @@ +2001-01-04 Not Zed + + * mail-ops.c (mail_do_send_mail): Removed old implementation. + + * folder-browser.c (do_message_selected): If we haven't got a real + uid, then clear the display instead. + + * message-list.c (message_list_drag_data_get): Use new save + message function, and also wait for it to finish before + continuing. + (folder_changed): + (message_changed): Use mail_proxy_event instead of + mail_do_forward. + (mail_regen_list): New iplementation to replace the old. + : remove from headers. Dont define timeit by default. + (main_folder_changed): + (message_list_set_folder): + (message_list_set_threaded): + (message_list_set_search): + (message_list_hide_add): + (message_list_hide_uids): + (message_list_hide_clear): Use mail_regen_list instead of + mail_do_regenerate_messagelist. + (mail_do_regenerate_messagelist): Removed the old stuff. No + functionality changed yet, just using different thread stuff. + + * mail-callbacks.c (save_msg_ok): Use new save message function. + + * component-factory.c (create_view): + (add_storage): Use mail_scan_subfolders to build the folder info. + (create_folder): Use new implementation with our own callback. + (owner_set_cb): Changed b ack to use mail_get_folder, but now wait + for it to finish. This will let any gui still run, but also gives + us the required synchronous operation. + (got_folder): Callback for when the folder has been opened. + + * mail-ops.c (mail_get_folderinfo): New function to just get the + folder info in another thread. + (mail_scan_subfolders): New scan subfolder implementation that + uses mail_get_folderinfo. + (mail_do_scan_subfolders): Removed old implementation. + (mail_create_folder): Nerw implementation to create a folder, only. + (mail_do_create_folder): Removed old implementation. + (mail_save_messages): New implementation, fixes a couple of minor + problems, and now provides a return so it can be waited on. Also + check that the writes worked, etc. + (mail_do_save_messages): Remove previous implementation. + (mail_do_flag_messages): Removed, nothing uses it. + (mail_do_flag_messages): Removed, nothing uses it anymore. + (mail_get_folder): REturn the operation id, so callers can wait + for it. + (sync_folder_desc): + (expunge_folder_desc): Add describe functions so we know what its + doing. + (mail_send_mail): More generic implementation of sending mail. + + * mail-mt.c (mail_msg_new): Lock around seq increment. And insert + each new message into a hash table of active messages. + (mail_msg_init): Init the active message table. + (mail_msg_free): Remove the message from the active message table. + (mail_msg_wait): New function, waits for a message to be + processed, by id. + (mail_msg_check_error): Dont display the error if it is a + user-cancelled operation. + (mail_proxy_event): new implementation of mail_op_forward_event. + Only real difference is it uses the new thread stuff, and you can + wait for it to finish if you want. + (mail_proxy_event): If we're already in the main thread, just call + the function. + 2001-01-03 Jeffrey Stedfast * mail-config-druid.c: New source file that implements diff --git a/mail/component-factory.c b/mail/component-factory.c index 7e951261a2..f89a9dbc80 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -94,7 +94,7 @@ create_view (EvolutionShellComponent *shell_component, } if (!gtk_object_get_data (GTK_OBJECT (storage), "connected")) - mail_do_scan_subfolders (CAMEL_STORE(store), storage); + mail_scan_subfolders (CAMEL_STORE(store), storage); camel_object_unref (CAMEL_OBJECT (store)); control = folder_browser_factory_new_control ("", corba_shell); @@ -108,6 +108,24 @@ create_view (EvolutionShellComponent *shell_component, return EVOLUTION_SHELL_COMPONENT_OK; } +static void +do_create_folder(char *uri, CamelFolder *folder, void *data) +{ + GNOME_Evolution_ShellComponentListener listener = data; + CORBA_Environment ev; + GNOME_Evolution_ShellComponentListener_Result result; + + if (folder) + result = GNOME_Evolution_ShellComponentListener_OK; + else + result = GNOME_Evolution_ShellComponentListener_INVALID_URI; + + CORBA_exception_init(&ev); + GNOME_Evolution_ShellComponentListener_notifyResult(listener, result, &ev); + CORBA_Object_release(listener, &ev); + CORBA_exception_free(&ev); +} + static void create_folder (EvolutionShellComponent *shell_component, const char *physical_uri, @@ -115,7 +133,17 @@ create_folder (EvolutionShellComponent *shell_component, const GNOME_Evolution_ShellComponentListener listener, void *closure) { - mail_do_create_folder (listener, physical_uri, type); + char *uri; + CORBA_Environment ev; + + CORBA_exception_init(&ev); + if (!strcmp(type, "mail")) { + uri = g_strdup_printf ("mbox://%s", physical_uri); + mail_create_folder(uri, do_create_folder, CORBA_Object_duplicate(listener, &ev)); + } else { + GNOME_Evolution_ShellComponentListener_notifyResult(listener, GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, &ev); + } + CORBA_exception_free(&ev); } static struct { @@ -127,6 +155,16 @@ static struct { { "Sent", &sent_folder }, }; +static void got_folder(char *uri, CamelFolder *folder, void *data) +{ + CamelFolder **fp = data; + + if (folder) { + *fp = folder; + camel_object_ref((CamelObject *)folder); + } +} + static void owner_set_cb (EvolutionShellComponent *shell_component, EvolutionShellClient *shell_client, @@ -158,7 +196,7 @@ owner_set_cb (EvolutionShellComponent *shell_component, for (i=0;ipending_uid); fb->pending_uid = g_strdup(fb->new_uid); } else { - fb->loading_uid = g_strdup(fb->new_uid); - mail_get_message(fb->folder, fb->loading_uid, done_message_selected, fb, mail_thread_new); + if (fb->new_uid) { + fb->loading_uid = g_strdup(fb->new_uid); + mail_get_message(fb->folder, fb->loading_uid, done_message_selected, fb, mail_thread_new); + } else { + mail_display_set_message(fb->mail_display, NULL); + } } return FALSE; @@ -973,11 +977,12 @@ static void on_message_selected (MessageList *ml, const char *uid, FolderBrowser *fb) { d(printf ("selecting uid %s (direct)\n", uid)); - g_free(fb->new_uid); - fb->new_uid = g_strdup(uid); + if (fb->loading_id != 0) gtk_timeout_remove(fb->loading_id); + g_free(fb->new_uid); + fb->new_uid = g_strdup(uid); fb->loading_id = gtk_timeout_add(100, (GtkFunction)do_message_selected, fb); } diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index a565da9f97..9c7cd1e2b8 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -266,6 +266,28 @@ free_psd (GtkWidget *composer, gpointer user_data) g_free (psd); } +struct _send_data { + EMsgComposer *composer; + struct post_send_data *psd; +}; + +static void +composer_sent_cb(char *uri, CamelMimeMessage *message, gboolean sent, void *data) +{ + struct _send_data *send = data; + + if (sent) { + if (send->psd) { + camel_folder_set_message_flags(send->psd->folder, send->psd->uid, send->psd->flags, send->psd->flags); + } + gtk_widget_destroy((GtkWidget *)send->composer); + } else { + gtk_widget_show((GtkWidget *)send->composer); + gtk_object_unref((GtkObject *)send->composer); + } + g_free(send); +} + void composer_send_cb (EMsgComposer *composer, gpointer data) { @@ -274,7 +296,8 @@ composer_send_cb (EMsgComposer *composer, gpointer data) const CamelInternetAddress *iaddr; const char *subject; struct post_send_data *psd = data; - + struct _send_data *send; + /* Config info */ xport = mail_config_get_transport (); @@ -305,15 +328,13 @@ composer_send_cb (EMsgComposer *composer, gpointer data) return; } } - - if (psd) { - mail_do_send_mail (xport->url, message, - psd->folder, psd->uid, psd->flags, - GTK_WIDGET (composer)); - } else { - mail_do_send_mail (xport->url, message, NULL, NULL, 0, - GTK_WIDGET (composer)); - } + + send = g_malloc(sizeof(*send)); + send->psd = psd; + send->composer = composer; + gtk_object_ref((GtkObject *)composer); + gtk_widget_hide((GtkWidget *)composer); + mail_send_mail(xport->url, message, composer_sent_cb, send); } void @@ -773,7 +794,7 @@ save_msg_ok (GtkWidget *widget, gpointer user_data) folder = gtk_object_get_data (GTK_OBJECT (user_data), "folder"); uids = gtk_object_get_data (GTK_OBJECT (user_data), "uids"); gtk_object_remove_no_notify (GTK_OBJECT (user_data), "uids"); - mail_do_save_messages (folder, uids, path); + mail_save_messages (folder, uids, path, NULL, NULL); } gtk_widget_destroy (GTK_WIDGET (user_data)); diff --git a/mail/mail-mt.c b/mail/mail-mt.c index 3441228ea4..b12bd2b2de 100644 --- a/mail/mail-mt.c +++ b/mail/mail-mt.c @@ -20,18 +20,32 @@ static void set_view_data(const char *current_message, int busy); -static unsigned int mail_msg_seq; +#define MAIL_MT_LOCK(x) pthread_mutex_lock(&x) +#define MAIL_MT_UNLOCK(x) pthread_mutex_unlock(&x) + +static unsigned int mail_msg_seq; /* sequence number of each message */ +static GHashTable *mail_msg_active; /* table of active messages, must hold mail_msg_lock to access */ +static pthread_mutex_t mail_msg_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t mail_msg_cond = PTHREAD_COND_INITIALIZER; + +static pthread_t mail_gui_thread; /* so we can tell when we're in the main thread, or not */ void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size) { struct _mail_msg *msg; - + + MAIL_MT_LOCK(mail_msg_lock); + msg = g_malloc0(size); msg->ops = ops; msg->seq = mail_msg_seq++; msg->msg.reply_port = reply_port; camel_exception_init(&msg->ex); + g_hash_table_insert(mail_msg_active, (void *)msg->seq, msg); + + MAIL_MT_UNLOCK(mail_msg_lock); + return msg; } @@ -41,6 +55,14 @@ void mail_msg_free(void *msg) if (m->ops->destroy_msg) m->ops->destroy_msg(m); + + MAIL_MT_LOCK(mail_msg_lock); + + g_hash_table_remove(mail_msg_active, (void *)m->seq); + pthread_cond_broadcast(&mail_msg_cond); + + MAIL_MT_UNLOCK(mail_msg_lock); + camel_exception_clear(&m->ex); g_free(m); } @@ -52,7 +74,8 @@ void mail_msg_check_error(void *msg) char *text; GnomeDialog *gd; - if (!camel_exception_is_set(&m->ex)) + if (!camel_exception_is_set(&m->ex) + || m->ex.id == CAMEL_EXCEPTION_USER_CANCEL) return; if (m->ops->describe_msg) @@ -68,6 +91,34 @@ void mail_msg_check_error(void *msg) g_free(text); } +/* waits for a message to be finished processing (freed) + the messageid is from struct _mail_msg->seq */ +void mail_msg_wait(unsigned int msgid) +{ + struct _mail_msg *m; + int ismain = pthread_self() == mail_gui_thread; + + if (ismain) { + MAIL_MT_LOCK(mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + while (m) { + MAIL_MT_UNLOCK(mail_msg_lock); + gtk_main_iteration(); + MAIL_MT_LOCK(mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + } + MAIL_MT_UNLOCK(mail_msg_lock); + } else { + MAIL_MT_LOCK(mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + while (m) { + pthread_cond_wait(&mail_msg_cond, &mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + } + MAIL_MT_UNLOCK(mail_msg_lock); + } +} + EMsgPort *mail_gui_port; static GIOChannel *mail_gui_channel; EMsgPort *mail_gui_reply_port; @@ -168,6 +219,9 @@ void mail_msg_init(void) e_thread_set_msg_destroy(mail_thread_new, mail_msg_destroy, 0); e_thread_set_msg_received(mail_thread_new, mail_msg_received, 0); e_thread_set_reply_port(mail_thread_new, mail_gui_reply_port); + + mail_msg_active = g_hash_table_new(NULL, NULL); + mail_gui_thread = pthread_self(); } /* ********************************************************************** */ @@ -181,9 +235,6 @@ struct _set_msg { static pthread_mutex_t status_lock = PTHREAD_MUTEX_INITIALIZER; #define STATUS_BUSY_PENDING (2) -#define MAIL_MT_LOCK(x) pthread_mutex_lock(&x) -#define MAIL_MT_UNLOCK(x) pthread_mutex_unlock(&x) - /* blah blah */ #define STATUS_DELAY (5) @@ -194,7 +245,7 @@ static int status_shown; static char *status_message_next; static int status_message_clear; static int status_timeout_id; -static int status_busy; +/*static int status_busy;*/ struct _status_msg { struct _mail_msg msg; @@ -439,7 +490,54 @@ mail_get_password(char *prompt, gboolean secret) return ret; } +/* ******************** */ +struct _proxy_msg { + struct _mail_msg msg; + CamelObjectEventHookFunc func; + CamelObject *o; + void *event_data; + void *data; +}; + +static void +do_proxy_event(struct _mail_msg *mm) +{ + struct _proxy_msg *m = (struct _proxy_msg *)mm; + + m->func(m->o, m->event_data, m->data); +} + +struct _mail_msg_op proxy_event_op = { + NULL, + do_proxy_event, + NULL, + NULL, +}; + +int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_data, void *data) +{ + struct _proxy_msg *m; + int id; + int ismain = pthread_self() == mail_gui_thread; + + if (ismain) { + func(o, event_data, data); + /* id of -1 is 'always finished' */ + return -1; + } else { + /* we dont have a reply port for this, we dont care when/if it gets executed, just queue it */ + m = mail_msg_new(&proxy_event_op, NULL, sizeof(*m)); + m->func = func; + m->o = o; + m->event_data = event_data; + m->data = data; + + id = m->msg.seq; + e_msgport_put(mail_gui_port, (EMsg *)m); + return id; + } +} /* ******************** */ diff --git a/mail/mail-mt.h b/mail/mail-mt.h index c98785660c..6ef4119f4c 100644 --- a/mail/mail-mt.h +++ b/mail/mail-mt.h @@ -25,6 +25,7 @@ #include "camel/camel-exception.h" #include "e-util/e-msgport.h" +#include "camel/camel-object.h" typedef struct _mail_msg { EMsg msg; /* parent type */ @@ -49,6 +50,7 @@ void mail_msg_init(void); void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size); void mail_msg_free(void *msg); void mail_msg_check_error(void *msg); +void mail_msg_wait(unsigned int msgid); /* set the status-bar message */ /* start/end a new op */ @@ -61,6 +63,9 @@ void mail_status(const char *msg); /* request a string/password */ char *mail_get_password(char *prompt, gboolean secret); +/* forward a camel event (or other call) to the gui thread */ +int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_data, void *data); + /* a message port that receives messages in the gui thread, used for sending port */ extern EMsgPort *mail_gui_port; /* a message port that receives messages in the gui thread, used for the reply port */ diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 7f4784e5c7..b4d0beb8be 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -518,11 +518,18 @@ mail_do_filter_ondemand (CamelFolder *source, GPtrArray *uids) /* ** SEND MAIL *********************************************************** */ -typedef struct send_mail_input_s -{ - gchar *xport_uri; +struct _send_mail_msg { + struct _mail_msg msg; + + char *uri; CamelMimeMessage *message; - + + void (*done)(char *uri, CamelMimeMessage *message, gboolean sent, void *data); + void *data; +}; + +#if 0 +{ /* If done_folder != NULL, will add done_flags to * the flags of the message done_uid in done_folder. */ @@ -532,93 +539,46 @@ typedef struct send_mail_input_s GtkWidget *composer; } -send_mail_input_t; +#endif -static gchar * -describe_send_mail (gpointer in_data, gboolean gerund) +static char *send_mail_desc(struct _mail_msg *mm, int done) { - send_mail_input_t *input = (send_mail_input_t *) in_data; + struct _send_mail_msg *m = (struct _send_mail_msg *)mm; + const char *subject; - if (gerund) { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Sending \"%s\""), - input->message->subject); - else - return - g_strdup - (_("Sending a message without a subject")); - } else { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Send \"%s\""), - input->message->subject); - else - return g_strdup (_("Send a message without a subject")); - } -} - -static void -setup_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - send_mail_input_t *input = (send_mail_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->message)); - if (input->done_folder) - camel_object_ref (CAMEL_OBJECT (input->done_folder)); - if (input->composer) { - gtk_object_ref (GTK_OBJECT (input->composer)); - gtk_widget_hide (GTK_WIDGET (input->composer)); - } + subject = camel_mime_message_get_subject(m->message); + if (subject && subject[0]) + return g_strdup_printf (_("Sending \"%s\""), subject); + else + return g_strdup(_("Sending message")); } -static void -do_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) +static void send_mail_send(struct _mail_msg *mm) { - send_mail_input_t *input = (send_mail_input_t *) in_data; + struct _send_mail_msg *m = (struct _send_mail_msg *)mm; extern CamelFolder *sent_folder; CamelMessageInfo *info; CamelTransport *xport; FilterContext *context; - char *x_mailer; - - mail_tool_camel_lock_up (); - x_mailer = g_strdup_printf ("Evolution %s (Developer Preview)", VERSION); - camel_medium_add_header (CAMEL_MEDIUM (input->message), "X-Mailer", - x_mailer); - g_free (x_mailer); - camel_mime_message_set_date (input->message, - CAMEL_MESSAGE_DATE_CURRENT, 0); + + camel_medium_add_header(CAMEL_MEDIUM (m->message), "X-Mailer", "Evolution " VERSION " (Developer Preview)"); + camel_mime_message_set_date(m->message, CAMEL_MESSAGE_DATE_CURRENT, 0); - xport = camel_session_get_transport (session, input->xport_uri, ex); - mail_tool_camel_lock_down (); - if (camel_exception_is_set (ex)) + xport = camel_session_get_transport(session, m->uri, &mm->ex); + if (camel_exception_is_set(&mm->ex)) return; - mail_tool_send_via_transport (xport, CAMEL_MEDIUM (input->message), ex); - camel_object_unref (CAMEL_OBJECT (xport)); - - if (camel_exception_is_set (ex)) + mail_tool_send_via_transport(xport, (CamelMedium *)m->message, &mm->ex); + camel_object_unref((CamelObject *)xport); + if (camel_exception_is_set(&mm->ex)) return; - /* if we replied to a message, mark the appropriate flags and stuff */ - if (input->done_folder) { - guint32 set; - - mail_tool_camel_lock_up (); - set = camel_folder_get_message_flags (input->done_folder, - input->done_uid); - camel_folder_set_message_flags (input->done_folder, - input->done_uid, - input->done_flags, - input->done_flags); - mail_tool_camel_lock_down (); - } - /* now lets run it through the outgoing filters */ - - info = g_new0 (CamelMessageInfo, 1); + info = camel_message_info_new(); info->flags = CAMEL_MESSAGE_SEEN; /* setup filter driver */ +#warning "Using a gtk object outside of the mian thread, joy" context = mail_load_evolution_rule_context (); if (!((RuleContext *)context)->error) { @@ -635,7 +595,7 @@ do_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) g_free (filename); } - filter_driver_filter_message (driver, input->message, info, "", FILTER_SOURCE_OUTGOING, ex); + filter_driver_filter_message (driver, m->message, info, "", FILTER_SOURCE_OUTGOING, &mm->ex); gtk_object_unref (GTK_OBJECT (driver)); @@ -644,67 +604,51 @@ do_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) } /* now to save the message in Sent */ - if (sent_folder) { - mail_tool_camel_lock_up (); - camel_folder_append_message (sent_folder, input->message, info, ex); - mail_tool_camel_lock_down (); - } + if (sent_folder) + camel_folder_append_message(sent_folder, m->message, info, &mm->ex); - g_free (info); + camel_message_info_free(info); } -static void -cleanup_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) +static void send_mail_sent(struct _mail_msg *mm) { - send_mail_input_t *input = (send_mail_input_t *) in_data; - - camel_object_unref (CAMEL_OBJECT (input->message)); - if (input->done_folder) - camel_object_unref (CAMEL_OBJECT (input->done_folder)); - - g_free (input->xport_uri); - g_free (input->done_uid); - - if (input->composer) { - if (!camel_exception_is_set (ex)) - gtk_widget_destroy (input->composer); - else - gtk_widget_show (input->composer); - } + struct _send_mail_msg *m = (struct _send_mail_msg *)mm; + + if (m->done) + m->done(m->uri, m->message, !camel_exception_is_set(&mm->ex), m->data); } -static const mail_operation_spec op_send_mail = { - describe_send_mail, - 0, - setup_send_mail, - do_send_mail, - cleanup_send_mail +static void send_mail_free(struct _mail_msg *mm) +{ + struct _send_mail_msg *m = (struct _send_mail_msg *)mm; + + camel_object_unref((CamelObject *)m->message); + g_free(m->uri); +} + +static struct _mail_msg_op send_mail_op = { + send_mail_desc, + send_mail_send, + send_mail_sent, + send_mail_free, }; -void -mail_do_send_mail (const char *xport_uri, - CamelMimeMessage *message, - CamelFolder *done_folder, - const char *done_uid, - guint32 done_flags, GtkWidget *composer) +int +mail_send_mail(const char *uri, CamelMimeMessage *message, void (*done) (char *uri, CamelMimeMessage *message, gboolean sent, void *data), void *data) { - send_mail_input_t *input; - - g_return_if_fail (xport_uri != NULL); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - g_return_if_fail (done_folder == NULL || - CAMEL_IS_FOLDER (done_folder)); - g_return_if_fail (done_folder == NULL || done_uid != NULL); - - input = g_new (send_mail_input_t, 1); - input->xport_uri = g_strdup (xport_uri); - input->message = message; - input->done_folder = done_folder; - input->done_uid = g_strdup (done_uid); - input->done_flags = done_flags; - input->composer = composer; - - mail_operation_queue (&op_send_mail, input, TRUE); + struct _send_mail_msg *m; + int id; + + m = mail_msg_new(&send_mail_op, NULL, sizeof(*m)); + m->uri = g_strdup(uri); + m->message = message; + camel_object_ref((CamelObject *)message); + m->data = data; + m->done = done; + + id = m->msg.seq; + e_thread_put(mail_thread_new, (EMsg *)m); + return id; } /* ** SEND MAIL QUEUE ***************************************************** */ @@ -1069,310 +1013,115 @@ mail_do_transfer_messages (CamelFolder *source, GPtrArray *uids, mail_operation_queue (&op_transfer_messages, input, TRUE); } -/* ** FLAG MESSAGES ******************************************************* */ - -typedef struct flag_messages_input_s -{ - CamelFolder *source; - GPtrArray *uids; - gboolean invert; - guint32 mask; - guint32 set; - gboolean flag_all; -} -flag_messages_input_t; - -static gchar * -describe_flag_messages (gpointer in_data, gboolean gerund) -{ - flag_messages_input_t *input = (flag_messages_input_t *) in_data; - - /* FIXME: change based on flags being applied? */ - - if (gerund) - return g_strdup_printf (_("Marking messages in folder \"%s\""), - mail_tool_get_folder_name (input->source)); - else - return g_strdup_printf (_("Mark messages in folder \"%s\""), - mail_tool_get_folder_name (input->source)); -} +/* ** SCAN SUBFOLDERS ***************************************************** */ -static void -setup_flag_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - flag_messages_input_t *input = (flag_messages_input_t *) in_data; +struct _get_folderinfo_msg { + struct _mail_msg msg; - camel_object_ref (CAMEL_OBJECT (input->source)); -} + CamelStore *store; + CamelFolderInfo *info; + void (*done)(CamelStore *store, CamelFolderInfo *info, void *data); + void *data; +}; -static void -do_flag_messages (gpointer in_data, gpointer op_data, CamelException *ex) +static char *get_folderinfo_desc(struct _mail_msg *mm, int done) { - flag_messages_input_t *input = (flag_messages_input_t *) in_data; - gint i; - time_t last_update = 0; - - mail_tool_camel_lock_up (); - camel_folder_freeze (input->source); - if (input->uids == NULL) - input->uids = camel_folder_get_uids (input->source); - mail_tool_camel_lock_down (); - - for (i = 0; i < input->uids->len; i++) { - const gboolean last_message = (i+1 == input->uids->len); - time_t now; + struct _get_folderinfo_msg *m = (struct _get_folderinfo_msg *)mm; + char *ret, *name; - time (&now); - if (last_message || ((now - last_update) > 2)){ - mail_op_set_message (_("Marking message %d of %d"), i + 1, - input->uids->len); - last_update = now; - } - - if (input->invert) { - CamelMessageInfo *info; - - mail_tool_camel_lock_up (); - info = camel_folder_get_message_info (input->source, input->uids->pdata[i]); - camel_folder_set_message_flags (input->source, input->uids->pdata[i], - input->mask, ~info->flags); - camel_folder_free_message_info(input->source, info); - mail_tool_camel_lock_down (); - } else { - mail_tool_set_uid_flags (input->source, input->uids->pdata[i], - input->mask, input->set); - } - - if (input->flag_all == FALSE) - g_free (input->uids->pdata[i]); - } - - mail_tool_camel_lock_up (); - if (input->flag_all) - camel_folder_free_uids (input->source, input->uids); - else - g_ptr_array_free (input->uids, TRUE); - camel_folder_thaw (input->source); - mail_tool_camel_lock_down (); + name = camel_service_get_name((CamelService *)m->store, TRUE); + ret = g_strdup_printf(_("Scanning folders in \"%s\""), name); + g_free(name); + return ret; } -static void -cleanup_flag_messages (gpointer in_data, gpointer op_data, - CamelException *ex) +static void get_folderinfo_get(struct _mail_msg *mm) { - flag_messages_input_t *input = (flag_messages_input_t *) in_data; + struct _get_folderinfo_msg *m = (struct _get_folderinfo_msg *)mm; - camel_object_unref (CAMEL_OBJECT (input->source)); + m->info = camel_store_get_folder_info(m->store, NULL, FALSE, TRUE, TRUE, &mm->ex); } -static const mail_operation_spec op_flag_messages = { - describe_flag_messages, - 0, - setup_flag_messages, - do_flag_messages, - cleanup_flag_messages -}; - -void -mail_do_flag_messages (CamelFolder *source, GPtrArray *uids, - gboolean invert, - guint32 mask, guint32 set) +static void get_folderinfo_got(struct _mail_msg *mm) { - flag_messages_input_t *input; + struct _get_folderinfo_msg *m = (struct _get_folderinfo_msg *)mm; - g_return_if_fail (CAMEL_IS_FOLDER (source)); - g_return_if_fail (uids != NULL); - - input = g_new (flag_messages_input_t, 1); - input->source = source; - input->uids = uids; - input->invert = invert; - input->mask = mask; - input->set = set; - input->flag_all = FALSE; - - mail_operation_queue (&op_flag_messages, input, TRUE); + if (m->done) + m->done(m->store, m->info, m->data); } -void -mail_do_flag_all_messages (CamelFolder *source, gboolean invert, - guint32 mask, guint32 set) +static void get_folderinfo_free(struct _mail_msg *mm) { - flag_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (source)); - - input = g_new (flag_messages_input_t, 1); - input->source = source; - input->uids = NULL; - input->invert = invert; - input->mask = mask; - input->set = set; - input->flag_all = TRUE; + struct _get_folderinfo_msg *m = (struct _get_folderinfo_msg *)mm; - mail_operation_queue (&op_flag_messages, input, TRUE); + if (m->info) + camel_store_free_folder_info(m->store, m->info); + camel_object_unref((CamelObject *)m->store); } -/* ** SCAN SUBFOLDERS ***************************************************** */ - -struct _scan_sub_msg { - CamelStore *store; - EvolutionStorage *storage; +static struct _mail_msg_op get_folderinfo_op = { + get_folderinfo_desc, + get_folderinfo_get, + get_folderinfo_got, + get_folderinfo_free, }; - -typedef struct scan_subfolders_input_s +int mail_get_folderinfo(CamelStore *store, void (*done)(CamelStore *store, CamelFolderInfo *info, void *data), void *data) { - CamelStore *store; - EvolutionStorage *storage; -} -scan_subfolders_input_t; + struct _get_folderinfo_msg *m; + int id; -typedef struct scan_subfolders_folderinfo_s -{ - char *path; - char *name; - char *uri; - gboolean highlighted; -} -scan_subfolders_folderinfo_t; - -typedef struct scan_subfolders_op_s -{ - GPtrArray *new_folders; -} -scan_subfolders_op_t; - -static int scan_subfolders_done; + m = mail_msg_new(&get_folderinfo_op, NULL, sizeof(*m)); + m->store = store; + camel_object_ref((CamelObject *)store); + m->done = done; + m->data = data; + id = m->msg.seq; -static gchar * -describe_scan_subfolders (gpointer in_data, gboolean gerund) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - char *name; + e_thread_put(mail_thread_new, (EMsg *)m); - name = camel_service_get_name (CAMEL_SERVICE (input->store), TRUE); - if (gerund) - return g_strdup_printf (_("Scanning folders in \"%s\""), name); - else - return g_strdup_printf (_("Scan folders in \"%s\""), name); - g_free (name); + return id; } -static void -setup_scan_subfolders (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data; - - camel_object_ref (CAMEL_OBJECT (input->store)); - gtk_object_ref (GTK_OBJECT (input->storage)); - - data->new_folders = g_ptr_array_new (); -} +/* ********************************************************************** */ -static void -add_folders (GPtrArray *folders, const char *prefix, CamelFolderInfo *fi) +static void do_add_subfolders(CamelStore *store, CamelFolderInfo *info, EvolutionStorage *storage, const char *prefix) { - scan_subfolders_folderinfo_t *info; + char *path, *name; - info = g_new (scan_subfolders_folderinfo_t, 1); - info->path = g_strdup_printf ("%s/%s", prefix, fi->name); - if (fi->unread_message_count > 0) { - info->name = g_strdup_printf ("%s (%d)", fi->name, - fi->unread_message_count); - info->highlighted = TRUE; - } else { - info->name = g_strdup (fi->name); - info->highlighted = FALSE; - } - info->uri = g_strdup (fi->url); - g_ptr_array_add (folders, info); - if (fi->child) - add_folders (folders, info->path, fi->child); - if (fi->sibling) - add_folders (folders, prefix, fi->sibling); -} - -static void -do_scan_subfolders (gpointer in_data, gpointer op_data, CamelException *ex) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data; - CamelFolderInfo *tree; + path = g_strdup_printf("%s/%s", prefix, info->name); + if (info->unread_message_count > 0) + name = g_strdup_printf("%s (%d)", info->name, info->unread_message_count); + else + name = g_strdup(info->name); - tree = camel_store_get_folder_info (input->store, NULL, FALSE, - TRUE, TRUE, ex); - if (tree) { - add_folders (data->new_folders, "", tree); - camel_store_free_folder_info (input->store, tree); - } + evolution_storage_new_folder(storage, path, name, "mail", info->url?info->url:"", + _("(No description)"), info->unread_message_count > 0); + g_free(name); + if (info->child) + do_add_subfolders(store, info->child, storage, path); + if (info->sibling) + do_add_subfolders(store, info->sibling, storage, prefix); + g_free(path); } -static void -cleanup_scan_subfolders (gpointer in_data, gpointer op_data, - CamelException *ex) +static void do_scan_subfolders(CamelStore *store, CamelFolderInfo *info, void *data) { - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data; - scan_subfolders_folderinfo_t *info; - int i; - - for (i = 0; i < data->new_folders->len; i++) { - info = data->new_folders->pdata[i]; - evolution_storage_new_folder (input->storage, info->path, - info->name, "mail", - info->uri ? info->uri : "", - _("(No description)"), - info->highlighted); - - g_free (info->uri); - g_free (info->name); - g_free (info->path); - g_free (info); - } - g_ptr_array_free (data->new_folders, TRUE); + EvolutionStorage *storage = data; - if (!camel_exception_is_set (ex)) { - gtk_object_set_data (GTK_OBJECT (input->storage), - "connected", GINT_TO_POINTER (1)); + if (info) { + gtk_object_set_data((GtkObject *)storage, "connected", (void *)1); + do_add_subfolders(store, info, storage, ""); } - - gtk_object_unref (GTK_OBJECT (input->storage)); - camel_object_unref (CAMEL_OBJECT (input->store)); - - scan_subfolders_done = TRUE; } -static const mail_operation_spec op_scan_subfolders = { - describe_scan_subfolders, - sizeof (scan_subfolders_op_t), - setup_scan_subfolders, - do_scan_subfolders, - cleanup_scan_subfolders -}; - -void -mail_do_scan_subfolders (CamelStore *store, EvolutionStorage *storage) +/* synchronous function to scan the & and add folders in a store */ +void mail_scan_subfolders(CamelStore *store, EvolutionStorage *storage) { - scan_subfolders_input_t *input; - - g_return_if_fail (CAMEL_IS_STORE (store)); - g_return_if_fail (EVOLUTION_IS_STORAGE (storage)); - - scan_subfolders_done = FALSE; - - input = g_new (scan_subfolders_input_t, 1); - input->store = store; - input->storage = storage; - - mail_operation_queue (&op_scan_subfolders, input, TRUE); + int id; - /* Ok, so this must run synchrounously, sigh */ - while (!scan_subfolders_done) { - gtk_main_iteration(); - } + id = mail_get_folderinfo(store, do_scan_subfolders, storage); + mail_msg_wait(id); } /* ** ATTACH MESSAGES ****************************************************** */ @@ -1437,6 +1186,9 @@ mail_build_attachment(CamelFolder *folder, GPtrArray *uids, /* ** LOAD FOLDER ********************************************************* */ +/* there hsould be some way to merge this and create folder, since both can + presumably create a folder ... */ + struct _get_folder_msg { struct _mail_msg msg; @@ -1464,8 +1216,6 @@ static void get_folder_got(struct _mail_msg *mm) { struct _get_folder_msg *m = (struct _get_folder_msg *)mm; - /* FIXME: what to do when it fails? */ - if (m->done) m->done(m->uri, m->folder, m->data); } @@ -1486,27 +1236,28 @@ static struct _mail_msg_op get_folder_op = { get_folder_free, }; -void +int mail_get_folder(const char *uri, void (*done) (char *uri, CamelFolder *folder, void *data), void *data) { struct _get_folder_msg *m; + int id; m = mail_msg_new(&get_folder_op, NULL, sizeof(*m)); m->uri = g_strdup(uri); m->data = data; m->done = done; + id = m->msg.seq; e_thread_put(mail_thread_new, (EMsg *)m); + return id; } /* ** CREATE FOLDER ******************************************************* */ -#if 0 - -/* possible new implementation (not yet finished) - However, i'm trying to find a way to remove this entirely and just use get_folder() +/* trying to find a way to remove this entirely and just use get_folder() to do the same thing. But i dont think it can be done, because one works on shell uri's (get folder), and the other only works for mail uri's ? */ + struct _create_folder_msg { struct _mail_msg msg; @@ -1526,7 +1277,6 @@ static char *create_folder_desc(struct _mail_msg *mm, int done) static void create_folder_get(struct _mail_msg *mm) { struct _create_folder_msg *m = (struct _create_folder_msg *)mm; - char *uri; /* FIXME: supply a way to make indexes optional */ m->folder = mail_tool_get_folder_from_urlname(m->uri, "mbox", @@ -1538,8 +1288,6 @@ static void create_folder_got(struct _mail_msg *mm) { struct _create_folder_msg *m = (struct _create_folder_msg *)mm; - /* FIXME: what to do when it fails? */ - if (m->done) m->done(m->uri, m->folder, m->data); } @@ -1572,117 +1320,6 @@ mail_create_folder(const char *uri, void (*done) (char *uri, CamelFolder *folder e_thread_put(mail_thread_new, (EMsg *)m); } -#endif - -/* ** CREATE FOLDER ******************************************************* */ - -typedef struct create_folder_input_s -{ - GNOME_Evolution_ShellComponentListener listener; - char *uri; - char *type; -} -create_folder_input_t; - -typedef struct create_folder_data_s -{ - GNOME_Evolution_ShellComponentListener_Result result; -} -create_folder_data_t; - -static gchar * -describe_create_folder (gpointer in_data, gboolean gerund) -{ - create_folder_input_t *input = (create_folder_input_t *) in_data; - - if (gerund) { - return g_strdup_printf (_("Creating \"%s\""), input->uri); - } else { - return g_strdup_printf (_("Create \"%s\""), input->uri); - } -} - -static void -do_create_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - create_folder_input_t *input = (create_folder_input_t *) in_data; - create_folder_data_t *data = (create_folder_data_t *) op_data; - - CamelFolder *folder; - gchar *camel_url; - - if (strcmp (input->type, "mail") != 0) - data->result = - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE; - else { - camel_url = g_strdup_printf ("mbox://%s", input->uri); - /* FIXME: supply a way to make indexes optional */ - folder = mail_tool_get_folder_from_urlname (camel_url, - "mbox", CAMEL_STORE_FOLDER_CREATE - |CAMEL_STORE_FOLDER_BODY_INDEX, ex); - g_free (camel_url); - - if (!camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - data->result = GNOME_Evolution_ShellComponentListener_OK; - } else { - data->result = - GNOME_Evolution_ShellComponentListener_INVALID_URI; - } - } -} - -static void -cleanup_create_folder (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - create_folder_input_t *input = (create_folder_input_t *) in_data; - create_folder_data_t *data = (create_folder_data_t *) op_data; - - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult (input->listener, - data->result, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Exception while reporting result to shell " - "component listener.")); - CORBA_Object_release (input->listener, &ev); - - g_free (input->uri); - g_free (input->type); - - CORBA_exception_free (&ev); -} - -static const mail_operation_spec op_create_folder = { - describe_create_folder, - sizeof (create_folder_data_t), - NULL, - do_create_folder, - cleanup_create_folder -}; - -void -mail_do_create_folder (const GNOME_Evolution_ShellComponentListener listener, - const char *uri, const char *type) -{ - CORBA_Environment ev; - create_folder_input_t *input; - - g_return_if_fail (uri != NULL); - g_return_if_fail (type != NULL); - - input = g_new (create_folder_input_t, 1); - CORBA_exception_init (&ev); - input->listener = CORBA_Object_duplicate (listener, &ev); - CORBA_exception_free (&ev); - input->uri = g_strdup (uri); - input->type = g_strdup (type); - - mail_operation_queue (&op_create_folder, input, FALSE); -} /* ** SYNC FOLDER ********************************************************* */ @@ -1694,6 +1331,11 @@ struct _sync_folder_msg { void *data; }; +static char *sync_folder_desc(struct _mail_msg *mm, int done) +{ + return g_strdup(_("Synchronising folder")); +} + static void sync_folder_sync(struct _mail_msg *mm) { struct _sync_folder_msg *m = (struct _sync_folder_msg *)mm; @@ -1717,7 +1359,7 @@ static void sync_folder_free(struct _mail_msg *mm) } static struct _mail_msg_op sync_folder_op = { - NULL, + sync_folder_desc, sync_folder_sync, sync_folder_synced, sync_folder_free, @@ -1739,6 +1381,11 @@ mail_sync_folder(CamelFolder *folder, void (*done) (CamelFolder *folder, void *d /* ******************************************************************************** */ +static char *expunge_folder_desc(struct _mail_msg *mm, int done) +{ + return g_strdup(_("Expunging folder")); +} + static void expunge_folder_expunge(struct _mail_msg *mm) { struct _sync_folder_msg *m = (struct _sync_folder_msg *)mm; @@ -1748,7 +1395,7 @@ static void expunge_folder_expunge(struct _mail_msg *mm) /* we just use the sync stuff where we can, since it would be the same */ static struct _mail_msg_op expunge_folder_op = { - NULL, + expunge_folder_desc, expunge_folder_expunge, sync_folder_synced, sync_folder_free, @@ -2161,179 +1808,181 @@ mail_do_setup_trash (const char *name, const char *store_uri, CamelFolder **fold /* ** SAVE MESSAGES ******************************************************* */ -typedef struct save_messages_input_s { +struct _save_messages_msg { + struct _mail_msg msg; + CamelFolder *folder; GPtrArray *uids; - gchar *path; -} save_messages_input_t; - -typedef struct save_messages_data_s { -} save_messages_data_t; + char *path; + void (*done)(CamelFolder *folder, GPtrArray *uids, char *path, void *data); + void *data; +}; -static gchar * -describe_save_messages (gpointer in_data, gboolean gerund) +static char *save_messages_desc(struct _mail_msg *mm, int done) { - save_messages_input_t *input = (save_messages_input_t *) in_data; - - if (gerund) - return g_strdup_printf (_("Saving messages from folder \"%s\""), - mail_tool_get_folder_name (input->folder)); - else - return g_strdup_printf (_("Save messages from folder \"%s\""), - mail_tool_get_folder_name (input->folder)); + return g_strdup(_("Saving messages")); } -static void -setup_save_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - save_messages_input_t *input = (save_messages_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->folder)); +/* tries to build a From line, based on message headers */ +/* this is a copy directly from camel-mbox-summary.c */ + +static char *tz_months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +static char *tz_days[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +static char * +build_from(struct _header_raw *header) +{ + GString *out = g_string_new("From "); + char *ret; + const char *tmp; + time_t thetime; + int offset; + struct tm tm; + + tmp = header_raw_find(&header, "Sender", NULL); + if (tmp == NULL) + tmp = header_raw_find(&header, "From", NULL); + if (tmp != NULL) { + struct _header_address *addr = header_address_decode(tmp); + + tmp = NULL; + if (addr) { + if (addr->type == HEADER_ADDRESS_NAME) { + g_string_append(out, addr->v.addr); + tmp = ""; + } + header_address_unref(addr); + } + } + if (tmp == NULL) + g_string_append(out, "unknown@nodomain.now.au"); + + /* try use the received header to get the date */ + tmp = header_raw_find(&header, "Received", NULL); + if (tmp) { + tmp = strrchr(tmp, ';'); + if (tmp) + tmp++; + } + + /* if there isn't one, try the Date field */ + if (tmp == NULL) + tmp = header_raw_find(&header, "Date", NULL); + + thetime = header_decode_date(tmp, &offset); + thetime += ((offset / 100) * (60 * 60)) + (offset % 100) * 60; + gmtime_r(&thetime, &tm); + g_string_sprintfa(out, " %s %s %d %02d:%02d:%02d %4d\n", + tz_days[tm.tm_wday], + tz_months[tm.tm_mon], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900); + + ret = out->str; + g_string_free(out, FALSE); + return ret; } -static void -do_save_messages (gpointer in_data, gpointer op_data, CamelException *ex) +static void save_messages_save(struct _mail_msg *mm) { - save_messages_input_t *input = (save_messages_input_t *) in_data; + struct _save_messages_msg *m = (struct _save_messages_msg *)mm; CamelStreamFilter *filtered_stream; CamelMimeFilterFrom *from_filter; CamelStream *stream; - time_t last_update = 0; - int fd, fid, i; - - fd = open (input->path, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd == -1) + int fd, i; + char *from; + + fd = open(m->path, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd == -1) { + camel_exception_setv(&mm->ex, CAMEL_EXCEPTION_SYSTEM, + _("Unable to create output file: %s\n %s"), m->path, strerror(errno)); return; + } - mail_tool_camel_lock_up (); - - stream = camel_stream_fs_new_with_fd (fd); - from_filter = camel_mime_filter_from_new (); - filtered_stream = camel_stream_filter_new_with_stream (stream); - fid = camel_stream_filter_add (filtered_stream, CAMEL_MIME_FILTER (from_filter)); + stream = camel_stream_fs_new_with_fd(fd); + from_filter = camel_mime_filter_from_new(); + filtered_stream = camel_stream_filter_new_with_stream(stream); + camel_stream_filter_add(filtered_stream, (CamelMimeFilter *)from_filter); + camel_object_unref((CamelObject *)from_filter); - for (i = 0; i < input->uids->len; i++) { + for (i=0; iuids->len; i++) { CamelMimeMessage *message; - const gboolean last_message = (i+1 == input->uids->len); - time_t now; - - /* - * Update the time display every 2 seconds - */ - time (&now); - if (last_message || ((now - last_update) > 2)) { - mail_op_set_message (_("Saving message %d of %d (uid \"%s\")"), - i + 1, input->uids->len, (char *)input->uids->pdata[i]); - last_update = now; - } + + mail_statusf(_("Saving message %d of %d (uid \"%s\")"), + i+1, m->uids->len, (char *)m->uids->pdata[i]); - message = camel_folder_get_message (input->folder, input->uids->pdata[i], ex); - g_free (input->uids->pdata[i]); - if (message && !camel_exception_is_set (ex)) { - struct _header_address *addr = NULL; - struct _header_raw *headers; - const char *sender, *str; - char *date_str; - time_t date; - int offset; - - /* first we must write the "From " line */ - camel_stream_write (stream, "From ", 5); - headers = CAMEL_MIME_PART (message)->headers; - - /* try to use the sender header */ - sender = header_raw_find (&headers, "Sender", NULL); - if (!sender) { - /* okay, try the field */ - sender = header_raw_find (&headers, "From", NULL); - addr = header_address_decode (sender); - sender = NULL; - if (addr) { - if (addr->type == HEADER_ADDRESS_NAME) - sender = addr->v.addr; - else - sender = NULL; - } - - if (!sender) - sender = "unknown@nodomain.com"; - } - for ( ; *sender && isspace ((unsigned char) *sender); sender++); - camel_stream_write (stream, sender, strlen (sender)); - if (addr) - header_address_unref (addr); - - /* try to use the received header to get the date */ - str = header_raw_find (&headers, "Received", NULL); - if (str) { - str = strrchr (str, ';'); - if (str) - str++; - } - - /* if there isn't one, try the Date field */ - if (!str) - str = header_raw_find (&headers, "Date", NULL); - - date = header_decode_date (str, &offset); - date += ((offset / 100) * (60 * 60)) + (offset % 100) * 60; - - date_str = header_format_date (date, offset); - camel_stream_printf (stream, " %s\n", date_str); - g_free (date_str); - - /* now write the message data */ - camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (filtered_stream)); - camel_object_unref (CAMEL_OBJECT (message)); - } else { + message = camel_folder_get_message(m->folder, m->uids->pdata[i], &mm->ex); + if (!message) + break; + + /* we need to flush after each stream write since we are writing to the same fd */ + from = build_from(((CamelMimePart *)message)->headers); + if (camel_stream_write_string(stream, from) == -1 + || camel_stream_flush(stream) == -1 + || camel_data_wrapper_write_to_stream((CamelDataWrapper *)message, (CamelStream *)filtered_stream) == -1 + || camel_stream_flush((CamelStream *)filtered_stream) == -1) { + camel_exception_setv(&mm->ex, CAMEL_EXCEPTION_SYSTEM, + _("Error saving messages to: %s:\n %s"), m->path, strerror(errno)); + g_free(from); + camel_object_unref((CamelObject *)message); break; } + g_free(from); + camel_object_unref((CamelObject *)message); } - - camel_stream_flush (CAMEL_STREAM (filtered_stream)); - - g_ptr_array_free (input->uids, TRUE); - - camel_stream_filter_remove (filtered_stream, fid); - camel_object_unref (CAMEL_OBJECT (from_filter)); - camel_object_unref (CAMEL_OBJECT (filtered_stream)); - camel_object_unref (CAMEL_OBJECT (stream)); - - mail_tool_camel_lock_down (); + + camel_object_unref((CamelObject *)filtered_stream); + camel_object_unref((CamelObject *)stream); } -static void -cleanup_save_messages (gpointer in_data, gpointer op_data, - CamelException *ex) +static void save_messages_saved(struct _mail_msg *mm) { - save_messages_input_t *input = (save_messages_input_t *) in_data; - - g_free (input->path); - - camel_object_unref (CAMEL_OBJECT (input->folder)); + struct _save_messages_msg *m = (struct _save_messages_msg *)mm; + + if (m->done) + m->done(m->folder, m->uids, m->path, m->data); +} + +static void save_messages_free(struct _mail_msg *mm) +{ + struct _save_messages_msg *m = (struct _save_messages_msg *)mm; + int i; + + for (i=0;iuids->len;i++) + g_free(m->uids->pdata[i]); + g_ptr_array_free(m->uids, TRUE); + camel_object_unref((CamelObject *)m->folder); + g_free(m->path); } -static const mail_operation_spec op_save_messages = { - describe_save_messages, - sizeof (save_messages_data_t), - setup_save_messages, - do_save_messages, - cleanup_save_messages +static struct _mail_msg_op save_messages_op = { + save_messages_desc, + save_messages_save, + save_messages_saved, + save_messages_free, }; -void -mail_do_save_messages (CamelFolder *folder, GPtrArray *uids, gchar *path) +int +mail_save_messages(CamelFolder *folder, GPtrArray *uids, const char *path, + void (*done) (CamelFolder *folder, GPtrArray *uids, char *path, void *data), void *data) { - save_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (uids != NULL); - g_return_if_fail (path != NULL); - - input = g_new (save_messages_input_t, 1); - input->folder = folder; - input->uids = uids; - input->path = g_strdup (path); - - mail_operation_queue (&op_save_messages, input, TRUE); + struct _save_messages_msg *m; + int id; + + m = mail_msg_new(&save_messages_op, NULL, sizeof(*m)); + m->folder = folder; + camel_object_ref((CamelObject *)folder); + m->uids = uids; + m->path = g_strdup(path); + m->data = data; + m->done = done; + + id = m->msg.seq; + e_thread_put(mail_thread_new, (EMsg *)m); + + return id; } diff --git a/mail/mail-ops.h b/mail/mail-ops.h index 604c12c5ab..2256a20ba2 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -58,7 +58,6 @@ void mail_do_scan_subfolders (CamelStore *store, EvolutionStorage *storage); void mail_do_create_folder (const GNOME_Evolution_ShellComponentListener listener, const char *uri, const char *type); void mail_do_setup_trash (const char *name, const char *store_uri, CamelFolder **folder); -void mail_do_save_messages (CamelFolder *folder, GPtrArray *uids, gchar *path); /* get a single message, asynchronously */ void mail_get_message(CamelFolder *folder, const char *uid, @@ -70,8 +69,8 @@ void mail_get_messages(CamelFolder *folder, GPtrArray *uids, void (*done) (CamelFolder *folder, GPtrArray *uids, GPtrArray *msgs, void *data), void *data); /* same for a folder */ -void mail_get_folder(const char *uri, - void (*done) (char *uri, CamelFolder *folder, void *data), void *data); +int mail_get_folder(const char *uri, + void (*done) (char *uri, CamelFolder *folder, void *data), void *data); /* build an attachment */ void mail_build_attachment(CamelFolder *folder, GPtrArray *uids, @@ -82,3 +81,22 @@ void mail_sync_folder(CamelFolder *folder, void mail_expunge_folder(CamelFolder *folder, void (*done) (CamelFolder *folder, void *data), void *data); +/* get folder info asynchronously */ +int mail_get_folderinfo(CamelStore *store, + void (*done)(CamelStore *store, CamelFolderInfo *info, void *data), void *data); + +/* create a new mail folder */ +void mail_create_folder(const char *uri, + void (*done) (char *uri, CamelFolder *folder, void *data), void *data); + +/* save messages */ +int mail_save_messages(CamelFolder *folder, GPtrArray *uids, const char *path, + void (*done) (CamelFolder *folder, GPtrArray *uids, char *path, void *data), void *data); + +int mail_send_mail(const char *uri, CamelMimeMessage *message, + void (*done) (char *uri, CamelMimeMessage *message, gboolean sent, void *data), void *data); + +/* scan subfolders and add them to the storage, synchronous */ +/* FIXME: Move this to component-factory.c */ +void mail_scan_subfolders(CamelStore *store, EvolutionStorage *storage); + diff --git a/mail/message-list.c b/mail/message-list.c index 32b27de593..035e71f4f3 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include @@ -48,7 +47,7 @@ #include "art/score-higher.xpm" #include "art/score-highest.xpm" -#define TIMEIT +/*#define TIMEIT */ #ifdef TIMEIT #include @@ -105,7 +104,8 @@ static void hide_save_state(MessageList *ml); static void hide_load_state(MessageList *ml); /* note: @changes is owned/freed by the caller */ -static void mail_do_regenerate_messagelist (MessageList *list, const char *search, const char *hideexpr, CamelFolderChangeInfo *changes); +/*static void mail_do_regenerate_messagelist (MessageList *list, const char *search, const char *hideexpr, CamelFolderChangeInfo *changes);*/ +static void mail_regen_list(MessageList *ml, const char *search, const char *hideexpr, CamelFolderChangeInfo *changes); /* macros for working with id's (stored in the tree nodes) */ #define id_is_uid(id) (id[0] == 'u')/* is this a uid id? */ @@ -457,7 +457,7 @@ message_list_drag_data_get (ETable *table, uids = g_ptr_array_new (); message_list_foreach (mlist, add_uid, uids); - mail_do_save_messages (mlist->folder, uids, filename); + mail_msg_wait(mail_save_messages(mlist->folder, uids, filename, NULL, NULL)); gtk_selection_data_set (selection_data, selection_data->target, 8, (guchar *) filename, strlen (filename)); @@ -1770,7 +1770,9 @@ build_subtree_diff(MessageList *ml, ETreePath *parent, ETreePath *path, CamelFol } } +#ifndef BROKEN_ETREE static void build_flat_diff(MessageList *ml, CamelFolderChangeInfo *changes); +#endif static void build_flat (MessageList *ml, GPtrArray *uids, CamelFolderChangeInfo *changes) @@ -1814,6 +1816,8 @@ build_flat (MessageList *ml, GPtrArray *uids, CamelFolderChangeInfo *changes) } +#ifndef BROKEN_ETREE + /* used to sort the rows to match list order */ struct _uidsort { int row; @@ -1936,6 +1940,7 @@ build_flat_diff(MessageList *ml, CamelFolderChangeInfo *changes) #endif } +#endif /* ! BROKEN_ETREE */ static void main_folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) @@ -1962,7 +1967,7 @@ main_folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) } - mail_do_regenerate_messagelist(ml, ml->search, NULL, changes); + mail_regen_list(ml, ml->search, NULL, changes); } static void @@ -1978,7 +1983,7 @@ folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) } else { changes = NULL; } - mail_op_forward_event (main_folder_changed, o, changes, user_data); + mail_proxy_event (main_folder_changed, o, changes, user_data); } static void @@ -2002,7 +2007,7 @@ message_changed (CamelObject *o, gpointer event_data, gpointer user_data) * The other thread would be passed a uid parameter that pointed to freed data. * We copy it and free it in the handler. */ - mail_op_forward_event (main_message_changed, o, g_strdup ((gchar *)event_data), user_data); + mail_proxy_event (main_message_changed, o, g_strdup ((gchar *)event_data), user_data); } void @@ -2045,7 +2050,7 @@ message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder) hide_load_state(message_list); clear_tree(message_list); - mail_do_regenerate_messagelist (message_list, message_list->search, NULL, NULL); + mail_regen_list(message_list, message_list->search, NULL, NULL); } E_MAKE_TYPE (message_list, "MessageList", MessageList, message_list_class_init, message_list_init, PARENT_TYPE); @@ -2149,7 +2154,7 @@ message_list_set_threaded(MessageList *ml, gboolean threaded) if (ml->threaded ^ threaded) { ml->threaded = threaded; - mail_do_regenerate_messagelist(ml, ml->search, NULL, NULL); + mail_regen_list(ml, ml->search, NULL, NULL); } } @@ -2163,7 +2168,7 @@ message_list_set_search(MessageList *ml, const char *search) if (search != NULL && ml->search !=NULL && strcmp(search, ml->search)==0) return; - mail_do_regenerate_messagelist(ml, search, NULL, NULL); + mail_regen_list(ml, search, NULL, NULL); } /* returns the number of messages displayable *after* expression hiding has taken place */ @@ -2196,7 +2201,7 @@ void message_list_hide_add(MessageList *ml, const char *expr, unsigned in MESSAGE_LIST_UNLOCK(ml, hide_lock); - mail_do_regenerate_messagelist(ml, ml->search, expr, NULL); + mail_regen_list(ml, ml->search, expr, NULL); } /* hide specific uid's */ @@ -2223,7 +2228,7 @@ void message_list_hide_uids(MessageList *ml, GPtrArray *uids) } } MESSAGE_LIST_UNLOCK(ml, hide_lock); - mail_do_regenerate_messagelist(ml, ml->search, NULL, NULL); + mail_regen_list(ml, ml->search, NULL, NULL); break; } } @@ -2243,7 +2248,7 @@ void message_list_hide_clear(MessageList *ml) ml->hide_after = ML_HIDE_NONE_END; MESSAGE_LIST_UNLOCK(ml, hide_lock); - mail_do_regenerate_messagelist(ml, ml->search, NULL, NULL); + mail_regen_list(ml, ml->search, NULL, NULL); } #define HIDE_STATE_VERSION (1) @@ -2320,125 +2325,95 @@ static void hide_save_state(MessageList *ml) } /* ** REGENERATE MESSAGELIST ********************************************** */ -typedef struct regenerate_messagelist_input_s { +struct _regen_list_msg { + struct _mail_msg msg; + MessageList *ml; - CamelFolder *folder; char *search; char *hideexpr; CamelFolderChangeInfo *changes; gboolean dotree; /* we are building a tree */ -} regenerate_messagelist_input_t; -typedef struct regenerate_messagelist_data_s { GPtrArray *uids, /* list of uid's to use, if realuids is NULL, this is the actual uid's from search, else a simple ptrarray */ *realuids; /* actual uid's from search/get_uid's, or NULL */ CamelFolderThread *tree; - CamelFolderChangeInfo *changes; -} regenerate_messagelist_data_t; - -static gchar *describe_regenerate_messagelist (gpointer in_data, gboolean gerund); -static void setup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex); -static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex); -static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex); - -static gchar *describe_regenerate_messagelist (gpointer in_data, gboolean gerund) -{ - if (gerund) - return g_strdup (_("Rebuilding message view")); - else - return g_strdup (_("Rebuild message view")); -} - -static void setup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex) -{ - regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data; - - if (!IS_MESSAGE_LIST (input->ml)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No messagelist specified to regenerate"); - return; - } - - gtk_object_ref (GTK_OBJECT (input->ml)); -} +}; -static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex) +static void regen_list_regen(struct _mail_msg *mm) { - regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data; - regenerate_messagelist_data_t *data = (regenerate_messagelist_data_t *) op_data; + struct _regen_list_msg *m = (struct _regen_list_msg *)mm; int i; GPtrArray *uids, *uidnew; - if (input->search) { - data->uids = camel_folder_search_by_expression(input->ml->folder, input->search, ex); + if (m->search) { + m->uids = camel_folder_search_by_expression(m->ml->folder, m->search, &mm->ex); } else { - data->uids = camel_folder_get_uids (input->ml->folder); + m->uids = camel_folder_get_uids(m->ml->folder); } - if (camel_exception_is_set (ex)) { + if (camel_exception_is_set(&mm->ex)) return; - } /* see if we have a new expression to hide on */ - if (input->hideexpr) { - uidnew = camel_folder_search_by_expression(input->ml->folder, input->hideexpr, ex); + if (m->hideexpr) { + uidnew = camel_folder_search_by_expression(m->ml->folder, m->hideexpr, &mm->ex); /* well, lets not abort just because this faileld ... */ - camel_exception_clear(ex); + camel_exception_clear(&mm->ex); if (uidnew) { - MESSAGE_LIST_LOCK(input->ml, hide_lock); + MESSAGE_LIST_LOCK(m->ml, hide_lock); - if (input->ml->hidden == NULL) { - input->ml->hidden = g_hash_table_new(g_str_hash, g_str_equal); - input->ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); + if (m->ml->hidden == NULL) { + m->ml->hidden = g_hash_table_new(g_str_hash, g_str_equal); + m->ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); } for (i=0;ilen;i++) { - if (g_hash_table_lookup(input->ml->hidden, uidnew->pdata[i]) == 0) { - char *uid = e_mempool_strdup(input->ml->hidden_pool, uidnew->pdata[i]); - g_hash_table_insert(input->ml->hidden, uid, uid); + if (g_hash_table_lookup(m->ml->hidden, uidnew->pdata[i]) == 0) { + char *uid = e_mempool_strdup(m->ml->hidden_pool, uidnew->pdata[i]); + g_hash_table_insert(m->ml->hidden, uid, uid); } } - MESSAGE_LIST_UNLOCK(input->ml, hide_lock); + MESSAGE_LIST_UNLOCK(m->ml, hide_lock); - camel_folder_search_free(input->ml->folder, uidnew); + camel_folder_search_free(m->ml->folder, uidnew); } } - MESSAGE_LIST_LOCK(input->ml, hide_lock); + MESSAGE_LIST_LOCK(m->ml, hide_lock); - input->ml->hide_unhidden = data->uids->len; + m->ml->hide_unhidden = m->uids->len; /* what semantics do we want from hide_before, hide_after? probably <0 means measure from the end of the list */ /* perform uid hiding */ - if (input->ml->hidden || input->ml->hide_before != ML_HIDE_NONE_START || input->ml->hide_after != ML_HIDE_NONE_END) { + if (m->ml->hidden || m->ml->hide_before != ML_HIDE_NONE_START || m->ml->hide_after != ML_HIDE_NONE_END) { int start, end; uidnew = g_ptr_array_new(); - uids = data->uids; + uids = m->uids; /* first, hide matches */ - if (input->ml->hidden) { + if (m->ml->hidden) { for (i=0;ilen;i++) { - if (g_hash_table_lookup(input->ml->hidden, uids->pdata[i]) == 0) + if (g_hash_table_lookup(m->ml->hidden, uids->pdata[i]) == 0) g_ptr_array_add(uidnew, uids->pdata[i]); } } /* then calculate the subrange visible and chop it out */ - input->ml->hide_unhidden = uidnew->len; + m->ml->hide_unhidden = uidnew->len; - if (input->ml->hide_before != ML_HIDE_NONE_START || input->ml->hide_after != ML_HIDE_NONE_END) { + if (m->ml->hide_before != ML_HIDE_NONE_START || m->ml->hide_after != ML_HIDE_NONE_END) { GPtrArray *uid2 = g_ptr_array_new(); - start = input->ml->hide_before; + start = m->ml->hide_before; if (start < 0) - start += input->ml->hide_unhidden; - end = input->ml->hide_after; + start += m->ml->hide_unhidden; + end = m->ml->hide_after; if (end < 0) - end += input->ml->hide_unhidden; + end += m->ml->hide_unhidden; start = MAX(start, 0); end = MIN(end, uidnew->len); @@ -2449,85 +2424,87 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel g_ptr_array_free(uidnew, TRUE); uidnew = uid2; } - data->realuids = uids; - data->uids = uidnew; + m->realuids = uids; + m->uids = uidnew; } else { - data->realuids = NULL; + m->realuids = NULL; } - MESSAGE_LIST_UNLOCK(input->ml, hide_lock); + MESSAGE_LIST_UNLOCK(m->ml, hide_lock); - if (input->dotree && data->uids) - data->tree = camel_folder_thread_messages_new(input->ml->folder, data->uids); + if (m->dotree && m->uids) + m->tree = camel_folder_thread_messages_new(m->ml->folder, m->uids); else - data->tree = NULL; + m->tree = NULL; } -static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex) +static void regen_list_regened(struct _mail_msg *mm) { - regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data; - regenerate_messagelist_data_t *data = (regenerate_messagelist_data_t *) op_data; - GPtrArray *uids; + struct _regen_list_msg *m = (struct _regen_list_msg *)mm; - if (data->uids == NULL) { /*exception*/ - gtk_object_unref (GTK_OBJECT (input->ml)); + if (m->uids == NULL) return; - } - if (input->dotree) - build_tree(input->ml, data->tree, input->changes); + if (m->dotree) + build_tree(m->ml, m->tree, m->changes); else - build_flat(input->ml, data->uids, input->changes); + build_flat(m->ml, m->uids, m->changes); +} - /* work out if we have aux uid's to free, otherwise free the real ones */ - uids = data->realuids; - if (uids) - g_ptr_array_free(data->uids, TRUE); - else - uids = data->uids; +static void regen_list_free(struct _mail_msg *mm) +{ + struct _regen_list_msg *m = (struct _regen_list_msg *)mm; + GPtrArray *uids; - if (input->search) - camel_folder_search_free (input->ml->folder, uids); - else - camel_folder_free_uids (input->ml->folder, uids); + /* work out if we have aux uid's to free, otherwise free the real ones */ + uids = m->realuids; + if (uids) { + if (m->uids) + g_ptr_array_free(m->uids, TRUE); + } else + uids = m->uids; + + if (uids) { + if (m->search) + camel_folder_search_free(m->ml->folder, uids); + else + camel_folder_free_uids(m->ml->folder, uids); + } /* update what we have as our search string */ - if (input->ml->search && input->ml->search != input->search) - g_free(input->ml->search); - input->ml->search = input->search; + if (m->ml->search && m->ml->search != m->search) + g_free(m->ml->search); + m->ml->search = m->search; - if (data->tree) - camel_folder_thread_messages_destroy(data->tree); + if (m->tree) + camel_folder_thread_messages_destroy(m->tree); - g_free(input->hideexpr); + g_free(m->hideexpr); - if (input->changes) - camel_folder_change_info_free(input->changes); + if (m->changes) + camel_folder_change_info_free(m->changes); - gtk_object_unref (GTK_OBJECT (input->ml)); + gtk_object_unref((GtkObject *)m->ml); } -static const mail_operation_spec op_regenerate_messagelist = -{ - describe_regenerate_messagelist, - sizeof (regenerate_messagelist_data_t), - setup_regenerate_messagelist, - do_regenerate_messagelist, - cleanup_regenerate_messagelist +static struct _mail_msg_op regen_list_op = { + NULL, + regen_list_regen, + regen_list_regened, + regen_list_free, }; -/* if changes == NULL, then update the whole list, otherwise just update the changes */ static void -mail_do_regenerate_messagelist (MessageList *list, const gchar *search, const char *hideexpr, CamelFolderChangeInfo *changes) +mail_regen_list(MessageList *ml, const char *search, const char *hideexpr, CamelFolderChangeInfo *changes) { - regenerate_messagelist_input_t *input; + struct _regen_list_msg *m; - /* This may get called on empty folder-browsers by the bonobo ui - * callback for threaded view. - */ - if (!list->folder) + if (ml->folder == NULL) return; +#ifndef BROKEN_ETREE + /* this can sometimes crash,so ... */ + /* see if we need to goto the child thread at all anyway */ /* currently the only case is the flat view with updates and no search */ if (hideexpr == NULL && search == NULL && changes != NULL && !list->threaded) { @@ -2535,15 +2512,15 @@ mail_do_regenerate_messagelist (MessageList *list, const gchar *search, const ch camel_folder_change_info_free(changes); return; } +#endif - input = g_new (regenerate_messagelist_input_t, 1); - input->ml = list; - input->search = g_strdup (search); - input->hideexpr = g_strdup(hideexpr); - input->changes = changes; - input->dotree = list->threaded; + m = mail_msg_new(®en_list_op, NULL, sizeof(*m)); + m->ml = ml; + m->search = g_strdup(search); + m->hideexpr = g_strdup(hideexpr); + m->changes = changes; + m->dotree = ml->threaded; + gtk_object_ref((GtkObject *)ml); - /* just a quick hack, so dont unwarn yet, or die */ - mail_operation_run (&op_regenerate_messagelist, input, TRUE); - /*mail_operation_queue (&op_regenerate_messagelist, input, TRUE);*/ + e_thread_put(mail_thread_new, (EMsg *)m); } -- cgit