diff options
-rw-r--r-- | mail/ChangeLog | 30 | ||||
-rw-r--r-- | mail/Makefile.am | 2 | ||||
-rw-r--r-- | mail/component-factory.c | 1 | ||||
-rw-r--r-- | mail/folder-browser-factory.c | 3 | ||||
-rw-r--r-- | mail/mail-callbacks.c | 2 | ||||
-rw-r--r-- | mail/mail-config.c | 80 | ||||
-rw-r--r-- | mail/mail-local.c | 255 | ||||
-rw-r--r-- | mail/mail-ops.c | 324 | ||||
-rw-r--r-- | mail/mail-ops.h | 7 | ||||
-rw-r--r-- | mail/mail-threads.c | 1158 | ||||
-rw-r--r-- | mail/mail-threads.h | 76 | ||||
-rw-r--r-- | mail/session.c | 65 | ||||
-rw-r--r-- | mail/subscribe-dialog.c | 253 | ||||
-rw-r--r-- | mail/subscribe-dialog.h | 2 |
14 files changed, 433 insertions, 1825 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index e6e1a86ce0..9f4bf803c5 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,33 @@ +2001-02-21 Not Zed <NotZed@Ximian.com> + + * mail-callbacks.c (composer_postpone_cb): Fix for api changes to + append_mail. + + * Makefile.am (evolution_mail_SOURCES): Removed mail-threads.[ch]. + + * mail-threads.[ch]: Removed. + + * subscribe-dialog.c (subscribe_do_get_store): Chagned to use new + thread stuff. This is really getting boring. + (subscribe_do_subscribe_folder): Changed to use new thread stuff. + Last one at last, phew. + + * session.c (register_callback): Changed to use new thread stuff. + YUCK. I dropped some functionality, now the timeout callback + return is ignored, so basically it keeps running till finished. + + * mail-ops.c (mail_operation_run): Removed, no longer used/needed. + (mail_do_append_mail): Changed to use new thread stuff. + (mail_do_transfer_messages): ditto. + + * mail-local.c (local_storage_new_folder_cb): Use new thread + stuff, also only run synchronous for this operation. + (mail_local_reconfigure_folder): + (reconfigure_clicked): Changed to use new mail thread stuff. + + * mail-config.c (mail_config_check_service): Changed to use new + thread stuff. + 2001-02-20 Dan Winship <danw@ximian.com> * mail-vtrash.c (get_trash_get): Pass NULL, not "/" for @top. diff --git a/mail/Makefile.am b/mail/Makefile.am index 15901728bb..57b5defac2 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -85,8 +85,6 @@ evolution_mail_SOURCES = \ mail-send-recv.h \ mail-summary.c \ mail-summary.h \ - mail-threads.c \ - mail-threads.h \ mail-tools.c \ mail-tools.h \ mail-types.h \ diff --git a/mail/component-factory.c b/mail/component-factory.c index b3877e4884..762ec0764b 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -241,7 +241,6 @@ idle_quit (gpointer user_data) g_hash_table_foreach (storages_hash, free_storage, NULL); g_hash_table_destroy (storages_hash); - mail_operations_terminate (); gtk_main_quit (); return FALSE; diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c index febef09397..197baf2f19 100644 --- a/mail/folder-browser-factory.c +++ b/mail/folder-browser-factory.c @@ -254,8 +254,7 @@ control_activate (BonoboControl *control, update_pixmaps (uic); - /* this doesn't actually appear to work ? */ - /*bonobo_ui_component_set_prop(uic, "/Toolbar/Stop", "sensitive", "0", NULL);*/ + bonobo_ui_component_set_prop(uic, "/commands/MailStop", "sensitive", "0", NULL); bonobo_ui_component_thaw (uic, NULL); } diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index aa25793eaa..d25f2ffaef 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -365,7 +365,7 @@ composer_postpone_cb (EMsgComposer *composer, gpointer data) camel_medium_add_header (CAMEL_MEDIUM (message), "X-Evolution-Transport", account->transport->url); /* Save the message in Outbox */ - mail_do_append_mail (outbox_folder, message, NULL); + mail_append_mail (outbox_folder, message, NULL, NULL, NULL); if (psd) camel_folder_set_message_flags (psd->folder, psd->uid, psd->flags, psd->flags); diff --git a/mail/mail-config.c b/mail/mail-config.c index bdf739bafe..cdb98cd0f9 100644 --- a/mail/mail-config.c +++ b/mail/mail-config.c @@ -33,6 +33,7 @@ #include "mail.h" #include "mail-config.h" #include "mail-ops.h" +#include "mail-mt.h" typedef struct { gboolean thread_list; @@ -819,53 +820,49 @@ mail_config_folder_to_cachename (CamelFolder *folder, const char *prefix) /* Async service-checking/authtype-lookup code. */ +struct _check_msg { + struct _mail_msg msg; -typedef struct { char *url; CamelProviderType type; gboolean connect; GList **authtypes; - gboolean success; -} check_service_input_t; - -static char * -describe_check_service (gpointer in_data, gboolean gerund) -{ - if (gerund) - return g_strdup (_("Connecting to server")); - else - return g_strdup (_("Connect to server")); -} + gboolean *success; +}; -static void -do_check_service (gpointer in_data, gpointer op_data, CamelException *ex) +static void check_service_check(struct _mail_msg *mm) { - check_service_input_t *input = in_data; + struct _check_msg *m = (struct _check_msg *)mm; CamelService *service = NULL; - if (input->authtypes) { - service = camel_session_get_service (session, input->url, input->type, ex); + if (m->authtypes) { + service = camel_session_get_service (session, m->url, m->type, &mm->ex); if (!service) return; - *input->authtypes = camel_service_query_auth_types (service, input->connect, ex); - } else if (input->connect) { - service = camel_session_get_service_connected (session, input->url, input->type, ex); + *m->authtypes = camel_service_query_auth_types (service, m->connect, &mm->ex); + } else if (m->connect) { + service = camel_session_get_service_connected (session, m->url, m->type, &mm->ex); } if (service) camel_object_unref (CAMEL_OBJECT (service)); - if (!camel_exception_is_set (ex)) - input->success = TRUE; + + *m->success = !camel_exception_is_set(&mm->ex); +} + +static void check_service_free(struct _mail_msg *mm) +{ + struct _check_msg *m = (struct _check_msg *)mm; + + g_free(m->url); } -static const mail_operation_spec op_check_service = { - describe_check_service, - 0, +static struct _mail_msg_op check_service_op = { NULL, - do_check_service, - NULL + check_service_check, + NULL, + check_service_free }; - /** * mail_config_check_service: * @url: service url @@ -886,17 +883,20 @@ static const mail_operation_spec op_check_service = { gboolean mail_config_check_service (CamelURL *url, CamelProviderType type, gboolean connect, GList **authtypes) { - check_service_input_t input; - - input.url = camel_url_to_string (url, TRUE); - input.type = type; - input.connect = connect; - input.authtypes = authtypes; - input.success = FALSE; - - mail_operation_queue (&op_check_service, &input, FALSE); - mail_operation_wait_for_finish (); - g_free (input.url); + gboolean ret = FALSE; + struct _check_msg *m; + int id; + + m = mail_msg_new(&check_service_op, NULL, sizeof(*m)); + m->url = camel_url_to_string(url, TRUE); + m->type = type; + m->connect = connect; + m->authtypes = authtypes; + m->success = &ret; + + id = m->msg.seq; + e_thread_put(mail_thread_queued, (EMsg *)m); + mail_msg_wait(id); - return input.success; + return ret; } diff --git a/mail/mail-local.c b/mail/mail-local.c index 0cdc45daac..087d8d94bb 100644 --- a/mail/mail-local.c +++ b/mail/mail-local.c @@ -57,7 +57,6 @@ #include "mail.h" #include "mail-local.h" #include "mail-tools.h" -#include "mail-threads.h" #include "folder-browser.h" #include "mail-mt.h" @@ -437,19 +436,21 @@ local_folder_changed_proxy (CamelObject *folder, gpointer event_data, gpointer u GINT_TO_POINTER (unread), user_data); } -static char * -describe_register_folder (gpointer in_data, gboolean gerund) -{ - if (gerund) - return g_strdup (_("Registering local folder")); - else - return g_strdup (_("Register local folder")); -} +/* ********************************************************************** */ +/* Register folder */ + +struct _register_msg { + struct _mail_msg msg; + + MailLocalFolder *local_folder; +}; + static void -do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) +register_folder_register(struct _mail_msg *mm) { - MailLocalFolder *local_folder = in_data; + struct _register_msg *m = (struct _register_msg *)mm; + MailLocalFolder *local_folder = m->local_folder; char *name, *path = local_folder->uri + 7; struct _local_meta *meta; CamelStore *store; @@ -460,7 +461,7 @@ do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) g_free (name); name = g_strdup_printf ("%s:%s", meta->format, path); - store = camel_session_get_store (session, name, ex); + store = camel_session_get_store (session, name, &mm->ex); g_free (name); if (!store) { free_metainfo (meta); @@ -470,7 +471,7 @@ do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) flags = CAMEL_STORE_FOLDER_CREATE; if (meta->indexed) flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - local_folder->folder = camel_store_get_folder (store, meta->name, flags, ex); + local_folder->folder = camel_store_get_folder (store, meta->name, flags, &mm->ex); if (local_folder->folder) { camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), "folder_changed", local_folder_changed_proxy, @@ -486,30 +487,36 @@ do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) } static void -cleanup_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) +register_folder_registered(struct _mail_msg *mm) { - MailLocalFolder *local_folder = in_data; + struct _register_msg *m = (struct _register_msg *)mm; + MailLocalFolder *local_folder = m->local_folder; int unread; - if (!local_folder->folder) { - free_local_folder(local_folder); - return; + if (local_folder->folder) { + g_hash_table_insert (local_folder->local_store->folders, local_folder->uri + 8, local_folder); + + unread = local_folder->last_unread; + local_folder->last_unread = 0; + local_folder_changed (CAMEL_OBJECT (local_folder->folder), GINT_TO_POINTER (unread), local_folder); + m->local_folder = NULL; } +} - g_hash_table_insert (local_folder->local_store->folders, local_folder->uri + 8, local_folder); +static void +register_folder_free(struct _mail_msg *mm) +{ + struct _register_msg *m = (struct _register_msg *)mm; - unread = local_folder->last_unread; - local_folder->last_unread = 0; - local_folder_changed (CAMEL_OBJECT (local_folder->folder), GINT_TO_POINTER (unread), local_folder); + if (m->local_folder) + free_local_folder(m->local_folder); } -static const mail_operation_spec op_register_folder = -{ - describe_register_folder, - 0, +static struct _mail_msg_op register_folder_op = { NULL, - do_register_folder, - cleanup_register_folder + register_folder_register, + register_folder_registered, + register_folder_free, }; static void @@ -520,6 +527,8 @@ local_storage_new_folder_cb (EvolutionStorageListener *storage_listener, { MailLocalStore *local_store = data; MailLocalFolder *local_folder; + struct _register_msg *m; + int id; if (strcmp (folder->type, "mail") != 0 || strncmp (folder->physical_uri, "file://", 7) != 0 || @@ -534,31 +543,14 @@ local_storage_new_folder_cb (EvolutionStorageListener *storage_listener, local_folder->local_store = local_store; camel_object_ref((CamelObject *)local_store); - /* Note: This needs to be synchronous, as that is what the shell - expects. Doesn't that suck. */ - /* This used to be made 'synchronous' by having us wait for - outstanding requests, which was BAD */ - - /*mail_operation_queue (&op_register_folder, local_folder, FALSE);*/ - { - CamelException *ex = camel_exception_new(); + m = mail_msg_new(®ister_folder_op, NULL, sizeof(*m)); - do_register_folder(local_folder, NULL, ex); - cleanup_register_folder(local_folder, NULL, ex); + m->local_folder = local_folder; -#if 0 - /* yay, so we can't do this, because we've probably got the bloody - splash screen up */ - if (camel_exception_is_set(ex)) { - char *msg = g_strdup_printf(_("Unable to register folder '%s':\n%s"), - path, camel_exception_get_description(ex)); - GnomeDialog *gd = (GnomeDialog *)gnome_error_dialog(msg); - gnome_dialog_run_and_close(gd); - g_free(msg); - } -#endif - camel_exception_free(ex); - } + /* run synchronous, the shell expects it (I think) */ + id = m->msg.seq; + e_thread_put(mail_thread_queued, (EMsg *)m); + mail_msg_wait(id); } static void @@ -699,15 +691,20 @@ update_progress(char *fmt, float percent) /* ******************** */ -typedef struct reconfigure_folder_input_s { +/* we should have our own progress bar for this */ + +struct _reconfigure_msg { + struct _mail_msg msg; + FolderBrowser *fb; gchar *newtype; GtkWidget *frame; GtkWidget *apply; GtkWidget *cancel; GtkOptionMenu *optionlist; -} reconfigure_folder_input_t; +}; +#if 0 static gchar * describe_reconfigure_folder (gpointer in_data, gboolean gerund) { @@ -722,19 +719,12 @@ describe_reconfigure_folder (gpointer in_data, gboolean gerund) input->fb->uri, input->newtype); } +#endif static void -setup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - gtk_object_ref (GTK_OBJECT (input->fb)); -} - -static void -do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) +reconfigure_folder_reconfigure(struct _mail_msg *mm) { - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; + struct _reconfigure_msg *m = (struct _reconfigure_msg *)mm; MailLocalFolder *local_folder = NULL; CamelStore *fromstore = NULL, *tostore = NULL; char *fromurl = NULL, *tourl = NULL; @@ -747,21 +737,21 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) struct _local_meta *meta = NULL; guint32 flags; - d(printf("reconfiguring folder: %s to type %s\n", input->fb->uri, input->newtype)); + d(printf("reconfiguring folder: %s to type %s\n", m->fb->uri, m->newtype)); mail_status_start(_("Reconfiguring folder")); /* NOTE: This var is cleared by the folder_browser via the set_uri method */ - input->fb->reconfigure = TRUE; + m->fb->reconfigure = TRUE; /* get the actual location of the mailbox */ - url = camel_url_new(input->fb->uri, ex); - if (camel_exception_is_set(ex)) { - g_warning("%s is not a workable url!", input->fb->uri); + url = camel_url_new(m->fb->uri, &mm->ex); + if (camel_exception_is_set(&mm->ex)) { + g_warning("%s is not a workable url!", m->fb->uri); goto cleanup; } - tmpname = strchr (input->fb->uri, '/'); + tmpname = strchr (m->fb->uri, '/'); if (tmpname) { while (*tmpname == '/') tmpname++; @@ -769,7 +759,7 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) } else local_folder = NULL; if (!local_folder) { - g_warning("%s is not a registered local folder!", input->fb->uri); + g_warning("%s is not a registered local folder!", m->fb->uri); goto cleanup; } @@ -779,7 +769,7 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) /* first, 'close' the old folder */ update_progress(_("Closing current folder"), 0.0); - camel_folder_sync(local_folder->folder, FALSE, ex); + camel_folder_sync(local_folder->folder, FALSE, &mm->ex); camel_object_unhook_event(CAMEL_OBJECT (local_folder->folder), "folder_changed", local_folder_changed_proxy, local_folder); @@ -789,22 +779,22 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) /* Once for the FolderBrowser, once for the local store */ camel_object_unref(CAMEL_OBJECT(local_folder->folder)); camel_object_unref(CAMEL_OBJECT(local_folder->folder)); - local_folder->folder = input->fb->folder = NULL; + local_folder->folder = m->fb->folder = NULL; camel_url_set_protocol (url, meta->format); fromurl = camel_url_to_string (url, FALSE); - camel_url_set_protocol (url, input->newtype); + camel_url_set_protocol (url, m->newtype); tourl = camel_url_to_string (url, FALSE); d(printf("opening stores %s and %s\n", fromurl, tourl)); - fromstore = camel_session_get_store(session, fromurl, ex); + fromstore = camel_session_get_store(session, fromurl, &mm->ex); - if (camel_exception_is_set(ex)) + if (camel_exception_is_set(&mm->ex)) goto cleanup; - tostore = camel_session_get_store(session, tourl, ex); - if (camel_exception_is_set(ex)) + tostore = camel_session_get_store(session, tourl, &mm->ex); + if (camel_exception_is_set(&mm->ex)) goto cleanup; /* rename the old mbox and open it again, without indexing */ @@ -812,17 +802,17 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) d(printf("renaming %s to %s, and opening it\n", meta->name, tmpname)); update_progress(_("Renaming old folder and opening"), 0.0); - camel_store_rename_folder(fromstore, meta->name, tmpname, ex); - if (camel_exception_is_set(ex)) { + camel_store_rename_folder(fromstore, meta->name, tmpname, &mm->ex); + if (camel_exception_is_set(&mm->ex)) { goto cleanup; } /* we dont need to set the create flag ... or need an index if it has one */ - fromfolder = camel_store_get_folder(fromstore, tmpname, 0, ex); - if (fromfolder == NULL || camel_exception_is_set(ex)) { + fromfolder = camel_store_get_folder(fromstore, tmpname, 0, &mm->ex); + if (fromfolder == NULL || camel_exception_is_set(&mm->ex)) { /* try and recover ... */ - camel_exception_clear (ex); - camel_store_rename_folder(fromstore, tmpname, meta->name, ex); + camel_exception_clear (&mm->ex); + camel_store_rename_folder(fromstore, tmpname, meta->name, &mm->ex); goto cleanup; } @@ -833,12 +823,12 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) flags = CAMEL_STORE_FOLDER_CREATE; if (meta->indexed) flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - tofolder = camel_store_get_folder(tostore, meta->name, flags, ex); - if (tofolder == NULL || camel_exception_is_set(ex)) { + tofolder = camel_store_get_folder(tostore, meta->name, flags, &mm->ex); + if (tofolder == NULL || camel_exception_is_set(&mm->ex)) { d(printf("cannot open destination folder\n")); /* try and recover ... */ - camel_exception_clear (ex); - camel_store_rename_folder(fromstore, tmpname, meta->name, ex); + camel_exception_clear (&mm->ex); + camel_store_rename_folder(fromstore, tmpname, meta->name, &mm->ex); goto cleanup; } @@ -846,23 +836,23 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) uids = camel_folder_get_uids(fromfolder); for (i=0;i<uids->len;i++) { mail_statusf("Copying message %d of %d", i, uids->len); - camel_folder_move_message_to(fromfolder, uids->pdata[i], tofolder, ex); - if (camel_exception_is_set(ex)) { + camel_folder_move_message_to(fromfolder, uids->pdata[i], tofolder, &mm->ex); + if (camel_exception_is_set(&mm->ex)) { camel_folder_free_uids(fromfolder, uids); goto cleanup; } } camel_folder_free_uids(fromfolder, uids); - camel_folder_expunge(fromfolder, ex); + camel_folder_expunge(fromfolder, &mm->ex); d(printf("delete old mbox ...\n")); - camel_store_delete_folder(fromstore, tmpname, ex); + camel_store_delete_folder(fromstore, tmpname, &mm->ex); /* switch format */ g_free(meta->format); - meta->format = g_strdup(input->newtype); + meta->format = g_strdup(m->newtype); if (save_metainfo(meta) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + camel_exception_setv (&mm->ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot save folder metainfo; " "you'll probably find you can't\n" "open this folder anymore: %s"), @@ -870,8 +860,15 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) } cleanup: - if (local_folder && !local_folder->folder) - do_register_folder (local_folder, NULL, ex); + if (local_folder && !local_folder->folder) { + struct _register_msg *rm = mail_msg_new(®ister_folder_op, NULL, sizeof(*m)); + + /* fake the internal part of this operation, nasty hackish thing */ + rm->local_folder = local_folder; + register_folder_register((struct _mail_msg *)rm); + rm->local_folder = NULL; + mail_msg_free((struct _mail_msg *)rm); + } if (tofolder) camel_object_unref (CAMEL_OBJECT (tofolder)); if (fromfolder) @@ -889,58 +886,60 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) } static void -cleanup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) +reconfigure_folder_reconfigured(struct _mail_msg *mm) { - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; + struct _reconfigure_msg *m = (struct _reconfigure_msg *)mm; char *uri; - if (camel_exception_is_set(ex)) { + if (camel_exception_is_set(&mm->ex)) { gnome_error_dialog (_("If you can no longer open this mailbox, then\n" "you may need to repair it manually.")); } /* force a reload of the newly formatted folder */ d(printf("opening new source\n")); - uri = g_strdup(input->fb->uri); - folder_browser_set_uri(input->fb, uri); + uri = g_strdup(m->fb->uri); + folder_browser_set_uri(m->fb, uri); g_free(uri); +} - mail_status_end(); +static void +reconfigure_folder_free(struct _mail_msg *mm) +{ + struct _reconfigure_msg *m = (struct _reconfigure_msg *)mm; - gtk_object_unref (GTK_OBJECT (input->fb)); - g_free (input->newtype); + gtk_object_unref (GTK_OBJECT (m->fb)); + g_free (m->newtype); } -static const mail_operation_spec op_reconfigure_folder = -{ - describe_reconfigure_folder, - 0, - setup_reconfigure_folder, - do_reconfigure_folder, - cleanup_reconfigure_folder +static struct _mail_msg_op reconfigure_folder_op = { + NULL, + reconfigure_folder_reconfigure, + reconfigure_folder_reconfigured, + reconfigure_folder_free, }; static void -reconfigure_clicked(GnomeDialog *d, int button, reconfigure_folder_input_t *data) +reconfigure_clicked(GnomeDialog *d, int button, struct _reconfigure_msg *m) { if (button == 0) { GtkMenu *menu; int type; char *types[] = { "mbox", "maildir", "mh" }; - menu = (GtkMenu *)gtk_option_menu_get_menu(data->optionlist); + menu = (GtkMenu *)gtk_option_menu_get_menu(m->optionlist); type = g_list_index(GTK_MENU_SHELL(menu)->children, gtk_menu_get_active(menu)); if (type < 0 || type > 2) type = 0; - gtk_widget_set_sensitive(data->frame, FALSE); - gtk_widget_set_sensitive(data->apply, FALSE); - gtk_widget_set_sensitive(data->cancel, FALSE); + gtk_widget_set_sensitive(m->frame, FALSE); + gtk_widget_set_sensitive(m->apply, FALSE); + gtk_widget_set_sensitive(m->cancel, FALSE); - data->newtype = g_strdup (types[type]); - mail_operation_queue (&op_reconfigure_folder, data, TRUE); + m->newtype = g_strdup (types[type]); + e_thread_put(mail_thread_queued, (EMsg *)m); } else - g_free (data); + mail_msg_free((struct _mail_msg *)m); if (button != -1) gnome_dialog_close(d); @@ -952,31 +951,31 @@ mail_local_reconfigure_folder(FolderBrowser *fb) CamelStore *store; GladeXML *gui; GnomeDialog *gd; - reconfigure_folder_input_t *data; + struct _reconfigure_msg *m; if (fb->folder == NULL) { g_warning("Trying to reconfigure nonexistant folder"); return; } - data = g_new (reconfigure_folder_input_t, 1); - + m = mail_msg_new(&reconfigure_folder_op, NULL, sizeof(*m)); store = camel_folder_get_parent_store(fb->folder); gui = glade_xml_new(EVOLUTION_GLADEDIR "/local-config.glade", "dialog_format"); gd = (GnomeDialog *)glade_xml_get_widget (gui, "dialog_format"); - data->frame = glade_xml_get_widget (gui, "frame_format"); - data->apply = glade_xml_get_widget (gui, "apply_format"); - data->cancel = glade_xml_get_widget (gui, "cancel_format"); - data->optionlist = (GtkOptionMenu *)glade_xml_get_widget (gui, "option_format"); - data->newtype = NULL; - data->fb = fb; + m->frame = glade_xml_get_widget (gui, "frame_format"); + m->apply = glade_xml_get_widget (gui, "apply_format"); + m->cancel = glade_xml_get_widget (gui, "cancel_format"); + m->optionlist = (GtkOptionMenu *)glade_xml_get_widget (gui, "option_format"); + m->newtype = NULL; + m->fb = fb; + gtk_object_ref((GtkObject *)fb); gtk_label_set_text((GtkLabel *)glade_xml_get_widget (gui, "label_format"), ((CamelService *)store)->url->protocol); - gtk_signal_connect((GtkObject *)gd, "clicked", reconfigure_clicked, data); + gtk_signal_connect((GtkObject *)gd, "clicked", reconfigure_clicked, m); gtk_object_unref((GtkObject *)gui); gnome_dialog_run_and_close (GNOME_DIALOG (gd)); diff --git a/mail/mail-ops.c b/mail/mail-ops.c index f1d72acf8c..9e75eb36a0 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -32,7 +32,6 @@ #include <camel/camel-mime-filter-from.h> #include <camel/camel-operation.h> #include "mail.h" -#include "mail-threads.h" #include "mail-tools.h" #include "mail-ops.h" #include "mail-vfolder.h" @@ -46,8 +45,6 @@ #define d(x) x -int mail_operation_run(const mail_operation_spec *op, void *in, int free); - #define mail_tool_camel_lock_down() #define mail_tool_camel_lock_up() @@ -733,150 +730,108 @@ mail_send_queue(CamelFolder *queue, const char *destination, /* ** APPEND MESSAGE TO FOLDER ******************************************** */ -typedef struct append_mail_input_s -{ +struct _append_msg { + struct _mail_msg msg; + CamelFolder *folder; CamelMimeMessage *message; CamelMessageInfo *info; -} -append_mail_input_t; -static gchar * -describe_append_mail (gpointer in_data, gboolean gerund) + void (*done)(CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *info, int ok, void *data); + void *data; +}; + +static char *append_mail_desc(struct _mail_msg *mm, int done) { - append_mail_input_t *input = (append_mail_input_t *) in_data; - - if (gerund) { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Appending \"%s\""), - input->message->subject); - else - return - g_strdup (_("Appending a message without a subject")); - } else { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Appending \"%s\""), - input->message->subject); - else - return g_strdup (_("Appending a message without a subject")); - } + return g_strdup(_("Saving message to folder")); } -static void -setup_append_mail (gpointer in_data, gpointer op_data, CamelException *ex) +static void append_mail_append(struct _mail_msg *mm) { - append_mail_input_t *input = (append_mail_input_t *) in_data; + struct _append_msg *m = (struct _append_msg *)mm; - camel_object_ref (CAMEL_OBJECT (input->message)); - camel_object_ref (CAMEL_OBJECT (input->folder)); + camel_mime_message_set_date(m->message, CAMEL_MESSAGE_DATE_CURRENT, 0); + camel_folder_append_message(m->folder, m->message, m->info, &mm->ex); } -static void -do_append_mail (gpointer in_data, gpointer op_data, CamelException *ex) +static void append_mail_appended(struct _mail_msg *mm) { - append_mail_input_t *input = (append_mail_input_t *) in_data; - - camel_mime_message_set_date (input->message, - CAMEL_MESSAGE_DATE_CURRENT, 0); - - mail_tool_camel_lock_up (); - - /* now to save the message in the specified folder */ - camel_folder_append_message (input->folder, input->message, input->info, ex); - - mail_tool_camel_lock_down (); + struct _append_msg *m = (struct _append_msg *)mm; + + if (m->done) + m->done(m->folder, m->message, m->info, !camel_exception_is_set(&mm->ex), m->data); } -static void -cleanup_append_mail (gpointer in_data, gpointer op_data, CamelException *ex) +static void append_mail_free(struct _mail_msg *mm) { - append_mail_input_t *input = (append_mail_input_t *) in_data; - - camel_object_unref (CAMEL_OBJECT (input->message)); - camel_object_unref (CAMEL_OBJECT (input->folder)); + struct _append_msg *m = (struct _append_msg *)mm; + + camel_object_unref((CamelObject *)m->message); + camel_object_unref((CamelObject *)m->folder); } -static const mail_operation_spec op_append_mail = { - describe_append_mail, - 0, - setup_append_mail, - do_append_mail, - cleanup_append_mail +static struct _mail_msg_op append_mail_op = { + append_mail_desc, + append_mail_append, + append_mail_appended, + append_mail_free }; void -mail_do_append_mail (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info) +mail_append_mail (CamelFolder *folder, + CamelMimeMessage *message, + CamelMessageInfo *info, + void (*done)(CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *info, int ok, void *data), void *data) { - append_mail_input_t *input; - + struct _append_msg *m; + g_return_if_fail (CAMEL_IS_FOLDER (folder)); g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - input = g_new (append_mail_input_t, 1); - input->folder = folder; - input->message = message; - input->info = info; - - mail_operation_queue (&op_append_mail, input, TRUE); + m = mail_msg_new(&append_mail_op, NULL, sizeof(*m)); + m->folder = folder; + camel_object_ref((CamelObject *)folder); + m->message = message; + camel_object_ref((CamelObject *)message); + m->info = info; + + m->done = done; + m->data = data; + + e_thread_put(mail_thread_new, (EMsg *)m); } /* ** TRANSFER MESSAGES **************************************************** */ -typedef struct transfer_messages_input_s -{ +struct _transfer_msg { + struct _mail_msg msg; + CamelFolder *source; GPtrArray *uids; - gboolean delete_from_source; - gchar *dest_uri; -} transfer_messages_input_t; - -static gchar * -describe_transfer_messages (gpointer in_data, gboolean gerund) -{ - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; - char *format; - - if (gerund) { - if (input->delete_from_source) - format = _("Moving messages from \"%s\" into \"%s\""); - else - format = _("Copying messages from \"%s\" into \"%s\""); - } else { - if (input->delete_from_source) - format = _("Move messages from \"%s\" into \"%s\""); - else - format = _("Copy messages from \"%s\" into \"%s\""); - } - - return g_strdup_printf (format, - mail_tool_get_folder_name (input->source), - input->dest_uri); -} + gboolean delete; + char *dest_uri; +}; -static void -setup_transfer_messages (gpointer in_data, gpointer op_data, - CamelException *ex) +static char *transfer_messages_desc(struct _mail_msg *mm, int done) { - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; + struct _transfer_msg *m = (struct _transfer_msg *)mm; - camel_object_ref (CAMEL_OBJECT (input->source)); + return g_strdup_printf(m->delete?_("Moving messages to %s"):_("Copying messages to %s"), + m->dest_uri); + } -static void -do_transfer_messages (gpointer in_data, gpointer op_data, CamelException *ex) +static void transfer_messages_transfer(struct _mail_msg *mm) { - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; + struct _transfer_msg *m = (struct _transfer_msg *)mm; CamelFolder *dest; - gint i; - time_t last_update = 0; - gchar *desc; + int i; + char *desc; void (*func) (CamelFolder *, const char *, CamelFolder *, CamelException *); - if (input->delete_from_source) { + if (m->delete) { func = camel_folder_move_message_to; desc = _("Moving"); } else { @@ -884,59 +839,45 @@ do_transfer_messages (gpointer in_data, gpointer op_data, CamelException *ex) desc = _("Copying"); } - dest = mail_tool_uri_to_folder (input->dest_uri, ex); - if (camel_exception_is_set (ex)) + dest = mail_tool_uri_to_folder (m->dest_uri, &mm->ex); + if (camel_exception_is_set (&mm->ex)) return; - mail_tool_camel_lock_up (); - camel_folder_freeze (input->source); + camel_folder_freeze (m->source); camel_folder_freeze (dest); - for (i = 0; i < input->uids->len; i++) { - 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 (_("%s message %d of %d (uid \"%s\")"), desc, - i + 1, input->uids->len, (char *) input->uids->pdata[i]); - last_update = now; - } - - (func) (input->source, - input->uids->pdata[i], dest, - ex); - g_free (input->uids->pdata[i]); - if (camel_exception_is_set (ex)) + for (i = 0; i < m->uids->len; i++) { + mail_statusf(_("%s message %d of %d (uid \"%s\")"), desc, + i + 1, m->uids->len, (char *)m->uids->pdata[i]); + + (func) (m->source, m->uids->pdata[i], dest, &mm->ex); + if (camel_exception_is_set (&mm->ex)) break; } - camel_folder_thaw (input->source); - camel_folder_thaw (dest); - camel_object_unref (CAMEL_OBJECT (dest)); - mail_tool_camel_lock_down (); + camel_folder_thaw(m->source); + camel_folder_thaw(dest); + camel_object_unref((CamelObject *)dest); } -static void -cleanup_transfer_messages (gpointer in_data, gpointer op_data, - CamelException *ex) +static void transfer_messages_free(struct _mail_msg *mm) { - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; + struct _transfer_msg *m = (struct _transfer_msg *)mm; + int i; + + camel_object_unref((CamelObject *)m->source); + g_free(m->dest_uri); + for (i=0;i<m->uids->len;i++) + g_free(m->uids->pdata[i]); + g_ptr_array_free(m->uids, TRUE); - camel_object_unref (CAMEL_OBJECT (input->source)); - g_free (input->dest_uri); - g_ptr_array_free (input->uids, TRUE); } -static const mail_operation_spec op_transfer_messages = { - describe_transfer_messages, - 0, - setup_transfer_messages, - do_transfer_messages, - cleanup_transfer_messages +static struct _mail_msg_op transfer_messages_op = { + transfer_messages_desc, + transfer_messages_transfer, + NULL, + transfer_messages_free, }; void @@ -944,19 +885,20 @@ mail_do_transfer_messages (CamelFolder *source, GPtrArray *uids, gboolean delete_from_source, gchar *dest_uri) { - transfer_messages_input_t *input; + struct _transfer_msg *m; g_return_if_fail (CAMEL_IS_FOLDER (source)); g_return_if_fail (uids != NULL); g_return_if_fail (dest_uri != NULL); - input = g_new (transfer_messages_input_t, 1); - input->source = source; - input->uids = uids; - input->delete_from_source = delete_from_source; - input->dest_uri = g_strdup (dest_uri); + m = mail_msg_new(&transfer_messages_op, NULL, sizeof(*m)); + m->source = source; + camel_object_ref((CamelObject *)source); + m->uids = uids; + m->delete = delete_from_source; + m->dest_uri = g_strdup (dest_uri); - mail_operation_queue (&op_transfer_messages, input, TRUE); + e_thread_put(mail_thread_queued, (EMsg *)m); } /* ** SCAN SUBFOLDERS ***************************************************** */ @@ -1561,82 +1503,6 @@ mail_get_messages(CamelFolder *folder, GPtrArray *uids, e_thread_put(mail_thread_new, (EMsg *)m); } - -/* dum de dum, below is an entirely async 'operation' thingy */ -struct _op_data { - void *out; - void *in; - CamelException *ex; - const mail_operation_spec *op; - int pipe[2]; - int free; - GIOChannel *channel; -}; - -static void * -runthread(void *oin) -{ - struct _op_data *o = oin; - - o->op->callback(o->in, o->out, o->ex); - - printf("thread run, sending notificaiton\n"); - - write(o->pipe[1], "", 1); - - return oin; -} - -static gboolean -runcleanup(GIOChannel *source, GIOCondition cond, void *d) -{ - struct _op_data *o = d; - - printf("got notification, blup\n"); - - o->op->cleanup(o->in, o->out, o->ex); - - /*close(o->pipe[0]);*/ - close(o->pipe[1]); - - if (o->free) - g_free(o->in); - g_free(o->out); - camel_exception_free(o->ex); - g_free(o); - - g_io_channel_unref(source); - - return FALSE; -} - -#include <pthread.h> - -/* quick hack, like queue, but it runs it instantly in a new thread ! */ -int -mail_operation_run(const mail_operation_spec *op, void *in, int free) -{ - struct _op_data *o; - pthread_t id; - - o = g_malloc0(sizeof(*o)); - o->op = op; - o->in = in; - o->out = g_malloc0(op->datasize); - o->ex = camel_exception_new(); - o->free = free; - pipe(o->pipe); - - o->channel = g_io_channel_unix_new(o->pipe[0]); - g_io_add_watch(o->channel, G_IO_IN, (GIOFunc)runcleanup, o); - - o->op->setup(o->in, o->out, o->ex); - - pthread_create(&id, 0, runthread, o); - - return TRUE; -} - /* ** SAVE MESSAGES ******************************************************* */ struct _save_messages_msg { diff --git a/mail/mail-ops.h b/mail/mail-ops.h index 3ef3239100..74a197cb56 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -30,16 +30,15 @@ #include "filter/filter-context.h" -#include "mail-threads.h" #include "evolution-storage.h" /*EvolutionStorage */ #include "e-util/e-msgport.h" /* utility functions */ FilterContext *mail_load_filter_context(void); -void mail_do_append_mail (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info); +void mail_append_mail (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info, + void (*done)(CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *info, int ok, void *data), void *data); + void mail_do_transfer_messages (CamelFolder *source, GPtrArray *uids, gboolean delete_from_source, gchar *dest_uri); diff --git a/mail/mail-threads.c b/mail/mail-threads.c deleted file mode 100644 index 8f0e263765..0000000000 --- a/mail/mail-threads.c +++ /dev/null @@ -1,1158 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Peter Williams (peterw@helixcode.com) - * - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> - -#include <string.h> -#include <errno.h> -#include <glib.h> - -#include <gal/widgets/e-gui-utils.h> - -#include "folder-browser-factory.h" - -#include "camel/camel-object.h" -#include "mail.h" -#include "mail-threads.h" - -#define DEBUG(p) g_print p - -/** - * A function and its userdata - **/ - -typedef struct closure_s -{ - gpointer in_data; - gboolean free_in_data; - gpointer op_data; - const mail_operation_spec *spec; - CamelException *ex; - gchar *infinitive; - gchar *gerund; -} -closure_t; - -/** - * A command issued through the compipe - **/ - -typedef struct com_msg_s -{ - enum com_msg_type_e { - STARTING, - -#if 0 - PERCENTAGE, - HIDE_PBAR, - SHOW_PBAR, -#endif - - MESSAGE, - PASSWORD, - ERROR, - FORWARD_EVENT, - FINISHED - } type; - - gfloat percentage; - gchar *message; - - closure_t *clur; - - /* Password stuff */ - gchar **reply; - gboolean secret; - gboolean *success; - - /* Event stuff */ - CamelObjectEventHookFunc event_hook; - CamelObject *event_obj; - gpointer event_event_data; - gpointer event_user_data; -} com_msg_t; - -/** - * Stuff needed for blocking - **/ - -typedef struct block_info_s { - GMutex *mutex; - GCond *cond; - gboolean val; -} block_info_t; - -#define BLOCK_INFO_INIT { NULL, NULL, FALSE } - -/** - * @dispatch_thread_started: gboolean that tells us whether - * the dispatch thread has been launched. - **/ - -static gboolean dispatch_thread_started = FALSE; - -/** - * @queue_len : the number of operations pending - * and being executed. - * - * Because camel is not thread-safe we work - * with the restriction that more than one mailbox - * cannot be accessed at once. Thus we cannot - * concurrently check mail and move messages, etc. - **/ - -static gint queue_len = 0; - -/** - * @main_compipe: The pipe through which the dispatcher communicates - * with the main thread for GTK+ calls - * - * @chan_reader: the GIOChannel that reads our pipe - * - * @MAIN_READER: the fd in our main pipe that.... reads! - * @MAIN_WRITER: the fd in our main pipe that.... writes! - */ - -#define MAIN_READER main_compipe[0] -#define MAIN_WRITER main_compipe[1] -#define DISPATCH_READER dispatch_compipe[0] -#define DISPATCH_WRITER dispatch_compipe[1] - -static int main_compipe[2] = { -1, -1 }; -static int dispatch_compipe[2] = { -1, -1 }; - -GIOChannel *chan_reader = NULL; - -/** - * @modal_block: a condition maintained so that the - * calling thread (the dispatch thread) blocks correctly - * until the user has responded to some kind of modal - * dialog boxy thing. - */ - -static block_info_t modal_block = BLOCK_INFO_INIT; - -/** - * @finish_block: A condition so that the dispatch thread - * blocks until the main thread has finished the cleanup. - **/ - -static block_info_t finish_block = BLOCK_INFO_INIT; - -/** - * @current_message: The current message for the status bar. - * @busy_status: Whether we are currently busy doing some async operation, - * for status bar purposes. - */ - -static char *current_message = NULL; -static gboolean busy = FALSE; - -/** - * Static prototypes - **/ - -static void ui_set_busy (void); - -static void ui_unset_busy (void); -static void ui_set_message (const char *message); -static void ui_unset_message (void); - -static void block_prepare (block_info_t *info); -static void block_wait (block_info_t *info); -static void block_hold (block_info_t *info); -static void block_release (block_info_t *info); - -static void *dispatch (void * data); -static void check_dispatcher (void); -static void check_compipes (void); -static gboolean read_msg (GIOChannel * source, GIOCondition condition, - gpointer userdata); - -static void show_error (com_msg_t * msg); - -static void get_password (com_msg_t * msg); -static void get_password_cb (gchar * string, gpointer data); - -static void cleanup_op (com_msg_t * msg); - -static closure_t *new_closure (const mail_operation_spec * spec, gpointer input, - gboolean free_in_data); -static void free_closure (closure_t *clur); - -/* Pthread code */ -/* FIXME: support other thread types!!!! */ - -#ifdef G_THREADS_IMPL_POSIX - -#include <pthread.h> - -/** - * @dispatch_thread: the pthread_t (when using pthreads, of - * course) representing our dispatcher routine. Never used - * except to make pthread_create happy - **/ - -static pthread_t dispatch_thread; - -/* FIXME: do we need to set any attributes for our thread? - * If so, we need to create a pthread_attr structure and - * fill it in somewhere. But the defaults should be good - * enough. - */ - -#elif defined( G_THREADS_IMPL_SOLARIS ) - -#include <thread.h> - -static thread_t dispatch_thread; - -#else /* no supported thread impl */ -void -f (void) -{ - Error_No_supported_thread_implementation_recognized (); - choke on this; -} -#endif - -static int -pipe_write (int fd, const void *buf, size_t count) -{ - size_t res; - - do { - res = write (fd, buf, count); - } - while (res == -1 && errno == EINTR); - - return res; -} - -static size_t -pipe_read (int fd, void *buf, size_t count) -{ - size_t res; - - do { - res = read (fd, buf, count); - } while (res == -1 && errno == EINTR); - - return res; -} - -/** - * mail_operation_queue: - * @spec: describes the operation to be performed - * @input: input data for the operation. - * - * Runs a mail operation asynchronously. If no other operation is running, - * we start another thread and call the callback in that thread. The function - * can then use the mail_op_ functions to perform limited UI returns, while - * the main UI is completely unlocked. - * - * If an async operation is going on when this function is called again, - * it waits for the currently executing operation to finish, then - * executes the callback function in another thread. - * - * Returns TRUE on success, FALSE on some sort of queueing error. - **/ - -gboolean -mail_operation_queue (const mail_operation_spec * spec, gpointer input, - gboolean free_in_data) -{ - closure_t *clur; - - g_assert (spec); - - clur = new_closure (spec, input, free_in_data); - - if (spec->setup) - (spec->setup) (clur->in_data, clur->op_data, clur->ex); - - if (camel_exception_is_set (clur->ex)) { - if (clur->ex->id != CAMEL_EXCEPTION_USER_CANCEL) { - GtkWidget *err_dialog; - gchar *msg; - - msg = - g_strdup_printf - (_("Error while preparing to %s:\n" "%s"), - clur->infinitive, - camel_exception_get_description (clur->ex)); - err_dialog = gnome_error_dialog (msg); - g_free (msg); - gnome_dialog_set_close (GNOME_DIALOG (err_dialog), - TRUE); - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - - g_warning ("Setup failed for `%s': %s", - clur->infinitive, - camel_exception_get_description (clur-> - ex)); - } - - free_closure (clur); - return FALSE; - } - - if (queue_len == 0) { - check_compipes (); - check_dispatcher (); - } /* else add self to queue */ - - pipe_write (DISPATCH_WRITER, clur, sizeof (closure_t)); - /* dispatch allocates a separate buffer - * to hold the closure; it's in the pipe and - * can safely be freed - */ - g_free (clur); - queue_len++; - return TRUE; -} - -#if 0 -/** - * mail_op_set_percentage: - * @percentage: the percentage that will be displayed in the progress bar - * - * Set the percentage of the progress bar for the currently executing operation. - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_set_percentage (gfloat percentage) -{ - com_msg_t msg; - - msg.type = PERCENTAGE; - msg.percentage = percentage; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -/** - * mail_op_hide_progressbar: - * - * Hide the progress bar in the status box - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_hide_progressbar (void) -{ - com_msg_t msg; - - msg.type = HIDE_PBAR; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -/** - * mail_op_show_progressbar: - * - * Show the progress bar in the status box - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_show_progressbar (void) -{ - com_msg_t msg; - - msg.type = SHOW_PBAR; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -#endif - -/** - * mail_op_set_message: - * @str: message - * - * Set the message displayed above the progress bar for the currently - * executing operation. - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -static void -set_message (gchar *str) -{ - com_msg_t msg; - - msg.type = MESSAGE; - msg.message = str; - - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -void -mail_op_set_message_plain (const gchar *str) -{ - set_message (g_strdup (str)); -} - -/** - * mail_op_set_message: - * @fmt: printf-style format string for the message - * @...: arguments to the format string - * - * Set the message displayed above the progress bar for the currently - * executing operation. - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_set_message (const gchar *fmt, ...) -{ - gchar *str; - va_list val; - - va_start (val, fmt); - str = g_strdup_vprintf (fmt, val); - va_end (val); - - set_message (str); -} - -/** - * mail_op_get_password: - * @prompt: the question put to the user - * @secret: whether the dialog box shold print stars when the user types - * @dest: where to store the reply - * - * Asks the user for a password (or string entry in general). Waits for - * the user's response. On success, returns TRUE and @dest contains the - * response. On failure, returns FALSE and @dest contains the error - * message. - **/ - -gboolean -mail_op_get_password (gchar * prompt, gboolean secret, gchar ** dest) -{ - com_msg_t msg; - gboolean result; - - msg.type = PASSWORD; - msg.secret = secret; - msg.message = prompt; - msg.reply = dest; - msg.success = &result; - - (*dest) = NULL; - - block_prepare (&modal_block); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - block_wait (&modal_block); - - return result; -} - -/** - * mail_op_error: - * @fmt: printf-style format string for the error - * @...: arguments to the format string - * - * Opens an error dialog for the currently executing operation. - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_error (gchar * fmt, ...) -{ - com_msg_t msg; - va_list val; - - va_start (val, fmt); - msg.type = ERROR; - msg.message = g_strdup_vprintf (fmt, val); - va_end (val); - - block_prepare (&modal_block); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - block_wait (&modal_block); -} - -/** - * mail_op_forward_event: - * - * Communicate a camel event over to the main thread. - **/ - -void -mail_op_forward_event (CamelObjectEventHookFunc func, CamelObject *o, - gpointer event_data, gpointer user_data) -{ - com_msg_t msg; - - msg.type = FORWARD_EVENT; - msg.event_hook = func; - msg.event_obj = o; - msg.event_event_data = event_data; - msg.event_user_data = user_data; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} -/** - * mail_operation_wait_for_finish: - * - * Waits for the currently executing async operations - * to finish executing - */ - -void -mail_operation_wait_for_finish (void) -{ - while (queue_len) - gtk_main_iteration (); - /* Sigh. Otherwise we deadlock upon exit. */ - GDK_THREADS_LEAVE (); -} - -/** - * mail_operations_are_executing: - * - * Returns TRUE if operations are being executed asynchronously - * when called, FALSE if not. - **/ - -gboolean -mail_operations_are_executing (void) -{ - return (queue_len > 0); -} - -/** - * mail_operations_terminate: - * - * Let the operations finish then terminate the dispatch thread - **/ - -void -mail_operations_terminate (void) -{ - closure_t clur; - - mail_operation_wait_for_finish(); - - memset (&clur, 0, sizeof (closure_t)); - clur.spec = NULL; - - /* DISPATCH_WRITER will only have been initialized if any - * calls have been made using the old thread system. - */ - if (DISPATCH_WRITER != -1) { - pipe_write (DISPATCH_WRITER, &clur, sizeof (closure_t)); - - close (DISPATCH_WRITER); - } - close (MAIN_READER); -} - -void -mail_operations_get_status (int *busy_return, - const char **message_return) -{ - *busy_return = busy; - *message_return = current_message; -} - -/* ** Static functions **************************************************** */ - -static void check_dispatcher (void) -{ - int res; - - if (dispatch_thread_started) - return; - -#if defined( G_THREADS_IMPL_POSIX ) - res = pthread_create (&dispatch_thread, NULL, - (void *) &dispatch, NULL); -#elif defined( G_THREADS_IMPL_SOLARIS ) - res = thr_create (NULL, 0, (void *) &dispatch, NULL, 0, &dispatch_thread); -#else /* no known impl */ - Error_No_thread_create_implementation (); - choke on this; -#endif - if (res != 0) { - g_warning ("Error launching dispatch thread!"); - /* FIXME: more error handling */ - } else - dispatch_thread_started = TRUE; -} - -/** - * check_compipes: - * - * Check and see if our pipe has been opened and open - * it if necessary. - **/ - -static void -check_compipes (void) -{ - if (MAIN_READER < 0) { - if (pipe (main_compipe) < 0) { - g_warning ("Call to pipe(2) failed!"); - - /* FIXME: better error handling. How do we react? */ - return; - } - - chan_reader = g_io_channel_unix_new (MAIN_READER); - g_io_add_watch (chan_reader, G_IO_IN, read_msg, NULL); - } - - if (DISPATCH_READER < 0) { - if (pipe (dispatch_compipe) < 0) { - g_warning ("Call to pipe(2) failed!"); - - /* FIXME: better error handling. How do we react? */ - return; - } - } -} - -/** - * dispatch: - * @clur: The operation to execute and its parameters - * - * Start a thread that executes the closure and exit - * it when done. - */ - -static void * -dispatch (void *unused) -{ - size_t len; - closure_t *clur; - com_msg_t msg; - - /* Let the compipes be created */ - sleep (1); - - while (1) { - clur = g_new (closure_t, 1); - len = pipe_read (DISPATCH_READER, clur, sizeof (closure_t)); - - if (len <= 0) - break; - - if (len != sizeof (closure_t)) { - g_warning ("dispatcher: Didn't read full message!"); - continue; - } - - if (clur->spec == NULL) - break; - - msg.type = STARTING; - msg.message = g_strdup (clur->gerund); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - - (clur->spec->callback) (clur->in_data, clur->op_data, clur->ex); - - if (camel_exception_is_set (clur->ex)) { - if (clur->ex->id != CAMEL_EXCEPTION_USER_CANCEL) { - g_warning ("Callback failed for `%s': %s", - clur->infinitive, - camel_exception_get_description (clur-> - ex)); - mail_op_error (_("Error while `%s':\n%s"), - clur->gerund, - camel_exception_get_description (clur-> - ex)); - } - } - - msg.type = FINISHED; - msg.clur = clur; - - /* Wait for the cleanup to finish before starting our next op */ - block_prepare (&finish_block); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - block_wait (&finish_block); - } - - close (DISPATCH_READER); - close (MAIN_WRITER); - -#ifdef G_THREADS_IMPL_POSIX - pthread_exit (0); -#elif defined( G_THREADS_IMPL_SOLARIS ) - thr_exit (NULL); -#else /* no known impl */ - Error_No_thread_exit_implemented (); - choke on this; -#endif - return NULL; - /*NOTREACHED*/ -} - -/** - * read_msg: - * @source: the channel that has data to read - * @condition: the reason we were called - * @userdata: unused - * - * A message has been recieved on our pipe; perform the appropriate - * action. - **/ - -static gboolean -read_msg (GIOChannel * source, GIOCondition condition, gpointer userdata) -{ - com_msg_t *msg; - guint size; - - msg = g_new0 (com_msg_t, 1); - - g_io_channel_read (source, (gchar *) msg, - sizeof (com_msg_t) / sizeof (gchar), &size); - - if (size != sizeof (com_msg_t)) { - g_warning (_("Incomplete message written on pipe!")); - msg->type = ERROR; - msg->message = - g_strdup (_ - ("Error reading commands from dispatching thread.")); - } - - /* This is very important, though I'm not quite sure why - * it is as we are in the main thread right now. - */ - - /*g_message ("DLG: IN: read_msg");*/ - - switch (msg->type) { - case STARTING: - DEBUG (("*** Message -- STARTING %s\n", msg->message)); - ui_set_busy (); - ui_set_message (msg->message); - g_free (msg->message); - break; -#if 0 - case PERCENTAGE: - DEBUG (("*** Message -- PERCENTAGE\n")); - g_warning ("PERCENTAGE operation unsupported"); - break; - case HIDE_PBAR: - DEBUG (("*** Message -- HIDE_PBAR\n")); - g_warning ("HIDE_PBAR operation unsupported"); - break; - case SHOW_PBAR: - DEBUG (("*** Message -- SHOW_PBAR\n")); - g_warning ("HIDE_PBAR operation unsupported"); - break; -#endif - - case MESSAGE: - DEBUG (("*** Message -- MESSAGE\n")); - ui_set_message (msg->message); - g_free (msg->message); - break; - - case PASSWORD: - DEBUG (("*** Message -- PASSWORD\n")); - g_assert (msg->reply); - g_assert (msg->success); - get_password (msg); - break; - - case ERROR: - DEBUG (("*** Message -- ERROR\n")); - show_error (msg); - break; - - /* Don't fall through; dispatch_func does the FINISHED - * call for us - */ - - case FORWARD_EVENT: - DEBUG (("*** Message -- FORWARD_EVENT %p\n", msg->event_hook)); - g_assert (msg->event_hook); - (msg->event_hook) (msg->event_obj, msg->event_event_data, msg->event_user_data); - break; - - case FINISHED: - DEBUG (("*** Message -- FINISH %s\n", msg->clur->gerund)); - cleanup_op (msg); - break; - - default: - g_warning (_("Corrupted message from dispatching thread?")); - break; - } - - /*g_message ("DLG: OUT: read_msg");*/ - g_free (msg); - - return TRUE; -} - -/** - * cleanup_op: - * - * Cleanup after a finished operation - **/ - -static void -cleanup_op (com_msg_t * msg) -{ - block_hold (&finish_block); - - /* Run the cleanup */ - - if (msg->clur->spec->cleanup) - (msg->clur->spec->cleanup) (msg->clur->in_data, - msg->clur->op_data, - msg->clur->ex); - - /* Tell the dispatch thread that it can start - * the next operation */ - - block_release (&finish_block); - - /* Print an exception if the cleanup caused one */ - - if (camel_exception_is_set (msg->clur->ex) && - msg->clur->ex->id != CAMEL_EXCEPTION_USER_CANCEL) { - g_warning ("Error on cleanup of `%s': %s", - msg->clur->infinitive, - camel_exception_get_description (msg->clur->ex)); - } - - free_closure (msg->clur); - queue_len--; - - ui_unset_busy (); - ui_unset_message (); -} - -/** - * show_error: - * - * Show the error dialog and wait for user OK - **/ - -static void -show_error (com_msg_t * msg) -{ - GtkWidget *err_dialog; - - /* Create the dialog */ - - err_dialog = gnome_error_dialog (msg->message); - g_free (msg->message); - - /* Stop the other thread until the user reacts */ - - ui_unset_busy (); - block_hold (&modal_block); - - /* Show the dialog. */ - - /* Do not GDK_THREADS_ENTER; we're inside the read_msg - * handler which takes care of this for us. Oh, if - * only GDK_THREADS_ENTER were recursive... - */ - - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - - /* Allow the other thread to proceed */ - - block_release (&modal_block); - ui_set_busy (); -} - -static void -focus_on_entry(GtkWidget *widget, gpointer user_data) -{ - if (GTK_IS_ENTRY(widget)) { - gtk_widget_grab_focus(widget); - } -} - -/** - * get_password: - * - * Ask for a password and put the answer in *(msg->reply) - **/ - -static void -get_password (com_msg_t * msg) -{ - GtkWidget *dialog; - int button; - - /* Create the dialog */ - - dialog = gnome_request_dialog (msg->secret, msg->message, NULL, - 0, get_password_cb, msg, NULL); - - /* Stop the other thread */ - - ui_unset_busy (); - block_hold (&modal_block); - - /* Show the dialog (or report an error) */ - - if (dialog == NULL) { - *(msg->success) = FALSE; - *(msg->reply) = g_strdup (_("Could not create dialog box.")); - button = -1; - } else { - e_container_foreach_leaf (GTK_CONTAINER (dialog), - focus_on_entry, NULL); - *(msg->reply) = NULL; - button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - } - - if (button == 1 || *(msg->reply) == NULL) { - *(msg->success) = FALSE; - *(msg->reply) = g_strdup (_("User cancelled query.")); - } else if (button >= 0) { - *(msg->success) = TRUE; - } - - /* Allow the other thread to proceed */ - - block_release (&modal_block); - ui_set_busy (); -} - -static void -get_password_cb (gchar * string, gpointer data) -{ - com_msg_t *msg = (com_msg_t *) data; - - if (string) - *(msg->reply) = g_strdup (string); - else - *(msg->reply) = NULL; -} - -static closure_t * -new_closure (const mail_operation_spec * spec, gpointer input, - gboolean free_in_data) -{ - closure_t *clur; - - clur = g_new0 (closure_t, 1); - clur->spec = spec; - clur->in_data = input; - clur->free_in_data = free_in_data; - clur->ex = camel_exception_new (); - - clur->op_data = g_malloc (spec->datasize); - - camel_exception_init (clur->ex); - - clur->infinitive = (spec->describe) (input, FALSE); - clur->gerund = (spec->describe) (input, TRUE); - - return clur; -} - -static void -free_closure (closure_t *clur) -{ - clur->spec = NULL; - - if (clur->free_in_data) - g_free (clur->in_data); - clur->in_data = NULL; - - g_free (clur->op_data); - clur->op_data = NULL; - - camel_exception_free (clur->ex); - clur->ex = NULL; - - g_free (clur->infinitive); - g_free (clur->gerund); - - g_free (clur); -} - -/* ******************** */ - -/** - * - * Thread A calls block_prepare - * Thread A causes thread B to do something - * Thread A calls block_wait - * Thread A continues when thread B calls block_release - * - * Thread B gets thread A's message - * Thread B calls block_hold - * Thread B does something - * Thread B calls block_release - * - **/ - -static void -block_prepare (block_info_t *info) -{ - if (info->cond == NULL) { - info->cond = g_cond_new (); - info->mutex = g_mutex_new (); - } - - g_mutex_lock (info->mutex); - info->val = FALSE; -} - -static void -block_wait (block_info_t *info) -{ - g_assert (info->cond); - - while (info->val == FALSE) - g_cond_wait (info->cond, info->mutex); - - g_mutex_unlock (info->mutex); -} -static void -block_hold (block_info_t *info) -{ - g_assert (info->cond); - - g_mutex_lock (info->mutex); - info->val = FALSE; -} - -static void -block_release (block_info_t *info) -{ - g_assert (info->cond); - - info->val = TRUE; - g_cond_signal (info->cond); - g_mutex_unlock (info->mutex); -} - -/* ******************** */ - -/* FIXME FIXME FIXME This is a totally evil hack. */ - -static GNOME_Evolution_ShellView -retrieve_shell_view_interface_from_control (BonoboControl *control) -{ - Bonobo_ControlFrame control_frame; - GNOME_Evolution_ShellView shell_view_interface; - CORBA_Environment ev; - - control_frame = bonobo_control_get_control_frame (control); - - if (control_frame == NULL) - return CORBA_OBJECT_NIL; - - CORBA_exception_init (&ev); - shell_view_interface = Bonobo_Unknown_queryInterface (control_frame, - "IDL:GNOME/Evolution/ShellView:1.0", - &ev); - CORBA_exception_free (&ev); - - if (shell_view_interface != CORBA_OBJECT_NIL) - gtk_object_set_data (GTK_OBJECT (control), - "mail_threads_shell_view_interface", - shell_view_interface); - else - g_warning ("Control frame doesn't have Evolution/ShellView."); - - return shell_view_interface; -} - -static void -update_active_views (void) -{ - EList *controls; - EIterator *it; - - controls = folder_browser_factory_get_control_list (); - for (it = e_list_get_iterator (controls); e_iterator_is_valid (it); e_iterator_next (it)) { - BonoboControl *control; - GNOME_Evolution_ShellView shell_view_interface; - CORBA_Environment ev; - - control = BONOBO_CONTROL (e_iterator_get (it)); - - shell_view_interface = gtk_object_get_data (GTK_OBJECT (control), "mail_threads_shell_view_interface"); - - if (shell_view_interface == CORBA_OBJECT_NIL) - shell_view_interface = retrieve_shell_view_interface_from_control (control); - - CORBA_exception_init (&ev); - - if (shell_view_interface != CORBA_OBJECT_NIL) { - if (current_message == NULL && ! busy) { - GNOME_Evolution_ShellView_unsetMessage (shell_view_interface, &ev); - } else { - if (current_message == NULL) - GNOME_Evolution_ShellView_setMessage (shell_view_interface, - "", - busy, - &ev); - else - GNOME_Evolution_ShellView_setMessage (shell_view_interface, - current_message, - busy, - &ev); - } - } - - CORBA_exception_free (&ev); - } - gtk_object_unref(GTK_OBJECT(it)); -} - -static void -ui_set_busy (void) -{ - busy = TRUE; - update_active_views (); -} - -static void -ui_unset_busy (void) -{ - busy = FALSE; - update_active_views (); -} - -static void -ui_set_message (const char *message) -{ - g_free (current_message); - current_message = g_strdup (message); - update_active_views (); -} - -static void -ui_unset_message (void) -{ - g_free (current_message); - current_message = NULL; - update_active_views (); -} diff --git a/mail/mail-threads.h b/mail/mail-threads.h deleted file mode 100644 index 83a78e782a..0000000000 --- a/mail/mail-threads.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Peter Williams (peterw@helixcode.com) - * - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _MAIL_THREADS_H_ -#define _MAIL_THREADS_H_ - -#include <camel/camel-exception.h> -#include <camel/camel-object.h> -#include <stdlib.h> /*size_t */ - -/* Returns a g_strdup'ed string that describes what's going to happen, - * tersely but specifically. - */ -typedef gchar *(*mail_op_describe_func) (gpointer /*input_data*/, gboolean /*gerund*/); -typedef void (*mail_op_func) (gpointer, gpointer, CamelException *); - -typedef struct _mail_operation_spec -{ - mail_op_describe_func describe; - size_t datasize; - mail_op_func setup; - mail_op_func callback; - mail_op_func cleanup; -} -mail_operation_spec; - -/* Schedule to operation to happen eventually */ - -gboolean mail_operation_queue (const mail_operation_spec * spec, - gpointer input, gboolean free_in_data); - -/* User interface hooks for the other thread */ - -#if 0 -void mail_op_set_percentage (gfloat percentage); -void mail_op_hide_progressbar (void); -void mail_op_show_progressbar (void); -#endif - -void mail_op_set_message_plain (const gchar *str); -void mail_op_set_message (const gchar *fmt, ...) G_GNUC_PRINTF (1, 2); -void mail_op_error (gchar * fmt, ...) G_GNUC_PRINTF (1, 2); -gboolean mail_op_get_password (gchar * prompt, gboolean secret, - gchar ** dest); -void mail_op_forward_event (CamelObjectEventHookFunc func, CamelObject *o, - gpointer event_data, gpointer user_data); -/* Wait for the async operations to finish */ -void mail_operation_wait_for_finish (void); -gboolean mail_operations_are_executing (void); -void mail_operations_terminate (void); - -void mail_operations_get_status (int *busy_return, const char **message_return); -void mail_operations_update_status (void); - -#endif /* defined _MAIL_THREADS_H_ */ diff --git a/mail/session.c b/mail/session.c index 8e8ff6e4bf..53c694206b 100644 --- a/mail/session.c +++ b/mail/session.c @@ -25,7 +25,6 @@ #include <gnome.h> #include "mail.h" #include "mail-session.h" -#include "mail-threads.h" #include "mail-mt.h" CamelSession *session; @@ -173,63 +172,54 @@ mail_session_remember_password (const char *url) /* ******************** */ -typedef struct _timeout_data_s { +struct _timeout_data { CamelTimeoutCallback cb; gpointer camel_data; gboolean result; -} timeout_data_t; - -static gchar * -describe_camel_timeout (gpointer in_data, gboolean gerund) -{ - /* FIXME this is so wrong */ +}; - if (gerund) - return g_strdup ("Keeping connection alive"); - else - return g_strdup ("Keep connection alive"); -} +struct _timeout_msg { + struct _mail_msg msg; -static void -noop_camel_timeout (gpointer in_data, gpointer op_data, CamelException *ex) -{ -} + CamelTimeoutCallback cb; + gpointer camel_data; +}; -static void -do_camel_timeout (gpointer in_data, gpointer op_data, CamelException *ex) +static void timeout_timeout(struct _mail_msg *mm) { - timeout_data_t *td = (timeout_data_t *) in_data; + struct _timeout_msg *m = (struct _timeout_msg *)mm; - td->result = (td->cb) (td->camel_data); + /* we ignore the callback result, do we care?? no. */ + m->cb(m->camel_data); } -static const mail_operation_spec spec_camel_timeout = -{ - describe_camel_timeout, - 0, - noop_camel_timeout, - do_camel_timeout, - noop_camel_timeout +static struct _mail_msg_op timeout_op = { + NULL, + timeout_timeout, + NULL, + NULL, }; static gboolean camel_timeout (gpointer data) { - timeout_data_t *td = (timeout_data_t *) data; + struct _timeout_data *td = data; + struct _timeout_msg *m; - if (td->result == FALSE) { - g_free (td); - return FALSE; - } + m = mail_msg_new(&timeout_op, NULL, sizeof(*m)); + + m->cb = td->cb; + m->camel_data = td->camel_data; + + e_thread_put(mail_thread_queued, (EMsg *)m); - mail_operation_queue (&spec_camel_timeout, td, FALSE); return TRUE; } static guint register_callback (guint32 interval, CamelTimeoutCallback cb, gpointer camel_data) { - timeout_data_t *td; + struct _timeout_data *td; /* We do this because otherwise the timeout can get called * more often than the dispatch thread can get rid of it, @@ -238,13 +228,12 @@ register_callback (guint32 interval, CamelTimeoutCallback cb, gpointer camel_dat */ g_return_val_if_fail (interval > 1000, 0); - td = g_new (timeout_data_t, 1); + td = g_malloc(sizeof(*td)); td->result = TRUE; td->cb = cb; td->camel_data = camel_data; - return gtk_timeout_add_full (interval, camel_timeout, NULL, - td, g_free); + return gtk_timeout_add_full(interval, camel_timeout, NULL, td, g_free); } static gboolean diff --git a/mail/subscribe-dialog.c b/mail/subscribe-dialog.c index 354fc0e780..4a6b773fb8 100644 --- a/mail/subscribe-dialog.c +++ b/mail/subscribe-dialog.c @@ -22,7 +22,7 @@ */ #include <config.h> -#include <gnome.h> + #include "subscribe-dialog.h" #include "e-util/e-html-utils.h" #include <gtkhtml/gtkhtml.h> @@ -44,8 +44,10 @@ #include "mail.h" #include "mail-tools.h" -#include "mail-threads.h" -#include "camel/camel.h" +#include "mail-mt.h" +#include "camel/camel-exception.h" +#include "camel/camel-store.h" +#include "camel/camel-session.h" #include "art/empty.xpm" #include "art/mark.xpm" @@ -158,83 +160,70 @@ typedef void (*SubscribeFolderCallback)(SubscribeDialog *sc, gboolean success, g /* ** GET STORE ******************************************************* */ -typedef struct get_store_input_s { +struct _get_store_msg { + struct _mail_msg msg; + SubscribeDialog *sc; - gchar *url; + char *url; SubscribeGetStoreCallback cb; gpointer cb_data; -} get_store_input_t; - -typedef struct get_store_data_s { CamelStore *store; -} get_store_data_t; +}; -static gchar * -describe_get_store (gpointer in_data, gboolean gerund) +static char *get_store_desc(struct _mail_msg *mm, int done) { - get_store_input_t *input = (get_store_input_t *) in_data; + struct _get_store_msg *m = (struct _get_store_msg *)mm; - if (gerund) { - return g_strdup_printf (_("Getting store for \"%s\""), input->url); - } - else { - return g_strdup_printf (_("Get store for \"%s\""), input->url); - } + return g_strdup_printf(_("Getting store for \"%s\""), m->url); } -static void -setup_get_store (gpointer in_data, gpointer op_data, CamelException *ex) +static void get_store_get(struct _mail_msg *mm) { + struct _get_store_msg *m = (struct _get_store_msg *)mm; + + m->store = camel_session_get_store (session, m->url, &mm->ex); } -static void -do_get_store (gpointer in_data, gpointer op_data, CamelException *ex) +static void get_store_got(struct _mail_msg *mm) { - get_store_input_t *input = (get_store_input_t *)in_data; - get_store_data_t *data = (get_store_data_t*)op_data; - - mail_tool_camel_lock_up (); - data->store = camel_session_get_store (session, input->url, ex); - mail_tool_camel_lock_down (); + struct _get_store_msg *m = (struct _get_store_msg *)mm; - if (camel_exception_is_set (ex)) - data->store = NULL; + m->cb(m->sc, m->store, m->cb_data); } -static void -cleanup_get_store (gpointer in_data, gpointer op_data, CamelException *ex) +static void get_store_free(struct _mail_msg *mm) { - get_store_input_t *input = (get_store_input_t *)in_data; - get_store_data_t *data = (get_store_data_t*)op_data; - - input->cb (input->sc, data->store, input->cb_data); + struct _get_store_msg *m = (struct _get_store_msg *)mm; - g_free (input->url); + if (m->store) + camel_object_unref((CamelObject *)m->store); + g_free(m->url); } -static const mail_operation_spec op_get_store = { - describe_get_store, - sizeof (get_store_data_t), - setup_get_store, - do_get_store, - cleanup_get_store +static struct _mail_msg_op get_store_op = { + get_store_desc, + get_store_get, + get_store_got, + get_store_free, }; static void subscribe_do_get_store (SubscribeDialog *sc, const char *url, SubscribeGetStoreCallback cb, gpointer cb_data) { - get_store_input_t *input; - + struct _get_store_msg *m; + int id; + g_return_if_fail (url != NULL); - - input = g_new (get_store_input_t, 1); - input->sc = sc; - input->url = g_strdup (url); - input->cb = cb; - input->cb_data = cb_data; - mail_operation_queue (&op_get_store, input, TRUE); - mail_operation_wait_for_finish (); + m = mail_msg_new(&get_store_op, NULL, sizeof(*m)); + m->sc = sc; + m->url = g_strdup(url); + m->cb = cb; + m->cb_data = cb_data; + + id = m->msg.seq; + e_thread_put(mail_thread_queued, (EMsg *)m); + mail_msg_wait(id); } /* ** SUBSCRIBE FOLDER ******************************************************* */ @@ -265,78 +254,46 @@ storage_tree_path (CamelFolderInfo *info) return path; } -typedef struct subscribe_folder_input_s { +/* ********************************************************************** */ +/* Subscribe folder */ + +struct _subscribe_msg { + struct _mail_msg msg; + SubscribeDialog *sc; CamelStore *store; - CamelFolderInfo *info; gboolean subscribe; SubscribeFolderCallback cb; gpointer cb_data; -} subscribe_folder_input_t; -typedef struct subscribe_folder_data_s { char *path; char *name; char *full_name; char *url; -} subscribe_folder_data_t; +}; -static gchar * -describe_subscribe_folder (gpointer in_data, gboolean gerund) +static char *subscribe_folder_desc(struct _mail_msg *mm, int done) { - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - - if (gerund) { - if (input->subscribe) - return g_strdup_printf - (_("Subscribing to folder \"%s\""), - input->info->name); - else - return g_strdup_printf - (_("Unsubscribing from folder \"%s\""), - input->info->name); - } else { - if (input->subscribe) - return g_strdup_printf (_("Subscribe to folder \"%s\""), - input->info->name); - else - return g_strdup_printf (_("Unsubscribe from folder \"%s\""), - input->info->name); - } -} + struct _subscribe_msg *m = (struct _subscribe_msg *)mm; -static void -setup_subscribe_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - subscribe_folder_data_t *data = (subscribe_folder_data_t *) op_data; - - data->path = storage_tree_path (input->info); - data->name = g_strdup (input->info->name); - data->full_name = g_strdup (input->info->full_name); - data->url = g_strdup (input->info->url); - - camel_object_ref (CAMEL_OBJECT (input->store)); - gtk_object_ref (GTK_OBJECT (input->sc)); + if (m->subscribe) + return g_strdup_printf(_("Subscribing to folder \"%s\""), m->name); + else + return g_strdup_printf(_("Unsubscribing to folder \"%s\""), m->name); } -static void -do_subscribe_folder (gpointer in_data, gpointer op_data, CamelException *ex) +static void subscribe_folder_subscribe(struct _mail_msg *mm) { - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - subscribe_folder_data_t *data = (subscribe_folder_data_t *) op_data; + struct _subscribe_msg *m = (struct _subscribe_msg *)mm; - mail_tool_camel_lock_up (); - if (input->subscribe) - camel_store_subscribe_folder (input->store, data->full_name, ex); + if (m->subscribe) + camel_store_subscribe_folder(m->store, m->full_name, &mm->ex); else - camel_store_unsubscribe_folder (input->store, data->full_name, ex); - mail_tool_camel_lock_down (); + camel_store_unsubscribe_folder(m->store, m->full_name, &mm->ex); } static void -recursive_add_folder (EvolutionStorage *storage, const char *path, - const char *name, const char *url) +recursive_add_folder (EvolutionStorage *storage, const char *path, const char *name, const char *url) { char *parent, *pname, *p; @@ -355,64 +312,71 @@ recursive_add_folder (EvolutionStorage *storage, const char *path, g_free (parent); } - evolution_storage_new_folder (storage, path, name, "mail", url, - name, FALSE); + evolution_storage_new_folder (storage, path, name, "mail", url, name, FALSE); } -static void -cleanup_subscribe_folder (gpointer in_data, gpointer op_data, - CamelException *ex) +static void subscribe_folder_subscribed(struct _mail_msg *mm) { - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - subscribe_folder_data_t *data = (subscribe_folder_data_t *) op_data; + struct _subscribe_msg *m = (struct _subscribe_msg *)mm; - if (!camel_exception_is_set (ex)) { - if (input->subscribe) - recursive_add_folder (input->sc->storage, - data->path, data->name, - data->url); + if (!camel_exception_is_set (&mm->ex)) { + if (m->subscribe) + recursive_add_folder(m->sc->storage, m->path, m->name, m->url); else - evolution_storage_removed_folder (input->sc->storage, data->path); + evolution_storage_removed_folder(m->sc->storage, m->path); } - if (input->cb) - input->cb (input->sc, !camel_exception_is_set (ex), input->cb_data); - - g_free (data->path); - g_free (data->name); - g_free (data->full_name); - g_free (data->url); + if (m->cb) + m->cb(m->sc, !camel_exception_is_set(&mm->ex), m->cb_data); +} + +static void subscribe_folder_free(struct _mail_msg *mm) +{ + struct _subscribe_msg *m = (struct _subscribe_msg *)mm; + + g_free(m->path); + g_free(m->name); + g_free(m->full_name); + g_free(m->url); - camel_object_unref (CAMEL_OBJECT (input->store)); - gtk_object_unref (GTK_OBJECT (input->sc)); + camel_object_unref((CamelObject *)m->store); + /* in wrong thread to do this? + gtk_object_unref (GTK_OBJECT (input->sc));*/ } -static const mail_operation_spec op_subscribe_folder = { - describe_subscribe_folder, - sizeof (subscribe_folder_data_t), - setup_subscribe_folder, - do_subscribe_folder, - cleanup_subscribe_folder +static struct _mail_msg_op subscribe_folder_op = { + subscribe_folder_desc, + subscribe_folder_subscribe, + subscribe_folder_subscribed, + subscribe_folder_free, }; static void subscribe_do_subscribe_folder (SubscribeDialog *sc, CamelStore *store, CamelFolderInfo *info, gboolean subscribe, SubscribeFolderCallback cb, gpointer cb_data) { - subscribe_folder_input_t *input; + struct _subscribe_msg *m; g_return_if_fail (CAMEL_IS_STORE (store)); g_return_if_fail (info); - - input = g_new (subscribe_folder_input_t, 1); - input->sc = sc; - input->store = store; - input->info = info; - input->subscribe = subscribe; - input->cb = cb; - input->cb_data = cb_data; - - mail_operation_queue (&op_subscribe_folder, input, TRUE); + + m = mail_msg_new(&subscribe_folder_op, NULL, sizeof(*m)); + m->sc = sc; + m->store = store; + camel_object_ref((CamelObject *)store); + m->subscribe = subscribe; + m->cb = cb; + m->cb_data = cb_data; + + m->path = storage_tree_path (info); + m->name = g_strdup (info->name); + m->full_name = g_strdup (info->full_name); + m->url = g_strdup (info->url); + + /* + gtk_object_ref (GTK_OBJECT (sc));*/ + + e_thread_put(mail_thread_new, (EMsg *)m); } @@ -871,10 +835,9 @@ store_cb (SubscribeDialog *sc, CamelStore *store, gpointer data) return; if (camel_store_supports_subscriptions (store)) { + camel_object_ref((CamelObject *)store); sc->store_list = g_list_prepend (sc->store_list, store); e_table_model_row_inserted (sc->store_model, 0); - } else { - camel_object_unref (CAMEL_OBJECT (store)); } } diff --git a/mail/subscribe-dialog.h b/mail/subscribe-dialog.h index 34267efafd..68cd8a4876 100644 --- a/mail/subscribe-dialog.h +++ b/mail/subscribe-dialog.h @@ -25,7 +25,7 @@ #define _SUBSCRIBE_DIALOG_H_ #include "mail-types.h" -#include "camel.h" +#include "camel/camel-store.h" #include <gtk/gtktable.h> #include <gal/e-table/e-tree-model.h> #include <bonobo/bonobo-control.h> |