From aa68bd85f17d3fecdcbcaa77f3957ba7bb6d559a Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Fri, 23 Jun 2000 19:07:01 +0000 Subject: Land most of the stuff to move fetch_mail, send_mail, expunge_folder, init_imap, and init_news to async operation. svn path=/trunk/; revision=3711 --- mail/ChangeLog | 35 ++++++- mail/component-factory.c | 98 +++++++++++++++--- mail/mail-ops.c | 263 ++++++++++++++++++++++++++++++++++------------- mail/mail-threads.c | 97 ++++++++++++++--- mail/main.c | 2 + mail/session.c | 21 ++++ 6 files changed, 415 insertions(+), 101 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index 503c0fda66..b1f961a6da 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -2,7 +2,40 @@ * component-factory.c: Include e-util/e-setup.h for the prototype of evolution_dir; prototype create_news_storage. - + (real_create_imap_storage, real_create_news_storage): New + functions moving the camel stuff into the async callback. + (create_imap_storage, create_news_storage): Chopped in + half to move camel stuff as above. + + * mail-ops.c: Include "mail-threads.h" for threading protos. + (real_fetch_mail, real_send_mail, real_expunge_folder): + New functions moving the camel stuff into the async callback. + (async_mail_exception_dialog): A version of mail_exception_dialog + to be called from the async handlers (just calls mail_op_error()) + (fetch_mail, expunge_folder, composer_send_cb): Cut in half to + move camel stuff as above. + (cleanup_send_mail): Clean up after the async real_send_mail + with the gtk_object_destroys et al. + + * mail-threads.c: Instead of hiding the progress bar, make it + zip back and forth constantly. + (progress_timeout): New func. Timeout called to make the pbar + shimmy. + (timeout_toggle): New func. Turn on and off the shimmy effect. + (check_cond): New func. Make sure that the GCond for modal + operation is initialized before mail_op_{error,get_password}. + (show_error_clicked, read_msg, get_password_clicked): Move + over to timeout_toggle. + (mail_op_error,mail_op_get_password): Add check_cond() call. + + * main.c: (main) Call g_thread_init. + + * session.c: Change auth_callback stuff over to assume that it's + being called async. Note: no real good way to tell if this is + the case or not. + (request_callback): ifdef'ed out + (evolution_auth_callback): Use mail_op_get_password. + 2000-06-22 Jeffrey Stedfast * folder-browser.c (folder_browser_load_folder): Now should diff --git a/mail/component-factory.c b/mail/component-factory.c index 60b11c6b38..a48ac18379 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -35,6 +35,7 @@ #include "evolution-shell-component.h" #include "folder-browser.h" #include "mail.h" /* YUCK FIXME */ +#include "mail-threads.h" #include "e-util/e-gui-utils.h" #include "e-util/e-setup.h" @@ -43,7 +44,9 @@ static void create_vfolder_storage (EvolutionShellComponent *shell_component); static void create_imap_storage (EvolutionShellComponent *shell_component); +static void real_create_imap_storage( gpointer user_data ); static void create_news_storage (EvolutionShellComponent *shell_component); +static void real_create_news_storage( gpointer user_data ); #ifdef USING_OAF #define COMPONENT_FACTORY_ID "OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" @@ -248,17 +251,18 @@ create_vfolder_storage (EvolutionShellComponent *shell_component) } } +struct create_info_s { + EvolutionStorage *storage; + char *source; +}; + static void create_imap_storage (EvolutionShellComponent *shell_component) { Evolution_Shell corba_shell; EvolutionStorage *storage; char *cpath, *source, *server, *p; - CamelStore *store; - CamelFolder *folder; - CamelException *ex; - GPtrArray *lsub; - int i, max; + struct create_info_s *ii; cpath = g_strdup_printf ("=%s/config=/mail/source", evolution_dir); source = gnome_config_get_string (cpath); @@ -295,7 +299,34 @@ create_imap_storage (EvolutionShellComponent *shell_component) /* save the storage for later */ gtk_object_set_data (GTK_OBJECT (shell_component), "e-storage", storage); - + + ii = g_new( struct create_info_s, 1 ); + ii->storage = storage; + ii->source = g_strdup( source ); + mail_operation_try( "Create IMAP Storage", real_create_imap_storage, g_free, ii ); + + /* Note the g_free as our cleanup function deleting the ii struct when we're done */ +} + +static void +real_create_imap_storage( gpointer user_data ) +{ + CamelException *ex; + EvolutionStorage *storage; + char *p, *source; + CamelStore *store; + CamelFolder *folder; + GPtrArray *lsub; + int i, max; + struct create_info_s *ii; + + ii = (struct create_info_s *) user_data; + storage = ii->storage; + source = ii->source; + + mail_op_hide_progressbar(); + mail_op_set_message( "Connecting to IMAP service..." ); + ex = camel_exception_new (); store = camel_session_get_store (session, source, ex); @@ -308,6 +339,8 @@ create_imap_storage (EvolutionShellComponent *shell_component) goto cleanup; } + mail_op_set_message( "Connected. Examining folders..." ); + folder = camel_store_get_root_folder (store, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { goto cleanup; @@ -326,10 +359,16 @@ create_imap_storage (EvolutionShellComponent *shell_component) path = g_strdup_printf ("/%s", (char *)lsub->pdata[i]); buf = g_strdup_printf ("%s/%s", source, path); g_print ("Adding %s\n", path); + + mail_op_set_message( "Adding %s", path ); + evolution_storage_new_folder (storage, path, "mail", buf, "description"); } cleanup: + g_free( ii->source ); + if( camel_exception_is_set( ex ) ) + mail_op_error( "%s", camel_exception_get_description( ex ) ); camel_exception_free (ex); } @@ -339,11 +378,7 @@ create_news_storage (EvolutionShellComponent *shell_component) Evolution_Shell corba_shell; EvolutionStorage *storage; char *cpath, *source, *server, *p; - CamelStore *store; - CamelFolder *folder; - CamelException *ex; - GPtrArray *lsub; - int i, max; + struct create_info_s *ni; cpath = g_strdup_printf ("=%s/config=/news/source", evolution_dir); source = gnome_config_get_string (cpath); @@ -375,7 +410,34 @@ create_news_storage (EvolutionShellComponent *shell_component) /* save the storage for later */ gtk_object_set_data (GTK_OBJECT (shell_component), "e-storage", storage); - + + ni = g_new( struct create_info_s, 1 ); + ni->storage = storage; + ni->source = g_strdup( source ); + mail_operation_try( "Create News Storage", real_create_news_storage, g_free, ni ); + + /* again note the g_free cleanup func */ +} + +static void +real_create_news_storage( gpointer user_data ) +{ + EvolutionStorage *storage; + char *source; + CamelStore *store; + CamelFolder *folder; + CamelException *ex; + GPtrArray *lsub; + int i, max; + struct create_info_s *ni; + + ni = (struct create_info_s *) user_data; + storage = ni->storage; + source = ni->source; + + mail_op_hide_progressbar(); + mail_op_set_message( "Connecting to news service..." ); + ex = camel_exception_new (); store = camel_session_get_store (session, source, ex); @@ -388,6 +450,8 @@ create_news_storage (EvolutionShellComponent *shell_component) goto cleanup; } + mail_op_set_message( "Connected. Examining folders..." ); + folder = camel_store_get_root_folder (store, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { goto cleanup; @@ -403,12 +467,16 @@ create_news_storage (EvolutionShellComponent *shell_component) path = g_strdup_printf ("/%s", (char *)lsub->pdata[i]); buf = g_strdup_printf ("%s%s", source, path); g_print ("Adding %s\n", path); + + mail_op_set_message( "Adding %s", path ); + + /* FIXME: should be s,"mail","news",? */ evolution_storage_new_folder (storage, path, "mail", buf, "description"); } cleanup: + g_free( ni->source ); + if( camel_exception_is_set( ex ) ) + mail_op_error( "%s", camel_exception_get_description( ex ) ); camel_exception_free (ex); } - - - diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 6f27acefd4..feddab24e2 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -27,6 +27,7 @@ #include #include #include "mail.h" +#include "mail-threads.h" #include "folder-browser.h" #include "e-util/e-setup.h" #include "filter/filter-editor.h" @@ -42,6 +43,36 @@ #include #endif +struct post_send_data { + CamelFolder *folder; + const char *uid; + guint32 flags; +}; + +typedef struct rfm_s { + FolderBrowser *fb; + char *source_url; +} rfm_t; + +typedef struct rsm_s { + EMsgComposer *composer; + CamelTransport *transport; + CamelMimeMessage *message; + const char *subject; + char *from; + struct post_send_data *psd; + gboolean ok; +} rsm_t; + +static void +real_fetch_mail( gpointer user_data ); + +static void +real_send_mail( gpointer user_data ); + +static void +cleanup_send_mail( gpointer userdata ); + static void mail_exception_dialog (char *head, CamelException *ex, gpointer widget) { @@ -55,6 +86,12 @@ mail_exception_dialog (char *head, CamelException *ex, gpointer widget) g_free (msg); } +static void +async_mail_exception_dialog (char *head, CamelException *ex, gpointer unused ) +{ + mail_op_error( "%s: %s", head, camel_exception_get_description( ex ) ); +} + static gboolean check_configured (void) { @@ -74,13 +111,11 @@ check_configured (void) return configured; } -/* FIXME: This is BROKEN! It fetches mail into whatever folder you're - * currently viewing. - */ void -fetch_mail (GtkWidget *button, gpointer user_data) +real_fetch_mail (gpointer user_data ) { - FolderBrowser *fb = FOLDER_BROWSER (user_data); + rfm_t *info; + FolderBrowser *fb = NULL; CamelException *ex; CamelStore *store = NULL; CamelFolder *folder = NULL; @@ -89,20 +124,9 @@ fetch_mail (GtkWidget *button, gpointer user_data) char *userrules, *systemrules; char *tmp_mbox = NULL, *source; - if (!check_configured ()) - return; - - path = g_strdup_printf ("=%s/config=/mail/source", evolution_dir); - url = gnome_config_get_string (path); - g_free (path); - if (!url) { - GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (fb), - GTK_TYPE_WINDOW); - - gnome_error_dialog_parented ("You have no remote mail source " - "configured", GTK_WINDOW (win)); - return; - } + info = (rfm_t *) user_data; + fb = info->fb; + url = info->source_url; path = CAMEL_SERVICE (fb->folder->parent_store)->url->path; ex = camel_exception_new (); @@ -123,7 +147,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "Couldn't create temporary " "mbox: %s", g_strerror (errno)); - mail_exception_dialog ("Unable to move mail", ex, fb); + async_mail_exception_dialog ("Unable to move mail", ex, fb ); goto cleanup; } close (tmpfd); @@ -135,7 +159,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) switch (camel_movemail (source, tmp_mbox, ex)) { case -1: - mail_exception_dialog ("Unable to move mail", ex, fb); + async_mail_exception_dialog ("Unable to move mail", ex, fb); /* FALL THROUGH */ case 0: @@ -146,7 +170,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) strrchr (tmp_mbox, '/') + 1, FALSE, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - mail_exception_dialog ("Unable to move mail", ex, fb); + async_mail_exception_dialog ("Unable to move mail", ex, fb); goto cleanup; } } else { @@ -154,20 +178,20 @@ fetch_mail (GtkWidget *button, gpointer user_data) store = camel_session_get_store (session, url, ex); if (!store) { - mail_exception_dialog ("Unable to get new mail", ex, fb); + async_mail_exception_dialog ("Unable to get new mail", ex, fb); goto cleanup; } camel_service_connect (CAMEL_SERVICE (store), ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_USER_CANCEL) - mail_exception_dialog ("Unable to get new mail", ex, fb); + async_mail_exception_dialog ("Unable to get new mail", ex, fb); goto cleanup; } sourcefolder = camel_store_get_folder (store, "inbox", FALSE, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - mail_exception_dialog ("Unable to get new mail", ex, fb); + async_mail_exception_dialog ("Unable to get new mail", ex, fb); goto cleanup; } @@ -183,7 +207,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) strrchr (tmp_mbox, '/') + 1, TRUE, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - mail_exception_dialog ("Unable to move mail", ex, fb); + async_mail_exception_dialog ("Unable to move mail", ex, fb); goto cleanup; } @@ -194,7 +218,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) printf("copying message %d to dest\n", i + 1); msg = camel_folder_get_message_by_uid (sourcefolder, uids->pdata[i], ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - mail_exception_dialog ("Unable to read message", ex, fb); + async_mail_exception_dialog ("Unable to read message", ex, fb); gtk_object_unref((GtkObject *)msg); gtk_object_unref((GtkObject *)sourcefolder); goto cleanup; @@ -202,7 +226,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) camel_folder_append_message (folder, msg, ex); if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - mail_exception_dialog ("Unable to write message", ex, fb); + async_mail_exception_dialog ("Unable to write message", ex, fb); gtk_object_unref((GtkObject *)msg); gtk_object_unref((GtkObject *)sourcefolder); goto cleanup; @@ -214,7 +238,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) camel_folder_free_uids (sourcefolder, uids); camel_folder_sync (sourcefolder, TRUE, ex); if (camel_exception_is_set (ex)) - mail_exception_dialog ("", ex, fb); + async_mail_exception_dialog ("", ex, fb); gtk_object_unref((GtkObject *)sourcefolder); } else { printf("we can search on this folder, performing search!\n"); @@ -226,7 +250,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) gnome_ok_dialog ("No new messages."); goto cleanup; } else if (camel_exception_is_set (ex)) { - mail_exception_dialog ("Unable to get new mail", ex, fb); + async_mail_exception_dialog ("Unable to get new mail", ex, fb); goto cleanup; } @@ -242,7 +266,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) g_free(systemrules); if (filter_driver_run(filter, folder, fb->folder) == -1) { - mail_exception_dialog ("Unable to get new mail", ex, fb); + async_mail_exception_dialog ("Unable to get new mail", ex, fb); goto cleanup; } @@ -269,12 +293,41 @@ fetch_mail (GtkWidget *button, gpointer user_data) camel_exception_free (ex); } +/* FIXME: This is BROKEN! It fetches mail into whatever folder you're + * currently viewing. + */ +void +fetch_mail (GtkWidget *button, gpointer user_data) +{ + char *path, *url = NULL; + rfm_t *info; + + if (!check_configured ()) + return; -struct post_send_data { - CamelFolder *folder; - const char *uid; - guint32 flags; -}; + path = g_strdup_printf ("=%s/config=/mail/source", evolution_dir); + url = gnome_config_get_string (path); + g_free (path); + + if (!url) { + GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), + GTK_TYPE_WINDOW); + + gnome_error_dialog_parented ("You have no remote mail source " + "configured", GTK_WINDOW (win)); + return; + } + + /* This must be dynamically allocated so as not to be clobbered + * when we return. Actually, making it static in the whole file + * would probably work. + */ + + info = g_new( rfm_t, 1 ); + info->fb = FOLDER_BROWSER( user_data ); + info->source_url = url; + mail_operation_try( _("Fetching mail"), real_fetch_mail, NULL, info ); +} static gboolean ask_confirm_for_empty_subject (EMsgComposer *composer) @@ -295,11 +348,84 @@ ask_confirm_for_empty_subject (EMsgComposer *composer) return FALSE; } +static void +real_send_mail( gpointer user_data ) +{ + rsm_t *info = (rsm_t *) user_data; + EMsgComposer *composer = NULL; + CamelTransport *transport = NULL; + CamelException *ex = NULL; + CamelMimeMessage *message = NULL; + const char *subject = NULL; + char *from = NULL; + struct post_send_data *psd = NULL; + + mail_op_hide_progressbar(); + mail_op_set_message( "Connecting to transport..." ); + + ex = camel_exception_new (); + composer = info->composer; + transport = info->transport; + message = info->message; + subject = info->subject; + from = info->from; + psd = info->psd; + + camel_mime_message_set_from (message, from); + camel_medium_add_header (CAMEL_MEDIUM (message), "X-Mailer", + "Evolution (Developer Preview)"); + camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); + + camel_service_connect (CAMEL_SERVICE (transport), ex); + + mail_op_set_message( "Connected. Sending..." ); + + if (!camel_exception_is_set (ex)) + camel_transport_send (transport, CAMEL_MEDIUM (message), ex); + + if (!camel_exception_is_set (ex)) { + mail_op_set_message( "Sent. Disconnecting..." ); + camel_service_disconnect (CAMEL_SERVICE (transport), ex); + } + + if (camel_exception_is_set (ex)) { + async_mail_exception_dialog ("Could not send message", ex, composer); + info->ok = FALSE; + } else { + if (psd) { + guint32 set; + + set = camel_folder_get_message_flags (psd->folder, + psd->uid, ex); + camel_folder_set_message_flags (psd->folder, psd->uid, + psd->flags, ~set, ex); + } + info->ok = TRUE; + + } + + camel_exception_free (ex); +} + +static void +cleanup_send_mail( gpointer userdata ) +{ + rsm_t *info = (rsm_t *) userdata; + + if( info->ok ) { + gtk_object_destroy (GTK_OBJECT (info->composer)); + } + + gtk_object_unref (GTK_OBJECT (info->message)); + g_free( info ); +} + static void composer_send_cb (EMsgComposer *composer, gpointer data) { static CamelTransport *transport = NULL; struct post_send_data *psd = data; + rsm_t *info; static char *from = NULL; const char *subject; CamelException *ex; @@ -356,32 +482,15 @@ composer_send_cb (EMsgComposer *composer, gpointer data) } } - camel_mime_message_set_from (message, from); - camel_medium_add_header (CAMEL_MEDIUM (message), "X-Mailer", - "Evolution (Developer Preview)"); - camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); - - camel_service_connect (CAMEL_SERVICE (transport), ex); - if (!camel_exception_is_set (ex)) - camel_transport_send (transport, CAMEL_MEDIUM (message), ex); - if (!camel_exception_is_set (ex)) - camel_service_disconnect (CAMEL_SERVICE (transport), ex); - if (camel_exception_is_set (ex)) - mail_exception_dialog ("Could not send message", ex, composer); - else { - if (psd) { - guint32 set; - - set = camel_folder_get_message_flags (psd->folder, - psd->uid, ex); - camel_folder_set_message_flags (psd->folder, psd->uid, - psd->flags, ~set, ex); - } - gtk_object_destroy (GTK_OBJECT (composer)); - } + info = g_new0( rsm_t, 1 ); + info->composer = composer; + info->transport = transport; + info->message = message; + info->subject = subject; + info->from = from; + info->psd = psd; - camel_exception_free (ex); - gtk_object_unref (GTK_OBJECT (message)); + mail_operation_try( "Send Message", real_send_mail, cleanup_send_mail, info ); } static void @@ -517,24 +626,34 @@ delete_msg (GtkWidget *button, gpointer user_data) e_table_select_row (E_TABLE (ml->etable), ml->selected_row + 1); } -void -expunge_folder (BonoboUIHandler *uih, void *user_data, const char *path) +static void real_expunge_folder( gpointer user_data ) { FolderBrowser *fb = FOLDER_BROWSER(user_data); CamelException ex; - if (fb->message_list->folder) { - camel_exception_init(&ex); + mail_op_hide_progressbar(); + mail_op_set_message( "Expunging %s...", fb->message_list->folder->full_name ); - camel_folder_expunge(fb->message_list->folder, &ex); + camel_exception_init(&ex); - /* FIXME: is there a better way to force an update? */ - /* FIXME: Folder should raise a signal to say its contents has changed ... */ - e_table_model_changed (fb->message_list->table_model); + camel_folder_expunge(fb->message_list->folder, &ex); - if (camel_exception_get_id (&ex) != CAMEL_EXCEPTION_NONE) { - mail_exception_dialog ("Unable to expunge deleted messages", &ex, fb); - } + /* FIXME: is there a better way to force an update? */ + /* FIXME: Folder should raise a signal to say its contents has changed ... */ + e_table_model_changed (fb->message_list->table_model); + + if (camel_exception_get_id (&ex) != CAMEL_EXCEPTION_NONE) { + async_mail_exception_dialog ("Unable to expunge deleted messages", &ex, fb); + } +} + +void +expunge_folder (BonoboUIHandler *uih, void *user_data, const char *path) +{ + FolderBrowser *fb = FOLDER_BROWSER(user_data); + + if (fb->message_list->folder) { + mail_operation_try( "Expunge Folder", real_expunge_folder, NULL, fb ); } } diff --git a/mail/mail-threads.c b/mail/mail-threads.c index 8dc6ef2d48..1df871719a 100644 --- a/mail/mail-threads.c +++ b/mail/mail-threads.c @@ -97,6 +97,14 @@ static GtkWidget *queue_window_pending = NULL; static GtkWidget *queue_window_message = NULL; static GtkWidget *queue_window_progress = NULL; +/** + * @progress_timeout_handle: the handle to our timer + * function so that we can remove it when the progress bar + * mode changes. + **/ + +static int progress_timeout_handle = -1; + /** * @op_queue: The list of operations the are scheduled * to proceed after the currently executing one. When @@ -146,6 +154,7 @@ static void create_queue_window( void ); static void dispatch( closure_t *clur ); static void *dispatch_func( void *data ); static void check_compipe( void ); +static void check_cond( void ); static gboolean read_msg( GIOChannel *source, GIOCondition condition, gpointer userdata ); static void remove_next_pending( void ); static void show_error( com_msg_t *msg ); @@ -153,6 +162,8 @@ static void show_error_clicked( void ); static void get_password( com_msg_t *msg ); static void get_password_cb( gchar *string, gpointer data ); static void get_password_clicked( GnomeDialog *dialog, gint button, gpointer user_data ); +static gboolean progress_timeout( gpointer data ); +static void timeout_toggle( gboolean active ); /* Pthread code */ /* FIXME: support other thread types!!!! */ @@ -183,7 +194,8 @@ choke on this: no thread type defined * mail_operation_try: * @description: A user-friendly string describing the operation. * @callback: the function to call in another thread to start the operation - * @cleanup: the function to call in the main thread when the callback is finished + * @cleanup: the function to call in the main thread when the callback is finished. + * NULL is allowed. * @user_data: extra data passed to the callback * * Runs a mail operation asynchronously. If no other operation is running, @@ -354,6 +366,8 @@ gboolean mail_op_get_password( gchar *prompt, gboolean secret, gchar **dest ) com_msg_t msg; gboolean result; + check_cond(); + msg.type = PASSWORD; msg.secret = secret; msg.message = prompt; @@ -388,7 +402,9 @@ void mail_op_error( gchar *fmt, ... ) { com_msg_t msg; va_list val; - + + check_cond(); + va_start( val, fmt ); msg.type = ERROR; msg.message = g_strdup_vprintf( fmt, val ); @@ -508,10 +524,18 @@ static void check_compipe( void ) chan_reader = g_io_channel_unix_new( READER ); g_io_add_watch( chan_reader, G_IO_IN, read_msg, NULL ); +} - /* Misc */ - modal_cond = g_cond_new(); +/** + * check_cond: + * + * See if our condition is initialized and do so if necessary + **/ +static void check_cond( void ) +{ + if( modal_cond == NULL ) + modal_cond = g_cond_new(); } /** @@ -610,11 +634,15 @@ static gboolean read_msg( GIOChannel *source, GIOCondition condition, gpointer u g_free( msg ); break; case HIDE_PBAR: - gtk_widget_hide( GTK_WIDGET( queue_window_progress ) ); + gtk_progress_set_activity_mode( GTK_PROGRESS( queue_window_progress ), TRUE ); + timeout_toggle( TRUE ); + g_free( msg ); break; case SHOW_PBAR: - gtk_widget_show( GTK_WIDGET( queue_window_progress ) ); + timeout_toggle( FALSE ); + gtk_progress_set_activity_mode( GTK_PROGRESS( queue_window_progress ), FALSE ); + g_free( msg ); break; case MESSAGE: @@ -716,8 +744,8 @@ static void show_error( com_msg_t *msg ) G_LOCK( modal_lock ); + timeout_toggle( FALSE ); modal_may_proceed = FALSE; - /*gnome_dialog_run_and_close( GNOME_DIALOG( err_dialog ) );*/ gtk_widget_show( GTK_WIDGET( err_dialog ) ); } @@ -731,6 +759,7 @@ static void show_error( com_msg_t *msg ) static void show_error_clicked( void ) { modal_may_proceed = TRUE; + timeout_toggle( TRUE ); g_cond_signal( modal_cond ); G_UNLOCK( modal_lock ); } @@ -763,7 +792,7 @@ static void get_password( com_msg_t *msg ) G_UNLOCK( modal_lock ); } else { *(msg->reply) = NULL; - /*ret = gnome_dialog_run_and_close( GNOME_DIALOG(dialog) );*/ + timeout_toggle( FALSE ); gtk_widget_show( GTK_WIDGET( dialog ) ); } } @@ -785,14 +814,56 @@ static void get_password_clicked( GnomeDialog *dialog, gint button, gpointer use if( button == 1 || *(msg->reply) == NULL ) { *(msg->success) = FALSE; *(msg->reply) = g_strdup( _("User cancelled query.") ); - goto done; - } - - *(msg->success) = TRUE; + } else + *(msg->success) = TRUE; - done: g_free( msg ); modal_may_proceed = TRUE; + timeout_toggle( TRUE ); g_cond_signal( modal_cond ); G_UNLOCK( modal_lock ); } + +/* NOT totally copied from gtk+/gtk/testgtk.c, really! */ + +static gboolean +progress_timeout (gpointer data) +{ + gfloat new_val; + GtkAdjustment *adj; + + adj = GTK_PROGRESS (data)->adjustment; + + new_val = adj->value + 1; + if (new_val > adj->upper) + new_val = adj->lower; + + gtk_progress_set_value (GTK_PROGRESS (data), new_val); + + return TRUE; +} + +/** + * timeout_toggle: + * + * Turn on and off our timeout to zip the progressbar along, + * protecting against recursion (Ie, call with TRUE twice + * in a row. + **/ + +static void +timeout_toggle( gboolean active ) +{ + if( (GTK_PROGRESS( queue_window_progress ))->activity_mode == 0 ) + return; + + if( active ) { + if( progress_timeout_handle < 0 ) + progress_timeout_handle = gtk_timeout_add( 80, progress_timeout, queue_window_progress ); + } else { + if( progress_timeout_handle >= 0 ) { + gtk_timeout_remove( progress_timeout_handle ); + progress_timeout_handle = -1; + } + } +} diff --git a/mail/main.c b/mail/main.c index c7e72bd69e..5332213147 100644 --- a/mail/main.c +++ b/mail/main.c @@ -66,6 +66,8 @@ main (int argc, char *argv []) bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR); textdomain (PACKAGE); + g_thread_init( NULL ); + init_corba (&argc, argv); init_bonobo (); gtkhtmllib_init (argc, argv); diff --git a/mail/session.c b/mail/session.c index 259a087377..09b1250cf1 100644 --- a/mail/session.c +++ b/mail/session.c @@ -9,11 +9,20 @@ #include #include #include "mail.h" +#include "mail-threads.h" #include "e-util/e-setup.h" CamelSession *session; GHashTable *passwords; +/* FIXME: Will this ever be called in a non-async + * manner? Better hope not, cause if that happens + * we deadlock.... + */ + +#define ASYNC_AUTH_CALLBACK + +#ifndef ASYNC_AUTH_CALLBACK static void request_callback (gchar *string, gpointer data) { @@ -24,13 +33,17 @@ request_callback (gchar *string, gpointer data) else *ans = NULL; } +#endif static char * evolution_auth_callback (CamelAuthCallbackMode mode, char *data, gboolean secret, CamelService *service, char *item, CamelException *ex) { +#ifndef ASYNC_AUTH_CALLBACK GtkWidget *dialog; +#endif + char *key, *ans; if (!passwords) @@ -66,6 +79,7 @@ evolution_auth_callback (CamelAuthCallbackMode mode, char *data, return g_strdup (ans); } +#ifndef ASYNC_AUTH_CALLBACK /* XXX parent window? */ dialog = gnome_request_dialog (secret, data, NULL, 0, request_callback, &ans, NULL); @@ -82,6 +96,13 @@ evolution_auth_callback (CamelAuthCallbackMode mode, char *data, g_free (key); return NULL; } +#else + if( mail_op_get_password( data, secret, &ans ) == FALSE ) { + camel_exception_set( ex, CAMEL_EXCEPTION_USER_CANCEL, ans ); + g_free( key ); + return NULL; + } +#endif g_hash_table_insert (passwords, key, g_strdup (ans)); return ans; -- cgit