From: Javier Fernandez Garcia-Boente Date: Mon, 7 May 2007 07:50:36 +0000 (+0000) Subject: * Fix some detected memory leaks X-Git-Tag: git_migration_finished~3697 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=976c05744180efac28a9dc421acefcff18659d67;hp=5ff64b5b4c5c0c8101bd5a4f3a22d20cb6710d77 * Fix some detected memory leaks * New update_progress function for get_msg_async operation. * Reply/Forward actions use now get_msg_asyc function * Open a message in edit or view window using asynchronous operations: get_msg_asyc * In optimized view, toolbar is hide/show based on current operation mode pmo-trunk-r1766 --- diff --git a/src/maemo/modest-main-window.c b/src/maemo/modest-main-window.c index 33437ed..68bf108 100644 --- a/src/maemo/modest-main-window.c +++ b/src/maemo/modest-main-window.c @@ -132,6 +132,8 @@ struct _ModestMainWindowPrivate { GtkWidget *accounts_popup; GtkWidget *details_widget; + /* Optimized view enabled */ + gboolean optimized_view; ModestHeaderView *header_view; ModestFolderView *folder_view; @@ -234,6 +236,8 @@ modest_main_window_init (ModestMainWindow *obj) priv->accounts_popup = NULL; priv->details_widget = NULL; + priv->optimized_view = FALSE; + priv->progress_widgets = NULL; priv->progress_bar = NULL; priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL; @@ -763,10 +767,14 @@ modest_main_window_show_toolbar (ModestWindow *self, GtkWidget *placeholder = NULL; gint insert_index; - parent_priv = MODEST_WINDOW_GET_PRIVATE(self); + g_return_if_fail (MODEST_IS_MAIN_WINDOW (self)); priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self); + parent_priv = MODEST_WINDOW_GET_PRIVATE(self); + + /* Set optimized view status */ + priv->optimized_view = !show_toolbar; - if (!parent_priv->toolbar && show_toolbar) { + if (!parent_priv->toolbar) { parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar"); @@ -815,18 +823,16 @@ modest_main_window_show_toolbar (ModestWindow *self, NULL, self); } - /* TODO: Why is this sometimes NULL? murrayc */ - if (parent_priv->toolbar) { - if (show_toolbar) { - /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ - /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */ - gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE); + if (show_toolbar) { + /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ + /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */ + gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE); + + gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); + set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL); + } else + gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar)); - gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); - set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL); - } else - gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar)); - } } /* @@ -1151,14 +1157,16 @@ static void set_toolbar_mode (ModestMainWindow *self, ModestToolBarModes mode) { - ModestWindowPrivate *parent_priv; - ModestMainWindowPrivate *priv; - GtkAction *sort_action, *refresh_action, *cancel_action; - + ModestWindowPrivate *parent_priv = NULL; + ModestMainWindowPrivate *priv = NULL; + GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL; + g_return_if_fail (MODEST_IS_MAIN_WINDOW (self)); parent_priv = MODEST_WINDOW_GET_PRIVATE(self); priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self); + + g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar)); sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort"); refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive"); @@ -1183,6 +1191,10 @@ set_toolbar_mode (ModestMainWindow *self, if (cancel_action) gtk_action_set_visible (cancel_action, FALSE); + + /* Hide toolbar if optimized view is enabled */ + if (priv->optimized_view) + gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar)); break; case TOOLBAR_MODE_TRANSFER: if (sort_action) @@ -1197,12 +1209,14 @@ set_toolbar_mode (ModestMainWindow *self, } if (priv->progress_bar) gtk_widget_show (priv->progress_bar); + + /* Show toolbar if it's hiden (optimized view ) */ + if (priv->optimized_view) + gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); break; default: g_return_if_reached (); } - - gtk_widget_show_all (GTK_WIDGET (self)); } static void diff --git a/src/maemo/modest-msg-edit-window.c b/src/maemo/modest-msg-edit-window.c index e3f16cc..45f2738 100644 --- a/src/maemo/modest-msg-edit-window.c +++ b/src/maemo/modest-msg-edit-window.c @@ -1637,6 +1637,7 @@ modest_msg_edit_window_show_toolbar (ModestWindow *self, { ModestWindowPrivate *parent_priv; + g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self)); parent_priv = MODEST_WINDOW_GET_PRIVATE(self); /* FIXME: we can not just use the code of diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index c5b46d5..5c4cfdf 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -90,6 +90,8 @@ static void on_queue_changed (ModestMailOperationQue ModestMailOperationQueueNotification type, ModestMsgViewWindow *self); +static void view_msg_cb (const GObject *obj, const TnyMsg *msg, gpointer user_data); + static void set_toolbar_mode (ModestMsgViewWindow *self, ModestToolBarModes mode); @@ -132,6 +134,9 @@ struct _ModestMsgViewWindowPrivate { GtkWidget *prev_toolitem; GtkWidget *next_toolitem; + /* Optimized view enabled */ + gboolean optimized_view; + GtkTreeModel *header_model; GtkTreeIter iter; @@ -201,6 +206,9 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj) priv->msg_view = NULL; priv->header_model = NULL; priv->clipboard_change_handler = 0; + + priv->optimized_view = FALSE; + } static void @@ -260,6 +268,13 @@ set_toolbar_mode (ModestMsgViewWindow *self, if (priv->cancel_toolitem) gtk_widget_hide (priv->cancel_toolitem); + + /* Hide toolbar if optimized view is enabled */ + if (priv->optimized_view) { + gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE); + gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar)); + } + break; case TOOLBAR_MODE_TRANSFER: widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew"); @@ -286,32 +301,16 @@ set_toolbar_mode (ModestMsgViewWindow *self, if (priv->cancel_toolitem) gtk_widget_show (priv->cancel_toolitem); + + /* Show toolbar if it's hiden (optimized view ) */ + if (priv->optimized_view) { + gtk_widget_set_no_show_all (parent_priv->toolbar, FALSE); + gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); + } + break; default: - widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew"); - gtk_action_set_sensitive (widget, TRUE); - widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); - gtk_action_set_sensitive (widget, TRUE); - widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage"); - gtk_action_set_sensitive (widget, TRUE); - widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo"); - gtk_action_set_sensitive (widget, TRUE); - widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"); - gtk_action_set_sensitive (widget, TRUE); - - if (priv->cancel_toolitem) - gtk_widget_show (priv->prev_toolitem); - - if (priv->next_toolitem) - gtk_widget_show (priv->next_toolitem); - - if (priv->progress_bar) - gtk_widget_hide (priv->progress_bar); - if (priv->progress_bar) - gtk_widget_hide (priv->progress_bar); - - if (priv->cancel_toolitem) - gtk_widget_hide (priv->cancel_toolitem); + g_return_if_reached (); } } @@ -374,8 +373,12 @@ init_window (ModestMsgViewWindow *obj, TnyMsg *msg) g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_view_window_find_toolbar_close), obj); g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj); - priv->clipboard_change_handler = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change", G_CALLBACK (modest_msg_view_window_clipboard_owner_change), obj); - modest_msg_view_window_clipboard_owner_change (gtk_clipboard_get (GDK_SELECTION_PRIMARY), NULL, obj); + /* TODO: I dont knonw why, but when get_msg_async is used, */ + /* this code makes application doest not work (jfernandez) */ + if (FALSE) { + priv->clipboard_change_handler = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change", G_CALLBACK (modest_msg_view_window_clipboard_owner_change), obj); + modest_msg_view_window_clipboard_owner_change (gtk_clipboard_get (GDK_SELECTION_PRIMARY), NULL, obj); + } gtk_widget_show_all (GTK_WIDGET(main_vbox)); gtk_box_pack_end (GTK_BOX (main_vbox), priv->find_toolbar, FALSE, FALSE, 0); } @@ -847,9 +850,9 @@ modest_msg_view_window_is_first_message (ModestMsgViewWindow *window) gboolean modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) { + ModestMailOperation *mail_op = NULL; ModestMsgViewWindowPrivate *priv; GtkTreeIter tmp_iter; - gboolean has_next = FALSE; g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE); priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); @@ -858,8 +861,7 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) tmp_iter = priv->iter; while (gtk_tree_model_iter_next (priv->header_model, &tmp_iter)) { TnyHeader *header; - TnyFolder *folder; - TnyMsg *msg; + guint op_status; priv->iter = tmp_iter; gtk_tree_model_get (priv->header_model, &(priv->iter), TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, @@ -869,25 +871,21 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) continue; - folder = tny_header_get_folder (header); - if (!folder) - break; - msg = tny_folder_get_msg (folder, header, NULL); - if (!msg) { - g_object_unref (folder); - break; - } - has_next = TRUE; - modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), msg); - modest_msg_view_window_update_dimmed (window); - modest_msg_view_window_update_priority (window); - gtk_widget_grab_focus (priv->msg_view); + /* New mail operation */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(window)); + 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); + op_status = modest_mail_operation_get_status (mail_op); - g_object_unref (msg); - break; + g_object_unref (mail_op); + + if (op_status == MODEST_MAIL_OPERATION_STATUS_FAILED) + return FALSE; + else + return TRUE; } - return has_next; + return FALSE; } else { return FALSE; } @@ -896,20 +894,19 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) gboolean modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) { - ModestMsgViewWindowPrivate *priv; + ModestMsgViewWindowPrivate *priv = NULL; + ModestMailOperation *mail_op = NULL; g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE); priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); if (priv->header_model) { GtkTreePath *path; - gboolean has_prev = FALSE; path = gtk_tree_model_get_path (priv->header_model, &(priv->iter)); while (gtk_tree_path_prev (path)) { TnyHeader *header; - TnyFolder *folder; - TnyMsg *msg; + guint op_status; gtk_tree_model_get_iter (priv->header_model, &(priv->iter), path); gtk_tree_model_get (priv->header_model, &(priv->iter), TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, @@ -918,28 +915,45 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) break; if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) continue; - folder = tny_header_get_folder (header); - if (!folder) - break; - msg = tny_folder_get_msg (folder, header, NULL); - if (!msg) { - g_object_unref (folder); - break; - } - has_prev = TRUE; - modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), msg); - modest_msg_view_window_update_dimmed (window); - modest_msg_view_window_update_priority (window); - gtk_widget_grab_focus (priv->msg_view); + + /* New mail operation */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(window)); + 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); + + gtk_tree_path_free (path); - g_object_unref (msg); - break; + op_status = modest_mail_operation_get_status (mail_op); + if (op_status == MODEST_MAIL_OPERATION_STATUS_FAILED) + return FALSE; + else + return TRUE; } - gtk_tree_path_free (path); - return has_prev; } else { return FALSE; } + + return FALSE; +} + +static void +view_msg_cb(const GObject *obj, const TnyMsg *msg, gpointer user_data) +{ + ModestMsgViewWindow *self = NULL; + ModestMsgViewWindowPrivate *priv = NULL; + TnyMsg *new_msg = NULL; + + g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (obj)); + g_return_if_fail (TNY_IS_MSG (msg)); + self = MODEST_MSG_VIEW_WINDOW (obj); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self); + + /* Set new message */ + new_msg = g_object_ref (G_OBJECT(msg)); + modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), new_msg); + modest_msg_view_window_update_dimmed (self); + modest_msg_view_window_update_priority (self); + gtk_widget_grab_focus (priv->msg_view); } static TnyFolderType @@ -1092,7 +1106,10 @@ modest_msg_view_window_show_toolbar (ModestWindow *self, parent_priv = MODEST_WINDOW_GET_PRIVATE(self); priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self); - if (!parent_priv->toolbar && show_toolbar) { + /* Set optimized view status */ + priv->optimized_view = !show_toolbar; + + if (!parent_priv->toolbar) { parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar"); @@ -1138,13 +1155,16 @@ modest_msg_view_window_show_toolbar (ModestWindow *self, gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0); } - /* TODO: Why is this sometimes NULL? murrayc */ - if (parent_priv->toolbar) { - if (show_toolbar) { - gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); - set_toolbar_mode (MODEST_MSG_VIEW_WINDOW(self), TOOLBAR_MODE_NORMAL); - } else - gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar)); + if (show_toolbar) { + /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ + /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */ + gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE); + + gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); + set_toolbar_mode (MODEST_MSG_VIEW_WINDOW(self), TOOLBAR_MODE_NORMAL); + } else { + gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE); + gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar)); } } @@ -1256,7 +1276,6 @@ on_queue_changed (ModestMailOperationQueue *queue, break; case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED: if (mode == TOOLBAR_MODE_TRANSFER) { - set_toolbar_mode (MODEST_MSG_VIEW_WINDOW(self), TOOLBAR_MODE_NORMAL); while (tmp) { modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data), mail_op); diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index ed80eeb..c35b1b4 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -311,8 +311,8 @@ GdkPixbuf* modest_platform_get_icon (const gchar *name) { GError *err = NULL; - GdkPixbuf* pixbuf; - GtkIconTheme *current_theme; + GdkPixbuf* pixbuf = NULL; + GtkIconTheme *current_theme = NULL; g_return_val_if_fail (name, NULL); diff --git a/src/maemo/modest-scroll-area.c b/src/maemo/modest-scroll-area.c index c63106d..a04b87f 100644 --- a/src/maemo/modest-scroll-area.c +++ b/src/maemo/modest-scroll-area.c @@ -161,27 +161,27 @@ static void modest_scroll_area_fixed_allocate (GtkWidget *widget, static int calculate_size (GtkWidget *widget) { - int size = 0; - - if (GTK_IS_TEXT_VIEW (widget)) - return 0; - - if (GTK_IS_CONTAINER (widget)) { - GList *children = gtk_container_get_children (GTK_CONTAINER (widget)); - while (children != NULL) { - GtkWidget *wid = GTK_WIDGET (children->data); - gint sz = calculate_size (wid); - if ((GTK_WIDGET_VISIBLE (wid))) { - size += sz; - } - - children = g_list_next (children); - } - } else { - size = widget->allocation.height; - } - - return size; + int size = 0; + + if (GTK_IS_TEXT_VIEW (widget)) + return 0; + + if (GTK_IS_CONTAINER (widget)) { + GList *tmp = NULL; + GList *children = gtk_container_get_children (GTK_CONTAINER (widget)); + for (tmp = children; tmp != NULL; tmp = g_list_next (tmp)) { + GtkWidget *wid = GTK_WIDGET (tmp->data); + gint sz = calculate_size (wid); + if ((GTK_WIDGET_VISIBLE (wid))) { + size += sz; + } + } + g_list_free (children); + } else { + size = widget->allocation.height; + } + + return size; } static void modest_scroll_area_child_requisition (GtkWidget *widget, diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 88e973b..320f716 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -66,7 +66,17 @@ static void update_folders_status_cb (GObject *obj, static void update_process_msg_status_cb (GObject *obj, TnyStatus *status, - gpointer user_data); + gpointer user_data); +static void get_msg_cb (TnyFolder *folder, + gboolean cancelled, + TnyMsg *msg, + GError **err, + gpointer user_data); + +static void get_msg_status_cb (GObject *obj, + TnyStatus *status, + gpointer user_data); + enum _ModestMailOperationSignals { @@ -93,6 +103,13 @@ struct _ModestMailOperationPrivate { priv->status = new_status;\ } +typedef struct _GetMsgAsyncHelper { + ModestMailOperation *mail_op; + GetMsgAsynUserCallback user_callback; + guint pending_ops; + gpointer user_data; +} GetMsgAsyncHelper; + typedef struct _RefreshFolderAsyncHelper { ModestMailOperation *mail_op; @@ -411,6 +428,11 @@ update_folders_status_cb (GObject *obj, g_return_if_fail (status != NULL); g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH); + /* Temporary FIX: useful when tinymail send us status + information *after* calling the function callback */ + if (!MODEST_IS_MAIL_OPERATION (user_data)) + return; + self = MODEST_MAIL_OPERATION (user_data); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); @@ -788,12 +810,12 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, /* ************************** MSG ACTIONS ************************* */ /* ******************************************************************* */ -void modest_mail_operation_process_msg (ModestMailOperation *self, - TnyHeader *header, - guint num_ops, - TnyGetMsgCallback user_callback, - gpointer user_data) +void modest_mail_operation_get_msg (ModestMailOperation *self, + TnyHeader *header, + GetMsgAsynUserCallback user_callback, + gpointer user_data) { + GetMsgAsyncHelper *helper = NULL; TnyFolder *folder; ModestMailOperationPrivate *priv; @@ -804,15 +826,20 @@ void modest_mail_operation_process_msg (ModestMailOperation *self, folder = tny_header_get_folder (header); priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; - priv->total = num_ops; /* Get message from folder */ if (folder) { - /* The callback will call it per each header */ - tny_folder_get_msg_async (folder, header, user_callback, update_process_msg_status_cb, user_data); + helper = g_slice_new0 (GetMsgAsyncHelper); + helper->mail_op = self; + helper->user_callback = user_callback; + helper->pending_ops = 1; + helper->user_data = user_data; + + tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper); + g_object_unref (G_OBJECT (folder)); } else { - /* Set status failed and set an error */ + /* Set status failed and set an error */ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, @@ -820,21 +847,172 @@ void modest_mail_operation_process_msg (ModestMailOperation *self, } } +static void +get_msg_cb (TnyFolder *folder, + gboolean cancelled, + TnyMsg *msg, + GError **error, + gpointer user_data) +{ + GetMsgAsyncHelper *helper = NULL; + ModestMailOperation *self = NULL; + ModestMailOperationPrivate *priv = NULL; + + helper = (GetMsgAsyncHelper *) user_data; + g_return_if_fail (helper != NULL); + self = helper->mail_op; + g_return_if_fail (MODEST_IS_MAIL_OPERATION(self)); + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + + helper->pending_ops--; + + /* Check errors and cancel */ + if (*error) { + priv->error = g_error_copy (*error); + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + goto out; + } + 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; + } + + priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; + + /* If user defined callback function was defined, call it */ + if (helper->user_callback) { + helper->user_callback (priv->source, msg, helper->user_data); + } + + /* Free */ + out: + if (helper->pending_ops == 0) { + g_slice_free (GetMsgAsyncHelper, helper); + + /* Notify the queue */ + modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + } +} + +static void +get_msg_status_cb (GObject *obj, + TnyStatus *status, + gpointer user_data) +{ + GetMsgAsyncHelper *helper = NULL; + ModestMailOperation *self; + ModestMailOperationPrivate *priv; + + g_return_if_fail (status != NULL); + g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG); + + helper = (GetMsgAsyncHelper *) user_data; + g_return_if_fail (helper != NULL); + + /* Temporary FIX: useful when tinymail send us status + information *after* calling the function callback */ + if (!MODEST_IS_MAIL_OPERATION (helper->mail_op)) + return; + + self = helper->mail_op; + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + + priv->done += status->position; + priv->total = status->of_total; + + if (priv->done == 1 && priv->total == 100) + return; + + g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); +} + + +void modest_mail_operation_process_msg (ModestMailOperation *self, + TnyList *header_list, + GetMsgAsynUserCallback user_callback, + gpointer user_data) +{ + ModestMailOperationPrivate *priv = NULL; + GetMsgAsyncHelper *helper = NULL; + TnyHeader *header = NULL; + TnyFolder *folder = NULL; + TnyIterator *iter = NULL; + + g_return_if_fail (MODEST_IS_MAIL_OPERATION (self)); + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); + priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; + + iter = tny_list_create_iterator (header_list); + priv->total = tny_list_get_length(header_list); + + helper = g_slice_new0 (GetMsgAsyncHelper); + helper->mail_op = self; + helper->user_callback = user_callback; + helper->pending_ops = priv->total; + helper->user_data = user_data; + + while (!tny_iterator_is_done (iter)) { + + header = TNY_HEADER (tny_iterator_get_current (iter)); + folder = tny_header_get_folder (header); + + /* Get message from folder */ + if (folder) { + /* The callback will call it per each header */ + tny_folder_get_msg_async (folder, header, get_msg_cb, update_process_msg_status_cb, helper); + g_object_unref (G_OBJECT (folder)); + } else { + /* Set status failed and set an error */ + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, + MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, + _("Error trying to get a message. No folder found for header")); + + /* Notify the queue */ + modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + + /* free */ + g_slice_free (GetMsgAsyncHelper, helper); + break; + } + + g_object_unref (header); + tny_iterator_next (iter); + } +} + static void update_process_msg_status_cb (GObject *obj, TnyStatus *status, gpointer user_data) { + GetMsgAsyncHelper *helper = NULL; ModestMailOperation *self; ModestMailOperationPrivate *priv; g_return_if_fail (status != NULL); - g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH); + g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG); - self = MODEST_MAIL_OPERATION (user_data); + helper = (GetMsgAsyncHelper *) user_data; + g_return_if_fail (helper != NULL); + + /* Temporary FIX: useful when tinymail send us status + information *after* calling the function callback */ + if (!MODEST_IS_MAIL_OPERATION (helper->mail_op)) + return; + + self = helper->mail_op; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - priv->done += status->position; + if (status->of_total > 0) + priv->done += status->position/status->of_total; + + g_print("TEST: %d/%d", priv->done, priv->total); if (priv->done == 1 && priv->total == 100) return; diff --git a/src/modest-mail-operation.h b/src/modest-mail-operation.h index 809e744..4650b3f 100644 --- a/src/modest-mail-operation.h +++ b/src/modest-mail-operation.h @@ -87,6 +87,20 @@ struct _ModestMailOperationClass { void (*progress_changed) (ModestMailOperation *self, gpointer user_data); }; +/** + * GetMsgAsynUserCallback: + * + * @obj: a #GObject generic object which has created current mail operation. + * @msg: a #TnyMsg message retrieved by async operation. + * @user_data: generic data passed to user defined function. + * + * This function will be called after get_msg_cb private function, which is + * used as tinymail operation callback. The private function fills private + * fields of mail operation and calls user defined callback if it exists. + */ +typedef void (*GetMsgAsynUserCallback) (const GObject *obj, const TnyMsg *msg, gpointer user_data); + + /* member functions */ GType modest_mail_operation_get_type (void) G_GNUC_CONST; @@ -112,7 +126,7 @@ ModestMailOperationId modest_mail_operation_get_id (ModestMailOperation *self); /** - * modest_mail_operation_get_id + * modest_mail_operation_is_mine * @self: a #ModestMailOperation * @source: a #GObject to check if it have created @self operation. * @@ -356,22 +370,34 @@ void modest_mail_operation_remove_msg (ModestMailOperation *self, gboolean remove_to_trash); /** + * modest_mail_operation_get_msg: + * @self: a #ModestMailOperation + * @header_list: the #TnyHeader of the message to get + * @user_callback: a #GetMsgAsynUserCallback function to call after tinymail callback execution. + * @user_data: generic user data which will be passed to @user_callback function. + * + * Gets a message from header using an user defined @callback function + * pased as argument. This operation is asynchronous, so the + * #ModestMailOperation should be added to #ModestMailOperationQueue + **/ +void modest_mail_operation_get_msg (ModestMailOperation *self, + TnyHeader *header, + GetMsgAsynUserCallback user_callback, + gpointer user_data); +/** * modest_mail_operation_process_msg: * @self: a #ModestMailOperation - * @header: the #TnyHeader of the message to get - * @num_ops: number of times to repeat operation with next header. + * @header_list: a #TnyList of #TnyHeader objects to get and process * @user_callback: a #TnyGetMsgCallback function to call after tinymail operation execution. * @user_data: user data passed to both, user_callback and update_status_callback. * - * Gets a message and process it using @callback function - * pased as argument. This operation is assynchronous, so the - * #ModestMailOperation should be added to - * #ModestMailOperationQueue + * Gets messages from headers list and process hem using @callback function + * pased as argument. This operation is asynchronous, so the + * #ModestMailOperation should be added to #ModestMailOperationQueue **/ void modest_mail_operation_process_msg (ModestMailOperation *self, - TnyHeader *header, - guint num_ops, - TnyGetMsgCallback user_callback, + TnyList *headers_list, + GetMsgAsynUserCallback user_callback, gpointer user_data); /* Functions to control mail operations */ diff --git a/src/modest-tny-account-store.c b/src/modest-tny-account-store.c index aaa8101..3d70bb0 100644 --- a/src/modest-tny-account-store.c +++ b/src/modest-tny-account-store.c @@ -449,8 +449,8 @@ get_cached_accounts (TnyAccountStore *self, TnyList *list, TnyAccountType type) static GSList* get_accounts (TnyAccountStore *self, TnyList *list, TnyAccountType type) { - ModestTnyAccountStorePrivate *priv; - GSList *account_names, *cursor; + ModestTnyAccountStorePrivate *priv = NULL; + GSList *account_names = NULL, *cursor = NULL; GSList *accounts = NULL; priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self); diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index a9718fb..90a4928 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -87,8 +87,15 @@ typedef struct _ReplyForwardHelper { guint reply_forward_type; ReplyForwardAction action; gchar *account_name; + guint pending_ops; } ReplyForwardHelper; +typedef struct _HeaderActivatedHelper { + GtkTreeModel *model; + GtkTreeIter iter; + TnyFolder *folder; +} HeaderActivatedHelper; + /* * The do_headers_action uses this kind of functions to perform some * action to each member of a list of headers @@ -101,10 +108,10 @@ do_headers_action (ModestWindow *win, gpointer user_data); -static void reply_forward_func (gpointer data, gpointer user_data); +static void open_msg_func (const GObject *obj, const TnyMsg *msg, gpointer user_data); + +static void reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data); -static void get_msg_cb (TnyFolder *folder, gboolean canceled, TnyMsg *msg, GError **err, - gpointer user_data); static void reply_forward (ReplyForwardAction action, ModestWindow *win); static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title); @@ -403,10 +410,60 @@ modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) static void -reply_forward_func (gpointer data, gpointer user_data) +open_msg_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) +{ + ModestWindowMgr *mgr = NULL; + ModestWindow *parent_win = NULL; + ModestWindow *win = NULL; + HeaderActivatedHelper *helper = NULL; + TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN; + gchar *account = NULL; + + g_return_if_fail (MODEST_IS_WINDOW(obj)); + g_return_if_fail (user_data != NULL); + parent_win = MODEST_WINDOW(obj); + helper = (HeaderActivatedHelper *) user_data; + + /* Get account */ + account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(parent_win))); + if (!account) + account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); + + /* Gets foldert type (OUTBOX headers will be opened in edit window */ +/* folder_type = modest_tny_folder_guess_folder_type (helper->folder); */ + if (modest_tny_folder_is_local_folder (helper->folder)) + folder_type = modest_tny_folder_get_local_folder_type (helper->folder); + + switch (folder_type) { + case TNY_FOLDER_TYPE_DRAFTS: + win = modest_msg_edit_window_new ((TnyMsg *) msg, account); + break; + default: + if (helper->model != NULL) + win = modest_msg_view_window_new_with_header_model ((TnyMsg *) msg, account, helper->model, helper->iter); + else + win = modest_msg_view_window_new ((TnyMsg *) msg, account); + } + + /* Register and show new window */ + if (win != NULL) { + mgr = modest_runtime_get_window_mgr (); + modest_window_mgr_register_window (mgr, win); + gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win)); + gtk_widget_show_all (GTK_WIDGET(win)); + } + + /* Free */ + g_free(account); +/* g_object_unref (G_OBJECT(msg)); */ + g_object_unref (G_OBJECT(helper->folder)); + g_slice_free (HeaderActivatedHelper, helper); +} + +static void +reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) { - TnyMsg *msg, *new_msg; - GetMsgAsyncHelper *helper; + TnyMsg *new_msg; ReplyForwardHelper *rf_helper; ModestWindow *msg_win; ModestEditType edit_type; @@ -416,10 +473,11 @@ reply_forward_func (gpointer data, gpointer user_data) TnyAccount *account = NULL; ModestWindowMgr *mgr; gchar *signature = NULL; - - msg = TNY_MSG (data); - helper = (GetMsgAsyncHelper *) user_data; - rf_helper = (ReplyForwardHelper *) helper->user_data; + + g_return_if_fail (user_data != NULL); + rf_helper = (ReplyForwardHelper *) user_data; + + rf_helper->pending_ops--; from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), rf_helper->account_name); @@ -430,23 +488,24 @@ reply_forward_func (gpointer data, gpointer user_data) rf_helper->account_name, MODEST_ACCOUNT_SIGNATURE, FALSE); } + /* Create reply mail */ switch (rf_helper->action) { case ACTION_REPLY: new_msg = - modest_tny_msg_create_reply_msg (msg, from, signature, + modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type, MODEST_TNY_MSG_REPLY_MODE_SENDER); break; case ACTION_REPLY_TO_ALL: new_msg = - modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type, + modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type, MODEST_TNY_MSG_REPLY_MODE_ALL); edit_type = MODEST_EDIT_TYPE_REPLY; break; case ACTION_FORWARD: new_msg = - modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type); + modest_tny_msg_create_forward_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type); edit_type = MODEST_EDIT_TYPE_FORWARD; break; default: @@ -475,7 +534,7 @@ reply_forward_func (gpointer data, gpointer user_data) goto cleanup; } - tny_folder_add_msg (folder, msg, &err); + tny_folder_add_msg (folder, (TnyMsg *) msg, &err); if (err) { g_printerr ("modest: error adding msg to Drafts folder: %s", err->message); @@ -499,8 +558,10 @@ cleanup: if (account) g_object_unref (G_OBJECT (account)); -/* g_free (rf_helper->account_name); */ -/* g_slice_free (ReplyForwardHelper, rf_helper); */ + if (rf_helper->pending_ops == 0) { + g_free (rf_helper->account_name); + g_slice_free (ReplyForwardHelper, rf_helper); + } } /* * Common code for the reply and forward actions @@ -508,11 +569,10 @@ cleanup: static void reply_forward (ReplyForwardAction action, ModestWindow *win) { - TnyList *header_list; + ModestMailOperation *mail_op = NULL; + TnyList *header_list = NULL; + ReplyForwardHelper *rf_helper = NULL; guint reply_forward_type; - TnyHeader *header; - GetMsgAsyncHelper *helper; - ReplyForwardHelper *rf_helper; g_return_if_fail (MODEST_IS_WINDOW(win)); @@ -532,19 +592,12 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) rf_helper = g_slice_new0 (ReplyForwardHelper); rf_helper->reply_forward_type = reply_forward_type; rf_helper->action = action; - + rf_helper->pending_ops = tny_list_get_length (header_list); rf_helper->account_name = g_strdup (modest_window_get_active_account (win)); if (!rf_helper->account_name) rf_helper->account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); - helper = g_slice_new0 (GetMsgAsyncHelper); - helper->window = win; - helper->func = reply_forward_func; - helper->iter = tny_list_create_iterator (header_list); - helper->user_data = rf_helper; - helper->num_ops = tny_list_get_length (header_list); - if (MODEST_IS_MSG_VIEW_WINDOW(win)) { TnyMsg *msg; msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win)); @@ -552,20 +605,18 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) g_printerr ("modest: no message found\n"); return; } else - reply_forward_func (msg, helper); + reply_forward_func (G_OBJECT(win), msg, rf_helper); } else { - header = TNY_HEADER (tny_iterator_get_current (helper->iter)); - - helper->mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), helper->mail_op); - modest_mail_operation_process_msg (helper->mail_op, header, helper->num_ops, get_msg_cb, helper); + + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_process_msg (mail_op, header_list, reply_forward_func, rf_helper); /* Clean */ - g_object_unref (G_OBJECT (header)); + g_object_unref(mail_op); } } - void modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win) { @@ -868,61 +919,6 @@ modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow * MODEST_CONF_HEADER_VIEW_KEY); } -/* - * This function is a generic handler for the tny_folder_get_msg_async - * call. It expects as user_data a #GetMsgAsyncHelper. This helper - * contains a user provided function that is called inside this - * method. This will allow us to use this callback in many different - * places. This callback performs the common actions for the - * get_msg_async call, more specific actions will be done by the user - * function - */ -static void -get_msg_cb (TnyFolder *folder, gboolean canceled, TnyMsg *msg, GError **err, gpointer user_data) -{ - GetMsgAsyncHelper *helper; - - helper = (GetMsgAsyncHelper *) user_data; - - /* Check errors */ - if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) { - modest_ui_actions_on_item_not_found (NULL, - MODEST_ITEM_TYPE_MESSAGE, - helper->window); - return; - } - - /* Call user function */ - if (helper->func) - helper->func (msg, user_data); - - /* Process next element (if exists) */ - tny_iterator_next (helper->iter); - if (tny_iterator_is_done (helper->iter)) { - /* Notify the queue */ - if (helper->mail_op != NULL) - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), helper->mail_op); - - /* Free resources */ - TnyList *headers; - ReplyForwardHelper *rf_helper = (ReplyForwardHelper *) helper->user_data; - headers = tny_iterator_get_list (helper->iter); - g_object_unref (G_OBJECT (headers)); - g_object_unref (G_OBJECT (helper->iter)); - g_object_unref (G_OBJECT (helper->mail_op)); - if (rf_helper != NULL) { - g_free (rf_helper->account_name); - g_slice_free (ReplyForwardHelper, rf_helper); - } - g_slice_free (GetMsgAsyncHelper, helper); - } else { - TnyHeader *header; - header = TNY_HEADER (tny_iterator_get_current (helper->iter)); - modest_mail_operation_process_msg (helper->mail_op, header, helper->num_ops, get_msg_cb, helper); - - g_object_unref (G_OBJECT(header)); - } -} void modest_ui_actions_on_header_selected (ModestHeaderView *header_view, @@ -947,16 +943,94 @@ modest_ui_actions_on_header_selected (ModestHeaderView *header_view, -void -modest_ui_actions_on_header_activated (ModestHeaderView *header_view, TnyHeader *header, +/* void */ +/* modest_ui_actions_on_header_activated (ModestHeaderView *header_view, TnyHeader *header, */ +/* ModestMainWindow *main_window) */ +/* { */ +/* ModestWindow *win = NULL; */ +/* TnyFolder *folder = NULL; */ +/* TnyMsg *msg = NULL; */ +/* TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN; */ +/* ModestWindowMgr *mgr; */ +/* GtkTreeModel *model; */ +/* GtkTreeIter iter; */ +/* GtkTreeSelection *sel = NULL; */ +/* GList *sel_list = NULL; */ + +/* g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); */ + +/* if (!header) */ +/* return; */ + +/* folder = tny_header_get_folder (header); */ +/* if (!folder) { */ +/* g_printerr ("modest: cannot get folder for header\n"); */ +/* return; */ +/* } */ +/* if (modest_tny_folder_is_local_folder (folder)) */ +/* folder_type = modest_tny_folder_get_local_folder_type (folder); */ + +/* /\* FIXME: make async?; check error *\/ */ +/* msg = tny_folder_get_msg (folder, header, NULL); */ +/* if (!msg) { */ +/* g_printerr ("modest: cannot get msg for header\n"); */ +/* goto cleanup; */ +/* } */ + +/* /\* Look if we already have a message view for that header *\/ */ +/* mgr = modest_runtime_get_window_mgr (); */ +/* win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header)); */ + +/* /\* If not, create a new window *\/ */ +/* if (!win) { */ +/* gchar *account; */ + +/* account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window))); */ +/* if (!account) */ +/* account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); */ + +/* sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); */ +/* sel_list = gtk_tree_selection_get_selected_rows (sel, &model); */ +/* if (sel_list != NULL) { */ +/* gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) sel_list->data); */ + +/* switch (folder_type) { */ +/* case TNY_FOLDER_TYPE_DRAFTS: */ +/* win = modest_msg_edit_window_new (msg, account); */ +/* break; */ +/* default: */ +/* win = modest_msg_view_window_new_with_header_model (msg, account, model, iter); */ +/* } */ + +/* g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); */ +/* g_list_free (sel_list); */ +/* } else { */ +/* win = modest_msg_view_window_new (msg, account); */ +/* } */ +/* modest_window_mgr_register_window (mgr, win); */ + +/* gtk_window_set_transient_for (GTK_WINDOW (win), */ +/* GTK_WINDOW (main_window)); */ +/* } */ + +/* gtk_widget_show_all (GTK_WIDGET(win)); */ + +/* g_object_unref (G_OBJECT (msg)); */ + +/* cleanup: */ +/* g_object_unref (G_OBJECT (folder)); */ +/* } */ + +void +modest_ui_actions_on_header_activated (ModestHeaderView *header_view, + TnyHeader *header, ModestMainWindow *main_window) { + ModestMailOperation *mail_op = NULL; + HeaderActivatedHelper *helper = NULL; + ModestWindowMgr *mgr = NULL; ModestWindow *win = NULL; - TnyFolder *folder = NULL; - TnyMsg *msg = NULL; - TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN; - ModestWindowMgr *mgr; - GtkTreeModel *model; + GtkTreeModel *model = NULL; GtkTreeIter iter; GtkTreeSelection *sel = NULL; GList *sel_list = NULL; @@ -966,63 +1040,37 @@ modest_ui_actions_on_header_activated (ModestHeaderView *header_view, TnyHeader if (!header) return; - folder = tny_header_get_folder (header); - if (!folder) { - g_printerr ("modest: cannot get folder for header\n"); - return; - } - if (modest_tny_folder_is_local_folder (folder)) - folder_type = modest_tny_folder_get_local_folder_type (folder); - - /* FIXME: make async?; check error */ - msg = tny_folder_get_msg (folder, header, NULL); - if (!msg) { - g_printerr ("modest: cannot get msg for header\n"); - goto cleanup; - } - - /* Look if we already have a message view for that header */ + /* Look if we already have a message view for that header */ mgr = modest_runtime_get_window_mgr (); win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header)); + if (win) return; + + /* Build helper */ + helper = g_slice_new0 (HeaderActivatedHelper); + helper->folder = tny_header_get_folder (header); + helper->model = NULL; + + /* Get headers tree model and selected iter to build message view */ + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); + sel_list = gtk_tree_selection_get_selected_rows (sel, &model); + if (sel_list != NULL) { + gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) sel_list->data); + + /* Fill helpers */ + helper->model = model; + helper->iter = iter; - /* If not, create a new window */ - if (!win) { - gchar *account; - - account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window))); - if (!account) - account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); - - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); - sel_list = gtk_tree_selection_get_selected_rows (sel, &model); - if (sel_list != NULL) { - gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) sel_list->data); - - switch (folder_type) { - case TNY_FOLDER_TYPE_DRAFTS: - win = modest_msg_edit_window_new (msg, account); - break; - default: - win = modest_msg_view_window_new_with_header_model (msg, account, model, iter); - } - - g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (sel_list); - } else { - win = modest_msg_view_window_new (msg, account); - } - modest_window_mgr_register_window (mgr, win); - - gtk_window_set_transient_for (GTK_WINDOW (win), - GTK_WINDOW (main_window)); + g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); + g_list_free (sel_list); } - gtk_widget_show_all (GTK_WIDGET(win)); + /* New mail operation */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(main_window)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msg (mail_op, header, open_msg_func, helper); - g_object_unref (G_OBJECT (msg)); - -cleanup: - g_object_unref (G_OBJECT (folder)); + /* Free */ + g_object_unref (mail_op); } void diff --git a/src/widgets/modest-attachments-view.c b/src/widgets/modest-attachments-view.c index 7c15c79..fd30044 100644 --- a/src/widgets/modest-attachments-view.c +++ b/src/widgets/modest-attachments-view.c @@ -101,6 +101,8 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn ModestAttachmentsViewPriv *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (attachments_view); TnyList *parts; TnyIterator *iter; + + if (msg == priv->msg) return; if (priv->msg) g_object_unref (priv->msg); diff --git a/src/widgets/modest-folder-view.c b/src/widgets/modest-folder-view.c index ba979f6..46f87cb 100644 --- a/src/widgets/modest-folder-view.c +++ b/src/widgets/modest-folder-view.c @@ -336,8 +336,8 @@ static void icon_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { - GObject *rendobj, *instance; - GdkPixbuf *pixbuf; + GObject *rendobj = NULL, *instance = NULL; + GdkPixbuf *pixbuf = NULL; TnyFolderType type; gchar *fname = NULL; const gchar *account_id = NULL; diff --git a/src/widgets/modest-header-view.c b/src/widgets/modest-header-view.c index cb9b1e9..5b3f5e3 100644 --- a/src/widgets/modest-header-view.c +++ b/src/widgets/modest-header-view.c @@ -856,11 +856,8 @@ void modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder) { ModestHeaderViewPrivate *priv; - ModestWindow *win = NULL; priv = MODEST_HEADER_VIEW_GET_PRIVATE(self); - win = MODEST_WINDOW(gtk_widget_get_toplevel (GTK_WIDGET(self))); - g_return_if_fail (MODEST_IS_WINDOW (win)); if (priv->folder) { g_object_unref (priv->folder); @@ -880,7 +877,7 @@ modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder) g_signal_emit (G_OBJECT(self), signals[HEADER_SELECTED_SIGNAL], 0, NULL); /* Create the mail operation */ - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, NULL); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);