From: Sergio Villar Senin Date: Wed, 4 Jul 2007 13:37:34 +0000 (+0000) Subject: * Added a method to unregister a header in the window manager in case of error X-Git-Tag: git_migration_finished~2973 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=63f8fe0a7c7eeae9c390bc87fb97703fe54438d8 * Added a method to unregister a header in the window manager in case of error * Changed the way the information dialogs are shown, now they do not use gtk_dialog_run * Refactored the code that opens a message in the msg view window * Refactored the code that asks the user for a download approval * Reverted some changes in the modest_mail_operation_get_msg, the callback must be always called even in case of error * Modified all the modest_mail_operation_get_msg callbacks to handle properly errors in the mail operation pmo-trunk-r2565 --- diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index ff345e0..9f71d67 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -104,8 +104,6 @@ static gboolean set_toolbar_transfer_mode (ModestMsgViewWindow *self); static void update_window_title (ModestMsgViewWindow *window); -static gboolean download_uncached_message (TnyHeader *header, GtkWindow *win); - /* list my signals */ enum { @@ -1022,11 +1020,79 @@ modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window) } +/** + * Reads the message whose summary item is @header. It takes care of + * several things, among others: + * + * If the message was not previously downloaded then ask the user + * before downloading. If there is no connection launch the connection + * dialog. Update toolbar dimming rules. + * + * Returns: TRUE if the mail operation was started, otherwise if the + * user do not want to download the message, or if the user do not + * want to connect, then the operation is not issued + **/ +static gboolean +message_reader (ModestMsgViewWindow *window, + ModestMsgViewWindowPrivate *priv, + TnyHeader *header, + GtkTreeIter iter) +{ + ModestMailOperation *mail_op = NULL; + GtkTreePath *path = NULL; + ModestMailOperationTypeOperation op_type; + + /* Msg download completed */ + if (tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED) { + op_type = MODEST_MAIL_OPERATION_TYPE_OPEN; + } else { + TnyFolder *folder; + GtkResponseType response; + + op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; + + /* Ask the user if he wants to download the message */ + response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window), + _("mcen_nc_get_msg")); + if (response == GTK_RESPONSE_CANCEL) + return FALSE; + + /* Offer the connection dialog if necessary */ + /* FIXME: should this stuff go directly to the mail + operation instead of spread it all over the + code? */ + folder = tny_header_get_folder (header); + if (folder) { + if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (folder))) { + g_object_unref (folder); + return FALSE; + } + g_object_unref (folder); + } + } + + /* Get the path, will be freed by the callback */ + path = gtk_tree_model_get_path (priv->header_model, &iter); + + /* New mail operation */ + mail_op = modest_mail_operation_new_with_error_handling (op_type, + G_OBJECT(window), + modest_ui_actions_get_msgs_full_error_handler, + NULL); + + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msg (mail_op, header, view_msg_cb, path); + g_object_unref (mail_op); + + /* Update toolbar dimming rules */ + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window)); + + return TRUE; +} + gboolean modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) { - TnyHeaderFlags flags; - ModestMailOperation *mail_op = NULL; ModestMsgViewWindowPrivate *priv; GtkTreePath *path= NULL; GtkTreeIter tmp_iter; @@ -1043,56 +1109,26 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) path); while (gtk_tree_model_iter_next (priv->header_model, &tmp_iter)) { TnyHeader *header; - GtkTreePath *path; - gtk_tree_model_get (priv->header_model, &tmp_iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + gtk_tree_model_get (priv->header_model, &tmp_iter, + TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); if (!header) break; - if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) - continue; - if (!download_uncached_message (header, GTK_WINDOW (window))) { - break; + if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) { + g_object_unref (header); + continue; } - /* Update the row reference */ - gtk_tree_row_reference_free (priv->row_reference); - path = gtk_tree_model_get_path (priv->header_model, &tmp_iter); - priv->row_reference = gtk_tree_row_reference_new (priv->header_model, path); - gtk_tree_path_free (path); - - /* Mark as read */ - flags = tny_header_get_flags (header); - if (!(flags & TNY_HEADER_FLAG_SEEN)) - tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); - - /* Msg download completed */ - if (flags & TNY_HEADER_FLAG_CACHED) { - /* No download is necessary, because the message is cached: */ - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_OPEN, G_OBJECT(window)); - } else { - /* Offer the connection dialog if necessary: */ - TnyFolder *folder = tny_header_get_folder(header); - if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (folder))) { - g_object_unref (folder); - return FALSE; - } - if (folder) { - g_object_unref (folder); - folder = NULL; - } - - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window)); + /* Read the message & show it */ + if (!message_reader (window, priv, header, tmp_iter)) { + g_object_unref (header); + break; } - - /* New mail operation */ - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_get_msg (mail_op, header, view_msg_cb, NULL); - g_object_unref (mail_op); - /* Update toolbar dimming rules */ - modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window)); + /* Free */ + g_object_unref (header); return TRUE; } @@ -1105,10 +1141,7 @@ gboolean modest_msg_view_window_select_first_message (ModestMsgViewWindow *self) { ModestMsgViewWindowPrivate *priv = NULL; - ModestMailOperation *mail_op = NULL; TnyHeader *header = NULL; - TnyHeaderFlags flags; - GtkTreePath *path = NULL; GtkTreeIter iter; g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE); @@ -1130,30 +1163,8 @@ modest_msg_view_window_select_first_message (ModestMsgViewWindow *self) return modest_msg_view_window_select_next_message (self); } - /* Update the row reference */ - gtk_tree_row_reference_free (priv->row_reference); - path = gtk_tree_path_new_first (); - priv->row_reference = gtk_tree_row_reference_new (priv->header_model, path); - gtk_tree_path_free (path); - - /* Mark as read */ - flags = tny_header_get_flags (header); - if (!(flags & TNY_HEADER_FLAG_SEEN)) - tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); - - /* Msg download completed */ - if (flags & TNY_HEADER_FLAG_CACHED) - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_OPEN, G_OBJECT(self)); - else - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(self)); - - /* New mail operation */ - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_get_msg (mail_op, header, view_msg_cb, NULL); - g_object_unref (mail_op); - - /* Update toolbar dimming rules */ - modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self)); + /* Read the message & show it */ + message_reader (self, priv, header, iter); /* Free */ g_object_unref (header); @@ -1164,10 +1175,8 @@ modest_msg_view_window_select_first_message (ModestMsgViewWindow *self) gboolean modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) { - TnyHeaderFlags flags; ModestMsgViewWindowPrivate *priv = NULL; GtkTreePath *path; - ModestMailOperation *mail_op = NULL; g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE); priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); @@ -1192,30 +1201,11 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) continue; } - if (!download_uncached_message (header, GTK_WINDOW (window))) { + /* Read the message & show it */ + if (!message_reader (window, priv, header, iter)) { + g_object_unref (header); break; } - /* Update the row reference */ - gtk_tree_row_reference_free (priv->row_reference); - priv->row_reference = gtk_tree_row_reference_new (priv->header_model, path); - - /* Mark as read */ - flags = tny_header_get_flags (header); - if (!(flags & TNY_HEADER_FLAG_SEEN)) - tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); - - /* Msg download completed */ - if (flags & TNY_HEADER_FLAG_CACHED) - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_OPEN, G_OBJECT(window)); - else - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window)); - - /* New mail operation */ - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_get_msg (mail_op, header, view_msg_cb, NULL); - - /* Update toolbar dimming rules */ - modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window)); g_object_unref (header); @@ -1234,15 +1224,29 @@ view_msg_cb (ModestMailOperation *mail_op, { ModestMsgViewWindow *self = NULL; ModestMsgViewWindowPrivate *priv = NULL; + GtkTreePath *path; - g_return_if_fail (TNY_IS_MSG (msg)); + /* If there was any error */ + path = (GtkTreePath *) user_data; + if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) { + gtk_tree_path_free (path); + return; + } /* Get the window */ self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op); g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self)); - priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self); + /* Update the row reference */ + gtk_tree_row_reference_free (priv->row_reference); + priv->row_reference = gtk_tree_row_reference_new (priv->header_model, path); + gtk_tree_path_free (path); + + /* Mark header as read */ + if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN)) + tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); + /* Set new message */ modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), msg); modest_msg_view_window_update_priority (self); @@ -1934,22 +1938,3 @@ update_window_title (ModestMsgViewWindow *window) gtk_window_set_title (GTK_WINDOW (window), subject); } - -static gboolean -download_uncached_message (TnyHeader *header, GtkWindow *win) -{ - TnyHeaderFlags flags; - gboolean retval = TRUE; - - flags = tny_header_get_flags (header); - - if (! (flags & TNY_HEADER_FLAG_CACHED)) { - GtkResponseType response; - response = - modest_platform_run_confirmation_dialog (GTK_WINDOW (win), - _("mcen_nc_get_msg")); - if (response == GTK_RESPONSE_CANCEL) - retval = FALSE; - } - return retval; -} diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index 1b337fc..914b112 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -880,9 +880,12 @@ modest_platform_run_information_dialog (GtkWindow *parent_window, dialog = hildon_note_new_information (parent_window, message); - gtk_dialog_run (GTK_DIALOG (dialog)); + g_signal_connect_swapped (dialog, + "response", + G_CALLBACK (gtk_widget_destroy), + dialog); - gtk_widget_destroy (GTK_WIDGET (dialog)); + gtk_widget_show_all (dialog); } diff --git a/src/modest-mail-operation-queue.c b/src/modest-mail-operation-queue.c index 53cd086..db3465f 100644 --- a/src/modest-mail-operation-queue.c +++ b/src/modest-mail-operation-queue.c @@ -257,9 +257,9 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, prevent possible application crashes. It's useful also for detecting mail operations with invalid status and error handling */ - if (modest_mail_operation_get_error (mail_op) != NULL) + if (modest_mail_operation_get_error (mail_op) != NULL) { modest_mail_operation_execute_error_handler (mail_op); - else { + } else { if (status == MODEST_MAIL_OPERATION_STATUS_CANCELED) g_warning ("%s: operation canceled \n", __FUNCTION__); else diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index d9c203a..316274e 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -1643,42 +1643,33 @@ get_msg_cb (TnyFolder *folder, if (*error) { priv->error = g_error_copy (*error); priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - goto out; - } - if (cancelled) { + } else if (cancelled) { priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, _("Error trying to refresh the contents of %s"), tny_folder_get_name (folder)); - goto out; - } - - /* The mail operation might have been canceled in which case we do not - want to notify anyone anymore. */ - if(priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED) { + } else { priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; + } - /* If user defined callback function was defined, call it */ - if (helper->user_callback) { - /* This callback is called into an iddle by tinymail, - and idles are not in the main lock */ - gdk_threads_enter (); - helper->user_callback (self, helper->header, msg, helper->user_data); - gdk_threads_leave (); - } + /* If user defined callback function was defined, call it even + if the operation failed*/ + if (helper->user_callback) { + /* This callback is called into an iddle by tinymail, + and idles are not in the main lock */ + gdk_threads_enter (); + helper->user_callback (self, helper->header, msg, helper->user_data); + gdk_threads_leave (); } - out: /* Free */ + g_object_unref (helper->mail_op); g_object_unref (helper->header); g_slice_free (GetMsgAsyncHelper, helper); /* Notify about operation end */ - if(priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED) - modest_mail_operation_notify_end (self); - - g_object_unref (G_OBJECT (self)); + modest_mail_operation_notify_end (self); } static void diff --git a/src/modest-tny-account-store.c b/src/modest-tny-account-store.c index 8ef3743..004e88a 100644 --- a/src/modest-tny-account-store.c +++ b/src/modest-tny-account-store.c @@ -1073,7 +1073,7 @@ modest_tny_account_store_alert (TnyAccountStore *self, TnyAlertType type, break; } - GtkWidget *dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, + GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, gtktype, GTK_BUTTONS_YES_NO, prompt); #endif /* #ifdef MODEST_PLATFORM_MAEMO */ @@ -1081,7 +1081,7 @@ modest_tny_account_store_alert (TnyAccountStore *self, TnyAlertType type, const int response = gtk_dialog_run (GTK_DIALOG (dialog)); if (question) { retval = (response == GTK_RESPONSE_YES) || - (response == GTK_RESPONSE_OK); + (response == GTK_RESPONSE_OK); } gtk_widget_destroy (dialog); diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 8fa2044..b99cf71 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -105,11 +105,9 @@ typedef struct _ReplyForwardHelper { */ typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data); -static void -do_headers_action (ModestWindow *win, - HeadersFunc func, - gpointer user_data); - +static void do_headers_action (ModestWindow *win, + HeadersFunc func, + gpointer user_data); static void open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, @@ -610,6 +608,27 @@ cleanup: g_object_unref (G_OBJECT(folder)); } +gboolean +modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg) +{ + ModestMailOperationStatus status; + + /* If there is no message or the operation was not successful */ + status = modest_mail_operation_get_status (mail_op); + if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) { + + /* Remove the header from the preregistered uids */ + modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), + header); + + return FALSE; + } + + return TRUE; +} + static void open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, @@ -623,8 +642,10 @@ open_msg_cb (ModestMailOperation *mail_op, gchar *account = NULL; TnyFolder *folder; - /* TODO: Show an error? (review the specs) */ - if (!msg) + /* Do nothing if there was any problem with the mail + operation. The error will be shown by the error_handler of + the mail operation */ + if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) return; parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op); @@ -710,24 +731,25 @@ cleanup: g_object_unref (folder); } -/* - * This function is the error handler of the - * modest_mail_operation_get_msgs_full operation - */ -static void +void modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op, gpointer user_data) { const GError *error; + GObject *win = modest_mail_operation_get_source (mail_op); error = modest_mail_operation_get_error (mail_op); if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) { - GObject *win = modest_mail_operation_get_source (mail_op); modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, error->message); - g_object_unref (win); + } else { + modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, + _("mail_ni_ui_folder_get_msg_folder_error")); } + + if (win) + g_object_unref (win); } /* @@ -887,6 +909,10 @@ reply_forward_cb (ModestMailOperation *mail_op, TnyAccount *account = NULL; ModestWindowMgr *mgr = NULL; gchar *signature = NULL; + + /* If there was any error */ + if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) + return; g_return_if_fail (user_data != NULL); rf_helper = (ReplyForwardHelper *) user_data; @@ -3058,7 +3084,9 @@ open_msg_for_purge_cb (ModestMailOperation *mail_op, gint pending_purges = 0; gboolean some_purged = FALSE; ModestWindow *win = MODEST_WINDOW (user_data); - if (!msg) + + /* If there was any error */ + if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) return; /* Once the message has been retrieved for purging, we check if diff --git a/src/modest-ui-actions.h b/src/modest-ui-actions.h index b311969..f95bfba 100644 --- a/src/modest-ui-actions.h +++ b/src/modest-ui-actions.h @@ -409,5 +409,35 @@ void modest_ui_actions_on_search_messages (GtkAction *action, void modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action, ModestWindow *window); +/** + * modest_ui_actions_msg_retrieval_check + * @mail_op: a #ModestMailOperation + * @header: a #TnyHeader + * @msg: a #TnyMsg + * + * This function checks that the message has been retrieved + * successfully. It it was not the case it unregisters the header from + * the window manager because it won't do it automatically unless the + * operation run fine + * + * Returns: TRUE if the operation was OK, otherwise FALSE + **/ +gboolean modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg); + + +/** + * modest_ui_actions_get_msgs_full_error_handler + * @mail_op: a #ModestMailOperation + * + * Error handler for message retrieval operations like + * modest_mail_operation_get_msg or + * modest_mail_operation_get_msgs_full + **/ +void modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op, + gpointer user_data); + + G_END_DECLS #endif /* __MODEST_UI_ACTIONS_H__ */ diff --git a/src/widgets/modest-window-mgr.c b/src/widgets/modest-window-mgr.c index 1d768e0..3995637 100644 --- a/src/widgets/modest-window-mgr.c +++ b/src/widgets/modest-window-mgr.c @@ -239,7 +239,23 @@ modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header) g_free (uid); } +void +modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header) +{ + ModestWindowMgrPrivate *priv; + gchar* uid; + + g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); + g_return_if_fail (TNY_IS_HEADER(header)); + + priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + uid = modest_tny_folder_get_header_unique_id (header); + + if (has_uid (priv->preregistered_uids, uid)) + priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid); + g_free (uid); +} static gint compare_msguids (ModestWindow *win, diff --git a/src/widgets/modest-window-mgr.h b/src/widgets/modest-window-mgr.h index 9cc2134..455f17c 100644 --- a/src/widgets/modest-window-mgr.h +++ b/src/widgets/modest-window-mgr.h @@ -168,9 +168,20 @@ gboolean modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHe * removed when the window itself will registered * **/ -void modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header); +void modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header); +/** + * modest_window_mgr_unregister_header + * @self: a #ModestWindowMgr + * @header: a valid #TnyHeader + * + * unregister the uid. We could need to do that if there is any error + * retrieving a message. In that case the window will not be + * registered and thus the header will not be removed, so we must do + * it manually + **/ +void modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header); /** * modest_window_mgr_get_hibernation_is_prevented: