aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog16
-rw-r--r--mail/component-factory.c3
-rw-r--r--mail/mail-ops.c8
-rw-r--r--mail/mail-send-recv.c294
-rw-r--r--mail/mail-send-recv.h7
5 files changed, 239 insertions, 89 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index f5d6fbe646..4b1183ec52 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,19 @@
+2001-02-09 Not Zed <NotZed@Ximian.com>
+
+ * mail-ops.c (filter_folder_free): only free driver, if set.
+ (fetch_mail_fetched): Unref the driver here, so it can cleanup
+ before we call the 'done' callback.
+
+ * component-factory.c (owner_set_cb): Add setup for mail
+ autoreceive stuff.
+
+ * mail-send-recv.c (free_info_data): Free the send info's from teh
+ active hash, not the running list.
+ (receive_done): As we finish downloads, remove them and clean them
+ up, and also close the window.
+ (mail_autoreceive_setup): New function to setup & maintain
+ automatic download stuff.
+
2001-02-08 Jeffrey Stedfast <fejj@ximian.com>
* mail-config-druid.c (construct): Set the sensitivity of the spin
diff --git a/mail/component-factory.c b/mail/component-factory.c
index 95e578e5f0..376b3b14a7 100644
--- a/mail/component-factory.c
+++ b/mail/component-factory.c
@@ -49,6 +49,7 @@
#include "component-factory.h"
#include "mail-summary.h"
+#include "mail-send-recv.h"
CamelFolder *drafts_folder = NULL;
CamelFolder *outbox_folder = NULL;
@@ -211,6 +212,8 @@ owner_set_cb (EvolutionShellComponent *shell_component,
}
mail_session_enable_interaction (TRUE);
+
+ mail_autoreceive_setup();
}
static void
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 3b81d62d6a..231b22ad95 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -209,7 +209,8 @@ filter_folder_free(struct _mail_msg *mm)
camel_operation_unref(m->cancel);
if (m->destination)
camel_object_unref((CamelObject *)m->destination);
- camel_object_unref((CamelObject *)m->driver);
+ if (m->driver)
+ camel_object_unref((CamelObject *)m->driver);
}
static struct _mail_msg_op filter_folder_op = {
@@ -333,6 +334,11 @@ fetch_mail_fetched(struct _mail_msg *mm)
{
struct _fetch_mail_msg *m = (struct _fetch_mail_msg *)mm;
+ /* we unref this here as it may have more work to do (syncing
+ folders and whatnot) before we are really done */
+ camel_object_unref((CamelObject *)m->fmsg.driver);
+ m->fmsg.driver = NULL;
+
if (m->done)
m->done(m->source_uri, m->data);
}
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index ca47d461cf..09afe0d0d3 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -49,8 +49,6 @@
#include <libgnomeui/gnome-window-icon.h>
-GHashTable *active_downloads = NULL;
-
/* send/receive email */
/* ********************************************************************** */
@@ -68,8 +66,6 @@ struct _folder_info {
struct _send_data {
GList *infos;
- int active; /* how many still active */
-
GnomeDialog *gd;
int cancelled;
@@ -78,6 +74,8 @@ struct _send_data {
GMutex *lock;
GHashTable *folders;
+
+ GHashTable *active; /* send_info's by uri */
};
typedef enum {
@@ -104,6 +102,22 @@ struct _send_info {
struct _send_data *data;
};
+static struct _send_data *send_data = NULL;
+
+static struct _send_data *setup_send_data(void)
+{
+ struct _send_data *data;
+
+ if (send_data == NULL) {
+ send_data = data = g_malloc0(sizeof(*data));
+ data->lock = g_mutex_new();
+ data->folders = g_hash_table_new(g_str_hash, g_str_equal);
+ data->inbox = mail_tool_get_local_inbox(NULL);
+ data->active = g_hash_table_new(g_str_hash, g_str_equal);
+ }
+ return send_data;
+}
+
static void
receive_cancel(GtkButton *button, struct _send_info *info)
{
@@ -120,56 +134,66 @@ receive_cancel(GtkButton *button, struct _send_info *info)
static void
free_folder_info(void *key, struct _folder_info *info, void *data)
{
- camel_folder_thaw (info->folder);
+ /*camel_folder_thaw (info->folder); */
camel_object_unref((CamelObject *)info->folder);
g_free(info->uri);
}
+static void free_send_info(void *key, struct _send_info *info, void *data)
+{
+ g_free(info->uri);
+ camel_operation_unref(info->cancel);
+ g_free(info);
+}
+
static void
-free_info_data(void *datain)
+free_send_data(void)
{
- struct _send_data *data = datain;
- GList *list = data->infos;
-
- while (list) {
- struct _send_info *info = list->data;
- g_free(info->uri);
- camel_operation_unref(info->cancel);
- list = list->next;
- }
+ struct _send_data *data = send_data;
+
+ g_assert(g_hash_table_size(data->active) == 0);
g_list_free(data->infos);
+ g_hash_table_foreach(data->active, (GHFunc)free_send_info, NULL);
+ g_hash_table_destroy(data->active);
g_hash_table_foreach(data->folders, (GHFunc)free_folder_info, NULL);
g_hash_table_destroy(data->folders);
g_mutex_free(data->lock);
if (data->inbox) {
- camel_folder_thaw (data->inbox);
+ /*camel_folder_thaw (data->inbox); */
camel_object_unref((CamelObject *)data->inbox);
}
g_free(data);
+ send_data = NULL;
+}
+
+
+static void cancel_send_info(void *key, struct _send_info *info, void *data)
+{
+ receive_cancel(info->stop, info);
+}
+
+static void hide_send_info(void *key, struct _send_info *info, void *data)
+{
+ info->stop = NULL;
+ info->bar = NULL;
}
static void
dialogue_clicked(GnomeDialog *gd, int button, struct _send_data *data)
{
- GList *scan;
-
switch(button) {
- case 0: /* ok */
- gnome_dialog_close(gd);
- break;
- case 1:
+ case 0:
printf("cancelled whole thing\n");
if (!data->cancelled) {
data->cancelled = TRUE;
- scan = data->infos;
- while (scan) {
- struct _send_info *info = scan->data;
- receive_cancel(info->stop, info);
- scan = scan->next;
- }
+ g_hash_table_foreach(data->active, (GHFunc)cancel_send_info, NULL);
}
- gnome_dialog_set_sensitive(gd, 1, FALSE);
+ gnome_dialog_set_sensitive(gd, 0, FALSE);
+ break;
+ case -1: /* dialogue vanished, so make out its just hidden */
+ printf("hiding dialogue\n");
+ g_hash_table_foreach(data->active, (GHFunc)hide_send_info, NULL);
break;
}
}
@@ -188,15 +212,10 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
GtkProgressBar *bar;
GtkButton *stop;
struct _send_info *info;
-
- data = g_malloc0(sizeof(*data));
- data->lock = g_mutex_new();
- data->folders = g_hash_table_new(g_str_hash, g_str_equal);
- data->inbox = mail_tool_get_local_inbox(NULL);
- camel_folder_freeze (data->inbox);
-
- gd = (GnomeDialog *)gnome_dialog_new(_("Send & Receive mail"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
- gnome_dialog_set_sensitive(gd, 0, FALSE);
+
+ data = setup_send_data();
+
+ gd = (GnomeDialog *)gnome_dialog_new(_("Send & Receive mail"), GNOME_STOCK_BUTTON_CANCEL, NULL);
gnome_window_icon_set_from_file((GtkWindow *)gd, EVOLUTION_DATADIR "images/evolution/evolution-inbox.png");
frame= (GtkFrame *)gtk_frame_new(_("Receiving"));
@@ -214,19 +233,36 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
continue;
}
- info = g_malloc0(sizeof(*info));
- /* imap is handled differently */
- if (!strncmp(source->url, "imap:", 5))
- info->type = SEND_UPDATE;
- else
- info->type = SEND_RECEIVE;
- printf("adding source %s\n", source->url);
+ /* see if we have an outstanding download active */
+ info = g_hash_table_lookup(data->active, source->url);
+ if (info == NULL) {
+ info = g_malloc0(sizeof(*info));
+ /* imap is handled differently */
+ if (!strncmp(source->url, "imap:", 5))
+ info->type = SEND_UPDATE;
+ else
+ info->type = SEND_RECEIVE;
+ printf("adding source %s\n", source->url);
+
+ info->uri = g_strdup(source->url);
+ info->keep = source->keep_on_server;
+ info->cancel = camel_operation_new(operation_status, info);
+ info->state = SEND_ACTIVE;
+
+ g_hash_table_insert(data->active, info->uri, info);
+ list = g_list_prepend(list, info);
+ } else if (info->bar != NULL) {
+ /* incase we get the same source pop up again */
+ sources = sources->next;
+ continue;
+ }
label = (GtkLabel *)gtk_label_new(source->url);
bar = (GtkProgressBar *)gtk_progress_bar_new();
stop = (GtkButton *)gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL);
gtk_progress_set_show_text((GtkProgress *)bar, TRUE);
+
if (info->type == SEND_UPDATE) {
gtk_progress_set_format_string((GtkProgress *)bar, _("Updating ..."));
} else {
@@ -238,17 +274,8 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
gtk_table_attach(table, (GtkWidget *)stop, 2, 3, row, row+1, GTK_EXPAND|GTK_FILL, 0, 3, 1);
info->bar = bar;
- info->uri = g_strdup(source->url);
- info->keep = source->keep_on_server;
- info->cancel = camel_operation_new(operation_status, info);
info->stop = stop;
info->data = data;
- info->state = SEND_ACTIVE;
- data->active++;
-
- g_hash_table_insert(active_downloads, info->uri, info);
-
- list = g_list_prepend(list, info);
gtk_signal_connect((GtkObject *)stop, "clicked", receive_cancel, info);
sources = sources->next;
@@ -264,10 +291,21 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
gtk_container_add((GtkContainer *)frame, (GtkWidget *)table);
gtk_widget_show((GtkWidget *)frame);
- info = g_malloc0(sizeof(*info));
- info->type = SEND_SEND;
- printf("adding dest %s\n", destination);
-
+ info = g_hash_table_lookup(data->active, destination);
+ if (info == NULL) {
+ info = g_malloc0(sizeof(*info));
+ info->type = SEND_SEND;
+ printf("adding dest %s\n", destination);
+
+ info->uri = g_strdup(destination);
+ info->keep = FALSE;
+ info->cancel = camel_operation_new(operation_status, info);
+ info->state = SEND_ACTIVE;
+
+ g_hash_table_insert(data->active, info->uri, info);
+ list = g_list_prepend(list, info);
+ }
+
label = (GtkLabel *)gtk_label_new(destination);
bar = (GtkProgressBar *)gtk_progress_bar_new();
stop = (GtkButton *)gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL);
@@ -280,17 +318,8 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
gtk_table_attach(table, (GtkWidget *)stop, 2, 3, row, row+1, GTK_EXPAND|GTK_FILL, 0, 3, 1);
info->bar = bar;
- info->uri = g_strdup(destination);
- info->keep = FALSE;
- info->cancel = camel_operation_new(NULL, NULL);
info->stop = stop;
info->data = data;
- info->state = SEND_ACTIVE;
- data->active++;
-
- g_hash_table_insert(active_downloads, info->uri, info);
-
- list = g_list_prepend(list, info);
gtk_signal_connect((GtkObject *)stop, "clicked", receive_cancel, info);
gtk_widget_show_all((GtkWidget *)table);
@@ -302,7 +331,6 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
data->infos = list;
data->gd = gd;
- gtk_object_set_data_full((GtkObject *)gd, "info_data", data, free_info_data);
return data;
}
@@ -463,13 +491,19 @@ receive_done (char *uri, void *data)
if (info->stop)
gtk_widget_set_sensitive((GtkWidget *)info->stop, FALSE);
- info->data->active--;
- if (info->data->active == 0 && info->data) {
- gnome_dialog_set_sensitive(info->data->gd, 0, TRUE);
- gnome_dialog_set_sensitive(info->data->gd, 1, FALSE);
+ /* remove/free this active download */
+ g_hash_table_remove(info->data->active, info->uri);
+ info->data->infos = g_list_remove(info->data->infos, info);
+ g_free(info->uri);
+ camel_operation_unref(info->cancel);
+
+ if (g_hash_table_size(info->data->active) == 0) {
+ if (info->data->gd)
+ gtk_object_unref((GtkObject *)info->data->gd);
+ free_send_data();
}
- g_hash_table_remove(active_downloads, info->uri);
+ g_free(info);
}
/* same for updating */
@@ -510,7 +544,7 @@ receive_get_folder(CamelFilterDriver *d, const char *uri, void *data, CamelExcep
camel_object_unref((CamelObject *)oldinfo->folder);
oldinfo->folder = folder;
} else {
- camel_folder_freeze (folder);
+ /*camel_folder_freeze (folder); */
oldinfo = g_malloc0(sizeof(*oldinfo));
oldinfo->folder = folder;
oldinfo->uri = g_strdup(uri);
@@ -550,9 +584,6 @@ void mail_send_receive(void)
extern CamelFolder *outbox_folder;
const MailConfigAccount *account;
- if (active_downloads == NULL)
- active_downloads = g_hash_table_new(g_str_hash, g_str_equal);
-
if (gd != NULL) {
g_assert(GTK_WIDGET_REALIZED(gd));
gdk_window_show(gd->window);
@@ -609,24 +640,114 @@ void mail_send_receive(void)
gtk_object_unref((GtkObject *)fc);
}
-#if 0
+struct _auto_data {
+ char *uri;
+ int keep; /* keep on server flag */
+ int period; /* in seconds */
+ int timeout_id;
+};
+
+static GHashTable *auto_active;
+
+static gboolean
+auto_timeout(void *data)
+{
+ struct _auto_data *info = data;
+
+ mail_receive_uri(info->uri, info->keep);
+
+ return TRUE;
+}
+
+static void auto_setup_set(void *key, struct _auto_data *info, GHashTable *set)
+{
+ g_hash_table_insert(set, info->uri, info);
+}
+
+static void auto_clean_set(void *key, struct _auto_data *info, GHashTable *set)
+{
+ printf("removing auto-check for %s\n", info->uri);
+ g_hash_table_remove(set, info->uri);
+ gtk_timeout_remove(info->timeout_id);
+ g_free(info->uri);
+ g_free(info);
+}
+
+/* call to setup initial, and after changes are made to the config */
+/* FIXME: Need a cleanup funciton for when object is deactivated */
+void
+mail_autoreceive_setup(void)
+{
+ GSList *sources;
+ GHashTable *set_hash;
+
+ sources = mail_config_get_sources();
+ if (!sources)
+ return;
+
+ if (auto_active == NULL)
+ auto_active = g_hash_table_new(g_str_hash, g_str_equal);
+
+ set_hash = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_foreach(auto_active, (GHFunc)auto_setup_set, set_hash);
+
+ while (sources) {
+ MailConfigService *source = sources->data;
+ if (source->url && source->auto_check) {
+ struct _auto_data *info;
+
+ printf("setting up auto-receive mail for : %s\n", source->url);
+
+ g_hash_table_remove(set_hash, source->url);
+ info = g_hash_table_lookup(auto_active, source->url);
+ if (info) {
+ info->keep = source->keep_on_server;
+ if (info->period != source->auto_check_time*60) {
+ info->period = source->auto_check_time*60;
+ gtk_timeout_remove(info->timeout_id);
+ info->timeout_id = gtk_timeout_add(info->period*1000, auto_timeout, info);
+ }
+ } else {
+ info = g_malloc0(sizeof(*info));
+ info->uri = g_strdup(source->url);
+ info->keep = source->keep_on_server;
+ info->period = source->auto_check_time*60;
+ info->timeout_id = gtk_timeout_add(info->period*1000, auto_timeout, info);
+ g_hash_table_insert(auto_active, info->uri, info);
+ /* If we do this at startup, it can cause the logon dialogue to be hidden,
+ so lets not */
+ /*mail_receive_uri(source->url, source->keep_on_server);*/
+ }
+ }
+
+ sources = sources->next;
+ }
+
+ g_hash_table_foreach(set_hash, (GHFunc)auto_clean_set, auto_active);
+ g_hash_table_destroy(set_hash);
+}
+
/* we setup the download info's in a hashtable, if we later need to build the gui, we insert
them in to add them. */
void mail_receive_uri(const char *uri, int keep)
{
FilterContext *fc;
struct _send_info *info;
+ struct _send_data *data;
+ extern CamelFolder *outbox_folder;
- if (active_downloads == NULL)
- active_downloads = g_hash_table_new(g_str_hash, g_str_equal);
-
- info = g_hash_table_lookup(active_downloads);
- if (info != NULL)
+ data = setup_send_data();
+ info = g_hash_table_lookup(data->active, uri);
+ if (info != NULL) {
+ printf("download of %s still in progress\n", uri);
return;
+ }
+
+ printf("starting non-interactive download of '%s'\n", uri);
info = g_malloc0(sizeof(*info));
/* imap is handled differently */
- if (!strncmp(source->url, "imap:", 5))
+ if (!strncmp(uri, "imap:", 5))
info->type = SEND_UPDATE;
else
info->type = SEND_RECEIVE;
@@ -638,9 +759,8 @@ void mail_receive_uri(const char *uri, int keep)
info->stop = NULL;
info->data = data;
info->state = SEND_ACTIVE;
- data->active++;
- g_hash_table_insert(active_downloads, info);
+ g_hash_table_insert(data->active, info->uri, info);
fc = mail_load_filter_context();
switch(info->type) {
@@ -668,4 +788,4 @@ void mail_receive_uri(const char *uri, int keep)
}
gtk_object_unref((GtkObject *)fc);
}
-#endif
+
diff --git a/mail/mail-send-recv.h b/mail/mail-send-recv.h
index f52e1417a6..ef3a502b4c 100644
--- a/mail/mail-send-recv.h
+++ b/mail/mail-send-recv.h
@@ -30,7 +30,12 @@ extern "C" {
#pragma }
#endif /* __cplusplus }*/
-void mail_send_receive (void);
+/* send/receive all uri's */
+void mail_send_receive(void);
+/* receive a single uri */
+void mail_receive_uri(const char *uri, int keep);
+/* setup auto receive stuff */
+void mail_autoreceive_setup(void);
#ifdef __cplusplus
}