aboutsummaryrefslogtreecommitdiffstats
path: root/mail/e-mail-reader-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/e-mail-reader-utils.c')
-rw-r--r--mail/e-mail-reader-utils.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
index 16964674b0..374bed0f0e 100644
--- a/mail/e-mail-reader-utils.c
+++ b/mail/e-mail-reader-utils.c
@@ -34,6 +34,7 @@
#include "mail/e-mail-backend.h"
#include "mail/e-mail-browser.h"
+#include "mail/e-mail-folder-utils.h"
#include "mail/em-composer-utils.h"
#include "mail/em-format-html-print.h"
#include "mail/em-utils.h"
@@ -43,6 +44,25 @@
#include "mail/mail-vfolder.h"
#include "mail/message-list.h"
+typedef struct _AsyncContext AsyncContext;
+
+struct _AsyncContext {
+ EActivity *activity;
+ EMailReader *reader;
+};
+
+static void
+async_context_free (AsyncContext *context)
+{
+ if (context->activity != NULL)
+ g_object_unref (context->activity);
+
+ if (context->reader != NULL)
+ g_object_unref (context->reader);
+
+ g_slice_free (AsyncContext, context);
+}
+
void
e_mail_reader_activate (EMailReader *reader,
const gchar *action_name)
@@ -337,6 +357,143 @@ exit:
em_utils_uids_free (uids);
}
+static void
+mail_reader_remove_duplicates_cb (CamelFolder *folder,
+ GAsyncResult *result,
+ AsyncContext *context)
+{
+ EAlertSink *alert_sink;
+ GHashTable *duplicates;
+ GtkWindow *parent_window;
+ guint n_duplicates;
+ GError *error = NULL;
+
+ alert_sink = e_mail_reader_get_alert_sink (context->reader);
+ parent_window = e_mail_reader_get_window (context->reader);
+
+ duplicates = e_mail_folder_find_duplicate_messages_finish (
+ folder, result, &error);
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warn_if_fail (duplicates == NULL);
+ e_activity_set_state (context->activity, E_ACTIVITY_CANCELLED);
+ async_context_free (context);
+ g_error_free (error);
+ return;
+
+ } else if (error != NULL) {
+ g_warn_if_fail (duplicates == NULL);
+ e_alert_submit (
+ alert_sink,
+ "mail:find-duplicate-messages",
+ error->message, NULL);
+ async_context_free (context);
+ g_error_free (error);
+ return;
+ }
+
+ g_return_if_fail (duplicates != NULL);
+
+ /* Finalize the activity here so we don't leave a message in
+ * the task bar while prompting the user for confirmation. */
+ e_activity_set_state (context->activity, E_ACTIVITY_COMPLETED);
+ g_object_unref (context->activity);
+ context->activity = NULL;
+
+ n_duplicates = g_hash_table_size (duplicates);
+
+ if (n_duplicates == 0) {
+ em_utils_prompt_user (
+ parent_window, NULL,
+ "mail:info-no-remove-duplicates",
+ camel_folder_get_display_name (folder), NULL);
+ } else {
+ gchar *confirmation;
+ gboolean proceed;
+
+ confirmation = g_strdup_printf (ngettext (
+ /* Translators: %s is replaced with a folder
+ * name %u with count of duplicate messages. */
+ "Folder '%s' contains %u duplicate message. "
+ "Are you sure you want to delete it?",
+ "Folder '%s' contains %u duplicate messages. "
+ "Are you sure you want to delete them?",
+ n_duplicates),
+ camel_folder_get_display_name (folder),
+ n_duplicates);
+
+ proceed = em_utils_prompt_user (
+ parent_window, NULL,
+ "mail:ask-remove-duplicates",
+ confirmation, NULL);
+
+ if (proceed) {
+ GHashTableIter iter;
+ gpointer key;
+
+ camel_folder_freeze (folder);
+
+ g_hash_table_iter_init (&iter, duplicates);
+
+ /* Mark duplicate messages for deletion. */
+ while (g_hash_table_iter_next (&iter, &key, NULL))
+ camel_folder_delete_message (folder, key);
+
+ camel_folder_thaw (folder);
+ }
+
+ g_free (confirmation);
+ }
+
+ g_hash_table_destroy (duplicates);
+
+ async_context_free (context);
+}
+
+void
+e_mail_reader_remove_duplicates (EMailReader *reader)
+{
+ AsyncContext *context;
+ GCancellable *cancellable;
+ EMailBackend *backend;
+ CamelFolder *folder;
+ GPtrArray *uids;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ folder = e_mail_reader_get_folder (reader);
+ uids = e_mail_reader_get_selected_uids (reader);
+ g_return_if_fail (uids != NULL);
+
+ /* XXX Either e_mail_reader_get_selected_uids()
+ * or MessageList should do this itself. */
+ g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
+
+ /* Find duplicate messages asynchronously. */
+
+ context = g_slice_new0 (AsyncContext);
+ context->activity = e_activity_new ();
+ context->reader = g_object_ref (reader);
+
+ cancellable = camel_operation_new ();
+ e_activity_set_cancellable (context->activity, cancellable);
+
+ backend = e_mail_reader_get_backend (reader);
+ e_shell_backend_add_activity (
+ E_SHELL_BACKEND (backend), context->activity);
+
+ e_mail_folder_find_duplicate_messages (
+ folder, uids, G_PRIORITY_DEFAULT,
+ cancellable, (GAsyncReadyCallback)
+ mail_reader_remove_duplicates_cb,
+ context);
+
+ g_object_unref (cancellable);
+
+ g_ptr_array_unref (uids);
+}
+
/* Helper for e_mail_reader_reply_to_message()
* XXX This function belongs in e-html-utils.c */
static gboolean