[evolution] Bug 499319 - Add "Empty Junk" to Junk folder context menu



commit f2ac49424354887be4c26005b9f34f5f5dbd5b89
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jun 15 16:58:49 2017 +0200

    Bug 499319 - Add "Empty Junk" to Junk folder context menu

 data/org.gnome.evolution.mail.gschema.xml.in |    5 +
 data/ui/evolution-mail.ui                    |    1 +
 src/mail/e-mail-reader-utils.c               |  160 ++++++++++++++++++++++++++
 src/mail/e-mail-reader-utils.h               |    6 +
 src/mail/e-mail-sidebar.c                    |    1 +
 src/mail/mail-config.ui                      |   16 +++
 src/mail/mail.error.xml                      |   11 ++
 src/modules/mail/e-mail-shell-view-actions.c |   43 +++++++
 src/modules/mail/e-mail-shell-view-actions.h |    2 +
 src/modules/mail/e-mail-shell-view.c         |    7 +
 src/modules/mail/em-mailer-prefs.c           |    6 +
 11 files changed, 258 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.evolution.mail.gschema.xml.in b/data/org.gnome.evolution.mail.gschema.xml.in
index def0bd9..3d0c3cf 100644
--- a/data/org.gnome.evolution.mail.gschema.xml.in
+++ b/data/org.gnome.evolution.mail.gschema.xml.in
@@ -456,6 +456,11 @@
       <_summary>Prompt when user expunges</_summary>
       <_description>Prompt the user when he or she tries to expunge a folder.</_description>
     </key>
+    <key name="prompt-on-empty-junk" type="b">
+      <default>true</default>
+      <_summary>Prompt when user calls Empty Junk</_summary>
+      <_description>Prompt the user when he or she tries to Empty a Junk folder.</_description>
+    </key>
     <key name="prompt-on-invalid-recip" type="b">
       <default>true</default>
       <_summary>Prompt before sending to recipients not entered as mail addresses</_summary>
diff --git a/data/ui/evolution-mail.ui b/data/ui/evolution-mail.ui
index eb455f3..edf2d07 100644
--- a/data/ui/evolution-mail.ui
+++ b/data/ui/evolution-mail.ui
@@ -102,6 +102,7 @@
     <menuitem action='mail-popup-account-properties'/>
     <menuitem action='mail-popup-folder-properties'/>
     <separator/>
+    <menuitem action='mail-popup-account-empty-junk'/>
     <menuitem action='mail-popup-account-expunge'/>
   </popup>
   <popup name='mail-message-popup'>
diff --git a/src/mail/e-mail-reader-utils.c b/src/mail/e-mail-reader-utils.c
index 1ee250f..8513c51 100644
--- a/src/mail/e-mail-reader-utils.c
+++ b/src/mail/e-mail-reader-utils.c
@@ -551,6 +551,166 @@ e_mail_reader_expunge_folder_name (EMailReader *reader,
        g_object_unref (activity);
 }
 
+static void
+mail_reader_empty_junk_thread (EAlertSinkThreadJobData *job_data,
+                              gpointer user_data,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+       AsyncContext *async_context = user_data;
+       CamelFolder *folder;
+       CamelFolderSummary *summary;
+       GPtrArray *uids;
+       guint ii;
+
+       g_return_if_fail (async_context != NULL);
+
+       folder = async_context->folder;
+
+       g_return_if_fail (CAMEL_IS_FOLDER (folder));
+       g_return_if_fail ((camel_folder_get_flags (folder) & CAMEL_FOLDER_IS_JUNK) != 0);
+
+       camel_folder_freeze (folder);
+
+       summary = camel_folder_get_folder_summary (folder);
+       if (summary)
+               camel_folder_summary_prepare_fetch_all (summary, NULL);
+
+       uids = camel_folder_get_uids (folder);
+       if (uids) {
+               for (ii = 0; ii < uids->len; ii++) {
+                       CamelMessageInfo *nfo;
+
+                       nfo = camel_folder_get_message_info (folder, uids->pdata[ii]);
+                       if (nfo) {
+                               camel_message_info_set_flags (nfo, CAMEL_MESSAGE_DELETED, 
CAMEL_MESSAGE_DELETED);
+                               g_object_unref (nfo);
+                       }
+               }
+
+               if (uids->len > 0)
+                       camel_folder_synchronize_sync (folder, FALSE, cancellable, error);
+
+               camel_folder_free_uids (folder, uids);
+       }
+
+       camel_folder_thaw (folder);
+}
+
+void
+e_mail_reader_empty_junk_folder (EMailReader *reader,
+                                CamelFolder *folder)
+{
+       GtkWindow *window;
+       const gchar *display_name;
+       gchar *full_display_name;
+       gboolean proceed;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+       g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+       window = e_mail_reader_get_window (reader);
+       display_name = camel_folder_get_display_name (folder);
+       full_display_name = e_mail_folder_to_full_display_name (folder, NULL);
+       if (full_display_name)
+               display_name = full_display_name;
+
+       proceed = e_util_prompt_user (window, "org.gnome.evolution.mail", "prompt-on-empty-junk",
+               "mail:ask-empty-junk", display_name, NULL);
+
+       if (proceed) {
+               AsyncContext *async_context;
+               EAlertSink *alert_sink;
+               EActivity *activity;
+               gchar *description;
+
+               alert_sink = e_mail_reader_get_alert_sink (reader);
+
+               async_context = g_slice_new0 (AsyncContext);
+               async_context->reader = g_object_ref (reader);
+               async_context->folder = g_object_ref (folder);
+
+               description = g_strdup_printf (_("Deleting messages in Junk folder ”%s”…"), display_name);
+
+               activity = e_alert_sink_submit_thread_job (alert_sink,
+                       description, "mail:failed-empty-junk", display_name,
+                       mail_reader_empty_junk_thread, async_context,
+                       (GDestroyNotify) async_context_free);
+
+               g_clear_object (&activity);
+               g_free (description);
+       }
+
+       g_free (full_display_name);
+}
+
+static void
+mail_reader_empty_junk_folder_name_cb (GObject *source_object,
+                                      GAsyncResult *result,
+                                      gpointer user_data)
+{
+       CamelFolder *folder;
+       EActivity *activity;
+       EAlertSink *alert_sink;
+       AsyncContext *async_context;
+       GError *local_error = NULL;
+
+       async_context = (AsyncContext *) user_data;
+
+       activity = async_context->activity;
+       alert_sink = e_activity_get_alert_sink (activity);
+
+       folder = camel_store_get_folder_finish (CAMEL_STORE (source_object), result, &local_error);
+
+       if (e_activity_handle_cancellation (activity, local_error)) {
+               g_error_free (local_error);
+
+       } else if (local_error != NULL) {
+               e_alert_submit (
+                       alert_sink, "mail:failed-empty-junk",
+                       async_context->folder_name,
+                       local_error->message, NULL);
+               g_error_free (local_error);
+
+       } else {
+               e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
+               e_mail_reader_empty_junk_folder (async_context->reader, folder);
+       }
+
+       async_context_free (async_context);
+       g_clear_object (&folder);
+}
+
+void
+e_mail_reader_empty_junk_folder_name (EMailReader *reader,
+                                     CamelStore *store,
+                                     const gchar *folder_name)
+{
+       EActivity *activity;
+       GCancellable *cancellable;
+       AsyncContext *async_context;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+       g_return_if_fail (CAMEL_IS_STORE (store));
+       g_return_if_fail (folder_name != NULL);
+
+       activity = e_mail_reader_new_activity (reader);
+       cancellable = e_activity_get_cancellable (activity);
+
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->activity = g_object_ref (activity);
+       async_context->reader = g_object_ref (reader);
+       async_context->folder_name = g_strdup (folder_name);
+
+       camel_store_get_folder (
+               store, folder_name,
+               0, G_PRIORITY_DEFAULT, cancellable,
+               mail_reader_empty_junk_folder_name_cb,
+               async_context);
+
+       g_object_unref (activity);
+}
+
 struct _process_autoarchive_msg {
        MailMsg base;
 
diff --git a/src/mail/e-mail-reader-utils.h b/src/mail/e-mail-reader-utils.h
index 46c95be..1fbd338 100644
--- a/src/mail/e-mail-reader-utils.h
+++ b/src/mail/e-mail-reader-utils.h
@@ -40,6 +40,12 @@ void         e_mail_reader_expunge_folder_name
                                                (EMailReader *reader,
                                                 CamelStore *store,
                                                 const gchar *folder_name);
+void           e_mail_reader_empty_junk_folder (EMailReader *reader,
+                                                CamelFolder *folder);
+void           e_mail_reader_empty_junk_folder_name
+                                               (EMailReader *reader,
+                                                CamelStore *store,
+                                                const gchar *folder_name);
 void           e_mail_reader_refresh_folder    (EMailReader *reader,
                                                 CamelFolder *folder);
 void           e_mail_reader_refresh_folder_name
diff --git a/src/mail/e-mail-sidebar.c b/src/mail/e-mail-sidebar.c
index 2d4f717..d6d6e59 100644
--- a/src/mail/e-mail-sidebar.c
+++ b/src/mail/e-mail-sidebar.c
@@ -463,6 +463,7 @@ mail_sidebar_check_state (EMailSidebar *sidebar)
                 * Used by Exchange and GroupWise accounts. */
                folder_type = (folder_flags & CAMEL_FOLDER_TYPE_MASK);
                is_trash |= (folder_type == CAMEL_FOLDER_TYPE_TRASH);
+               is_junk |= (folder_type == CAMEL_FOLDER_TYPE_JUNK);
 
                /* Is this a virtual folder (junk/trash/search)? */
                is_virtual |= (folder_flags & CAMEL_FOLDER_VIRTUAL);
diff --git a/src/mail/mail-config.ui b/src/mail/mail-config.ui
index 3424f9d..86c3ee3 100644
--- a/src/mail/mail-config.ui
+++ b/src/mail/mail-config.ui
@@ -2118,6 +2118,22 @@
                         <property name="position">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkCheckButton" id="chkConfirmEmptyJunk">
+                        <property name="label" translatable="yes">Confirm when emptying a _Junk 
folder</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="xalign">0.5</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
                   </object>
                 </child>
               </object>
diff --git a/src/mail/mail.error.xml b/src/mail/mail.error.xml
index d9a5e6b..2b82a3a 100644
--- a/src/mail/mail.error.xml
+++ b/src/mail/mail.error.xml
@@ -644,4 +644,15 @@ in the folder will be available in offline mode.</_secondary>
     <_secondary>A WebKitWebProcess crashed when displaying the signature. You can try again by moving to 
another signature and back. If the issue persists, please file a bug report in the GNOME 
bugzilla.</_secondary>
   </error>
 
+  <error id="ask-empty-junk" type="warning" default="GTK_RESPONSE_CANCEL">
+    <_primary>Are you sure you want to delete all the messages in the Junk folder?</_primary>
+    <_secondary xml:space="preserve">These messages will be shown in the Trash folder, where they can be 
permanently deleted later.</_secondary>
+    <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+    <button _label="_Empty Junk" response="GTK_RESPONSE_YES"/>
+  </error>
+
+  <error id="failed-empty-junk" type="error" default="GTK_RESPONSE_YES">
+    <_primary>Failed to empty Junk folder “{0}”</_primary>
+    <secondary>{1}</secondary>
+  </error>
 </error-list>
diff --git a/src/modules/mail/e-mail-shell-view-actions.c b/src/modules/mail/e-mail-shell-view-actions.c
index 1743a31..80c4726 100644
--- a/src/modules/mail/e-mail-shell-view-actions.c
+++ b/src/modules/mail/e-mail-shell-view-actions.c
@@ -475,6 +475,38 @@ action_mail_folder_expunge_cb (GtkAction *action,
        g_free (selected_folder_name);
 }
 
+static void
+action_mail_folder_empty_junk_cb (GtkAction *action,
+                                 EMailShellView *mail_shell_view)
+{
+       EMailShellContent *mail_shell_content;
+       EMailShellSidebar *mail_shell_sidebar;
+       EMailView *mail_view;
+       EMFolderTree *folder_tree;
+       CamelStore *selected_store = NULL;
+       gchar *selected_folder_name = NULL;
+
+       mail_shell_content = mail_shell_view->priv->mail_shell_content;
+       mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
+
+       mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+       folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+       /* Get the folder from the folder tree, not the message list.
+        * This correctly handles the use case of right-clicking on
+        * the "Junk" folder and selecting "Empty Junk" without
+        * actually selecting the folder. In that case the message
+        * list would not contain the correct folder. */
+       em_folder_tree_get_selected (folder_tree, &selected_store, &selected_folder_name);
+       g_return_if_fail (CAMEL_IS_STORE (selected_store));
+       g_return_if_fail (selected_folder_name != NULL);
+
+       e_mail_reader_empty_junk_folder_name (E_MAIL_READER (mail_view), selected_store, 
selected_folder_name);
+
+       g_object_unref (selected_store);
+       g_free (selected_folder_name);
+}
+
 typedef struct _AsyncContext {
        EActivity *activity;
        EMailShellView *mail_shell_view;
@@ -1601,6 +1633,13 @@ static GtkActionEntry mail_entries[] = {
          N_("Permanently remove all the deleted messages from all folders"),
          G_CALLBACK (action_mail_folder_expunge_cb) },
 
+       { "mail-account-empty-junk",
+         NULL,
+         N_("Empty _Junk"),
+         NULL,
+         N_("Delete all Junk messages from all folders"),
+         G_CALLBACK (action_mail_folder_empty_junk_cb) },
+
        { "mail-account-properties",
          "document-properties",
          N_("_Properties"),
@@ -1893,6 +1932,10 @@ static EPopupActionEntry mail_popup_entries[] = {
          NULL,
          "mail-account-expunge" },
 
+       { "mail-popup-account-empty-junk",
+         NULL,
+         "mail-account-empty-junk" },
+
        { "mail-popup-account-refresh",
          NULL,
          "mail-account-refresh" },
diff --git a/src/modules/mail/e-mail-shell-view-actions.h b/src/modules/mail/e-mail-shell-view-actions.h
index f3fbd32..bf6c65e 100644
--- a/src/modules/mail/e-mail-shell-view-actions.h
+++ b/src/modules/mail/e-mail-shell-view-actions.h
@@ -28,6 +28,8 @@
        E_SHELL_WINDOW_ACTION ((window), "mail-account-disable")
 #define E_SHELL_WINDOW_ACTION_MAIL_ACCOUNT_EXPUNGE(window) \
        E_SHELL_WINDOW_ACTION ((window), "mail-account-expunge")
+#define E_SHELL_WINDOW_ACTION_MAIL_ACCOUNT_EMPTY_JUNK(window) \
+       E_SHELL_WINDOW_ACTION ((window), "mail-account-empty-junk")
 #define E_SHELL_WINDOW_ACTION_MAIL_ACCOUNT_PROPERTIES(window) \
        E_SHELL_WINDOW_ACTION ((window), "mail-account-properties")
 #define E_SHELL_WINDOW_ACTION_MAIL_ACCOUNT_REFRESH(window) \
diff --git a/src/modules/mail/e-mail-shell-view.c b/src/modules/mail/e-mail-shell-view.c
index 3d25ed8..53ae0f9 100644
--- a/src/modules/mail/e-mail-shell-view.c
+++ b/src/modules/mail/e-mail-shell-view.c
@@ -1011,6 +1011,7 @@ mail_shell_view_update_actions (EShellView *shell_view)
        /* Be descriptive. */
        gboolean folder_allows_children;
        gboolean folder_can_be_deleted;
+       gboolean folder_is_junk;
        gboolean folder_is_outbox;
        gboolean folder_is_selected = FALSE;
        gboolean folder_is_store;
@@ -1056,6 +1057,8 @@ mail_shell_view_update_actions (EShellView *shell_view)
                (state & E_MAIL_SIDEBAR_FOLDER_IS_STORE);
        folder_is_trash =
                (state & E_MAIL_SIDEBAR_FOLDER_IS_TRASH);
+       folder_is_junk =
+               (state & E_MAIL_SIDEBAR_FOLDER_IS_JUNK);
        folder_is_virtual =
                (state & E_MAIL_SIDEBAR_FOLDER_IS_VIRTUAL);
        store_is_builtin =
@@ -1136,6 +1139,10 @@ mail_shell_view_update_actions (EShellView *shell_view)
        sensitive = folder_is_trash;
        gtk_action_set_sensitive (action, sensitive);
 
+       action = ACTION (MAIL_ACCOUNT_EMPTY_JUNK);
+       sensitive = folder_is_junk;
+       gtk_action_set_sensitive (action, sensitive);
+
        action = ACTION (MAIL_ACCOUNT_PROPERTIES);
        sensitive = folder_is_store && !store_is_builtin;
        gtk_action_set_sensitive (action, sensitive);
diff --git a/src/modules/mail/em-mailer-prefs.c b/src/modules/mail/em-mailer-prefs.c
index c82234c..1949f8d 100644
--- a/src/modules/mail/em-mailer-prefs.c
+++ b/src/modules/mail/em-mailer-prefs.c
@@ -1282,6 +1282,12 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs,
                widget, "active",
                G_SETTINGS_BIND_DEFAULT);
 
+       widget = e_builder_get_widget (prefs->priv->builder, "chkConfirmEmptyJunk");
+       g_settings_bind (
+               settings, "prompt-on-empty-junk",
+               widget, "active",
+               G_SETTINGS_BIND_DEFAULT);
+
        /* Mail Fonts */
        widget = e_builder_get_widget (prefs->priv->builder, "radFontUseSame");
        g_settings_bind (


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]