From cd1ae71abedf78491c1f34d1fb1a772064d87b8e Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Fri, 13 Jul 2007 17:05:36 +0000 Subject: [PATCH 1/1] * Added the operation cancel_all_operations to the progress objects * 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 | 4 +- src/maemo/modest-progress-bar-widget.c | 56 ++++++++++++++++--------- src/modest-mail-operation-queue.c | 8 ++-- src/modest-mail-operation.c | 70 ++++++++++++++------------------ src/modest-progress-object.c | 8 +++- src/modest-progress-object.h | 16 +++++--- 6 files changed, 90 insertions(+), 72 deletions(-) diff --git a/src/maemo/modest-main-window.c b/src/maemo/modest-main-window.c index 15bb6ca..630a5de 100644 --- a/src/maemo/modest-main-window.c +++ b/src/maemo/modest-main-window.c @@ -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); } } diff --git a/src/maemo/modest-progress-bar-widget.c b/src/maemo/modest-progress-bar-widget.c index 33b54bd..e8ce5d8 100644 --- a/src/maemo/modest-progress-bar-widget.c +++ b/src/maemo/modest-progress-bar-widget.c @@ -33,6 +33,7 @@ #include "modest-progress-bar-widget.h" #include #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); diff --git a/src/modest-mail-operation-queue.c b/src/modest-mail-operation-queue.c index db3465f..7bf680b 100644 --- a/src/modest-mail-operation-queue.c +++ b/src/modest-mail-operation-queue.c @@ -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 diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 47554e8..a1c308d 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -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 */ diff --git a/src/modest-progress-object.c b/src/modest-progress-object.c index 44cd6d1..6de3451 100644 --- a/src/modest-progress-object.c +++ b/src/modest-progress-object.c @@ -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; } - - diff --git a/src/modest-progress-object.h b/src/modest-progress-object.h index b8a59c2..55f7990 100644 --- a/src/modest-progress-object.h +++ b/src/modest-progress-object.h @@ -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 -- 1.7.9.5