From d8962e358761b10f60aea0afebeebd008b3c6104 Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Thu, 22 Jun 2000 13:42:25 +0000 Subject: Prettify the progress dialog a bit. svn path=/trunk/; revision=3689 --- mail/ChangeLog | 10 +++++++ mail/mail-ops.c | 79 +++++++++++++++++++++++++++++++++++++---------------- mail/mail-threads.c | 79 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 120 insertions(+), 48 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index 8d072f73aa..363bd9577b 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,13 @@ +2000-06-22 Peter Williams + + * mail-threads.c (various functions): Prettify the UI + so that the progress bar doesn't become all huge 'n stuff. + (mail_operation_try): Now save the operation's description, + so that we can display it later as the default message. + (read_msg): When the operation starts set the label to its + UI-friendly name. + (dispatch_func): Free the saved prettyname. + 2000-06-21 Christopher James Lahey * message-list.c: Removed an erroneous comment. diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 6f27acefd4..a6de2ae1cd 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -32,6 +32,7 @@ #include "filter/filter-editor.h" #include "filter/filter-driver.h" #include "widgets/e-table/e-table.h" +#include "mail-threads.h" /* FIXME: is there another way to do this? */ #include "Evolution.h" @@ -45,6 +46,7 @@ static void mail_exception_dialog (char *head, CamelException *ex, gpointer widget) { +#if 0 char *msg; GtkWindow *window = GTK_WINDOW (gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)); @@ -53,6 +55,9 @@ mail_exception_dialog (char *head, CamelException *ex, gpointer widget) camel_exception_get_description (ex)); gnome_error_dialog_parented (msg, window); g_free (msg); +#else + mail_op_error( "%s: %s", head, camel_exception_get_description( ex ) ); +#endif } static gboolean @@ -74,13 +79,16 @@ 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) +typedef struct rfm_s { FolderBrowser *fb; char *source_url; } rfm_t; + +static void +real_fetch_mail( gpointer user_data ); + +/* FIXME: provide status updates */ +static void +real_fetch_mail( gpointer user_data ) { - FolderBrowser *fb = FOLDER_BROWSER (user_data); + FolderBrowser *fb = NULL; CamelException *ex; CamelStore *store = NULL; CamelFolder *folder = NULL; @@ -89,24 +97,13 @@ 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; - } - + fb = ((rfm_t *) user_data)->fb; + url = ((rfm_t *) user_data)->source_url; path = CAMEL_SERVICE (fb->folder->parent_store)->url->path; ex = camel_exception_new (); + g_free( user_data ); + tmp_mbox = g_strdup_printf ("%s/movemail", path); /* If fetching mail from an mbox store, safely copy it to a @@ -121,7 +118,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) if (tmpfd == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Couldn't create temporary " + "Couldn't create temporary " "mbox: %s", g_strerror (errno)); mail_exception_dialog ("Unable to move mail", ex, fb); goto cleanup; @@ -137,7 +134,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) case -1: mail_exception_dialog ("Unable to move mail", ex, fb); /* FALL THROUGH */ - + case 0: goto cleanup; } @@ -269,6 +266,42 @@ 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; + + 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, info ); +} + struct post_send_data { CamelFolder *folder; diff --git a/mail/mail-threads.c b/mail/mail-threads.c index ebd2570570..d0a20ee2be 100644 --- a/mail/mail-threads.c +++ b/mail/mail-threads.c @@ -32,6 +32,13 @@ /* FIXME: support other thread types!!!! */ #define USE_PTHREADS +/* FIXME TODO: Do we need operations that don't get a progress window because + * they're quick, but we still want camel to be locked? We need some kind + * of flag to mail_operation_try, but then we also need some kind of monitor + * to open the window if it takes more than a second or something. That would + * probably entail another thread.... + */ + /** * A function and its userdata **/ @@ -39,6 +46,9 @@ typedef struct closure_s { void (*func)( gpointer ); gpointer data; + + gchar *prettyname; + /* gboolean gets_window; */ } closure_t; /** @@ -83,7 +93,8 @@ static GtkWidget *queue_window_progress = NULL; /** * @op_queue: The list of operations the are scheduled - * to proceed after the currently executing one. + * to proceed after the currently executing one. When + * only one operation is going, this is NULL. **/ static GSList *op_queue = NULL; @@ -93,6 +104,9 @@ static GSList *op_queue = NULL; * with the main thread for GTK+ calls * * @chan_reader: the GIOChannel that reads our pipe + * + * @READER: the fd in our pipe that.... reads! + * @WRITER: the fd in our pipe that.... writes! */ #define READER compipe[0] @@ -120,11 +134,17 @@ static void remove_next_pending( void ); /** * @dispatch_thread: the pthread_t (when using pthreads, of - * course) representing our dispatcher routine. + * 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? */ +/* 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. + */ #else /* defined USE_PTHREADS */ choke on this: no thread type defined @@ -136,9 +156,16 @@ choke on this: no thread type defined * @callback: the function to call in another thread to start the operation * @user_data: extra data passed to the callback * - * Waits for the currently executing operation to finished, then - * executes the callback function in another thread. Returns TRUE - * on success, FALSE on some sort of queueing error. + * 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 @@ -150,11 +177,13 @@ mail_operation_try( const gchar *description, void (*callback)( gpointer ), gpoi clur = g_new( closure_t, 1 ); clur->func = callback; clur->data = user_data; + clur->prettyname = g_strdup( description ); if( mail_operation_in_progress == FALSE ) { - /* We got the lock. Yippeee! This means that no operations - * are pending, either, so we'll create the queue window and - * show only the message and progress bar. + /* No operations are going on, none are pending. So + * we check to see if we're initialized (create the + * window and the pipes), and send off the operation + * on its merry way. */ mail_operation_in_progress = TRUE; @@ -177,10 +206,11 @@ mail_operation_try( const gchar *description, void (*callback)( gpointer ), gpoi GtkWidget *label; /* Zut. We already have an operation running. Well, - * queue ourselves up. */ - - /* Yes, prepend is faster. But we pop operations - * off the beginning later and that's a lot easier. + * queue ourselves up. + * + * Yes, g_slist_prepend is faster down here.. But we pop + * operations off the beginning of the list later and + * that's a lot faster. */ op_queue = g_slist_append( op_queue, clur ); @@ -189,7 +219,7 @@ mail_operation_try( const gchar *description, void (*callback)( gpointer ), gpoi label = gtk_label_new( description ); gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); gtk_box_pack_start( GTK_BOX( queue_window_pending ), label, - TRUE, TRUE, 2 ); + FALSE, TRUE, 2 ); /* If we want the next op to be on the bottom, uncomment this */ /* 1 = first on list always (0-based) */ @@ -337,22 +367,22 @@ create_queue_window( void ) vbox = gtk_vbox_new( FALSE, 4 ); - pending_vb = gtk_vbox_new( TRUE, 2 ); + pending_vb = gtk_vbox_new( FALSE, 2 ); queue_window_pending = pending_vb; pending_lb = gtk_label_new( _("Currently pending operations:") ); gtk_misc_set_alignment( GTK_MISC( pending_lb ), 0.0, 0.0 ); gtk_box_pack_start( GTK_BOX( pending_vb ), pending_lb, - TRUE, TRUE, 0 ); + FALSE, TRUE, 0 ); gtk_box_pack_start( GTK_BOX( vbox ), pending_vb, TRUE, TRUE, 4 ); /* FIXME: 'operation' is not the warmest cuddliest word. */ - progress_lb = gtk_label_new( _("Starting operation...") ); + progress_lb = gtk_label_new( "" ); queue_window_message = progress_lb; gtk_box_pack_start( GTK_BOX( vbox ), progress_lb, - TRUE, TRUE, 4 ); + FALSE, TRUE, 4 ); progress_bar = gtk_progress_bar_new(); queue_window_progress = progress_bar; @@ -362,7 +392,7 @@ create_queue_window( void ) gtk_progress_bar_set_bar_style( GTK_PROGRESS_BAR( progress_bar ), GTK_PROGRESS_CONTINUOUS ); gtk_box_pack_start( GTK_BOX( vbox ), progress_bar, - TRUE, TRUE, 4 ); + FALSE, TRUE, 4 ); gtk_container_add( GTK_CONTAINER( queue_window ), vbox ); } @@ -423,6 +453,7 @@ static void *dispatch_func( void *data ) closure_t *clur = (closure_t *) data; msg.type = STARTING; + msg.message = clur->prettyname; write( WRITER, &msg, sizeof( msg ) ); (clur->func)( clur->data ); @@ -430,6 +461,7 @@ static void *dispatch_func( void *data ) msg.type = FINISHED; write( WRITER, &msg, sizeof( msg ) ); + g_free( clur->prettyname ); g_free( data ); pthread_exit( 0 ); @@ -438,6 +470,8 @@ static void *dispatch_func( void *data ) /** * 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 @@ -468,8 +502,7 @@ static gboolean read_msg( GIOChannel *source, GIOCondition condition, gpointer u switch( msg.type ) { case STARTING: - gtk_label_set_text( GTK_LABEL( queue_window_message ), - _("Starting operation...") ); + gtk_label_set_text( GTK_LABEL( queue_window_message ), msg.message ); gtk_progress_bar_update( GTK_PROGRESS_BAR( queue_window_progress ), 0.0 ); break; case PERCENTAGE: @@ -559,8 +592,4 @@ static void remove_next_pending( void ) /* Hide it? */ if( g_list_next( children ) == NULL ) gtk_widget_hide( queue_window_pending ); - - /* FIXME: The window gets really messed up here */ - gtk_container_resize_children( GTK_CONTAINER( queue_window_pending ) ); - gtk_container_resize_children( GTK_CONTAINER( queue_window ) ); } -- cgit v1.2.3