Merge part-to-stream-in-plugins branch work also into master.
[modest] / src / hildon2 / modest-msg-view-window.c
index 9771982..bed6ebf 100644 (file)
@@ -505,6 +505,10 @@ init_window (ModestMsgViewWindow *obj)
        modest_msg_view_set_shadow_type (MODEST_MSG_VIEW (priv->msg_view), GTK_SHADOW_NONE);
        main_vbox = gtk_vbox_new  (FALSE, 6);
        priv->main_scroll = hildon_pannable_area_new ();
+        g_object_set (G_OBJECT (priv->main_scroll),
+                     "mov-mode", HILDON_MOVEMENT_MODE_BOTH,
+                     "hovershoot-max", 0,
+                     NULL);
        gtk_container_add (GTK_CONTAINER (priv->main_scroll), priv->msg_view);
        gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_scroll, TRUE, TRUE, 0);
        gtk_container_add   (GTK_CONTAINER(obj), main_vbox);
@@ -758,6 +762,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
                          G_CALLBACK (modest_ui_actions_on_details), obj);
        g_signal_connect (G_OBJECT(priv->msg_view), "link_contextual",
                          G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj);
+       g_signal_connect (G_OBJECT(priv->msg_view), "limit_error",
+                         G_CALLBACK (modest_ui_actions_on_limit_error), obj);
        g_signal_connect (G_OBJECT (priv->msg_view), "fetch_image",
                          G_CALLBACK (on_fetch_image), obj);
 
@@ -1944,13 +1950,16 @@ message_reader (ModestMsgViewWindow *window,
                GtkTreeRowReference *row_reference)
 {
        ModestWindowMgr *mgr;
-       TnyAccount *account;
+       TnyAccount *account = NULL;
        MsgReaderInfo *info;
 
        /* We set the header from model while we're loading */
        tny_header_view_set_header (TNY_HEADER_VIEW (priv->msg_view), header);
        gtk_window_set_title (GTK_WINDOW (window), _CS("ckdg_pb_updating"));
 
+       if (header)
+               folder = NULL;
+
        if (folder)
                g_object_ref (folder);
 
@@ -1995,7 +2004,8 @@ message_reader (ModestMsgViewWindow *window,
                                                                       TNY_FOLDER_STORE (folder),
                                                                       message_reader_performer, 
                                                                       info);
-                       g_object_unref (folder);
+                       if (folder)
+                               g_object_unref (folder);
                        return TRUE;
                }
        }
@@ -2003,7 +2013,9 @@ message_reader (ModestMsgViewWindow *window,
        if (header) {
                folder = tny_header_get_folder (header);
        }
-       account = tny_folder_get_account (folder);
+        if (folder)
+               account = tny_folder_get_account (folder);
+
        info = g_slice_new (MsgReaderInfo);
        info->msg_uid = g_strdup (msg_uid);
        if (folder)
@@ -2020,13 +2032,15 @@ message_reader (ModestMsgViewWindow *window,
                info->row_reference = NULL;
 
        message_reader_performer (FALSE, NULL, (GtkWindow *) window, account, info);
-       g_object_unref (account);
-       g_object_unref (folder);
+        if (account)
+               g_object_unref (account);
+       if (folder)
+               g_object_unref (folder);
 
        return TRUE;
 }
 
-gboolean        
+gboolean
 modest_msg_view_window_select_next_message (ModestMsgViewWindow *window)
 {
        ModestMsgViewWindowPrivate *priv;
@@ -2174,12 +2188,16 @@ view_msg_cb (ModestMailOperation *mail_op,
        /* Update the row reference */
        if (priv->row_reference != NULL) {
                gtk_tree_row_reference_free (priv->row_reference);
-               priv->row_reference = gtk_tree_row_reference_copy (row_reference);
+               priv->row_reference = row_reference?gtk_tree_row_reference_copy (row_reference):NULL;
                if (priv->next_row_reference != NULL) {
                        gtk_tree_row_reference_free (priv->next_row_reference);
                }
-               priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
-               select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE, priv->is_outbox);
+               if (row_reference) {
+                       priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
+                       select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE, priv->is_outbox);
+               } else {
+                       priv->next_row_reference = NULL;
+               }
        }
 
        /* Mark header as read */
@@ -2649,7 +2667,11 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                                                               &filepath);
 
                if (temp_stream != NULL) {
+                       ModestAccountMgr *mgr;
                        DecodeAsyncHelper *helper;
+                       gboolean decode_in_provider;
+                       ModestProtocol *protocol;
+                       const gchar *account; 
 
                        /* Activate progress hint */
                        set_progress_hint (window, TRUE);
@@ -2658,10 +2680,28 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                        helper->self = g_object_ref (window);
                        helper->file_path = g_strdup (filepath);
 
-                       tny_mime_part_decode_to_stream_async (mime_part, TNY_STREAM (temp_stream),
-                                                             on_decode_to_stream_async_handler,
-                                                             NULL,
-                                                             helper);
+                       decode_in_provider = FALSE;
+                       mgr = modest_runtime_get_account_mgr ();
+                       account = modest_window_get_active_account (MODEST_WINDOW (window));
+                       if (modest_account_mgr_account_is_multimailbox (mgr, account, &protocol)) {
+                               if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
+                                       decode_in_provider = 
+                                               modest_account_protocol_decode_part_to_stream_async (
+                                                       MODEST_ACCOUNT_PROTOCOL (protocol),
+                                                       mime_part,
+                                                       NULL,
+                                                       TNY_STREAM (temp_stream),
+                                                       on_decode_to_stream_async_handler,
+                                                       NULL,
+                                                       helper);
+                               }
+                       }
+
+                       if (!decode_in_provider)
+                               tny_mime_part_decode_to_stream_async (mime_part, TNY_STREAM (temp_stream),
+                                                                     on_decode_to_stream_async_handler,
+                                                                     NULL,
+                                                                     helper);
                        g_object_unref (temp_stream);
                        /* NOTE: files in the temporary area will be automatically
                         * cleaned after some time if they are no longer in use */
@@ -2767,6 +2807,8 @@ typedef struct
 {
        GList *pairs;
        GnomeVFSResult result;
+       gchar *uri;
+       ModestMsgViewWindow *window;
 } SaveMimePartInfo;
 
 static void save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct);
@@ -2787,6 +2829,9 @@ save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
        }
        g_list_free (info->pairs);
        info->pairs = NULL;
+       g_free (info->uri);
+       g_object_unref (info->window);
+       info->window = NULL;
        if (with_struct) {
                g_slice_free (SaveMimePartInfo, info);
        }
@@ -2802,7 +2847,13 @@ idle_save_mime_part_show_result (SaveMimePartInfo *info)
        if (info->result == GNOME_VFS_OK) {
                hildon_banner_show_information (NULL, NULL, _CS("sfil_ib_saved"));
        } else if (info->result == GNOME_VFS_ERROR_NO_SPACE) {
-               gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+               gchar *msg = NULL;
+
+               /* Check if the uri belongs to the external mmc */
+               if (g_str_has_prefix (info->uri, g_getenv (MODEST_MMC1_VOLUMEPATH_ENV)))
+                       msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+               else
+                       msg = g_strdup (_KR("cerm_memory_card_full"));
                modest_platform_information_banner (NULL, NULL, msg);
                g_free (msg);
        } else {
@@ -2824,8 +2875,33 @@ save_mime_part_to_file (SaveMimePartInfo *info)
        info->result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0644);
        if (info->result == GNOME_VFS_OK) {
                GError *error = NULL;
+               gboolean decode_in_provider;
+               gssize written;
+               ModestAccountMgr *mgr;
+               const gchar *account;
+               ModestProtocol *protocol = NULL;
+
                stream = tny_vfs_stream_new (handle);
-               if (tny_mime_part_decode_to_stream (pair->part, stream, &error) < 0) {
+
+               decode_in_provider = FALSE;
+               mgr = modest_runtime_get_account_mgr ();
+               account = modest_window_get_active_account (MODEST_WINDOW (info->window));
+               if (modest_account_mgr_account_is_multimailbox (mgr, account, &protocol)) {
+                       if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
+                               decode_in_provider = 
+                                       modest_account_protocol_decode_part_to_stream (
+                                               MODEST_ACCOUNT_PROTOCOL (protocol),
+                                               pair->part,
+                                               pair->filename,
+                                               stream,
+                                               &written,
+                                               &error);
+                       }
+               }
+               if (!decode_in_provider)
+                       written = tny_mime_part_decode_to_stream (pair->part, stream, &error);
+
+               if (written < 0) {
                        g_warning ("modest: could not save attachment %s: %d (%s)\n", pair->filename, error?error->code:-1, error?error->message:"Unknown error");
 
                        if ((error->domain == TNY_ERROR_DOMAIN) && 
@@ -2864,11 +2940,14 @@ save_mime_parts_to_file_with_checks (GtkWindow *parent,
 
         for (iter = files; (iter != NULL) && (replaced_files < 2); iter = g_list_next(iter)) {
                 SaveMimePartPair *pair = iter->data;
-                if (modest_utils_file_exists (pair->filename)) {
+               gchar *unescaped = g_uri_unescape_string (pair->filename, NULL);
+
+                if (modest_utils_file_exists (unescaped)) {
                        replaced_files++;
                        if (replaced_files == 1)
                                to_replace = iter;
                 }
+               g_free (unescaped);
         }
        if (replaced_files) {
                gint response;
@@ -2901,6 +2980,11 @@ save_mime_parts_to_file_with_checks (GtkWindow *parent,
 
 }
 
+typedef struct _SaveAttachmentsInfo {
+       TnyList *attachments_list;
+       ModestMsgViewWindow *window;
+} SaveAttachmentsInfo;
+
 static void
 save_attachments_response (GtkDialog *dialog,
                           gint       arg1,
@@ -2910,17 +2994,18 @@ save_attachments_response (GtkDialog *dialog,
        gchar *chooser_uri;
        GList *files_to_save = NULL;
        gchar *current_folder;
+       SaveAttachmentsInfo *sa_info = (SaveAttachmentsInfo *) user_data;
 
-       mime_parts = TNY_LIST (user_data);
+       mime_parts = TNY_LIST (sa_info->attachments_list);
 
        if (arg1 != GTK_RESPONSE_OK)
                goto end;
 
        chooser_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
        current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
-       if (current_folder && current_folder != '\0') {
+       if (current_folder && *current_folder != '\0') {
                GError *err = NULL;
-               modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH, 
+               modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH,
                                        current_folder,&err);
                if (err != NULL) {
                        g_debug ("Error storing latest used folder: %s", err->message);
@@ -2930,8 +3015,18 @@ save_attachments_response (GtkDialog *dialog,
        g_free (current_folder);
 
        if (!modest_utils_folder_writable (chooser_uri)) {
-               hildon_banner_show_information 
-                       (NULL, NULL, _FM("sfil_ib_readonly_location"));
+               const gchar *err_msg;
+
+#ifdef MODEST_PLATFORM_MAEMO
+               if (modest_maemo_utils_in_usb_mode ()) {
+                       err_msg = dgettext ("hildon-status-bar-usb", "usbh_ib_mmc_usb_connected");
+               } else {
+                       err_msg = _FM("sfil_ib_readonly_location");
+               }
+#else
+               err_msg = _FM("sfil_ib_readonly_location");
+#endif
+               hildon_banner_show_information (NULL, NULL, err_msg);
        } else {
                TnyIterator *iter;
 
@@ -2961,18 +3056,22 @@ save_attachments_response (GtkDialog *dialog,
                }
                g_object_unref (iter);
        }
-       g_free (chooser_uri);
 
        if (files_to_save != NULL) {
                SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
                info->pairs = files_to_save;
                info->result = TRUE;
+               info->uri = g_strdup (chooser_uri);
+               info->window = g_object_ref (sa_info->window);
                save_mime_parts_to_file_with_checks ((GtkWindow *) dialog, info);
        }
+       g_free (chooser_uri);
 
  end:
        /* Free and close the dialog */
        g_object_unref (mime_parts);
+       g_object_unref (sa_info->window);
+       g_slice_free (SaveAttachmentsInfo, sa_info);
        gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
@@ -2985,6 +3084,7 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window,
        gchar *conf_folder = NULL;
        gchar *filename = NULL;
        gchar *save_multiple_str = NULL;
+       const gchar *root_folder = "file:///";
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
@@ -3037,14 +3137,26 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window,
        save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), 
                                                      GTK_FILE_CHOOSER_ACTION_SAVE);
 
-       /* set folder */
-       conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH, NULL);
+       /* Get last used folder */
+       conf_folder = modest_conf_get_string (modest_runtime_get_conf (),
+                                             MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH, NULL);
+
+       /* File chooser stops working if we select "file:///" as current folder */
+       if (conf_folder && g_ascii_strcasecmp (root_folder, conf_folder) != 0) {
+               g_free (conf_folder);
+               conf_folder = NULL;
+       }
+
        if (conf_folder && conf_folder[0] != '\0') {
                gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (save_dialog), conf_folder);
        } else {
                gchar *docs_folder;
-               /* Set the default folder to images folder */
-               docs_folder = g_build_filename (g_getenv (MYDOCS_ENV), DOCS_FOLDER, NULL);
+               /* Set the default folder to documents folder */
+               docs_folder = (gchar *) g_strdup(g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
+               if (!docs_folder) {
+                       /* fallback */
+                       docs_folder = g_build_filename (g_getenv (MYDOCS_ENV), DOCS_FOLDER, NULL);
+               }
                gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (save_dialog), docs_folder);
                g_free (docs_folder);
        }
@@ -3061,13 +3173,18 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window,
        if (save_multiple_str) {
                g_object_set (G_OBJECT (save_dialog), "save-multiple", save_multiple_str, NULL);
                gtk_window_set_title (GTK_WINDOW (save_dialog), _FM("sfil_ti_save_objects_files"));
+               g_free (save_multiple_str);
        }
 
        /* We must run this asynchronously, because the hildon dialog
           performs a gtk_dialog_run by itself which leads to gdk
           deadlocks */
+       SaveAttachmentsInfo *sa_info;
+       sa_info = g_slice_new (SaveAttachmentsInfo);
+       sa_info->attachments_list = mime_parts;
+       sa_info->window = g_object_ref (window);
        g_signal_connect (save_dialog, "response", 
-                         G_CALLBACK (save_attachments_response), mime_parts);
+                         G_CALLBACK (save_attachments_response), sa_info);
 
        gtk_widget_show_all (save_dialog);
 }
@@ -3413,7 +3530,12 @@ setup_menu (ModestMsgViewWindow *self)
                                           APP_MENU_CALLBACK (modest_msg_view_window_show_find_toolbar),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_find_in_msg));
 
-       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_move_message"), NULL,
+       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self),
+                                          dngettext(GETTEXT_PACKAGE,
+                                                    "mcen_me_move_message",
+                                                    "mcen_me_move_messages",
+                                                    1),
+                                          NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_on_move_to),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_move_to));
 
@@ -3505,7 +3627,7 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
                        gtk_widget_destroy (picker_dialog);
 
                        if (selected)
-                               modest_address_book_add_address (selected);
+                               modest_address_book_add_address (selected, (GtkWindow *) self);
                        g_free (selected);
 
                } else {
@@ -3554,18 +3676,30 @@ void
 modest_msg_view_window_reload (ModestMsgViewWindow *self)
 {
        ModestMsgViewWindowPrivate *priv;
-       TnyHeader *header;
+       const gchar *msg_uid;
+       TnyHeader *header = NULL;
+       TnyFolder *folder = NULL;
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
-       header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (self));     
 
-       if (!message_reader (self, priv, header, NULL, NULL, priv->row_reference)) {
-               g_warning ("Shouldn't happen, trying to reload a message failed");
-       }
+       header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (self));
+       if (!header)
+               return;
 
+       folder = tny_header_get_folder (header);
        g_object_unref (header);
+
+       if (!folder)
+               return;
+
+       msg_uid = modest_msg_view_window_get_message_uid (self);
+        if (msg_uid)
+               if (!message_reader (self, priv, NULL, msg_uid, folder, priv->row_reference))
+                       g_warning ("Shouldn't happen, trying to reload a message failed");
+
+       g_object_unref (folder);
 }
 
 static void