From 01f333dee52a481a633858ef563dab221f01b945 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 9 Aug 2000 00:13:32 +0000 Subject: Add "Don't delete messages from server" button to remote SOURCEs that * mail-config-gui.c: Add "Don't delete messages from server" button to remote SOURCEs that aren't STORAGEs (ie, POP). (provider_list): Only list SOURCEs. (ie, not mh) * mail-config.c: Save/load "keep_on_server" flag. * mail-ops.c (fetch_remote_mail): New function, split out of real_fetch_mail. Deals with copying mail from a remote server into a temporary mbox, possibly using a CamelUIDCache to leave the messages on the server. svn path=/trunk/; revision=4617 --- mail/ChangeLog | 11 ++++ mail/mail-config-gui.c | 23 ++++++++- mail/mail-config.c | 7 +++ mail/mail-config.h | 1 + mail/mail-ops.c | 136 ++++++++++++++++++++++++++++++++----------------- 5 files changed, 130 insertions(+), 48 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index 1175d1a6de..da283d361e 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,5 +1,16 @@ 2000-08-08 Dan Winship + * mail-config-gui.c: Add "Don't delete messages from server" + button to remote SOURCEs that aren't STORAGEs (ie, POP). + (provider_list): Only list SOURCEs. (ie, not mh) + + * mail-config.c: Save/load "keep_on_server" flag. + + * mail-ops.c (fetch_remote_mail): New function, split out of + real_fetch_mail. Deals with copying mail from a remote server into + a temporary mbox, possibly using a CamelUIDCache to leave the + messages on the server. + * mail-crypto.c, mail-format.c, message-thread.c: Fix some compiler warnings. diff --git a/mail/mail-config-gui.c b/mail/mail-config-gui.c index 2d957af301..fda81c7b43 100644 --- a/mail/mail-config-gui.c +++ b/mail/mail-config-gui.c @@ -81,6 +81,7 @@ typedef struct GList *auth_items; GtkWidget *auth_html; GtkWidget *auth_detect; + GtkWidget *keep_on_server; gint pnum; } MailDialogServicePageItem; @@ -334,7 +335,8 @@ provider_list (GSList **sources, GSList **news, GSList **transports) if (strcmp (prov->domain, "mail")) continue; - if (prov->object_types[CAMEL_PROVIDER_STORE]) { + if (prov->object_types[CAMEL_PROVIDER_STORE] && + prov->flags & CAMEL_PROVIDER_IS_SOURCE) { *sources = provider_list_add (*sources, CAMEL_PROVIDER_STORE, prov); @@ -670,6 +672,9 @@ service_page_set_url (MailDialogServicePage *page, MailConfigService *service) } } + if (spitem->keep_on_server) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (spitem->keep_on_server), service->keep_on_server); + camel_exception_free (ex); camel_url_free (url); } @@ -762,8 +767,13 @@ static MailConfigService * service_page_extract (MailDialogServicePage *page) { MailConfigService *source = g_new0 (MailConfigService, 1); + MailDialogServicePageItem *spitem = page->spitem; source->url = service_page_get_url (page); + if (spitem->keep_on_server) { + source->keep_on_server = gtk_toggle_button_get_active ( + GTK_TOGGLE_BUTTON (spitem->keep_on_server)); + } return source; } @@ -894,7 +904,7 @@ service_page_item_new (MailDialogServicePage *page, MailService *mcs) description->parent->parent, TRUE, TRUE, 0); - table = gtk_table_new (5, 3, FALSE); + table = gtk_table_new (6, 3, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 10); gtk_container_set_border_width (GTK_CONTAINER (table), 8); @@ -959,6 +969,15 @@ service_page_item_new (MailDialogServicePage *page, MailService *mcs) row += 2; } + if ((mcs->provider->flags & CAMEL_PROVIDER_IS_REMOTE) && + !(mcs->provider->flags & CAMEL_PROVIDER_IS_STORAGE)) { + item->keep_on_server = gtk_check_button_new_with_label ( + _("Don't delete messages from server")); + gtk_table_attach (GTK_TABLE (table), item->keep_on_server, + 0, 3, row, row + 1, GTK_FILL, 0, 0, 0); + row++; + } + if (row != 0) { GtkWidget *btn; diff --git a/mail/mail-config.c b/mail/mail-config.c index c90ac45ef6..3427080cff 100644 --- a/mail/mail-config.c +++ b/mail/mail-config.c @@ -86,6 +86,7 @@ service_copy (MailConfigService *source) newsource = g_new0 (MailConfigService, 1); newsource->url = g_strdup (source->url); + newsource->keep_on_server = source->keep_on_server; return newsource; } @@ -202,6 +203,9 @@ mail_config_read () path = g_strdup_printf ("url_%d", i); s->url = gnome_config_get_string (path); g_free (path); + path = g_strdup_printf ("keep_on_server_%d", i); + s->keep_on_server = gnome_config_get_bool (path); + g_free (path); config->sources = g_slist_append (config->sources, s); } @@ -299,6 +303,9 @@ mail_config_write () path = g_strdup_printf ("url_%d", i); gnome_config_set_string (path, s->url); g_free (path); + path = g_strdup_printf ("keep_on_server_%d", i); + gnome_config_set_bool (path, s->keep_on_server); + g_free (path); } gnome_config_pop_prefix (); diff --git a/mail/mail-config.h b/mail/mail-config.h index 8e8c641d66..033bf18337 100644 --- a/mail/mail-config.h +++ b/mail/mail-config.h @@ -34,6 +34,7 @@ typedef struct typedef struct { gchar *url; + gboolean keep_on_server; } MailConfigService; typedef struct diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 2d94a94da2..70d0c0b82d 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -55,7 +56,7 @@ struct post_send_data { typedef struct rfm_s { FolderBrowser *fb; - char *source_url; + MailConfigService *source; } rfm_t; typedef struct rsm_s { @@ -129,6 +130,83 @@ filter_get_folder(FilterDriver *fd, const char *uri, void *data) return mail_uri_to_folder(uri); } +static void +fetch_remote_mail (CamelFolder *source, CamelFolder *dest, + gboolean keep_on_server, FolderBrowser *fb, + CamelException *ex) +{ + CamelUIDCache *cache; + GPtrArray *uids; + int i; + + uids = camel_folder_get_uids (source); + if (keep_on_server) { + GPtrArray *new_uids; + char *url, *p, *filename; + + url = camel_url_to_string ( + CAMEL_SERVICE (source->parent_store)->url, FALSE); + for (p = url; *p; p++) { + if (!isascii ((unsigned char)*p) || + strchr (" /'\"`&();|<>${}!", *p)) + *p = '_'; + } + filename = g_strdup_printf ("%s/config/cache-%s", + evolution_dir, url); + g_free (url); + + cache = camel_uid_cache_new (filename); + g_free (filename); + if (cache) { + new_uids = camel_uid_cache_get_new_uids (cache, uids); + camel_folder_free_uids (source, uids); + uids = new_uids; + } else { + async_mail_exception_dialog ("Could not read UID " + "cache file. You may " + "receive duplicate " + "messages.", NULL, fb); + } + } else + cache = NULL; + + printf ("got %d new messages in source\n", uids->len); + for (i = 0; i < uids->len; i++) { + CamelMimeMessage *msg; + + msg = camel_folder_get_message (source, uids->pdata[i], ex); + if (camel_exception_is_set (ex)) { + async_mail_exception_dialog ("Unable to get message", + ex, fb); + goto done; + } + + /* Append with flags = 0 since this is a new message */ + camel_folder_append_message (dest, msg, 0, ex); + if (camel_exception_is_set (ex)) { + async_mail_exception_dialog ("Unable to write message", + ex, fb); + gtk_object_unref (GTK_OBJECT (msg)); + goto done; + } + + if (!cache) + camel_folder_delete_message (source, uids->pdata[i]); + gtk_object_unref (GTK_OBJECT (msg)); + } + + camel_folder_sync (source, TRUE, ex); + + done: + if (cache) { + camel_uid_cache_free_uids (uids); + if (!camel_exception_is_set (ex)) + camel_uid_cache_save (cache); + camel_uid_cache_destroy (cache); + } else + camel_folder_free_uids (source, uids); +} + void real_fetch_mail (gpointer user_data) { @@ -144,10 +222,12 @@ real_fetch_mail (gpointer user_data) char *tmp_mbox = NULL, *source; guint handler_id = 0; struct stat st; + gboolean keep; info = (rfm_t *) user_data; fb = info->fb; - url = info->source_url; + url = info->source->url; + keep = info->source->keep_on_server; /* If using IMAP, don't do anything... */ if (!strncmp (url, "imap:", 5)) @@ -236,49 +316,17 @@ real_fetch_mail (gpointer user_data) /* can we perform filtering on this source? */ if (!(sourcefolder->has_summary_capability && sourcefolder->has_search_capability)) { - GPtrArray *uids; - int i; - folder = camel_store_get_folder (dest_store, "movemail", TRUE, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { + if (camel_exception_is_set (ex)) { async_mail_exception_dialog ("Unable to move mail", ex, fb); goto cleanup; } - - uids = camel_folder_get_uids (sourcefolder); - printf("got %d messages in source\n", uids->len); - for (i = 0; i < uids->len; i++) { - CamelMimeMessage *msg; - - msg = camel_folder_get_message (sourcefolder, uids->pdata[i], ex); - - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to get read message", ex, fb); - gtk_object_unref (GTK_OBJECT (sourcefolder)); - gtk_object_unref (GTK_OBJECT (msg)); - - goto cleanup; - } - - /* append with flags = 0 since this is a new message */ - camel_folder_append_message (folder, msg, 0, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to write message", ex, fb); - gtk_object_unref (GTK_OBJECT (msg)); - gtk_object_unref (GTK_OBJECT (sourcefolder)); - - goto cleanup; - } - - camel_folder_delete_message (sourcefolder, uids->pdata[i]); - gtk_object_unref (GTK_OBJECT (msg)); - } - camel_folder_free_uids (sourcefolder, uids); - camel_folder_sync (sourcefolder, TRUE, ex); - if (camel_exception_is_set (ex)) - async_mail_exception_dialog ("", ex, fb); + + fetch_remote_mail (sourcefolder, folder, keep, fb, ex); gtk_object_unref (GTK_OBJECT (sourcefolder)); + if (camel_exception_is_set (ex)) + goto cleanup; } else { folder = sourcefolder; } @@ -328,8 +376,6 @@ real_fetch_mail (gpointer user_data) gtk_object_unref((GtkObject *)driver); if (fc) gtk_object_unref((GtkObject *)fc); - if (url) - g_free (url); if (folder) { camel_folder_sync (folder, TRUE, ex); @@ -357,16 +403,13 @@ void fetch_mail (GtkWidget *button, gpointer user_data) { MailConfigService *source; - char *url = NULL; rfm_t *info; if (!check_configured ()) return; source = mail_config_get_default_source (); - url = source->url; - - if (!url) { + if (!source || !source->url) { GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), GTK_TYPE_WINDOW); @@ -382,7 +425,8 @@ fetch_mail (GtkWidget *button, gpointer user_data) info = g_new (rfm_t, 1); info->fb = FOLDER_BROWSER (user_data); - info->source_url = url; + info->source = source; + #ifdef USE_BROKEN_THREADS mail_operation_try (_("Fetching mail"), real_fetch_mail, NULL, info); #else -- cgit v1.2.3