* Added the operation cancel_all_operations to the progress objects
authorSergio Villar Senin <svillar@igalia.com>
Fri, 13 Jul 2007 17:05:36 +0000 (17:05 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Fri, 13 Jul 2007 17:05:36 +0000 (17:05 +0000)
* The cancel button now invokes the cancel_all operation
* Fixed modest_mail_operation cancel, now it really calls tny_account_cancel
* Removed the ugly did_a_cancel static boolean in the mail operations
* Fixed a leak with the new headers received when doing a send&receive
* Fixes NB#62946, several clicks on cancel do not make the application crash when S&R
* Fixed the new_headers count that was returned by the update_account_thread, it was wrong and was returning always 0 because the new_headers were freed before

pmo-trunk-r2735

src/maemo/modest-main-window.c
src/maemo/modest-progress-bar-widget.c
src/modest-mail-operation-queue.c
src/modest-mail-operation.c
src/modest-progress-object.c
src/modest-progress-object.h

index 15bb6ca..630a5de 100644 (file)
@@ -2015,10 +2015,10 @@ cancel_progressbar (GtkToolButton *toolbutton,
        
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
 
-       /* Get operation observers and cancel its current operation */
+       /* Get operation observers and cancel all the operations */
        tmp = priv->progress_widgets;
        while (tmp) {
-               modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
+               modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
                tmp=g_slist_next(tmp);
        }
 }
index 33b54bd..e8ce5d8 100644 (file)
@@ -33,6 +33,7 @@
 #include "modest-progress-bar-widget.h"
 #include <string.h>
 #include "modest-platform.h"
+#include "modest-runtime.h"
 
 /* 'private'/'protected' functions */
 static void modest_progress_bar_widget_class_init (ModestProgressBarWidgetClass *klass);
@@ -45,11 +46,11 @@ static void modest_progress_bar_add_operation    (ModestProgressObject *self,
 static void modest_progress_bar_remove_operation (ModestProgressObject *self,
                                                    ModestMailOperation  *mail_op);
 
-static void 
-modest_progress_bar_cancel_current_operation (ModestProgressObject *self);
+static void modest_progress_bar_cancel_current_operation (ModestProgressObject *self);
 
-static guint
-modest_progress_bar_num_pending_operations (ModestProgressObject *self);
+static void modest_progress_bar_cancel_all_operations    (ModestProgressObject *self);
+
+static guint modest_progress_bar_num_pending_operations (ModestProgressObject *self);
 
 static void on_progress_changed                    (ModestMailOperation  *mail_op, 
                                                    ModestMailOperationState *state,
@@ -90,9 +91,6 @@ struct _ModestProgressBarWidgetPrivate {
 /* globals */
 static GtkContainerClass *parent_class = NULL;
 
-/* Flag to show or not show Recv cancellation banner */
-static gboolean f_receivingOngoing = FALSE;
-
 /* uncomment the following if you have defined any signals */
 /* static guint signals[LAST_SIGNAL] = {0}; */
 
@@ -104,6 +102,7 @@ modest_progress_object_init (gpointer g, gpointer iface_data)
        klass->add_operation_func = modest_progress_bar_add_operation;
        klass->remove_operation_func = modest_progress_bar_remove_operation;
        klass->cancel_current_operation_func = modest_progress_bar_cancel_current_operation;
+       klass->cancel_all_operations_func = modest_progress_bar_cancel_all_operations;
        klass->num_pending_operations_func = modest_progress_bar_num_pending_operations;
 }
 
@@ -175,7 +174,7 @@ modest_progress_bar_widget_init (ModestProgressBarWidget *self)
        GtkAdjustment *adj;
 
        priv = MODEST_PROGRESS_BAR_WIDGET_GET_PRIVATE(self);
-       
+
        /* Alignment */
        align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
 
@@ -262,19 +261,22 @@ compare_observable_data (ObservableData *data1, ObservableData *data2)
 
 static void 
 modest_progress_bar_remove_operation (ModestProgressObject *self,
-                                       ModestMailOperation  *mail_op)
+                                     ModestMailOperation  *mail_op)
 {
        ModestProgressBarWidget *me;
        ModestProgressBarWidgetPrivate *priv;
        GSList *link;
        ObservableData *tmp_data = NULL;
+       gboolean is_current;
 
        me = MODEST_PROGRESS_BAR_WIDGET (self);
        priv = MODEST_PROGRESS_BAR_WIDGET_GET_PRIVATE (me);
 
+       is_current = (priv->current == mail_op);
+
        /* Find item */
        tmp_data = g_malloc0 (sizeof (ObservableData));
-        tmp_data->mail_op = mail_op;  
+        tmp_data->mail_op = mail_op;
        link = g_slist_find_custom (priv->observables,
                                    tmp_data,
                                    (GCompareFunc) compare_observable_data);
@@ -291,7 +293,7 @@ modest_progress_bar_remove_operation (ModestProgressObject *self,
        }
        
        /* Update the current mail operation */
-       if (priv->current == mail_op) {
+       if (is_current) {
                if (priv->observables)
                        priv->current = ((ObservableData *) priv->observables->data)->mail_op;
                else
@@ -328,17 +330,35 @@ modest_progress_bar_cancel_current_operation (ModestProgressObject *self)
 
        if (priv->current == NULL) return;
 
-       /* bug 59107: if received canceled we shall show banner */
-       if ( f_receivingOngoing )
-       {
-               f_receivingOngoing = FALSE;
-               modest_platform_information_banner (NULL, NULL, _("emev_ib_ui_pop3_msg_recv_cancel"));
-       }
+       /* If received canceled we shall show banner */
+       if (modest_mail_operation_get_type_operation (priv->current) ==
+           MODEST_MAIL_OPERATION_TYPE_RECEIVE)
+               modest_platform_information_banner (NULL, NULL, 
+                                                   _("emev_ib_ui_pop3_msg_recv_cancel"));
 
        modest_mail_operation_cancel (priv->current);
 }
 
 static void 
+modest_progress_bar_cancel_all_operations (ModestProgressObject *self)
+{
+       ModestProgressBarWidget *me;
+       ModestProgressBarWidgetPrivate *priv;
+
+       me = MODEST_PROGRESS_BAR_WIDGET (self);
+       priv = MODEST_PROGRESS_BAR_WIDGET_GET_PRIVATE (me);
+
+       /* If received canceled we shall show banner */
+       if (priv->current && modest_mail_operation_get_type_operation (priv->current) ==
+           MODEST_MAIL_OPERATION_TYPE_RECEIVE)
+               modest_platform_information_banner (NULL, NULL, 
+                                                   _("emev_ib_ui_pop3_msg_recv_cancel"));
+
+       /* Cancel all the mail operations */
+       modest_mail_operation_queue_cancel_all (modest_runtime_get_mail_operation_queue ());
+}
+
+static void 
 on_progress_changed (ModestMailOperation  *mail_op, 
                     ModestMailOperationState *state,
                     ModestProgressBarWidget *self)
@@ -346,7 +366,6 @@ on_progress_changed (ModestMailOperation  *mail_op,
        ModestProgressBarWidgetPrivate *priv;
        gboolean determined = FALSE;
 
-       f_receivingOngoing = FALSE;
        priv = MODEST_PROGRESS_BAR_WIDGET_GET_PRIVATE (self);
 
        /* If the mail operation is the currently shown one */
@@ -358,7 +377,6 @@ on_progress_changed (ModestMailOperation  *mail_op,
 
                switch (state->op_type) {
                case MODEST_MAIL_OPERATION_TYPE_RECEIVE:                
-                       f_receivingOngoing = TRUE;
                        if (determined)
                                msg = g_strdup_printf(_("mcen_me_receiving"),
                                                      state->done, state->total); 
index db3465f..7bf680b 100644 (file)
@@ -316,8 +316,10 @@ modest_mail_operation_queue_cancel (ModestMailOperationQueue *self,
 static void
 on_cancel_all_foreach (gpointer op, gpointer list)
 {
-       g_return_if_fail (list);
-       *((GSList**)list) = g_slist_prepend (*((GSList**)list), MODEST_MAIL_OPERATION (op));
+       GSList **new_list;
+
+       new_list = (GSList**) list;
+       *new_list = g_slist_prepend (*new_list, MODEST_MAIL_OPERATION (op));
 }
 
 void 
@@ -343,8 +345,6 @@ modest_mail_operation_queue_cancel_all (ModestMailOperationQueue *self)
        /* TODO: Reverse the list, to remove operations in order? */
 
        for(cur = operations_to_cancel; cur != NULL; cur = cur->next) {
-               /* This triggers a progress_changed signal in which we remove
-                * the operation from the queue. */
                if (!MODEST_IS_MAIL_OPERATION(cur->data))
                        g_printerr ("modest: cur->data is not a valid mail operation\n");
                else
index 47554e8..a1c308d 100644 (file)
@@ -83,8 +83,6 @@ static void     get_msg_status_cb (GObject *obj,
 
 static void     modest_mail_operation_notify_end (ModestMailOperation *self);
 
-static gboolean did_a_cancel = FALSE;
-
 enum _ModestMailOperationSignals 
 {
        PROGRESS_CHANGED_SIGNAL,
@@ -402,24 +400,26 @@ gboolean
 modest_mail_operation_cancel (ModestMailOperation *self)
 {
        ModestMailOperationPrivate *priv;
+       gboolean canceled = FALSE;
 
-       if (!MODEST_IS_MAIL_OPERATION (self)) {
-               g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
-               return FALSE;
-       }
+       g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
-       if (!priv) {
-               g_warning ("BUG: %s: priv == NULL", __FUNCTION__);
-               return FALSE;
-       }
 
-       did_a_cancel = TRUE;
+       /* Note that if we call cancel with an already canceled mail
+          operation the progress changed signal won't be emitted */
+       if (priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED)
+               return FALSE;
 
        /* Set new status */
        priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
        
-       return TRUE;
+       /* Cancel the mail operation. We need to wrap it between this
+          start/stop operations to allow following calls to the
+          account */
+       tny_account_cancel (priv->account);
+
+       return canceled;
 }
 
 guint 
@@ -1146,6 +1146,7 @@ update_account_thread (gpointer thr_user_data)
        TnyFolderStoreQuery *query = NULL;
        ModestMailOperationPrivate *priv = NULL;
        ModestTnySendQueue *send_queue = NULL;
+       gint num_new_headers;
 
        info = (UpdateAccountInfo *) thr_user_data;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
@@ -1192,10 +1193,12 @@ update_account_thread (gpointer thr_user_data)
        gint timeout = g_timeout_add (100, idle_notify_progress, info->mail_op);
 
        /* Refresh folders */
+       num_new_headers = 0;
        new_headers = g_ptr_array_new ();
        iter = tny_list_create_iterator (all_folders);
 
-       while (!tny_iterator_is_done (iter) && !priv->error && !did_a_cancel) {
+       while (!tny_iterator_is_done (iter) && !priv->error && 
+              priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
 
                InternalFolderObserver *observer;
                TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
@@ -1244,20 +1247,17 @@ update_account_thread (gpointer thr_user_data)
 
                g_object_unref (G_OBJECT (folder));
                if (priv->error)
-               {
                        priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-                       goto out;
-               }
-               
+
                tny_iterator_next (iter);
        }
 
-       did_a_cancel = FALSE;
-
        g_object_unref (G_OBJECT (iter));
        g_source_remove (timeout);
 
-       if (new_headers->len > 0) {
+       if (priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED && 
+           priv->status != MODEST_MAIL_OPERATION_STATUS_FAILED &&
+           new_headers->len > 0) {
                gint msg_num = 0;
 
                /* Order by date */
@@ -1305,12 +1305,17 @@ update_account_thread (gpointer thr_user_data)
 
                        msg_num++;
                }
-               g_ptr_array_foreach (new_headers, (GFunc) g_object_unref, NULL);
-               g_ptr_array_free (new_headers, FALSE);
        }
+
+       /* Get the number of new headers and free them */
+       num_new_headers = new_headers->len;
+       g_ptr_array_foreach (new_headers, (GFunc) g_object_unref, NULL);
+       g_ptr_array_free (new_headers, FALSE);
        
+       if (priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED)
+               goto out;
+
        /* Perform send (if operation was not cancelled) */
-       if (did_a_cancel) goto out;             
 /*     priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND; */
        priv->done = 0;
        priv->total = 0;
@@ -1350,7 +1355,7 @@ update_account_thread (gpointer thr_user_data)
                /* This thread is not in the main lock */
                idle_info = g_malloc0 (sizeof (UpdateAccountInfo));
                idle_info->mail_op = g_object_ref (info->mail_op);
-               idle_info->new_headers = (new_headers) ? new_headers->len : 0;
+               idle_info->new_headers = num_new_headers;
                idle_info->callback = info->callback;
                g_idle_add (idle_update_account_cb, idle_info);
        }
@@ -2075,21 +2080,6 @@ get_msg_status_cb (GObject *obj,
        self = helper->mail_op;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
 
-       if(priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED) {
-               TnyFolder *folder = tny_header_get_folder (helper->header);
-               if (folder) {
-                       TnyAccount *account;
-                       account = tny_folder_get_account (folder);
-                       if (account) {
-                               tny_account_cancel (account);
-                               g_object_unref (account);
-                       }
-                       g_object_unref (folder);
-               }
-              
-               return;
-       }
-
        priv->done = 1;
        priv->total = 1;
 
@@ -2592,7 +2582,7 @@ on_refresh_folder (TnyFolder   *folder,
        }
 
        /* Free */
-       g_object_unref (helper->mail_op);
+/*     g_object_unref (helper->mail_op); */
        g_slice_free   (RefreshAsyncHelper, helper);
 
        /* Notify about operation end */
index 44cd6d1..6de3451 100644 (file)
@@ -51,6 +51,12 @@ modest_progress_object_cancel_current_operation (ModestProgressObject *self)
        return MODEST_PROGRESS_OBJECT_GET_IFACE (self)->cancel_current_operation_func (self);
 }
 
+void 
+modest_progress_object_cancel_all_operations (ModestProgressObject *self)
+{
+       return MODEST_PROGRESS_OBJECT_GET_IFACE (self)->cancel_all_operations_func (self);
+}
+
 guint
 modest_progress_object_num_pending_operations (ModestProgressObject *self) 
 {
@@ -90,5 +96,3 @@ modest_progress_object_get_type (void)
        }
        return my_type;
 }
-
-
index b8a59c2..55f7990 100644 (file)
@@ -48,10 +48,13 @@ struct _ModestProgressObjectIface {
        GTypeInterface parent;
 
        /* the 'vtable': declare function pointers here, eg.: */
-       void (*add_operation_func) (ModestProgressObject *self, ModestMailOperation *mail_op);
-       void (*remove_operation_func) (ModestProgressObject *self, ModestMailOperation *mail_op);
-       void (*cancel_current_operation_func) (ModestProgressObject *self);
-       guint (*num_pending_operations_func) (ModestProgressObject *self);
+       void (*add_operation_func)    (ModestProgressObject *self, 
+                                      ModestMailOperation *mail_op);
+       void (*remove_operation_func) (ModestProgressObject *self, 
+                                      ModestMailOperation *mail_op);
+       void  (*cancel_current_operation_func) (ModestProgressObject *self);
+       void  (*cancel_all_operations_func)    (ModestProgressObject *self);
+       guint (*num_pending_operations_func)   (ModestProgressObject *self);
 };
 
 GType     modest_progress_object_get_type            (void) G_GNUC_CONST;
@@ -61,9 +64,12 @@ void      modest_progress_object_add_operation       (ModestProgressObject *self
 
 void      modest_progress_object_remove_operation    (ModestProgressObject *self,
                                                      ModestMailOperation  *mail_op);
+
 void      modest_progress_object_cancel_current_operation (ModestProgressObject *self);
 
-guint      modest_progress_object_num_pending_operations (ModestProgressObject *self);
+void      modest_progress_object_cancel_all_operations    (ModestProgressObject *self);
+
+guint      modest_progress_object_num_pending_operations  (ModestProgressObject *self);
 
 G_END_DECLS