aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog35
-rw-r--r--mail/component-factory.c98
-rw-r--r--mail/mail-ops.c263
-rw-r--r--mail/mail-threads.c97
-rw-r--r--mail/main.c2
-rw-r--r--mail/session.c21
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 <fejj@helixcode.com>
* 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 <errno.h>
#include <gnome.h>
#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 <sys/stat.h>
#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)
@@ -296,10 +349,83 @@ ask_confirm_for_empty_subject (EMsgComposer *composer)
}
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
@@ -98,6 +98,14 @@ 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
* only one operation is going, this is NULL.
@@ -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 <config.h>
#include <gnome.h>
#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;