Fixes an infinite loop while saving BS mime parts
[modest] / src / hildon2 / modest-msg-view-window.c
index b9271ff..0fff509 100644 (file)
@@ -117,12 +117,14 @@ struct _ModestMsgViewWindowPrivate {
        gulong row_deleted_handler;
        gulong row_inserted_handler;
        gulong rows_reordered_handler;
+       gulong fetch_image_redraw_handler;
 
        guint purge_timeout;
        GtkWidget *remove_attachment_banner;
 
        gchar *msg_uid;
        TnyMimePart *other_body;
+       TnyMsg * top_msg;
 
        GSList *sighandlers;
 };
@@ -472,6 +474,7 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        priv->row_deleted_handler = 0;
        priv->row_inserted_handler = 0;
        priv->rows_reordered_handler = 0;
+       priv->fetch_image_redraw_handler = 0;
        priv->progress_hint = FALSE;
        priv->fetching_images = 0;
 
@@ -620,11 +623,21 @@ modest_msg_view_window_finalize (GObject *obj)
           call this function before */
        modest_msg_view_window_disconnect_signals (MODEST_WINDOW (obj));
 
+       if (priv->fetch_image_redraw_handler > 0) {
+               g_source_remove (priv->fetch_image_redraw_handler);
+               priv->fetch_image_redraw_handler = 0;
+       }
+
        if (priv->other_body != NULL) {
                g_object_unref (priv->other_body);
                priv->other_body = NULL;
        }
 
+       if (priv->top_msg != NULL) {
+               g_object_unref (priv->top_msg);
+               priv->top_msg = NULL;
+       }
+
        if (priv->header_model != NULL) {
                g_object_unref (priv->header_model);
                priv->header_model = NULL;
@@ -875,6 +888,7 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        modest_msg_view_window_construct (window, modest_account_name, mailbox, msg_uid);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+       priv->top_msg = NULL;
 
        /* Remember the message list's TreeModel so we can detect changes
         * and change the list selection when necessary: */
@@ -953,6 +967,7 @@ modest_msg_view_window_new_from_uid (const gchar *modest_account_name,
        modest_msg_view_window_construct (window, modest_account_name, mailbox, msg_uid);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+       priv->top_msg = NULL;
 
        is_merge = g_str_has_prefix (msg_uid, "merge:");
 
@@ -1033,6 +1048,7 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
        modest_msg_view_window_construct (window, modest_account_name, mailbox, msg_uid);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+       priv->top_msg = NULL;
 
        /* Remember the message list's TreeModel so we can detect changes 
         * and change the list selection when necessary: */
@@ -1126,6 +1142,7 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg,
        modest_msg_view_window_construct (window, modest_account_name, mailbox, msg_uid);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+       priv->top_msg = NULL;
 
        /* Remember that this is a search result, 
         * so we can disable some UI appropriately: */
@@ -1160,6 +1177,7 @@ modest_msg_view_window_is_other_body (ModestMsgViewWindow *self)
 ModestWindow *
 modest_msg_view_window_new_with_other_body (TnyMsg *msg, 
                                            TnyMimePart *other_body,
+                                           TnyMsg *top_msg,
                                            const gchar *modest_account_name,
                                            const gchar *mailbox,
                                            const gchar *msg_uid)
@@ -1181,6 +1199,11 @@ modest_msg_view_window_new_with_other_body (TnyMsg *msg,
        } else {
                tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
        }
+       if (top_msg) {
+               priv->top_msg = g_object_ref (top_msg);
+       } else {
+               priv->top_msg = NULL;
+       }
        update_window_title (MODEST_MSG_VIEW_WINDOW (obj));
        update_branding (MODEST_MSG_VIEW_WINDOW (obj));
 
@@ -1195,12 +1218,13 @@ modest_msg_view_window_new_with_other_body (TnyMsg *msg,
 }
 
 ModestWindow *
-modest_msg_view_window_new_for_attachment (TnyMsg *msg, 
+modest_msg_view_window_new_for_attachment (TnyMsg *msg,
+                                          TnyMsg *top_msg,
                                           const gchar *modest_account_name,
                                           const gchar *mailbox,
                                           const gchar *msg_uid)
 {
-       return modest_msg_view_window_new_with_other_body (msg, NULL, modest_account_name, mailbox, msg_uid);
+       return modest_msg_view_window_new_with_other_body (msg, NULL, top_msg, modest_account_name, mailbox, msg_uid);
 }
 
 static void
@@ -1507,6 +1531,21 @@ modest_msg_view_window_get_message (ModestMsgViewWindow *self)
        return tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
 }
 
+TnyMsg*
+modest_msg_view_window_get_top_message (ModestMsgViewWindow *self)
+{
+       ModestMsgViewWindowPrivate *priv;
+       
+       g_return_val_if_fail (self, NULL);
+       
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
+
+       if (priv->top_msg)
+               return g_object_ref (priv->top_msg);
+       else
+               return NULL;
+}
+
 const gchar*
 modest_msg_view_window_get_message_uid (ModestMsgViewWindow *self)
 {
@@ -2234,30 +2273,6 @@ view_msg_cb (ModestMailOperation *mail_op,
                return;
        }
 
-       if (msg && TNY_IS_CAMEL_BS_MSG (msg)) {
-               TnyMimePart *body;
-               body = modest_tny_msg_find_body_part (msg, TRUE);
-               
-               if (body && !tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (body))) {
-                       /* We have body structure but not the body mime part. What we do
-                        * is restarting load of message */
-                       self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
-                       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
-
-                       tny_header_unset_flag (TNY_HEADER (header), TNY_HEADER_FLAG_CACHED);
-
-                       modest_msg_view_window_reload (self);
-
-                       if (row_reference)
-                               gtk_tree_row_reference_free (row_reference);
-                       g_object_unref (body);
-                       return;
-               }
-
-               if (body)
-                       g_object_unref  (body);
-       }
-
        /* Get the window */ 
        self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
@@ -2665,6 +2680,9 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
 {
        DecodeAsyncHelper *helper = (DecodeAsyncHelper *) user_data;
        const gchar *content_type;
+       ModestMsgViewWindowPrivate *priv;
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (helper->self);
 
        if (cancelled || err) {
                if (err) {
@@ -2691,7 +2709,7 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
        set_progress_hint (helper->self, FALSE);
 
        content_type = tny_mime_part_get_content_type (mime_part);
-       if (g_str_has_prefix (content_type, "message/rfc822")) {
+       if (content_type && g_str_has_prefix (content_type, "message/rfc822")) {
                ModestWindowMgr *mgr;
                ModestWindow *msg_win = NULL;
                TnyMsg * msg;
@@ -2702,6 +2720,7 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
 
                fd = g_open (helper->file_path, O_RDONLY, 0644);
                if (fd != -1) {
+                       TnyMsg *top_msg;
                        file_stream = tny_fs_stream_new (fd);
 
                        mgr = modest_runtime_get_window_mgr ();
@@ -2714,7 +2733,15 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
 
                        msg = tny_camel_msg_new ();
                        tny_camel_msg_parse (msg, file_stream);
-                       msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (msg), account, mailbox, helper->attachment_uid);
+
+                       if (priv->top_msg)
+                               top_msg = g_object_ref (priv->top_msg);
+                       else
+                               top_msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
+
+                       msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (msg), top_msg, 
+                                                                            account, mailbox, helper->attachment_uid);
+                       if (top_msg) g_object_unref (top_msg);
                        modest_window_set_zoom (MODEST_WINDOW (msg_win),
                                                modest_window_get_zoom (MODEST_WINDOW (helper->self)));
                        if (modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (helper->self)))
@@ -2733,7 +2760,7 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
                g_chmod(helper->file_path, 0444);
 
                /* Activate the file */
-               modest_platform_activate_file (helper->file_path, tny_mime_part_get_content_type (mime_part));
+               modest_platform_activate_file (helper->file_path, content_type);
        }
 
  free:
@@ -2917,6 +2944,7 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                if (found) {
                        g_debug ("window for this body is already being created");
                } else {
+                       TnyMsg *top_msg;
 
                        /* it's not found, so create a new window for it */
                        modest_window_mgr_register_header (mgr, header, attachment_uid); /* register the uid before building the window */
@@ -2924,9 +2952,16 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                        const gchar *mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (window));
                        if (!account)
                                account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
+
+                       if (priv->top_msg)
+                               top_msg = g_object_ref (priv->top_msg);
+                       else
+                               top_msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
                        
-                       msg_win = modest_msg_view_window_new_with_other_body (TNY_MSG (current_msg), TNY_MIME_PART (mime_part),
+                       msg_win = modest_msg_view_window_new_with_other_body (TNY_MSG (current_msg), TNY_MIME_PART (mime_part), top_msg,
                                                                              account, mailbox, attachment_uid);
+
+                       if (top_msg) g_object_unref (top_msg);
                        
                        modest_window_set_zoom (MODEST_WINDOW (msg_win),
                                                modest_window_get_zoom (MODEST_WINDOW (window)));
@@ -2952,14 +2987,20 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                         * thus, we don't do anything */
                        g_debug ("window for is already being created");
                } else {
+                       TnyMsg *top_msg;
                        /* it's not found, so create a new window for it */
                        modest_window_mgr_register_header (mgr, header, attachment_uid); /* register the uid before building the window */
                        gchar *account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (window)));
                        const gchar *mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (window));
                        if (!account)
                                account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
-                       msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (mime_part), account, 
-                                                                            mailbox, attachment_uid);
+                       if (priv->top_msg)
+                               top_msg = g_object_ref (priv->top_msg);
+                       else
+                               top_msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
+                       msg_win = modest_msg_view_window_new_for_attachment (
+                               TNY_MSG (mime_part), top_msg, account, 
+                               mailbox, attachment_uid);
                        modest_window_set_zoom (MODEST_WINDOW (msg_win),
                                                modest_window_get_zoom (MODEST_WINDOW (window)));
                        if (modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (window)))
@@ -3054,6 +3095,9 @@ save_mime_part_to_file_connect_handler (gboolean canceled,
                                        SaveMimePartInfo *info)
 {
        if (canceled || err) {
+               if (canceled && !err) {
+                       info->result = GNOME_VFS_ERROR_CANCELLED;
+               }
                g_idle_add ((GSourceFunc) idle_save_mime_part_show_result, info);
        } else {
                g_thread_create ((GThreadFunc)save_mime_part_to_file, info, FALSE, NULL);
@@ -3082,6 +3126,10 @@ save_mime_part_to_file_connect_idle (SaveMimePartInfo *info)
                                             TNY_ACCOUNT (account),
                                             (ModestConnectedPerformer) save_mime_part_to_file_connect_handler,
                                             info);
+
+       if (account)
+               g_object_unref (account);
+
        return FALSE;
 }
 
@@ -3094,8 +3142,34 @@ save_mime_part_to_file (SaveMimePartInfo *info)
 
        if (TNY_IS_CAMEL_BS_MIME_PART (pair->part) &&
            !tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (pair->part))) {
-               g_idle_add ((GSourceFunc) save_mime_part_to_file_connect_idle, info);
-               return NULL;
+               gboolean check_online = TRUE;
+               ModestMsgViewWindowPrivate *priv = NULL;
+
+               /* Check if we really need to connect to save the mime part */
+               priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (info->window);
+               if (g_str_has_prefix (priv->msg_uid, "merge:")) {
+                       check_online = FALSE;
+               } else {
+                       TnyAccountStore *acc_store;
+                       TnyAccount *account = NULL;
+
+                       acc_store = (TnyAccountStore*) modest_runtime_get_account_store ();
+                       account = tny_account_store_find_account (acc_store, priv->msg_uid);
+
+                       if (account) {
+                               if (tny_account_get_connection_status (account) ==
+                                   TNY_CONNECTION_STATUS_CONNECTED)
+                                       check_online = FALSE;
+                               g_object_unref (account);
+                       } else {
+                               check_online = !tny_device_is_online (tny_account_store_get_device (acc_store));
+                       }
+               }
+
+               if (check_online) {
+                       g_idle_add ((GSourceFunc) save_mime_part_to_file_connect_idle, info);
+                       return NULL;
+               }
        }
 
        info->result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0644);
@@ -3635,6 +3709,23 @@ typedef struct {
 } FetchImageData;
 
 gboolean
+on_fetch_image_timeout_refresh_view (gpointer userdata)
+{
+       ModestMsgViewWindowPrivate *priv;
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (userdata);
+       update_progress_hint (MODEST_MSG_VIEW_WINDOW (userdata));
+       /* Note that priv->msg_view is set to NULL when this window is
+          distroyed */
+       if (priv->msg_view && GTK_WIDGET_DRAWABLE (priv->msg_view)) {
+               gtk_widget_queue_draw (GTK_WIDGET (priv->msg_view));
+       }
+       priv->fetch_image_redraw_handler = 0;
+       g_object_unref (userdata);
+       return FALSE;
+}
+
+gboolean
 on_fetch_image_idle_refresh_view (gpointer userdata)
 {
 
@@ -3646,8 +3737,10 @@ on_fetch_image_idle_refresh_view (gpointer userdata)
 
                priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (fidata->window);
                priv->fetching_images--;
-               gtk_widget_queue_draw (fidata->msg_view);
-               update_progress_hint (MODEST_MSG_VIEW_WINDOW (fidata->window));
+               if (priv->fetch_image_redraw_handler == 0) {
+                       priv->fetch_image_redraw_handler = g_timeout_add (500, on_fetch_image_timeout_refresh_view, g_object_ref (fidata->window));
+               }
+
        }
        gdk_threads_leave ();