aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog119
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/component-factory.c20
-rw-r--r--mail/folder-browser-factory.c2
-rw-r--r--mail/folder-browser.c168
-rw-r--r--mail/folder-browser.h15
-rw-r--r--mail/mail-callbacks.c65
-rw-r--r--mail/mail-local.c67
-rw-r--r--mail/mail-mt.c517
-rw-r--r--mail/mail-mt.h73
-rw-r--r--mail/mail-ops.c801
-rw-r--r--mail/mail-ops.h30
-rw-r--r--mail/mail-tools.c8
-rw-r--r--mail/main.c3
-rw-r--r--mail/session.c3
15 files changed, 1254 insertions, 639 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 5146dc2595..d25aabe89e 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,122 @@
+2001-01-02 Not Zed <NotZed@HelixCode.com>
+
+ * mail-callbacks.c (view_msg): Fix for mail_get_message change,
+ use queue thread.
+
+ * folder-browser.c (done_message_selected): Fix mail_Get_message
+ calls, use new thread.
+ (do_message_selected): "
+
+ * mail-ops.c (mail_get_message): Add a thread argument so callers
+ can specify which queue it executes on.
+
+ * mail-mt.c (mail_msg_free): Fix a free order problem.
+ (mail_msg_destroy): Call mail_msg_free to do the work.
+ (mail_msgport_replied): "
+ (mail_msgport_replied): Check/display errors if we get them.
+ (mail_msgport_received): If we have a describe function, say what
+ we're doing, also set busy/unbusy.
+ (mail_msgport_replied): Clear busy when we get a reply.
+ (mail_get_password): Unset busy.
+ (mail_msg_received): Set busy as we go.
+ (mail_msg_destroy): Unset busy when done.
+ (mail_status): Blah blah, new status interface, the other wans't
+ workable with the way the shell api works.
+
+2000-12-29 Not Zed <NotZed@HelixCode.com>
+
+ * folder-browser.c (do_message_selected): If we are reconfiguring,
+ just keep polling till we are done (yeah kinda shitty, but easy).
+ (folder_browser_set_uri): Clear reconfigure flag here. ick.
+ (got_folder): And here too.
+ (on_right_click): Remove locking.
+ (hide_sender): and here too.
+ (hide_subject): And here.
+ (on_right_click): If we are in reconfigure, then the whole menu is disabled.
+
+ * mail-mt.c (status_busy_timeout): Clear the status_busy_timeout_id.
+
+ * mail-local.c (local_storage_new_folder_cb): Made getting folders
+ completely synchronous. The shell expects it, and it was only
+ synchronous before by a sideeffect.
+ (do_reconfigure_folder): Remove locking stuff.
+ (do_reconfigure_folder): Use our own much simpler copying routine
+ than that stupid move_folder_contents thing.
+ (update_progress): Use mail_status_message() instead.
+ (do_reconfigure_folder): Set the reconfigure flag during
+ reconfigure & set busy flag.
+ (cleanup_reconfigure_folder): clear busy flag.
+
+ * mail-tools.c (mail_tool_uri_to_folder): Remove the tool_lock
+ stuff.
+ (mail_tool_uri_to_folder_noex): Clear exception on exit.
+ (mail_tool_move_folder_contents): Get rid of this really stupid
+ function that is only used in one place.
+
+ * component-factory.c (owner_set_cb): Use direct calls to get the
+ folders, as this code must run synchronous. Remove the event wait
+ stuff.
+
+ * mail-callbacks.c (edit_msg): Call mail_get_messages, and create
+ the composers ourself.
+ (do_edit_messages): get_messages callback, create the composers
+ and connect to signals we need.
+ (view_msg): Dont call do_view_messages, just call
+ mail_get_messge for each to get them in parallel.
+ (do_view_message): view a single message.
+
+ * mail-ops.c (mail_edit_messages): Just use mail_get_messages
+ for this operation. Removed the other async operation stuff.
+ Changed my mind, just removed entirely.
+ (mail_do_view_messages): Removed.
+ (mail_do_setup_folder): Removed.
+ (mail_do_scan_subfolders): Make this run synchronously, as every
+ caller expects it to (even if they didn't realise).
+
+2000-12-28 Not Zed <NotZed@HelixCode.com>
+
+ * mail-callbacks.c (send_queued_mail): Dont expunge the folder
+ here, but in send_queue, otherwise it might execute out of order.
+ (expunge_folder): Remove the talbe prechange stuff, and infact
+ references to the message_list folder, as we have our own folder.
+ Also, dont allow expunge if we're already expunging.
+ (expunged_folder): Clkear the expunging flag if we're finished.
+
+ * folder-browser-factory.c (control_deactivate): Likewise here.
+ Hrm, i thought this function required a callback, silly me.
+
+ * mail-tools.c (mail_tool_make_message_attachment): Remov e
+ locking.
+
+ * folder-browser.c (on_message_selected): Use a timeout handler so
+ we dont select immediately.
+ (folder_browser_set_uri): Changed to use mail_get_folder.
+ (got_folder): New callback called when get_folder is finished.
+ (folder_browser_destroy): Use new sync interface.
+
+ * mail-ops.c (mail_get_message): New function to asynchrounously
+ get a message.
+ : #define out mail_tool_camel_lock stuff entirely.
+ (mail_get_folder): New function to asynchrounously get a folder.
+ (mail_do_load_folder): Removed, replaced by more generic function
+ above.
+ (mail_do_display_message): Removed, replaced by the more generic
+ funciton get_message.
+ (mail_get_messages): New function to get a list of messages
+ asynchronously.
+ (mail_sync_folder): New interface to sync a folder async.
+ (mail_expunge_folder): New interface for expunging folder, with
+ callback.
+ (do_send_queue): Remove lock stuff, and expunge if (and only if)
+ successful, also sync the sent folder while we're at it.
+
+ * session.c (mail_session_request_dialog): Changed to use new
+ mail_get_password call.
+
+ * mail-mt.[ch]: New threading/interthread messaging framework.
+
+ * main.c (main): Init the message/thread system.
+
2001-01-02 Dan Winship <danw@helixcode.com>
* mail-format.c (mail_part_is_inline):
diff --git a/mail/Makefile.am b/mail/Makefile.am
index ceb3e957ca..559f6fcae4 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -68,6 +68,8 @@ evolution_mail_SOURCES = \
mail-local.h \
mail-mlist-magic.c \
mail-mlist-magic.h \
+ mail-mt.c \
+ mail-mt.h \
mail-ops.c \
mail-ops.h \
mail-search-dialogue.c \
diff --git a/mail/component-factory.c b/mail/component-factory.c
index c4abc1ca74..7e951261a2 100644
--- a/mail/component-factory.c
+++ b/mail/component-factory.c
@@ -118,6 +118,15 @@ create_folder (EvolutionShellComponent *shell_component,
mail_do_create_folder (listener, physical_uri, type);
}
+static struct {
+ char *name;
+ CamelFolder **folder;
+} standard_folders[] = {
+ { "Drafts", &drafts_folder },
+ { "Outbox", &outbox_folder },
+ { "Sent", &sent_folder },
+};
+
static void
owner_set_cb (EvolutionShellComponent *shell_component,
EvolutionShellClient *shell_client,
@@ -126,6 +135,7 @@ owner_set_cb (EvolutionShellComponent *shell_component,
{
GSList *sources;
GNOME_Evolution_Shell corba_shell;
+ int i;
g_print ("evolution-mail: Yeeeh! We have an owner!\n"); /* FIXME */
@@ -146,11 +156,11 @@ owner_set_cb (EvolutionShellComponent *shell_component,
mail_local_storage_startup (shell_client, evolution_dir);
- mail_do_setup_folder ("Drafts", &drafts_folder);
- mail_do_setup_folder ("Outbox", &outbox_folder);
- mail_do_setup_folder ("Sent", &sent_folder);
- /* Don't proceed until those _folder variables are valid. */
- mail_operation_wait_for_finish ();
+ for (i=0;i<sizeof(standard_folders)/sizeof(standard_folders[0]);i++) {
+ char *uri = g_strdup_printf ("file://%s/local/%s", evolution_dir, standard_folders[i].name);
+ *standard_folders[i].folder = mail_tool_uri_to_folder_noex(uri);
+ g_free(uri);
+ }
mail_session_enable_interaction (TRUE);
}
diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c
index 9f53050c3c..dba7207e81 100644
--- a/mail/folder-browser-factory.c
+++ b/mail/folder-browser-factory.c
@@ -191,7 +191,7 @@ control_deactivate (BonoboControl *control,
bonobo_ui_component_unset_container (uic);
if (fb->folder)
- mail_do_sync_folder (fb->folder);
+ mail_sync_folder (fb->folder, NULL, NULL);
}
static void
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index 5a94c91ba9..d3ed8c7cfb 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -65,7 +65,7 @@ folder_browser_destroy (GtkObject *object)
g_free (folder_browser->uri);
if (folder_browser->folder) {
- mail_do_sync_folder (folder_browser->folder);
+ mail_sync_folder (folder_browser->folder, NULL, NULL);
camel_object_unref (CAMEL_OBJECT (folder_browser->folder));
}
@@ -109,11 +109,53 @@ folder_browser_class_init (GtkObjectClass *object_class)
#define EQUAL(a,b) (strcmp (a,b) == 0)
+static void
+got_folder(char *uri, CamelFolder *folder, void *data)
+{
+ FolderBrowser *fb = data;
+
+ printf("got folder '%s' = %p\n", uri, folder);
+
+ if (fb->folder == folder)
+ goto done;
+
+ if (fb->folder)
+ camel_object_unref((CamelObject *)fb->folder);
+ g_free(fb->uri);
+ fb->uri = g_strdup(uri);
+ fb->folder = folder;
+
+ if (folder == NULL)
+ goto done;
+
+ camel_object_ref((CamelObject *)folder);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (fb->search->entry),
+ camel_folder_has_search_capability (folder));
+ gtk_widget_set_sensitive (GTK_WIDGET (fb->search->option),
+ camel_folder_has_search_capability (folder));
+ message_list_set_threaded(fb->message_list, mail_config_thread_list());
+ message_list_set_folder(fb->message_list, folder);
+done:
+ gtk_object_unref((GtkObject *)fb);
+
+ /* Sigh, i dont like this (it can be set in reconfigure folder),
+ but its just easier right now to do it this way */
+ fb->reconfigure = FALSE;
+}
+
gboolean
folder_browser_set_uri (FolderBrowser *folder_browser, const char *uri)
{
- if (*uri)
- mail_do_load_folder (folder_browser, uri);
+ if (uri && *uri) {
+ gtk_object_ref((GtkObject *)folder_browser);
+ mail_get_folder(uri, got_folder, folder_browser);
+ } else {
+ /* Sigh, i dont like this (it can be set in reconfigure folder),
+ but its just easier right now to do it this way */
+ folder_browser->reconfigure = FALSE;
+ }
+
return TRUE;
}
@@ -507,8 +549,6 @@ hide_subject(GtkWidget *w, FolderBrowser *fb)
GString *expr;
if (fb->mail_display->current_message) {
- /* need to lock for full life of const data */
- mail_tool_camel_lock_up();
subject = camel_mime_message_get_subject(fb->mail_display->current_message);
if (subject) {
subject = strip_re(subject);
@@ -522,7 +562,6 @@ hide_subject(GtkWidget *w, FolderBrowser *fb)
return;
}
}
- mail_tool_camel_lock_down();
}
}
@@ -534,8 +573,6 @@ hide_sender(GtkWidget *w, FolderBrowser *fb)
GString *expr;
if (fb->mail_display->current_message) {
- /* need to lock for full life of const data */
- mail_tool_camel_lock_up();
from = camel_mime_message_get_from(fb->mail_display->current_message);
if (camel_internet_address_get(from, 0, &real, &addr)) {
expr = g_string_new("(match-all (header-contains \"from\" ");
@@ -546,7 +583,6 @@ hide_sender(GtkWidget *w, FolderBrowser *fb)
g_string_free(expr, TRUE);
return;
}
- mail_tool_camel_lock_down();
}
}
@@ -559,7 +595,7 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
GPtrArray *uids;
int enable_mask = 0;
int last_item, i;
- char *mailing_list_name;
+ char *mailing_list_name = NULL;
char *subject_match = NULL, *from_match = NULL;
EPopupMenu filter_menu[] = {
@@ -618,6 +654,11 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
};
last_item = (sizeof (filter_menu) / sizeof (*filter_menu)) - 2;
+
+ if (fb->reconfigure) {
+ enable_mask = 0;
+ goto display_menu;
+ }
if (fb->folder != drafts_folder)
enable_mask |= 1;
@@ -629,7 +670,6 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
const char *subject, *real, *addr;
const CamelInternetAddress *from;
- mail_tool_camel_lock_up();
mailing_list_name = mail_mlist_magic_detect_list (fb->mail_display->current_message, NULL, NULL);
if ((subject = camel_mime_message_get_subject(fb->mail_display->current_message))
@@ -641,8 +681,6 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
&& camel_internet_address_get(from, 0, &real, &addr)
&& addr && addr[0])
from_match = g_strdup(addr);
-
- mail_tool_camel_lock_down();
}
/* get a list of uids */
@@ -655,9 +693,11 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
gboolean have_seen = FALSE;
gboolean have_unseen = FALSE;
- mail_tool_camel_lock_up();
for (i = 0; i < uids->len; i++) {
info = camel_folder_get_message_info (fb->folder, uids->pdata[i]);
+ if (info == NULL)
+ continue;
+
if (info->flags & CAMEL_MESSAGE_SEEN)
have_seen = TRUE;
else
@@ -673,7 +713,6 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
if (have_seen && have_unseen && have_deleted && have_undeleted)
break;
}
- mail_tool_camel_lock_down();
if (!have_unseen)
enable_mask |= 4;
@@ -685,6 +724,13 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
if (!have_deleted)
enable_mask |= 32;
}
+
+ /* free uids */
+ for (i = 0; i < uids->len; i++)
+ g_free (uids->pdata[i]);
+ g_ptr_array_free (uids, TRUE);
+
+display_menu:
/* generate the "Filter on Mailing List menu item name */
if (mailing_list_name == NULL) {
@@ -712,11 +758,6 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
if (fb->message_list->hidden == NULL)
enable_mask |= 128;
- /* free uids */
- for (i = 0; i < uids->len; i++)
- g_free (uids->pdata[i]);
- g_ptr_array_free (uids, TRUE);
-
e_popup_menu_run (menu, (GdkEventButton *)event, enable_mask, 0, fb);
g_free(filter_menu[last_item].name);
@@ -850,23 +891,94 @@ folder_browser_gui_init (FolderBrowser *fb)
gtk_widget_show (GTK_WIDGET (fb));
}
+/* mark the message seen if the current message still matches */
static gint
-mark_msg_seen (gpointer data)
+do_mark_seen (gpointer data)
{
- MessageList *ml = data;
+ FolderBrowser *fb = data;
+
+ if (fb->new_uid && fb->loaded_uid
+ && strcmp(fb->new_uid, fb->loaded_uid) == 0) {
+ camel_folder_set_message_flags(fb->folder, fb->new_uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
+ }
- if (!ml->cursor_uid)
- return FALSE;
-
- camel_folder_set_message_flags(ml->folder, ml->cursor_uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
return FALSE;
}
+/* callback when we have the message to display, after async loading it (see below) */
+/* if we have pending uid's, it means another was selected before we finished displaying
+ the last one - so we cycle through and start loading the pending one immediately now */
+static void done_message_selected(CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *data)
+{
+ FolderBrowser *fb = data;
+ int timeout = mail_config_mark_as_seen_timeout ();
+
+ if (folder != fb->folder)
+ return;
+
+ mail_display_set_message(fb->mail_display, (CamelMedium *)msg);
+
+ /* pain, if we have pending stuff, re-run */
+ if (fb->pending_uid) {
+ g_free(fb->loading_uid);
+ fb->loading_uid = fb->pending_uid;
+ fb->pending_uid = NULL;
+
+ mail_get_message(fb->folder, fb->loading_uid, done_message_selected, fb, mail_thread_new);
+ return;
+ }
+
+ g_free(fb->loaded_uid);
+ fb->loaded_uid = fb->loading_uid;
+ fb->loading_uid = NULL;
+
+ /* if we are still on the same message, do the 'idle read' thing */
+ if (fb->seen_id)
+ gtk_timeout_remove(fb->seen_id);
+
+ if (msg) {
+ if (timeout > 0)
+ fb->seen_id = gtk_timeout_add(timeout, do_mark_seen, fb);
+ else
+ do_mark_seen(fb);
+ }
+}
+
+/* ok we waited enough, display it anyway (see below) */
+static gboolean
+do_message_selected(FolderBrowser *fb)
+{
+ d(printf ("selecting uid %s (delayed)\n", fb->new_uid));
+
+ /* keep polling if we are busy */
+ if (fb->reconfigure)
+ return TRUE;
+
+ fb->loading_id = 0;
+
+ /* if we are loading, then set a pending, but leave the loading, coudl cancel here (?) */
+ if (fb->loading_uid) {
+ g_free(fb->pending_uid);
+ fb->pending_uid = g_strdup(fb->new_uid);
+ } else {
+ fb->loading_uid = g_strdup(fb->new_uid);
+ mail_get_message(fb->folder, fb->loading_uid, done_message_selected, fb, mail_thread_new);
+ }
+
+ return FALSE;
+}
+
+/* when a message is selected, wait a while before trying to display it */
static void
on_message_selected (MessageList *ml, const char *uid, FolderBrowser *fb)
{
- d(printf ("selecting uid %s\n", uid));
- mail_do_display_message (ml, fb->mail_display, uid, mark_msg_seen);
+ d(printf ("selecting uid %s (direct)\n", uid));
+ g_free(fb->new_uid);
+ fb->new_uid = g_strdup(uid);
+ if (fb->loading_id != 0)
+ gtk_timeout_remove(fb->loading_id);
+
+ fb->loading_id = gtk_timeout_add(100, (GtkFunction)do_message_selected, fb);
}
static void
diff --git a/mail/folder-browser.h b/mail/folder-browser.h
index 054d64b8c7..41d282b7e5 100644
--- a/mail/folder-browser.h
+++ b/mail/folder-browser.h
@@ -35,7 +35,20 @@ struct _FolderBrowser {
*/
char *uri;
CamelFolder *folder;
-
+
+ /* async loading stuff */
+ char *loading_uid;/* what uid am i loading now */
+ char *pending_uid; /* what uid should i load next */
+ char *new_uid; /* place to save the next uid during idle timeout */
+ char *loaded_uid; /* what we have loaded */
+ guint loading_id, seen_id;
+
+ /* a folder we are expunging, dont use other than to compare the pointer value */
+ CamelFolder *expunging;
+
+ /* set to true when we are reconfiguring stuff == can't do much else */
+ int reconfigure;
+
MessageList *message_list;
MailDisplay *mail_display;
GtkWidget *vpaned;
diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c
index 32104dba76..736bba530e 100644
--- a/mail/mail-callbacks.c
+++ b/mail/mail-callbacks.c
@@ -225,8 +225,6 @@ send_queued_mail (GtkWidget *widget, gpointer user_data)
}
mail_do_send_queue (outbox_folder, transport->url);
-
- mail_do_expunge_folder (outbox_folder);
}
void
@@ -655,6 +653,26 @@ mark_as_unseen (BonoboUIComponent *uih, void *user_data, const char *path)
{
flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_SEEN, 0);
}
+
+static void
+do_edit_messages(CamelFolder *folder, GPtrArray *uids, GPtrArray *messages, void *data)
+{
+ /*FolderBrowser *fb = data;*/
+ int i;
+
+ for (i=0; i<messages->len; i++) {
+ EMsgComposer *composer;
+
+ composer = e_msg_composer_new_with_message(messages->pdata[i]);
+ if (composer) {
+ gtk_signal_connect (GTK_OBJECT (composer), "send",
+ composer_send_cb, NULL);
+ gtk_signal_connect (GTK_OBJECT (composer), "postpone",
+ composer_postpone_cb, NULL);
+ gtk_widget_show (GTK_WIDGET (composer));
+ }
+ }
+}
void
edit_msg (GtkWidget *widget, gpointer user_data)
@@ -678,8 +696,7 @@ edit_msg (GtkWidget *widget, gpointer user_data)
uids = g_ptr_array_new ();
message_list_foreach (fb->message_list, enumerate_msg, uids);
- /* FIXME: do we need to pass the postpone callback too? */
- mail_do_edit_messages (fb->folder, uids, (GtkSignalFunc) composer_send_cb);
+ mail_get_messages(fb->folder, uids, do_edit_messages, fb);
}
static void
@@ -777,15 +794,24 @@ undelete_msg (GtkWidget *button, gpointer user_data)
flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_DELETED, 0);
}
+static void expunged_folder(CamelFolder *f, void *data)
+{
+ FolderBrowser *fb = data;
+
+ fb->expunging = NULL;
+}
+
void
expunge_folder (BonoboUIComponent *uih, void *user_data, const char *path)
{
FolderBrowser *fb = FOLDER_BROWSER(user_data);
-
- e_table_model_pre_change (fb->message_list->table_model);
-
- if (fb->message_list->folder)
- mail_do_expunge_folder (fb->message_list->folder);
+
+ if (fb->folder
+ && (fb->expunging == NULL
+ || fb->folder != fb->expunging)) {
+ fb->expunging = fb->folder;
+ mail_expunge_folder(fb->folder, expunged_folder, fb);
+ }
}
static void
@@ -969,18 +995,35 @@ configure_folder (BonoboUIComponent *uih, void *user_data, const char *path)
mail_local_reconfigure_folder(fb);
}
+static void
+do_view_message(CamelFolder *folder, char *uid, CamelMimeMessage *message, void *data)
+{
+ /*FolderBrowser *fb = data;*/
+ GtkWidget *view;
+
+ if (message) {
+ view = mail_view_create(folder, uid, message);
+ gtk_widget_show(view);
+ }
+}
+
void
view_msg (GtkWidget *widget, gpointer user_data)
{
FolderBrowser *fb = user_data;
GPtrArray *uids;
-
+ int i;
+
if (!fb->folder)
return;
uids = g_ptr_array_new ();
message_list_foreach (fb->message_list, enumerate_msg, uids);
- mail_do_view_messages (fb->folder, uids, fb);
+ for (i=0;i<uids->len;i++) {
+ mail_get_message(fb->folder, uids->pdata[i], do_view_message, fb, mail_thread_queued);
+ g_free(uids->pdata[i]);
+ }
+ g_ptr_array_free(uids, TRUE);
}
void
diff --git a/mail/mail-local.c b/mail/mail-local.c
index c86518e07a..bd322f505b 100644
--- a/mail/mail-local.c
+++ b/mail/mail-local.c
@@ -59,6 +59,7 @@
#include "mail-tools.h"
#include "mail-threads.h"
#include "folder-browser.h"
+#include "mail-mt.h"
#define d(x)
@@ -179,7 +180,7 @@ static void
update_progress(char *fmt, float percent)
{
if (fmt)
- mail_op_set_message ("%s", fmt);
+ mail_status(fmt);
/*mail_op_set_percentage (percent);*/
}
@@ -237,7 +238,8 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex)
CamelStore *fromstore = NULL, *tostore = NULL;
char *fromurl = NULL, *tourl = NULL;
CamelFolder *fromfolder = NULL, *tofolder = NULL;
-
+ GPtrArray *uids;
+ int i;
char *metapath;
char *tmpname;
CamelURL *url = NULL;
@@ -246,6 +248,11 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex)
d(printf("reconfiguring folder: %s to type %s\n", input->fb->uri, input->newtype));
+ mail_status_start(_("Reconfiguring folder"));
+
+ /* NOTE: This var is cleared by the folder_browser via the set_uri method */
+ input->fb->reconfigure = TRUE;
+
/* get the actual location of the mailbox */
url = camel_url_new(input->fb->uri, ex);
if (camel_exception_is_set(ex)) {
@@ -261,9 +268,7 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex)
if (input->fb->folder != NULL) {
update_progress(_("Closing current folder"), 0.0);
- mail_tool_camel_lock_up ();
camel_folder_sync(input->fb->folder, FALSE, ex);
- mail_tool_camel_lock_down ();
camel_object_unref (CAMEL_OBJECT (input->fb->folder));
input->fb->folder = NULL;
}
@@ -275,16 +280,12 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex)
d(printf("opening stores %s and %s\n", fromurl, tourl));
- mail_tool_camel_lock_up ();
fromstore = camel_session_get_store(session, fromurl, ex);
- mail_tool_camel_lock_down ();
if (camel_exception_is_set(ex))
goto cleanup;
- mail_tool_camel_lock_up ();
tostore = camel_session_get_store(session, tourl, ex);
- mail_tool_camel_lock_down ();
if (camel_exception_is_set(ex))
goto cleanup;
@@ -293,10 +294,8 @@ 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);
- mail_tool_camel_lock_up ();
camel_store_rename_folder(fromstore, meta->name, tmpname, ex);
if (camel_exception_is_set(ex)) {
- mail_tool_camel_lock_down ();
goto cleanup;
}
@@ -306,7 +305,6 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex)
/* try and recover ... */
camel_exception_clear (ex);
camel_store_rename_folder(fromstore, tmpname, meta->name, ex);
- mail_tool_camel_lock_down ();
goto cleanup;
}
@@ -323,16 +321,24 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex)
/* try and recover ... */
camel_exception_clear (ex);
camel_store_rename_folder(fromstore, tmpname, meta->name, ex);
- mail_tool_camel_lock_down ();
goto cleanup;
}
update_progress(_("Copying messages"), 0.0);
- mail_tool_move_folder_contents (fromfolder, tofolder, FALSE, 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_free_uids(fromfolder, uids);
+ goto cleanup;
+ }
+ }
+ camel_folder_free_uids(fromfolder, uids);
+ camel_folder_expunge(fromfolder, ex);
d(printf("delete old mbox ...\n"));
camel_store_delete_folder(fromstore, tmpname, ex);
- mail_tool_camel_lock_down ();
/* switch format */
g_free(meta->format);
@@ -380,6 +386,8 @@ cleanup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException
folder_browser_set_uri(input->fb, uri);
g_free(uri);
+ mail_status_end();
+
gtk_object_unref (GTK_OBJECT (input->fb));
g_free (input->newtype);
}
@@ -418,9 +426,6 @@ reconfigure_clicked(GnomeDialog *d, int button, reconfigure_folder_input_t *data
gnome_dialog_close(d);
}
-/* kills a very annoying warning */
-void local_reconfigure_folder(FolderBrowser *fb);
-
void
mail_local_reconfigure_folder(FolderBrowser *fb)
{
@@ -809,6 +814,7 @@ do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex)
if (meta->indexed)
flags |= CAMEL_STORE_FOLDER_BODY_INDEX;
local_folder->folder = camel_store_get_folder (store, meta->name, flags, ex);
+ printf("got folder exception %s\n", camel_exception_get_description(ex));
local_folder->last_unread = camel_folder_get_unread_message_count(local_folder->folder);
camel_object_unref (CAMEL_OBJECT (store));
free_metainfo (meta);
@@ -868,7 +874,32 @@ local_storage_new_folder_cb (EvolutionStorageListener *storage_listener,
local_folder->path = g_strdup (path);
local_folder->local_store = local_store;
camel_object_ref((CamelObject *)local_store);
- mail_operation_queue (&op_register_folder, local_folder, FALSE);
+
+ /* 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();
+
+ do_register_folder(local_folder, NULL, ex);
+ cleanup_register_folder(local_folder, NULL, ex);
+
+#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);
+ }
}
static void
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
new file mode 100644
index 0000000000..3441228ea4
--- /dev/null
+++ b/mail/mail-mt.c
@@ -0,0 +1,517 @@
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "e-util/e-msgport.h"
+#include <glib.h>
+#include <pthread.h>
+
+#include "mail-mt.h"
+
+#include <gtk/gtk.h>
+#include <libgnomeui/gnome-dialog-util.h>
+#include <libgnomeui/gnome-dialog.h>
+#include <libgnome/gnome-i18n.h>
+#include <gal/widgets/e-gui-utils.h>
+
+#include "folder-browser-factory.h"
+
+#define d(x)
+
+static void set_view_data(const char *current_message, int busy);
+
+static unsigned int mail_msg_seq;
+
+void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size)
+{
+ struct _mail_msg *msg;
+
+ msg = g_malloc0(size);
+ msg->ops = ops;
+ msg->seq = mail_msg_seq++;
+ msg->msg.reply_port = reply_port;
+ camel_exception_init(&msg->ex);
+
+ return msg;
+}
+
+void mail_msg_free(void *msg)
+{
+ struct _mail_msg *m = msg;
+
+ if (m->ops->destroy_msg)
+ m->ops->destroy_msg(m);
+ camel_exception_clear(&m->ex);
+ g_free(m);
+}
+
+void mail_msg_check_error(void *msg)
+{
+ struct _mail_msg *m = msg;
+ char *what = NULL;
+ char *text;
+ GnomeDialog *gd;
+
+ if (!camel_exception_is_set(&m->ex))
+ return;
+
+ if (m->ops->describe_msg)
+ what = m->ops->describe_msg(m, FALSE);
+
+ if (what)
+ text = g_strdup_printf(_("Error while '%s':\n%s"), what, camel_exception_get_description(&m->ex));
+ else
+ text = g_strdup_printf(_("Error while performing operation:\n%s"), camel_exception_get_description(&m->ex));
+
+ gd = (GnomeDialog *)gnome_error_dialog(text);
+ gnome_dialog_run_and_close(gd);
+ g_free(text);
+}
+
+EMsgPort *mail_gui_port;
+static GIOChannel *mail_gui_channel;
+EMsgPort *mail_gui_reply_port;
+static GIOChannel *mail_gui_reply_channel;
+
+/* a couple of global threads available */
+EThread *mail_thread_queued; /* for operations that can (or should) be queued */
+EThread *mail_thread_new; /* for operations that should run in a new thread each time */
+
+static gboolean
+mail_msgport_replied(GIOChannel *source, GIOCondition cond, void *d)
+{
+ EMsgPort *port = (EMsgPort *)d;
+ mail_msg_t *m;
+
+ while (( m = (mail_msg_t *)e_msgport_get(port))) {
+ if (m->ops->reply_msg)
+ m->ops->reply_msg(m);
+ mail_msg_check_error(m);
+ if (m->ops->describe_msg)
+ mail_status_end();
+ mail_msg_free(m);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+mail_msgport_received(GIOChannel *source, GIOCondition cond, void *d)
+{
+ EMsgPort *port = (EMsgPort *)d;
+ mail_msg_t *m;
+
+ while (( m = (mail_msg_t *)e_msgport_get(port))) {
+ if (m->ops->describe_msg) {
+ char *text = m->ops->describe_msg(m, FALSE);
+ mail_status_start(text);
+ g_free(text);
+ }
+ if (m->ops->receive_msg)
+ m->ops->receive_msg(m);
+ if (m->msg.reply_port)
+ e_msgport_reply((EMsg *)m);
+ else {
+ if (m->ops->reply_msg)
+ m->ops->reply_msg(m);
+ if (m->ops->describe_msg)
+ mail_status_end();
+ mail_msg_free(m);
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+mail_msg_destroy(EThread *e, EMsg *msg, void *data)
+{
+ mail_msg_t *m = (mail_msg_t *)msg;
+
+ if (m->ops->describe_msg)
+ mail_status_end();
+ mail_msg_free(m);
+}
+
+static void
+mail_msg_received(EThread *e, EMsg *msg, void *data)
+{
+ mail_msg_t *m = (mail_msg_t *)msg;
+
+ if (m->ops->describe_msg) {
+ char *text = m->ops->describe_msg(m, FALSE);
+ printf("message received at thread\n");
+ mail_status_start(text);
+ g_free(text);
+ }
+
+ if (m->ops->receive_msg)
+ m->ops->receive_msg(m);
+}
+
+void mail_msg_init(void)
+{
+ mail_gui_reply_port = e_msgport_new();
+ mail_gui_reply_channel = g_io_channel_unix_new(e_msgport_fd(mail_gui_reply_port));
+ g_io_add_watch(mail_gui_reply_channel, G_IO_IN, mail_msgport_replied, mail_gui_reply_port);
+
+ mail_gui_port = e_msgport_new();
+ mail_gui_channel = g_io_channel_unix_new(e_msgport_fd(mail_gui_port));
+ g_io_add_watch(mail_gui_channel, G_IO_IN, mail_msgport_received, mail_gui_port);
+
+ mail_thread_queued = e_thread_new(E_THREAD_QUEUE);
+ e_thread_set_msg_destroy(mail_thread_queued, mail_msg_destroy, 0);
+ e_thread_set_msg_received(mail_thread_queued, mail_msg_received, 0);
+ e_thread_set_reply_port(mail_thread_queued, mail_gui_reply_port);
+
+ mail_thread_new = e_thread_new(E_THREAD_NEW);
+ e_thread_set_msg_destroy(mail_thread_new, mail_msg_destroy, 0);
+ e_thread_set_msg_received(mail_thread_new, mail_msg_received, 0);
+ e_thread_set_reply_port(mail_thread_new, mail_gui_reply_port);
+}
+
+/* ********************************************************************** */
+
+struct _set_msg {
+ struct _mail_msg msg;
+ char *text;
+};
+
+/* locks */
+static pthread_mutex_t status_lock = PTHREAD_MUTEX_INITIALIZER;
+#define STATUS_BUSY_PENDING (2)
+
+#define MAIL_MT_LOCK(x) pthread_mutex_lock(&x)
+#define MAIL_MT_UNLOCK(x) pthread_mutex_unlock(&x)
+
+/* blah blah */
+
+#define STATUS_DELAY (5)
+
+static int status_depth;
+static int status_showing;
+static int status_shown;
+static char *status_message_next;
+static int status_message_clear;
+static int status_timeout_id;
+static int status_busy;
+
+struct _status_msg {
+ struct _mail_msg msg;
+ char *text;
+ int busy;
+};
+
+static gboolean
+status_timeout(void *data)
+{
+ char *msg;
+ int busy = 0;
+
+ d(printf("got status timeout\n"));
+
+ MAIL_MT_LOCK(status_lock);
+ if (status_message_next) {
+ d(printf("setting message to '%s' busy %d\n", status_message_next, status_busy));
+ msg = status_message_next;
+ status_message_next = NULL;
+ busy = status_depth > 0;
+ status_message_clear = 0;
+ MAIL_MT_UNLOCK(status_lock);
+
+ /* copy msg so we can set it outside the lock */
+ /* unset first is a hack to avoid the stack stuff that doesn't and can't work anyway */
+ if (status_shown)
+ set_view_data(NULL, FALSE);
+ status_shown = TRUE;
+ set_view_data(msg, busy);
+ g_free(msg);
+ return TRUE;
+ }
+
+ /* the delay-clear stuff doesn't work yet. Dont care ... */
+
+ status_showing = FALSE;
+ status_message_clear++;
+ if (status_message_clear >= STATUS_DELAY && status_depth==0) {
+ d(printf("clearing message, busy = %d\n", status_depth));
+ } else {
+ d(printf("delaying clear\n"));
+ MAIL_MT_UNLOCK(status_lock);
+ return TRUE;
+ }
+
+ status_timeout_id = 0;
+
+ MAIL_MT_UNLOCK(status_lock);
+
+ if (status_shown)
+ set_view_data(NULL, FALSE);
+ status_shown = FALSE;
+
+ return FALSE;
+}
+
+static void do_set_status(struct _mail_msg *mm)
+{
+ struct _status_msg *m = (struct _status_msg *)mm;
+
+ MAIL_MT_LOCK(status_lock);
+
+ if (status_timeout_id != 0)
+ gtk_timeout_remove(status_timeout_id);
+
+ status_timeout_id = gtk_timeout_add(500, status_timeout, 0);
+ status_message_clear = 0;
+
+ MAIL_MT_UNLOCK(status_lock);
+
+ /* the 'clear' stuff doesn't really work yet, but oh well,
+ this stuff here needs a little changing for it to work */
+ if (status_shown)
+ set_view_data(NULL, status_depth != 0);
+ status_shown = 0;
+
+ if (m->text) {
+ status_shown = 1;
+ set_view_data(m->text, status_depth != 0);
+ }
+}
+
+static void do_del_status(struct _mail_msg *mm)
+{
+ struct _status_msg *m = (struct _status_msg *)mm;
+
+ g_free(m->text);
+}
+
+struct _mail_msg_op set_status_op = {
+ NULL,
+ do_set_status,
+ NULL,
+ do_del_status,
+};
+
+/* start a new operation */
+void mail_status_start(const char *msg)
+{
+ struct _status_msg *m = NULL;
+
+ MAIL_MT_LOCK(status_lock);
+ status_depth++;
+ MAIL_MT_UNLOCK(status_lock);
+
+ if (msg == NULL || msg[0] == 0)
+ msg = _("Working");
+
+ m = mail_msg_new(&set_status_op, NULL, sizeof(*m));
+ m->text = g_strdup(msg);
+ m->busy = TRUE;
+
+ e_msgport_put(mail_gui_port, &m->msg.msg);
+}
+
+/* end it */
+void mail_status_end(void)
+{
+ struct _status_msg *m = NULL;
+
+ m = mail_msg_new(&set_status_op, NULL, sizeof(*m));
+ m->text = NULL;
+
+ MAIL_MT_LOCK(status_lock);
+ status_depth--;
+ m->busy = status_depth = 0;
+ MAIL_MT_UNLOCK(status_lock);
+
+ e_msgport_put(mail_gui_port, &m->msg.msg);
+}
+
+/* message during it */
+void mail_status(const char *msg)
+{
+ if (msg == NULL || msg[0] == 0)
+ msg = _("Working");
+
+ MAIL_MT_LOCK(status_lock);
+
+ g_free(status_message_next);
+ status_message_next = g_strdup(msg);
+
+ MAIL_MT_UNLOCK(status_lock);
+}
+
+void mail_statusf(const char *fmt, ...)
+{
+ va_list ap;
+ char *text;
+
+ va_start(ap, fmt);
+ text = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+ mail_status(text);
+ g_free(text);
+}
+
+/* ********************************************************************** */
+
+struct _pass_msg {
+ struct _mail_msg msg;
+ char *prompt;
+ int secret;
+ char *result;
+};
+
+/* libgnomeui's idea of an api/gui is very weird ... hence this dumb hack */
+static void focus_on_entry(GtkWidget *widget, void *user_data)
+{
+ if (GTK_IS_ENTRY(widget))
+ gtk_widget_grab_focus(widget);
+}
+
+static void pass_got(char *string, void *data)
+{
+ struct _pass_msg *m = data;
+
+ if (string)
+ m->result = g_strdup (string);
+}
+
+static void
+do_get_pass(struct _mail_msg *mm)
+{
+ struct _pass_msg *m = (struct _pass_msg *)mm;
+ GtkWidget *dialogue;
+
+ /* this api is just awful ... hence the hacks */
+ dialogue = gnome_request_dialog(m->secret, m->prompt, NULL,
+ 0, pass_got, m, NULL);
+ e_container_foreach_leaf((GtkContainer *)dialogue, focus_on_entry, NULL);
+
+ /* hrm, we can't run this async since the gui_port from which we're called
+ will reply to our message for us */
+ gnome_dialog_run_and_close((GnomeDialog *)dialogue);
+
+ /*gtk_widget_show(dialogue);*/
+}
+
+static void
+do_free_pass(struct _mail_msg *mm)
+{
+ /*struct _pass_msg *m = (struct _pass_msg *)mm;*/
+
+ /* the string is passed out so we dont need to free it */
+}
+
+struct _mail_msg_op get_pass_op = {
+ NULL,
+ do_get_pass,
+ NULL,
+ do_free_pass,
+};
+
+/* returns the password, or NULL if cancelled */
+char *
+mail_get_password(char *prompt, gboolean secret)
+{
+ char *ret;
+ struct _pass_msg *m, *r;
+ EMsgPort *pass_reply;
+
+ pass_reply = e_msgport_new();
+
+ m = mail_msg_new(&get_pass_op, pass_reply, sizeof(*m));
+
+ m->prompt = prompt;
+ m->secret = secret;
+
+ e_msgport_put(mail_gui_port, (EMsg *)m);
+ e_msgport_wait(pass_reply);
+ r = (struct _pass_msg *)e_msgport_get(pass_reply);
+
+ g_assert(r == m);
+
+ ret = m->result;
+
+ mail_msg_free(m);
+ e_msgport_destroy(pass_reply);
+
+ return ret;
+}
+
+
+
+/* ******************** */
+
+/* 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
+set_view_data(const char *current_message, int busy)
+{
+ 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 || current_message[0] == 0) && ! busy) {
+ printf("clearing msg\n");
+ GNOME_Evolution_ShellView_unsetMessage (shell_view_interface, &ev);
+ } else {
+ printf("setting msg %s\n", current_message);
+ GNOME_Evolution_ShellView_setMessage (shell_view_interface,
+ current_message?current_message:"",
+ busy,
+ &ev);
+ }
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* yeah we only set the first one. Why? Because it seems to leave
+ random ones lying around otherwise. Shrug. */
+ break;
+ }
+ gtk_object_unref(GTK_OBJECT(it));
+}
diff --git a/mail/mail-mt.h b/mail/mail-mt.h
new file mode 100644
index 0000000000..c98785660c
--- /dev/null
+++ b/mail/mail-mt.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Authors: Michael Zucchi <notzed@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_MT
+#define _MAIL_MT
+
+#include "camel/camel-exception.h"
+#include "e-util/e-msgport.h"
+
+typedef struct _mail_msg {
+ EMsg msg; /* parent type */
+ struct _mail_msg_op *ops; /* operation functions */
+ unsigned int seq; /* seq number for synchronisation */
+ CamelException ex; /* an initialised camel exception, upto the caller to use this */
+} mail_msg_t;
+
+/* callback functions for thread message */
+typedef struct _mail_msg_op {
+ char *(*describe_msg)(struct _mail_msg *msg, int complete);
+
+ void (*receive_msg)(struct _mail_msg *msg); /* message received */
+ void (*reply_msg)(struct _mail_msg *msg); /* message replied */
+ void (*destroy_msg)(struct _mail_msg *msg); /* finalise message */
+} mail_msg_op_t;
+
+/* setup ports */
+void mail_msg_init(void);
+
+/* allocate a new message */
+void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size);
+void mail_msg_free(void *msg);
+void mail_msg_check_error(void *msg);
+
+/* set the status-bar message */
+/* start/end a new op */
+void mail_status_start(const char *msg);
+void mail_status_end(void);
+/* set a status during an op */
+void mail_statusf(const char *fmt, ...);
+void mail_status(const char *msg);
+
+/* request a string/password */
+char *mail_get_password(char *prompt, gboolean secret);
+
+/* a message port that receives messages in the gui thread, used for sending port */
+extern EMsgPort *mail_gui_port;
+/* a message port that receives messages in the gui thread, used for the reply port */
+extern EMsgPort *mail_gui_reply_port;
+
+/* some globally available threads */
+extern EThread *mail_thread_queued; /* for operations that can (or should) be queued */
+extern EThread *mail_thread_new; /* for operations that should run in a new thread each time */
+
+#endif /* ! _MAIL_MT */
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 34ec1c6493..50464e1859 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -37,11 +37,15 @@
#include "folder-browser.h"
#include "e-util/e-html-utils.h"
+#include "mail-mt.h"
+
#define d(x) x
-/* temporary 'hack' */
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()
+
/* ** FETCH MAIL ********************************************************** */
typedef struct fetch_mail_input_s
@@ -123,7 +127,7 @@ mail_op_report_status (FilterDriver *driver, enum filter_status_t status, const
/* FIXME: make it work */
switch (status) {
case FILTER_STATUS_START:
- mail_op_set_message_plain (desc);
+ mail_status(desc);
break;
case FILTER_STATUS_END:
break;
@@ -753,8 +757,6 @@ do_send_queue (gpointer in_data, gpointer op_data, CamelException *ex)
for (i = 0; i < uids->len; i++) {
CamelMimeMessage *message;
- mail_tool_camel_lock_up ();
-
message = camel_folder_get_message (input->folder_queue, uids->pdata[i], ex);
if (camel_exception_is_set (ex))
break;
@@ -764,7 +766,6 @@ do_send_queue (gpointer in_data, gpointer op_data, CamelException *ex)
camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0);
xport = camel_session_get_transport (session, input->xport_uri, ex);
- mail_tool_camel_lock_down ();
if (camel_exception_is_set (ex))
break;
@@ -774,26 +775,20 @@ do_send_queue (gpointer in_data, gpointer op_data, CamelException *ex)
if (camel_exception_is_set (ex))
break;
- mail_tool_camel_lock_up ();
set = camel_folder_get_message_flags (input->folder_queue,
uids->pdata[i]);
camel_folder_set_message_flags (input->folder_queue,
uids->pdata[i],
CAMEL_MESSAGE_DELETED, ~set);
- mail_tool_camel_lock_down ();
-
+
/* now to save the message in Sent */
if (sent_folder) {
CamelMessageInfo *info;
- mail_tool_camel_lock_up ();
-
info = g_new0 (CamelMessageInfo, 1);
info->flags = CAMEL_MESSAGE_SEEN;
camel_folder_append_message (sent_folder, message, info, ex);
g_free (info);
-
- mail_tool_camel_lock_down ();
}
}
@@ -802,6 +797,12 @@ do_send_queue (gpointer in_data, gpointer op_data, CamelException *ex)
for (i = 0; i < uids->len; i++)
g_free (uids->pdata[i]);
g_ptr_array_free (uids, TRUE);
+
+ if (!camel_exception_is_set(ex))
+ camel_folder_expunge(input->folder_queue, NULL);
+
+ if (sent_folder)
+ camel_folder_sync(sent_folder, FALSE, NULL);
}
static void
@@ -930,56 +931,6 @@ mail_do_append_mail (CamelFolder *folder,
mail_operation_queue (&op_append_mail, input, TRUE);
}
-/* ** EXPUNGE FOLDER ****************************************************** */
-
-static gchar *
-describe_expunge_folder (gpointer in_data, gboolean gerund)
-{
- CamelFolder *f = CAMEL_FOLDER (in_data);
-
- if (gerund)
- return g_strdup_printf (_("Expunging \"%s\""), mail_tool_get_folder_name (f));
- else
- return g_strdup_printf (_("Expunge \"%s\""), mail_tool_get_folder_name (f));
-}
-
-static void
-setup_expunge_folder (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- camel_object_ref (CAMEL_OBJECT (in_data));
-}
-
-static void
-do_expunge_folder (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- mail_tool_camel_lock_up ();
- camel_folder_expunge (CAMEL_FOLDER (in_data), ex);
- mail_tool_camel_lock_down ();
-}
-
-static void
-cleanup_expunge_folder (gpointer in_data, gpointer op_data,
- CamelException *ex)
-{
- camel_object_unref (CAMEL_OBJECT (in_data));
-}
-
-static const mail_operation_spec op_expunge_folder = {
- describe_expunge_folder,
- 0,
- setup_expunge_folder,
- do_expunge_folder,
- cleanup_expunge_folder
-};
-
-void
-mail_do_expunge_folder (CamelFolder *folder)
-{
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
-
- mail_operation_queue (&op_expunge_folder, folder, FALSE);
-}
-
/* ** TRANSFER MESSAGES **************************************************** */
typedef struct transfer_messages_input_s
@@ -1286,6 +1237,8 @@ typedef struct scan_subfolders_op_s
}
scan_subfolders_op_t;
+static int scan_subfolders_done;
+
static gchar *
describe_scan_subfolders (gpointer in_data, gboolean gerund)
{
@@ -1382,6 +1335,8 @@ cleanup_scan_subfolders (gpointer in_data, gpointer op_data,
gtk_object_unref (GTK_OBJECT (input->storage));
camel_object_unref (CAMEL_OBJECT (input->store));
+
+ scan_subfolders_done = TRUE;
}
static const mail_operation_spec op_scan_subfolders = {
@@ -1400,15 +1355,25 @@ mail_do_scan_subfolders (CamelStore *store, EvolutionStorage *storage)
g_return_if_fail (CAMEL_IS_STORE (store));
g_return_if_fail (EVOLUTION_IS_STORAGE (storage));
+ scan_subfolders_done = FALSE;
+
input = g_new (scan_subfolders_input_t, 1);
input->store = store;
input->storage = storage;
mail_operation_queue (&op_scan_subfolders, input, TRUE);
+
+ /* Ok, so this must run synchrounously, sigh */
+ while (!scan_subfolders_done) {
+ gtk_main_iteration();
+ }
}
/* ** ATTACH MESSAGE ****************************************************** */
+#warning "mail_do_attach_message() isn't used anywhere? Remove after confirming"
+#if 0
+
typedef struct attach_message_input_s
{
EMsgComposer *composer;
@@ -1512,6 +1477,8 @@ mail_do_attach_message (CamelFolder *folder, const char *uid,
mail_operation_queue (&op_attach_message, input, TRUE);
}
+#endif
+
/* ** FORWARD MESSAGES **************************************************** */
typedef struct forward_messages_input_s {
@@ -1734,100 +1701,66 @@ mail_do_forward_message (CamelMimeMessage *basis,
/* ** LOAD FOLDER ********************************************************* */
-typedef struct load_folder_input_s
-{
- FolderBrowser *fb;
- gchar *url;
-}
-load_folder_input_t;
+struct _get_folder_msg {
+ struct _mail_msg msg;
-static gchar *
-describe_load_folder (gpointer in_data, gboolean gerund)
-{
- load_folder_input_t *input = (load_folder_input_t *) in_data;
+ char *uri;
+ CamelFolder *folder;
+ void (*done) (char *uri, CamelFolder *folder, void *data);
+ void *data;
+};
- if (gerund) {
- return g_strdup_printf (_("Loading \"%s\""), input->url);
- } else {
- return g_strdup_printf (_("Load \"%s\""), input->url);
- }
+static char *get_folder_desc(struct _mail_msg *mm, int done)
+{
+ struct _get_folder_msg *m = (struct _get_folder_msg *)mm;
+
+ return g_strdup_printf(_("Opening folder %s"), m->uri);
}
-static void
-setup_load_folder (gpointer in_data, gpointer op_data, CamelException *ex)
+static void get_folder_get(struct _mail_msg *mm)
{
- load_folder_input_t *input = (load_folder_input_t *) in_data;
-
- gtk_object_ref (GTK_OBJECT (input->fb));
-
- if (input->fb->uri)
- g_free (input->fb->uri);
+ struct _get_folder_msg *m = (struct _get_folder_msg *)mm;
- input->fb->uri = input->url;
+ m->folder = mail_tool_uri_to_folder(m->uri, &mm->ex);
}
-static void
-do_load_folder (gpointer in_data, gpointer op_data, CamelException *ex)
+static void get_folder_got(struct _mail_msg *mm)
{
- load_folder_input_t *input = (load_folder_input_t *) in_data;
-
- CamelFolder *folder;
+ struct _get_folder_msg *m = (struct _get_folder_msg *)mm;
- folder = mail_tool_uri_to_folder (input->url, ex);
- if (!folder)
- return;
-
- if (input->fb->folder) {
- mail_tool_camel_lock_up ();
- camel_object_unref (CAMEL_OBJECT (input->fb->folder));
- mail_tool_camel_lock_down ();
- }
+ /* FIXME: what to do when it fails? */
- input->fb->folder = folder;
+ if (m->done)
+ m->done(m->uri, m->folder, m->data);
}
-static void
-cleanup_load_folder (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- load_folder_input_t *input = (load_folder_input_t *) in_data;
-
- if (input->fb->folder) {
- gtk_widget_set_sensitive (GTK_WIDGET (input->fb->search->entry),
- camel_folder_has_search_capability (input->
- fb->
- folder));
- gtk_widget_set_sensitive (GTK_WIDGET (input->fb->search->option),
- camel_folder_has_search_capability (input->
- fb->
- folder));
- message_list_set_threaded(input->fb->message_list, mail_config_thread_list());
- message_list_set_folder (input->fb->message_list, input->fb->folder);
- }
+static void get_folder_free(struct _mail_msg *mm)
+{
+ struct _get_folder_msg *m = (struct _get_folder_msg *)mm;
- gtk_object_unref (GTK_OBJECT (input->fb));
+ g_free(m->uri);
+ if (m->folder)
+ camel_object_unref((CamelObject *)m->folder);
}
-static const mail_operation_spec op_load_folder = {
- describe_load_folder,
- 0,
- setup_load_folder,
- do_load_folder,
- cleanup_load_folder
+static struct _mail_msg_op get_folder_op = {
+ get_folder_desc,
+ get_folder_get,
+ get_folder_got,
+ get_folder_free,
};
void
-mail_do_load_folder (FolderBrowser *fb, const char *url)
+mail_get_folder(const char *uri, void (*done) (char *uri, CamelFolder *folder, void *data), void *data)
{
- load_folder_input_t *input;
-
- g_return_if_fail (IS_FOLDER_BROWSER (fb));
- g_return_if_fail (url != NULL);
+ struct _get_folder_msg *m;
- input = g_new (load_folder_input_t, 1);
- input->fb = fb;
- input->url = g_strdup (url);
+ m = mail_msg_new(&get_folder_op, NULL, sizeof(*m));
+ m->uri = g_strdup(uri);
+ m->data = data;
+ m->done = done;
- mail_operation_queue (&op_load_folder, input, TRUE);
+ e_thread_put(mail_thread_new, (EMsg *)m);
}
/* ** CREATE FOLDER ******************************************************* */
@@ -1940,186 +1873,238 @@ mail_do_create_folder (const GNOME_Evolution_ShellComponentListener listener,
mail_operation_queue (&op_create_folder, input, FALSE);
}
-
/* ** SYNC FOLDER ********************************************************* */
-static gchar *
-describe_sync_folder (gpointer in_data, gboolean gerund)
+struct _sync_folder_msg {
+ struct _mail_msg msg;
+
+ CamelFolder *folder;
+ void (*done) (CamelFolder *folder, void *data);
+ void *data;
+};
+
+static void sync_folder_sync(struct _mail_msg *mm)
{
- CamelFolder *f = CAMEL_FOLDER (in_data);
+ struct _sync_folder_msg *m = (struct _sync_folder_msg *)mm;
- if (gerund) {
- return g_strdup_printf (_("Synchronizing \"%s\""), mail_tool_get_folder_name (f));
- } else {
- return g_strdup_printf (_("Synchronize \"%s\""), mail_tool_get_folder_name (f));
- }
+ camel_folder_sync(m->folder, FALSE, &mm->ex);
}
-static void
-setup_sync_folder (gpointer in_data, gpointer op_data, CamelException *ex) {
- camel_object_ref (CAMEL_OBJECT (in_data));
+static void sync_folder_synced(struct _mail_msg *mm)
+{
+ struct _sync_folder_msg *m = (struct _sync_folder_msg *)mm;
+
+ if (m->done)
+ m->done(m->folder, m->data);
}
-static void
-do_sync_folder (gpointer in_data, gpointer op_data, CamelException *ex)
+static void sync_folder_free(struct _mail_msg *mm)
{
- mail_tool_camel_lock_up ();
- camel_folder_sync (CAMEL_FOLDER (in_data), FALSE, ex);
- mail_tool_camel_lock_down ();
+ struct _sync_folder_msg *m = (struct _sync_folder_msg *)mm;
+
+ camel_object_unref((CamelObject *)m->folder);
}
-static void
-cleanup_sync_folder (gpointer in_data, gpointer op_data, CamelException *ex)
+static struct _mail_msg_op sync_folder_op = {
+ NULL,
+ sync_folder_sync,
+ sync_folder_synced,
+ sync_folder_free,
+};
+
+void
+mail_sync_folder(CamelFolder *folder, void (*done) (CamelFolder *folder, void *data), void *data)
{
- camel_object_unref (CAMEL_OBJECT (in_data));
+ struct _sync_folder_msg *m;
+
+ m = mail_msg_new(&sync_folder_op, NULL, sizeof(*m));
+ m->folder = folder;
+ camel_object_ref((CamelObject *)folder);
+ m->data = data;
+ m->done = done;
+
+ e_thread_put(mail_thread_new, (EMsg *)m);
}
-static const mail_operation_spec op_sync_folder = {
- describe_sync_folder,
- 0,
- setup_sync_folder,
- do_sync_folder,
- cleanup_sync_folder
+/* ******************************************************************************** */
+
+static void expunge_folder_expunge(struct _mail_msg *mm)
+{
+ struct _sync_folder_msg *m = (struct _sync_folder_msg *)mm;
+
+ camel_folder_expunge(m->folder, &mm->ex);
+}
+
+/* we just use the sync stuff where we can, since it would be the same */
+static struct _mail_msg_op expunge_folder_op = {
+ NULL,
+ expunge_folder_expunge,
+ sync_folder_synced,
+ sync_folder_free,
};
void
-mail_do_sync_folder (CamelFolder *folder)
+mail_expunge_folder(CamelFolder *folder, void (*done) (CamelFolder *folder, void *data), void *data)
{
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ struct _sync_folder_msg *m;
- /*mail_operation_queue (&op_sync_folder, folder, FALSE);*/
- mail_operation_run (&op_sync_folder, folder, FALSE);
+ m = mail_msg_new(&expunge_folder_op, NULL, sizeof(*m));
+ m->folder = folder;
+ camel_object_ref((CamelObject *)folder);
+ m->data = data;
+ m->done = done;
+
+ e_thread_put(mail_thread_new, (EMsg *)m);
}
-/* ** DISPLAY MESSAGE ***************************************************** */
+/* ** GET MESSAGE(s) ***************************************************** */
+
+struct _get_message_msg {
+ struct _mail_msg msg;
-typedef struct display_message_input_s
+ CamelFolder *folder;
+ char *uid;
+ void (*done) (CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *data);
+ void *data;
+ CamelMimeMessage *message;
+};
+
+static char *get_message_desc(struct _mail_msg *mm, int done)
{
- MessageList *ml;
- MailDisplay *md;
- gchar *uid;
- gint (*timeout) (gpointer);
+ struct _get_message_msg *m = (struct _get_message_msg *)mm;
+
+ return g_strdup_printf(_("Retrieving message %s"), m->uid);
}
-display_message_input_t;
-typedef struct display_message_data_s
+static void get_message_get(struct _mail_msg *mm)
{
- CamelMimeMessage *msg;
+ struct _get_message_msg *m = (struct _get_message_msg *)mm;
+
+ m->message = camel_folder_get_message(m->folder, m->uid, &mm->ex);
}
-display_message_data_t;
-static gchar *
-describe_display_message (gpointer in_data, gboolean gerund)
+static void get_message_got(struct _mail_msg *mm)
{
- display_message_input_t *input = (display_message_input_t *) in_data;
+ struct _get_message_msg *m = (struct _get_message_msg *)mm;
- if (gerund) {
- if (input->uid)
- return g_strdup_printf (_("Displaying message UID \"%s\""),
- input->uid);
- else
- return g_strdup (_("Clearing message display"));
- } else {
- if (input->uid)
- return g_strdup_printf (_("Display message UID \"%s\""),
- input->uid);
- else
- return g_strdup (_("Clear message display"));
- }
+ if (m->done)
+ m->done(m->folder, m->uid, m->message, m->data);
}
-static void
-setup_display_message (gpointer in_data, gpointer op_data,
- CamelException *ex)
+static void get_message_free(struct _mail_msg *mm)
{
- display_message_input_t *input = (display_message_input_t *) in_data;
- display_message_data_t *data = (display_message_data_t *) op_data;
+ struct _get_message_msg *m = (struct _get_message_msg *)mm;
- data->msg = NULL;
- gtk_object_ref (GTK_OBJECT (input->ml));
+ g_free(m->uid);
+ camel_object_unref((CamelObject *)m->folder);
}
-static void
-do_display_message (gpointer in_data, gpointer op_data, CamelException *ex)
+static struct _mail_msg_op get_message_op = {
+ get_message_desc,
+ get_message_get,
+ get_message_got,
+ get_message_free,
+};
+
+void
+mail_get_message(CamelFolder *folder, const char *uid, void (*done) (CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *data), void *data, EThread *thread)
{
- display_message_input_t *input = (display_message_input_t *) in_data;
- display_message_data_t *data = (display_message_data_t *) op_data;
+ struct _get_message_msg *m;
- if (input->uid == NULL) {
- data->msg = NULL;
- return;
- }
+ m = mail_msg_new(&get_message_op, NULL, sizeof(*m));
+ m->folder = folder;
+ camel_object_ref((CamelObject *)folder);
+ m->uid = g_strdup(uid);
+ m->data = data;
+ m->done = done;
- data->msg = camel_folder_get_message (input->ml->folder, input->uid, ex);
+ e_thread_put(thread, (EMsg *)m);
}
-static void
-cleanup_display_message (gpointer in_data, gpointer op_data,
- CamelException *ex)
+/* ********************************************************************** */
+
+struct _get_messages_msg {
+ struct _mail_msg msg;
+
+ CamelFolder *folder;
+ GPtrArray *uids;
+ GPtrArray *messages;
+
+ void (*done) (CamelFolder *folder, GPtrArray *uids, GPtrArray *msgs, void *data);
+ void *data;
+};
+
+static char * get_messages_desc(struct _mail_msg *mm, int done)
{
- display_message_input_t *input = (display_message_input_t *) in_data;
- display_message_data_t *data = (display_message_data_t *) op_data;
- MailDisplay *md = input->md;
+ return g_strdup_printf(_("Retrieving messages"));
+}
- if (data->msg == NULL) {
- mail_display_set_message (md, NULL);
- } else {
- gint timeout = mail_config_mark_as_seen_timeout ();
+static void get_messages_get(struct _mail_msg *mm)
+{
+ struct _get_messages_msg *m = (struct _get_messages_msg *)mm;
+ int i;
+ CamelMimeMessage *message;
- if (input->ml->seen_id)
- gtk_timeout_remove (input->ml->seen_id);
+ for (i=0; i<m->uids->len; i++) {
+ mail_statusf(_("Retrieving message number %d of %d (uid \"%s\")"),
+ i+1, m->uids->len, (char *) m->uids->pdata[i]);
- mail_display_set_message (md, CAMEL_MEDIUM (data->msg));
- camel_object_unref (CAMEL_OBJECT (data->msg));
+ message = camel_folder_get_message(m->folder, m->uids->pdata[i], &mm->ex);
+ if (message == NULL)
+ break;
- if (timeout > 0) {
- input->ml->seen_id = gtk_timeout_add (timeout,
- input->timeout,
- input->ml);
- } else {
- input->ml->seen_id = 0;
- input->timeout (input->ml);
- }
+ g_ptr_array_add(m->messages, message);
}
+}
+
+static void get_messages_got(struct _mail_msg *mm)
+{
+ struct _get_messages_msg *m = (struct _get_messages_msg *)mm;
- if (input->uid)
- g_free (input->uid);
- gtk_object_unref (GTK_OBJECT (input->ml));
+ if (m->done)
+ m->done(m->folder, m->uids, m->messages, m->data);
}
-static const mail_operation_spec op_display_message = {
- describe_display_message,
- sizeof (display_message_data_t),
- setup_display_message,
- do_display_message,
- cleanup_display_message
+static void get_messages_free(struct _mail_msg *mm)
+{
+ struct _get_messages_msg *m = (struct _get_messages_msg *)mm;
+ int i;
+
+ for (i=0;i<m->uids->len;i++)
+ g_free(m->uids->pdata[i]);
+ g_ptr_array_free(m->uids, TRUE);
+ for (i=0;i<m->messages->len;i++) {
+ if (m->messages->pdata[i])
+ camel_object_unref((CamelObject *)m->messages->pdata[i]);
+ }
+ g_ptr_array_free(m->messages, TRUE);
+ camel_object_unref((CamelObject *)m->folder);
+}
+
+static struct _mail_msg_op get_messages_op = {
+ get_messages_desc,
+ get_messages_get,
+ get_messages_got,
+ get_messages_free,
};
void
-mail_do_display_message (MessageList *ml, MailDisplay *md, const char *uid,
- gint (*timeout) (gpointer))
+mail_get_messages(CamelFolder *folder, GPtrArray *uids, void (*done) (CamelFolder *folder, GPtrArray *uids, GPtrArray *msgs, void *data), void *data)
{
- display_message_input_t *input;
-
- g_return_if_fail (IS_MESSAGE_LIST (ml));
- g_return_if_fail (timeout != NULL);
-
- if (uid == NULL) {
- mail_display_set_message (md, NULL);
- return;
- }
+ struct _get_messages_msg *m;
- input = g_new (display_message_input_t, 1);
- input->ml = ml;
- input->md = md;
- input->uid = g_strdup (uid);
- input->timeout = timeout;
+ m = mail_msg_new(&get_messages_op, NULL, sizeof(*m));
+ m->folder = folder;
+ camel_object_ref((CamelObject *)folder);
+ m->uids = uids;
+ m->messages = g_ptr_array_new();
+ m->data = data;
+ m->done = done;
- /* this is only temporary */
- /*mail_operation_queue (&op_display_message, input, TRUE);*/
- mail_operation_run (&op_display_message, input, TRUE);
+ e_thread_put(mail_thread_new, (EMsg *)m);
}
+
/* dum de dum, below is an entirely async 'operation' thingy */
struct _op_data {
void *out;
@@ -2195,180 +2180,6 @@ mail_operation_run(const mail_operation_spec *op, void *in, int free)
return TRUE;
}
-
-/* ** EDIT MESSAGES ******************************************************* */
-
-typedef struct edit_messages_input_s {
- CamelFolder *folder;
- GPtrArray *uids;
- GtkSignalFunc signal;
-} edit_messages_input_t;
-
-typedef struct edit_messages_data_s {
- GPtrArray *messages;
-} edit_messages_data_t;
-
-static gchar *
-describe_edit_messages (gpointer in_data, gboolean gerund)
-{
- edit_messages_input_t *input = (edit_messages_input_t *) in_data;
-
- if (gerund)
- return g_strdup_printf
- (_("Opening messages from folder \"%s\""),
- mail_tool_get_folder_name (input->folder));
- else
- return g_strdup_printf (_("Open messages from \"%s\""),
- mail_tool_get_folder_name (input->folder));
-}
-
-static void
-setup_edit_messages (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- edit_messages_input_t *input = (edit_messages_input_t *) in_data;
-
- camel_object_ref (CAMEL_OBJECT (input->folder));
-}
-
-static void
-do_edit_messages (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- edit_messages_input_t *input = (edit_messages_input_t *) in_data;
- edit_messages_data_t *data = (edit_messages_data_t *) op_data;
-
- int i;
-
- data->messages = g_ptr_array_new ();
-
- for (i = 0; i < input->uids->len; i++) {
- CamelMimeMessage *message;
-
- mail_tool_camel_lock_up ();
- message = camel_folder_get_message (input->folder, input->uids->pdata[i], ex);
- mail_tool_camel_lock_down ();
-
- if (message)
- g_ptr_array_add (data->messages, message);
-
- g_free (input->uids->pdata[i]);
- }
-}
-
-static void
-cleanup_edit_messages (gpointer in_data, gpointer op_data,
- CamelException *ex)
-{
- edit_messages_input_t *input = (edit_messages_input_t *) in_data;
- edit_messages_data_t *data = (edit_messages_data_t *) op_data;
-
- int i;
-
- for (i = 0; i < data->messages->len; i++) {
- EMsgComposer *composer;
-
- composer = e_msg_composer_new_with_message (data->messages->pdata[i]);
- camel_object_unref (CAMEL_OBJECT (data->messages->pdata[i]));
- if (!composer)
- continue;
-
- if (input->signal)
- gtk_signal_connect (GTK_OBJECT (composer), "send",
- input->signal, NULL);
-
- gtk_widget_show (GTK_WIDGET (composer));
- }
-
- g_ptr_array_free (input->uids, TRUE);
- g_ptr_array_free (data->messages, TRUE);
- camel_object_unref (CAMEL_OBJECT (input->folder));
-
-}
-
-static const mail_operation_spec op_edit_messages = {
- describe_edit_messages,
- sizeof (edit_messages_data_t),
- setup_edit_messages,
- do_edit_messages,
- cleanup_edit_messages
-};
-
-void
-mail_do_edit_messages (CamelFolder *folder, GPtrArray *uids,
- GtkSignalFunc signal)
-{
- edit_messages_input_t *input;
-
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
- g_return_if_fail (uids != NULL);
-
- input = g_new (edit_messages_input_t, 1);
- input->folder = folder;
- input->uids = uids;
- input->signal = signal;
-
- mail_operation_queue (&op_edit_messages, input, TRUE);
-}
-
-/* ** SETUP FOLDER ****************************************************** */
-
-typedef struct setup_folder_input_s {
- gchar *name;
- CamelFolder **folder;
-} setup_folder_input_t;
-
-static gchar *
-describe_setup_folder (gpointer in_data, gboolean gerund)
-{
- setup_folder_input_t *input = (setup_folder_input_t *) in_data;
-
- if (gerund)
- return g_strdup_printf (_("Loading %s Folder"), input->name);
- else
- return g_strdup_printf (_("Load %s Folder"), input->name);
-}
-
-static void
-do_setup_folder (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- setup_folder_input_t *input = (setup_folder_input_t *) in_data;
- gchar *url;
-
- url = g_strdup_printf ("file://%s/local/%s", evolution_dir,
- input->name);
- *(input->folder) = mail_tool_uri_to_folder (url, ex);
- g_free (url);
-}
-
-static void
-cleanup_setup_folder (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- setup_folder_input_t *input = (setup_folder_input_t *) in_data;
-
- g_free (input->name);
-}
-
-static const mail_operation_spec op_setup_folder = {
- describe_setup_folder,
- 0,
- NULL,
- do_setup_folder,
- cleanup_setup_folder
-};
-
-void
-mail_do_setup_folder (const char *name, CamelFolder **folder)
-{
- setup_folder_input_t *input;
-
- g_return_if_fail (name != NULL);
- g_return_if_fail (folder != NULL);
-
- input = g_new (setup_folder_input_t, 1);
- input->name = g_strdup (name);
- input->folder = folder;
- mail_operation_queue (&op_setup_folder, input, TRUE);
-}
-
/* ** SETUP TRASH VFOLDER ************************************************* */
typedef struct setup_trash_input_s {
@@ -2537,136 +2348,6 @@ mail_do_setup_trash (const char *name, const char *store_uri, CamelFolder **fold
mail_operation_queue (&op_setup_trash, input, TRUE);
}
-
-/* ** VIEW MESSAGES ******************************************************* */
-
-typedef struct view_messages_input_s {
- CamelFolder *folder;
- GPtrArray *uids;
- FolderBrowser *fb;
-} view_messages_input_t;
-
-typedef struct view_messages_data_s {
- GPtrArray *messages;
-} view_messages_data_t;
-
-static gchar *
-describe_view_messages (gpointer in_data, gboolean gerund)
-{
- view_messages_input_t *input = (view_messages_input_t *) in_data;
-
- if (gerund)
- return g_strdup_printf
- (_("Viewing messages from folder \"%s\""),
- mail_tool_get_folder_name (input->folder));
- else
- return g_strdup_printf (_("View messages from \"%s\""),
- mail_tool_get_folder_name (input->folder));
-}
-
-static void
-setup_view_messages (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- view_messages_input_t *input = (view_messages_input_t *) in_data;
-
- camel_object_ref (CAMEL_OBJECT (input->folder));
- gtk_object_ref (GTK_OBJECT (input->fb));
-}
-
-static void
-do_view_messages (gpointer in_data, gpointer op_data, CamelException *ex)
-{
- view_messages_input_t *input = (view_messages_input_t *) in_data;
- view_messages_data_t *data = (view_messages_data_t *) op_data;
- time_t last_update = 0;
- int i;
-
- data->messages = g_ptr_array_new ();
-
- for (i = 0; i < input->uids->len; i++) {
- CamelMimeMessage *message;
- const gboolean last_message = (i+1 == input->uids->len);
- time_t now;
-
- /*
- * Update display every 2 seconds
- */
- time (&now);
- if (last_message || ((now - last_update) > 2)) {
- mail_op_set_message (_("Retrieving message %d of %d (uid \"%s\")"),
- i + 1, input->uids->len, (char *)input->uids->pdata[i]);
- last_update = now;
- }
-
- mail_tool_camel_lock_up ();
- message = camel_folder_get_message (input->folder, input->uids->pdata[i], ex);
- mail_tool_camel_lock_down ();
-
- g_ptr_array_add (data->messages, message);
- }
-}
-
-static void
-cleanup_view_messages (gpointer in_data, gpointer op_data,
- CamelException *ex)
-{
- view_messages_input_t *input = (view_messages_input_t *) in_data;
- view_messages_data_t *data = (view_messages_data_t *) op_data;
-
- int i;
-
- for (i = 0; i < data->messages->len; i++) {
- CamelMimeMessage *msg;
- gchar *uid;
- GtkWidget *view;
-
- if (data->messages->pdata[i] == NULL)
- continue;
-
- msg = data->messages->pdata[i];
- uid = input->uids->pdata[i];
-
- view = mail_view_create (input->folder, uid, msg);
- gtk_widget_show (view);
-
- /*Owned by the mail_display now*/
- camel_object_unref (CAMEL_OBJECT (data->messages->pdata[i]));
- g_free (uid);
- }
-
- g_ptr_array_free (input->uids, TRUE);
- g_ptr_array_free (data->messages, TRUE);
- camel_object_unref (CAMEL_OBJECT (input->folder));
- gtk_object_unref (GTK_OBJECT (input->fb));
-}
-
-static const mail_operation_spec op_view_messages = {
- describe_view_messages,
- sizeof (view_messages_data_t),
- setup_view_messages,
- do_view_messages,
- cleanup_view_messages
-};
-
-void
-mail_do_view_messages (CamelFolder *folder, GPtrArray *uids,
- FolderBrowser *fb)
-{
- view_messages_input_t *input;
-
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
- g_return_if_fail (uids != NULL);
- g_return_if_fail (IS_FOLDER_BROWSER (fb));
-
- input = g_new (view_messages_input_t, 1);
- input->folder = folder;
- input->uids = uids;
- input->fb = fb;
-
- mail_operation_queue (&op_view_messages, input, TRUE);
-}
-
-
/* ** SAVE MESSAGES ******************************************************* */
typedef struct save_messages_input_s {
diff --git a/mail/mail-ops.h b/mail/mail-ops.h
index 17ed16c9c5..bd51e1cc32 100644
--- a/mail/mail-ops.h
+++ b/mail/mail-ops.h
@@ -28,6 +28,7 @@
#include "evolution-storage.h" /*EvolutionStorage */
#include "composer/e-msg-composer.h" /*EMsgComposer */
#include "message-list.h" /*MessageList */
+#include "mail-mt.h"
void mail_do_fetch_mail (const gchar *source_url, gboolean keep_on_server,
CamelFolder *destination,
@@ -45,7 +46,6 @@ void mail_do_send_queue (CamelFolder *folder_queue,
void mail_do_append_mail (CamelFolder *folder,
CamelMimeMessage *message,
CamelMessageInfo *info);
-void mail_do_expunge_folder (CamelFolder *folder);
void mail_do_transfer_messages (CamelFolder *source, GPtrArray *uids,
gboolean delete_from_source,
gchar *dest_uri);
@@ -60,16 +60,26 @@ void mail_do_attach_message (CamelFolder *folder, const char *uid,
void mail_do_forward_message (CamelMimeMessage *basis, CamelFolder *source,
GPtrArray *uids, /*array of allocated gchar *, will all be freed */
EMsgComposer *composer, gboolean attach);
-void mail_do_load_folder (FolderBrowser *fb, const char *url);
void mail_do_create_folder (const GNOME_Evolution_ShellComponentListener listener,
const char *uri, const char *type);
-void mail_do_sync_folder (CamelFolder *folder);
-void mail_do_display_message (MessageList *ml, MailDisplay *md, const char *uid,
- gint (*timeout) (gpointer));
-void mail_do_edit_messages (CamelFolder *folder, GPtrArray *uids,
- GtkSignalFunc signal);
-void mail_do_setup_folder (const char *name, CamelFolder **folder);
void mail_do_setup_trash (const char *name, const char *store_uri, CamelFolder **folder);
-void mail_do_view_messages (CamelFolder *folder, GPtrArray *uids,
- FolderBrowser *fb);
void mail_do_save_messages (CamelFolder *folder, GPtrArray *uids, gchar *path);
+
+/* get a single message, asynchronously */
+void mail_get_message(CamelFolder *folder, const char *uid,
+ void (*done) (CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *data), void *data,
+ EThread *thread);
+
+/* get several messages */
+void mail_get_messages(CamelFolder *folder, GPtrArray *uids,
+ void (*done) (CamelFolder *folder, GPtrArray *uids, GPtrArray *msgs, void *data), void *data);
+
+/* same for a folder */
+void mail_get_folder(const char *uri,
+ void (*done) (char *uri, CamelFolder *folder, void *data), void *data);
+
+void mail_sync_folder(CamelFolder *folder,
+ void (*done) (CamelFolder *folder, void *data), void *data);
+void mail_expunge_folder(CamelFolder *folder,
+ void (*done) (CamelFolder *folder, void *data), void *data);
+
diff --git a/mail/mail-tools.c b/mail/mail-tools.c
index 0014d48553..5bfefa758b 100644
--- a/mail/mail-tools.c
+++ b/mail/mail-tools.c
@@ -221,6 +221,7 @@ mail_tool_do_movemail (const gchar *source_url, CamelException *ex)
return dest_path;
}
+#if 0
void
mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean use_cache, CamelException *ex)
{
@@ -352,6 +353,7 @@ mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean
camel_object_unref (CAMEL_OBJECT (dest));
mail_tool_camel_lock_down();
}
+#endif
void
mail_tool_set_uid_flags (CamelFolder *folder, const char *uid, guint32 mask, guint32 set)
@@ -424,7 +426,6 @@ mail_tool_make_message_attachment (CamelMimeMessage *message)
const char *subject;
gchar *desc;
- mail_tool_camel_lock_up();
/*camel_object_ref (CAMEL_OBJECT (message));*/
subject = camel_mime_message_get_subject (message);
@@ -440,7 +441,6 @@ mail_tool_make_message_attachment (CamelMimeMessage *message)
CAMEL_DATA_WRAPPER (message));
camel_mime_part_set_content_type (part, "message/rfc822");
/*camel_object_unref (CAMEL_OBJECT (message));*/
- mail_tool_camel_lock_down();
return part;
}
@@ -493,7 +493,6 @@ mail_tool_uri_to_folder (const char *uri, CamelException *ex)
if (!strcmp (url->protocol, "vfolder")) {
folder = vfolder_uri_to_folder (uri, ex);
} else {
- mail_tool_camel_lock_up ();
store = camel_session_get_store (session, uri, ex);
if (store) {
char *name;
@@ -505,7 +504,6 @@ mail_tool_uri_to_folder (const char *uri, CamelException *ex)
folder = camel_store_get_folder (
store, name, CAMEL_STORE_FOLDER_CREATE, ex);
}
- mail_tool_camel_lock_down ();
}
if (camel_exception_is_set (ex)) {
@@ -544,6 +542,8 @@ mail_tool_uri_to_folder_noex (const char *uri)
gtk_widget_destroy (dialog);
}
+ camel_exception_clear(&ex);
+
return result;
}
diff --git a/mail/main.c b/mail/main.c
index 48ed4c1a7f..ce0b776b08 100644
--- a/mail/main.c
+++ b/mail/main.c
@@ -29,6 +29,7 @@
#include "component-factory.h"
#include "composer/evolution-composer.h"
#include "mail.h"
+#include "mail-mt.h"
#if 0
static int blowup(int status)
@@ -80,6 +81,8 @@ main (int argc, char *argv [])
e_cursors_init ();
+ mail_msg_init();
+
component_factory_init ();
evolution_composer_factory_init (composer_send_cb,
composer_postpone_cb);
diff --git a/mail/session.c b/mail/session.c
index 508ea80ed3..6fd85712e4 100644
--- a/mail/session.c
+++ b/mail/session.c
@@ -11,6 +11,7 @@
#include "mail.h"
#include "mail-session.h"
#include "mail-threads.h"
+#include "mail-mt.h"
CamelSession *session;
@@ -55,7 +56,7 @@ mail_session_request_dialog (const char *prompt, gboolean secret, const char *ke
ans == NULL)
return NULL;
} else {
- if (!mail_op_get_password ((char *) prompt, secret, &ans))
+ if ((ans = mail_get_password ((char *) prompt, secret)) == NULL)
return NULL;
}