* Merged PE1 fixes into the pe1 branch from the trunk.
authorVivek Sekar <viveksekar@gmail.com>
Mon, 12 May 2008 16:14:49 +0000 (16:14 +0000)
committerVivek Sekar <viveksekar@gmail.com>
Mon, 12 May 2008 16:14:49 +0000 (16:14 +0000)
  * added bug fixes for week 20 and updated the NEWS file

pmo-diablo-r4514

15 files changed:
NEWS
debian/changelog
src/dbus_api/modest-dbus-callbacks.c
src/maemo/modest-connection-specific-smtp-edit-window.c
src/maemo/modest-connection-specific-smtp-window.c
src/maemo/modest-msg-edit-window.c
src/maemo/modest-platform.c
src/modest-error.h
src/modest-mail-operation.c
src/modest-search.c
src/modest-tny-msg.c
src/modest-tny-send-queue.c
src/modest-ui-actions.c
src/widgets/modest-folder-view.c
src/widgets/modest-header-view.c

diff --git a/NEWS b/NEWS
index 42ae1a8..4af6658 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+* 2008-W20:
+- a couple of send and receive related issues fixed
+
+* 2008-W19:
+- a couple of rare hangs / crashes fixed
+
 * 2008-W18:
 - some more low-memory fixes
 - many small UI issues were fixed
index 0b3fabf..9c9bbf7 100644 (file)
@@ -1,3 +1,12 @@
+modest (1.0-2008.20-1) hardy; urgency=low
+
+  * Fixes: NB#84005, NB#84821, NB#84823, NB#84832, NB#85028, NB#85030
+  * Fixes: NB#85055, NB#79005, NB#81913, NB#84054, NB#84260, NB#84604
+  * Fixes: NB#84714, NB#84731, NB#85062, NB#85108, NB#85131, NB#84764
+  * Fixes: NB#84922, NB#83343, NB#84828, NB#85031, NB#84551
+
+ -- Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>  Mon, 12 May 2008 19:09:20 +0300
+
 modest (1.0-2008.19-1) hardy; urgency=low
 
   * Fixes: NB#84764, NB#84922, NB#84551, NB#84828, NB#83343
index 24cd7a8..6cb03ba 100644 (file)
@@ -409,7 +409,7 @@ on_show_opening_animation (gpointer userdata)
 }
 
 static gboolean
-on_hide_opening_animation (gpointer userdata)
+on_find_msg_async_destroy (gpointer userdata)
 {
        OpenMsgPerformerInfo *info = (OpenMsgPerformerInfo *) userdata;
 
@@ -423,10 +423,148 @@ on_hide_opening_animation (gpointer userdata)
                info->animation = NULL;
        }
 
+       if (info->uri)
+               g_free (info->uri);
+       
+       if (info->account)
+               g_object_unref (info->account);
+
        g_slice_free (OpenMsgPerformerInfo, info);
        return FALSE;
 }
 
+static void     
+find_msg_async_cb (TnyFolder *folder, 
+                   gboolean cancelled, 
+                   TnyMsg *msg, 
+                   GError *err, 
+                   gpointer user_data)
+{
+        TnyHeader *header;
+        gchar *msg_uid;
+        ModestWindowMgr *win_mgr;
+        ModestWindow *msg_view = NULL;
+        gboolean is_draft = FALSE;
+        OpenMsgPerformerInfo *info = (OpenMsgPerformerInfo *) user_data;
+
+        if (err || cancelled) {
+                g_idle_add (notify_msg_not_found_in_idle, NULL);
+                goto end;
+        }
+
+        header = tny_msg_get_header (msg);
+        if (header && (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED)) {
+                g_object_unref (header);
+                g_object_unref (msg);
+                g_idle_add (notify_msg_not_found_in_idle, NULL);
+                goto end;
+        }
+
+        msg_uid =  modest_tny_folder_get_header_unique_id (header);
+        win_mgr = modest_runtime_get_window_mgr ();
+
+        if (modest_tny_folder_is_local_folder (folder) &&
+            (modest_tny_folder_get_local_or_mmc_folder_type (folder) == TNY_FOLDER_TYPE_DRAFTS)) {
+                is_draft = TRUE;
+        }
+
+        if (modest_window_mgr_find_registered_header (win_mgr, header, &msg_view)) {
+                gtk_window_present (GTK_WINDOW(msg_view));
+        } else {
+                const gchar *modest_account_name;
+                TnyAccount *account;
+
+                modest_window_mgr_register_header (win_mgr, header, NULL);
+
+                account = tny_folder_get_account (folder);
+                if (account) {
+                        modest_account_name =
+                                modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+                } else {
+                        modest_account_name = NULL;
+                }
+                        
+                /* Drafts will be opened in the editor, and others will be opened in the viewer */
+                if (is_draft) {
+                       gchar *modest_account_name = NULL;
+                       gchar *from_header;
+                       
+                       /* we cannot edit without a valid account... */
+                       if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr (), TRUE)) {
+                               if (!modest_ui_actions_run_account_setup_wizard(NULL)) {
+                                       modest_window_mgr_unregister_header (win_mgr, 
+                                                                            header);
+                                       goto cleanup;
+                               }
+                       }
+               
+                       from_header = tny_header_dup_from (header);
+                       if (from_header) {
+                               GSList *accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
+                               GSList *node = NULL;
+                               for (node = accounts; node != NULL; node = g_slist_next (node)) {
+                                       gchar *from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr (), node->data);
+                                       
+                                       if (from && (strcmp (from_header, from) == 0)) {
+                                               g_free (modest_account_name);
+                                               modest_account_name = g_strdup (node->data);
+                                               g_free (from);
+                                               break;
+                                       }
+                                       g_free (from);
+                               }
+                               g_slist_foreach (accounts, (GFunc) g_free, NULL);
+                               g_slist_free (accounts);
+                               g_free (from_header);
+                       }
+                       
+                       if (modest_account_name == NULL) {
+                               modest_account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
+                       }
+                        msg_view = modest_msg_edit_window_new (msg, modest_account_name, TRUE);
+                       g_free (modest_account_name);
+               } else {
+                        TnyHeader *header;
+                       const gchar *modest_account_name;
+
+                       if (account) {
+                               modest_account_name = 
+                                       modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+                       } else {
+                               modest_account_name = NULL;
+                       }
+
+                        header = tny_msg_get_header (msg);
+                        msg_view = modest_msg_view_window_new_for_search_result (msg, modest_account_name, msg_uid);
+                        if (! (tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN)) {
+                               ModestMailOperation *mail_op;
+                               
+                                tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
+                               /* Sync folder, we need this to save the seen flag */
+                               mail_op = modest_mail_operation_new (NULL);
+                               modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                                                mail_op);
+                               modest_mail_operation_sync_folder (mail_op, folder, FALSE);
+                               g_object_unref (mail_op);
+                       }
+                        g_object_unref (header);
+                }
+
+               if (msg_view != NULL) {
+                       modest_window_mgr_register_window (win_mgr, msg_view);
+                       gtk_widget_show_all (GTK_WIDGET (msg_view));
+               }
+        }
+
+cleanup:
+        g_object_unref (header);
+        g_object_unref (msg);
+
+end:
+        on_find_msg_async_destroy (info);
+}
+
+
 static void 
 on_open_message_performer (gboolean canceled, 
                           GError *err,
@@ -435,103 +573,38 @@ on_open_message_performer (gboolean canceled,
                           gpointer user_data)
 {
        OpenMsgPerformerInfo *info;
-       gchar *uri;
-       TnyHeader *header;
-       gchar *msg_uid;
-       ModestWindowMgr *win_mgr;
-       ModestWindow *msg_view = NULL;
-       gboolean is_draft = FALSE;
        TnyFolder *folder = NULL;
-       TnyMsg *msg = NULL;
 
        info = (OpenMsgPerformerInfo *) user_data;
-       uri = info->uri;
-
-       if (canceled || err) {
-               goto frees;
-       }
-
-       /* Get folder */
-       if (!account) {
-               ModestTnyAccountStore *account_store;
-               ModestTnyLocalFoldersAccount *local_folders_account;
-               
-               account_store = modest_runtime_get_account_store ();
-               local_folders_account = MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (
-                       modest_tny_account_store_get_local_folders_account (account_store));
-               folder = modest_tny_local_folders_account_get_merged_outbox (local_folders_account);
-               g_object_unref (local_folders_account);
-       } else {
-               folder = tny_store_account_find_folder (TNY_STORE_ACCOUNT (account), uri, NULL);
-       }
-
-
-       if (!folder) {
-               g_idle_add (notify_msg_not_found_in_idle, NULL);
-               goto frees;
-       }
-       
-       if (modest_tny_folder_is_local_folder (folder) &&
-           (modest_tny_folder_get_local_or_mmc_folder_type (folder) == TNY_FOLDER_TYPE_DRAFTS)) {
-               is_draft = TRUE;
-       }
-
-       /* Get message */
-       msg = tny_folder_find_msg (folder, uri, NULL);
-       if (!msg) {
-               g_idle_add (notify_msg_not_found_in_idle, NULL);
-               goto frees;
-       }
-
-       header = tny_msg_get_header (msg);
-       if (header && (tny_header_get_flags (header)&TNY_HEADER_FLAG_DELETED)) {
-               g_object_unref (header);
-               g_object_unref (msg);
-               g_idle_add (notify_msg_not_found_in_idle, NULL);
-               goto frees;
-       }
-       msg_uid =  modest_tny_folder_get_header_unique_id (header); 
-       win_mgr = modest_runtime_get_window_mgr ();
-
-       if (modest_window_mgr_find_registered_header (win_mgr, header, &msg_view)) {
-               gtk_window_present (GTK_WINDOW(msg_view));
-       } else {
-               const gchar *modest_account_name;
-
-               /* g_debug ("creating new window for this msg"); */
-               modest_window_mgr_register_header (win_mgr, header, NULL);
-
-               if (account) {
-                       modest_account_name = 
-                               modest_tny_account_get_parent_modest_account_name_for_server_account (account);
-               } else {
-                       modest_account_name = NULL;
-               }
-                       
-               /* Drafts will be opened in the editor, and others will be opened in the viewer */
-               if (is_draft) {
-                       msg_view = modest_msg_edit_window_new (msg, modest_account_name, TRUE);
-               } else {
-                       TnyHeader *header;
-                       header = tny_msg_get_header (msg);
-                       msg_view = modest_msg_view_window_new_for_search_result (msg, modest_account_name, msg_uid);
-                       if (! (tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN))
-                               tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
-                       g_object_unref (header);
-                       
-               }               
-               modest_window_mgr_register_window (win_mgr, msg_view);
-               gtk_widget_show_all (GTK_WIDGET (msg_view));
-       }
-       g_object_unref (header);
-       g_object_unref (msg);
-       g_object_unref (folder);
-
- frees:
-       g_free (info->uri);
-       if (info->account)
-               g_object_unref (info->account);
-       g_idle_add (on_hide_opening_animation, info);
+        if (canceled || err) {
+                g_idle_add (notify_msg_not_found_in_idle, NULL);
+                on_find_msg_async_destroy (info);
+                return;
+        }
+
+        /* Get folder */
+        if (!account) {
+                ModestTnyAccountStore *account_store;
+                ModestTnyLocalFoldersAccount *local_folders_account;
+                
+                account_store = modest_runtime_get_account_store ();
+                local_folders_account = MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (
+                        modest_tny_account_store_get_local_folders_account (account_store));
+                folder = modest_tny_local_folders_account_get_merged_outbox (local_folders_account);
+                g_object_unref (local_folders_account);
+        } else {
+                folder = tny_store_account_find_folder (TNY_STORE_ACCOUNT (account), info->uri, NULL);
+        }
+        if (!folder) {
+                g_idle_add (notify_msg_not_found_in_idle, NULL);
+                on_find_msg_async_destroy (info);
+                return;
+        }
+        
+       info->animation_timeout = g_timeout_add (1000, on_show_opening_animation, info);
+        /* Get message */
+        tny_folder_find_msg_async (folder, info->uri, find_msg_async_cb, NULL, info);
+        g_object_unref (folder);
 }
 
 static gboolean
@@ -586,7 +659,8 @@ on_open_message (GArray * arguments, gpointer data, osso_rpc_t * retval)
                        info->account = g_object_ref (account);
                info->uri = uri;
                info->connect = TRUE;
-               info->animation_timeout = g_timeout_add (1000, on_show_opening_animation, info);
+               info->animation = NULL;
+               info->animation_timeout = 0;
 
                /* Try to get the message, if it's already downloaded
                   we don't need to connect */
@@ -603,10 +677,21 @@ on_open_message (GArray * arguments, gpointer data, osso_rpc_t * retval)
                        g_object_unref (local_folders_account);
                }
                if (folder) {
-                       TnyMsg *msg = tny_folder_find_msg (folder, uri, NULL);
-                       if (msg) {
-                               info->connect = FALSE;
-                               g_object_unref (msg);
+                       TnyDevice *device;
+                       gboolean device_online;
+
+                       device = modest_runtime_get_device();
+                       device_online = tny_device_is_online (device);
+                       if (device_online) {
+                               info->connect = TRUE;
+                       } else {
+                               TnyMsg *msg = tny_folder_find_msg (folder, uri, NULL);
+                               if (msg) {
+                                       info->connect = FALSE;
+                                       g_object_unref (msg);
+                               } else {
+                                       info->connect = TRUE;
+                               }
                        }
                        g_object_unref (folder);
                }
@@ -1825,5 +1910,7 @@ notify_msg_not_found_in_idle (gpointer user_data)
 {
        modest_platform_run_information_dialog (NULL, _("mail_ni_ui_folder_get_msg_folder_error"), FALSE);
 
+       g_idle_add (notify_error_in_dbus_callback, NULL);
+
        return FALSE;
 }
index c9b26fc..a3aa05b 100644 (file)
@@ -52,6 +52,10 @@ G_DEFINE_TYPE (ModestConnectionSpecificSmtpEditWindow, modest_connection_specifi
 #define CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE(o) \
        (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW, ModestConnectionSpecificSmtpEditWindowPrivate))
 
+static void on_response (GtkDialog *dialog,
+                        gint arg1,
+                        gpointer user_data);
+
 typedef struct _ModestConnectionSpecificSmtpEditWindowPrivate ModestConnectionSpecificSmtpEditWindowPrivate;
 
 struct _ModestConnectionSpecificSmtpEditWindowPrivate
@@ -227,8 +231,16 @@ on_response (GtkDialog *dialog, int response_id, gpointer user_data)
                        gtk_editable_select_region (GTK_EDITABLE (priv->entry_outgoingserver), 0, -1);
                        return;
                }
+       } else {
+               /* Ask user if they want to discard changes */
+               if (priv->is_dirty) {
+                       gint response;
+                       response = modest_platform_run_confirmation_dialog (GTK_WINDOW (user_data), 
+                                                                           _("imum_nc_wizard_confirm_lose_changes"));
+                       if (response == GTK_RESPONSE_CANCEL)
+                               g_signal_stop_emission_by_name (dialog, "response");
+               }
        }
-       
 }
 
 static void on_set_focus_child (GtkContainer *container, GtkWidget *widget, gpointer user_data)
@@ -503,8 +515,8 @@ modest_connection_specific_smtp_edit_window_get_settings (ModestConnectionSpecif
        return server_settings;
 }
 
-gboolean modest_connection_specific_smtp_edit_window_is_dirty(
-       ModestConnectionSpecificSmtpEditWindow *window)
+gboolean 
+modest_connection_specific_smtp_edit_window_is_dirty(ModestConnectionSpecificSmtpEditWindow *window)
 {
        ModestConnectionSpecificSmtpEditWindowPrivate *priv = 
                CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (window);
index e80a349..64513d2 100644 (file)
@@ -264,7 +264,7 @@ on_button_edit (GtkButton *button, gpointer user_data)
                        server_settings = NULL;
                }
                        
-               gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (self));
+               modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (window));
                
                gboolean dialog_finished = FALSE;
                while (!dialog_finished)
index cc907e6..a4c83fe 100644 (file)
@@ -269,6 +269,8 @@ struct _ModestMsgEditWindowPrivate {
        GtkWidget   *find_toolbar;
        gchar       *last_search;
 
+       GtkWidget   *font_dialog;
+
        GtkWidget   *scroll;
        guint        scroll_drag_timeout_id;
        gdouble      last_upper;
@@ -441,6 +443,8 @@ modest_msg_edit_window_init (ModestMsgEditWindow *obj)
        priv->scroll_drag_timeout_id = 0;
        priv->last_upper = 0.0;
 
+       priv->font_dialog = NULL;
+
        modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
                                            GTK_WINDOW(obj),"applications_email_editor");
 
@@ -919,6 +923,10 @@ modest_msg_edit_window_finalize (GObject *obj)
           call this function before */
        modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
 
+       if (priv->font_dialog != NULL) {
+               gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
+       }
+
        if (priv->clipboard_text != NULL) {
                g_free (priv->clipboard_text);
                priv->clipboard_text = NULL;
@@ -2874,7 +2882,9 @@ modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
                      NULL);
 
        gtk_widget_show_all (dialog);
+       priv->font_dialog = dialog;
        response = gtk_dialog_run (GTK_DIALOG (dialog));
+       priv->font_dialog = NULL;
        if (response == GTK_RESPONSE_OK) {
 
                g_object_get( dialog,
index 4d61dbd..4c76772 100644 (file)
@@ -860,21 +860,22 @@ modest_platform_run_folder_name_dialog (GtkWindow *parent_window,
                          G_CALLBACK (entry_changed),
                          dialog);
 
+
+       /* Some locales like pt_BR need this to get the full window
+          title shown */
+       gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
+
        /* Create the hbox */
        hbox = gtk_hbox_new (FALSE, 12);
-       gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
        gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
 
        /* Add hbox to dialog */
        gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
                            hbox, FALSE, FALSE, 0);
-
-       gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
-       gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
-
-       /* Some locales like pt_BR need this to get the full window
-          title shown */
-       gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
+       modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
+                                    GTK_WINDOW (dialog));
+       gtk_widget_show_all (GTK_WIDGET(dialog));
                
        result = gtk_dialog_run (GTK_DIALOG(dialog));
        if (result == GTK_RESPONSE_ACCEPT)
index f78a9f1..2e2d2ae 100644 (file)
@@ -48,6 +48,7 @@ typedef enum _ModestErrorCode {
        MODEST_MAIL_OPERATION_ERROR_RETRIEVAL_NUMBER_LIMIT, /* There were too many messages to retrieve. */
        MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED,
        MODEST_MAIL_OPERATION_ERROR_FILE_IO, /* couldn't retrieve a file to construct a mail */
+       MODEST_MAIL_OPERATION_ERROR_SEND_QUEUE_ADD_ERROR,
 } ModestErrorCode;
 
 G_END_DECLS
index 023d565..267e8e8 100644 (file)
@@ -600,6 +600,35 @@ modest_mail_operation_clone_state (ModestMailOperation *self)
 /* ************************** SEND   ACTIONS ************************* */
 /* ******************************************************************* */
 
+static void
+send_mail_on_added_to_outbox (TnySendQueue *send_queue, 
+                             gboolean cancelled, 
+                             TnyMsg *msg, 
+                             GError *err,
+                             gpointer user_data)
+{
+       ModestMailOperationPrivate *priv;
+       ModestMailOperation *self;
+
+       self = MODEST_MAIL_OPERATION (user_data);
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+       if (cancelled || err)
+               goto end;
+
+       if (err) {
+               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                            MODEST_MAIL_OPERATION_ERROR_SEND_QUEUE_ADD_ERROR,
+                            "Error adding a msg to the send queue\n");
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
+       } else {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+       }
+ end:
+       modest_mail_operation_notify_end (self);
+       g_object_unref (self);
+}
+
 void
 modest_mail_operation_send_mail (ModestMailOperation *self,
                                 TnyTransportAccount *transport_account,
@@ -631,22 +660,15 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
                             "modest: could not find send queue for account\n");
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                modest_mail_operation_notify_end (self);
-
        } else {
-               /* Add the msg to the queue */
                modest_mail_operation_notify_start (self);
-
-               tny_send_queue_add_async (send_queue, msg, NULL, NULL, NULL);
-               modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue), FALSE);
-
-               if (priv->error) {
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
-               } else {
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-               }
-               modest_mail_operation_notify_end (self);
+               /* Add the msg to the queue. The callback will
+                  finalize the mail operation */
+               tny_send_queue_add_async (send_queue, msg, send_mail_on_added_to_outbox, 
+                                         NULL, g_object_ref (self));
+               modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue), 
+                                                                 FALSE);
        }
-
 }
 
 
@@ -2820,7 +2842,6 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
        helper->dest_folder = g_object_ref(folder);
        helper->user_callback = user_callback;
        helper->user_data = user_data;
-       helper->delete = delete_original;
        helper->last_total_bytes = 0;
        helper->sum_total_bytes = 0;
        helper->total_bytes = compute_message_list_size (headers);
@@ -2864,11 +2885,14 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
                leave_on_server = FALSE;
        }
 
+       /* Do not delete messages if leave on server is TRUE */
+       helper->delete = (leave_on_server) ? FALSE : delete_original;
+
        modest_mail_operation_notify_start (self);
        tny_folder_transfer_msgs_async (src_folder, 
                                        helper->headers, 
                                        folder, 
-                                       (leave_on_server) ? FALSE : delete_original, 
+                                       helper->delete, 
                                        transfer_msgs_cb, 
                                        transfer_msgs_status_cb,
                                        helper);
index af5a8af..6146a8b 100644 (file)
@@ -346,7 +346,7 @@ search_mime_part_and_child_parts (TnyMimePart *part, ModestSearch *search)
        gboolean found = FALSE;
 
        /* Do not search into attachments */
-       if (modest_tny_mime_part_is_attachment_for_modest (part))
+       if (modest_tny_mime_part_is_attachment_for_modest (part) && !TNY_IS_MSG (part))
                return FALSE;
 
        #ifdef MODEST_HAVE_OGS
index b7c761d..de2d72c 100644 (file)
@@ -442,11 +442,20 @@ modest_tny_msg_find_body_part_from_mime_part (TnyMimePart *msg, gboolean want_ht
 
        /* no parts? assume it's single-part message */
        if (tny_iterator_is_done(iter)) {
-               const gchar *content_type;
+               gchar *content_type;
+               gchar *content_type_lower;
+               gboolean is_text_part;
                g_object_unref (G_OBJECT(iter));
-               content_type = tny_mime_part_get_content_type (msg);
+               content_type = g_strdup (tny_mime_part_get_content_type (msg));
+               if (content_type == NULL)
+                       return NULL;
+               content_type = g_strstrip (content_type);
+               content_type_lower = g_ascii_strdown (content_type, -1);
+               g_free (content_type);
+               is_text_part = g_str_has_prefix (content_type_lower, "text/");
+               g_free (content_type_lower);
                /* if this part cannot be a supported body return NULL */
-               if (!g_str_has_prefix (content_type, "text/")) {
+               if (!is_text_part) {
                        return NULL;
                } else {
                        return TNY_MIME_PART (g_object_ref(G_OBJECT(msg)));
index b67a9d9..3b27216 100644 (file)
@@ -192,6 +192,11 @@ modest_tny_send_queue_to_string (ModestTnySendQueue *self)
        return str;
 }
 
+typedef struct {
+       TnySendQueueAddCallback callback;
+       gpointer user_data;
+} AddAsyncHelper;
+
 static void
 _on_added_to_outbox (TnySendQueue *self, 
                     gboolean cancelled, 
@@ -204,6 +209,7 @@ _on_added_to_outbox (TnySendQueue *self,
        SendInfo *info = NULL;
        GList* existing = NULL;
        gchar* msg_id = NULL;
+       AddAsyncHelper *helper;
 
        g_return_if_fail (TNY_IS_SEND_QUEUE(self));
        g_return_if_fail (TNY_IS_CAMEL_MSG(msg));
@@ -231,6 +237,12 @@ _on_added_to_outbox (TnySendQueue *self,
 
  end:
        g_object_unref (G_OBJECT(header));
+
+       /* Call the user callback */
+       helper = (AddAsyncHelper *) user_data;
+       if (helper->callback)
+               helper->callback (self, cancelled, msg, err, helper->user_data);
+       g_slice_free (AddAsyncHelper, helper);
 }
 
 static void
@@ -268,7 +280,7 @@ _add_message (ModestTnySendQueue *self, TnyHeader *header)
                        break;
                
                /* Add new meesage info */
-               info = g_slice_new (SendInfo);
+               info = g_slice_new0 (SendInfo);
                info->msg_id = strdup(msg_uid);
                info->status = MODEST_TNY_SEND_QUEUE_WAITING;
                g_queue_push_tail (priv->queue, info);
@@ -288,8 +300,15 @@ modest_tny_send_queue_add_async (TnySendQueue *self,
                                 TnyStatusCallback status_callback, 
                                 gpointer user_data)
 {
+       AddAsyncHelper *helper = g_slice_new0 (AddAsyncHelper);
+       helper->callback = callback;
+       helper->user_data = user_data;
+
        /* Call the superclass passing our own callback */
-       TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg, _on_added_to_outbox, NULL, NULL);
+       TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg, 
+                                                            _on_added_to_outbox, 
+                                                            status_callback, 
+                                                            helper);
 }
 
 
@@ -398,13 +417,65 @@ modest_tny_send_queue_finalize (GObject *obj)
        G_OBJECT_CLASS(parent_class)->finalize (obj);
 }
 
+typedef struct {
+       TnyCamelTransportAccount *account;
+       ModestTnySendQueue *queue;
+} GetHeadersInfo;
+
+static void
+new_queue_get_headers_async_cb (TnyFolder *folder, 
+                               gboolean cancelled, 
+                               TnyList *headers, 
+                               GError *err, 
+                               gpointer user_data)
+{
+       ModestTnySendQueue *self;
+       TnyIterator *iter;
+       GetHeadersInfo *info;
+
+       info = (GetHeadersInfo *) user_data;
+       self = MODEST_TNY_SEND_QUEUE (info->queue);
+
+       /* In case of error set the transport account anyway */
+       if (cancelled || err)
+               goto set_transport;
+
+       /* Add messages to our internal queue */
+       iter = tny_list_create_iterator (headers);
+       while (!tny_iterator_is_done (iter)) {
+               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
+               _add_message (self, header);
+               g_object_unref (header);        
+               tny_iterator_next (iter);
+       }
+
+       /* Reenable suspended items */
+       modest_tny_send_queue_wakeup (self);
+
+       /* Frees */
+       g_object_unref (iter);
+       g_object_unref (headers);
+
+ set_transport:
+       /* Do this at the end, because it'll call tny_send_queue_flush
+          which will call tny_send_queue_get_outbox and
+          tny_send_queue_get_sentbox */
+       tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self),
+                                                   info->account);
+
+       /* Frees */
+       g_object_unref (info->account); 
+       g_object_unref (info->queue); 
+       g_slice_free (GetHeadersInfo, info);
+}
+
 ModestTnySendQueue*
 modest_tny_send_queue_new (TnyCamelTransportAccount *account)
 {
        ModestTnySendQueue *self = NULL;
        ModestTnySendQueuePrivate *priv = NULL;
-       TnyIterator *iter = NULL;
        TnyList *headers = NULL;
+       GetHeadersInfo *info;
        
        g_return_val_if_fail (TNY_IS_CAMEL_TRANSPORT_ACCOUNT(account), NULL);
        
@@ -430,35 +501,15 @@ modest_tny_send_queue_new (TnyCamelTransportAccount *account)
                                                               TNY_FOLDER_TYPE_OUTBOX);
        priv->sentbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account),
                                                               TNY_FOLDER_TYPE_SENT);
-
        priv->requested_send_receive = FALSE;
 
-
-       headers = tny_simple_list_new ();       
-       tny_folder_get_headers (priv->outbox, headers, TRUE, NULL);
-
-       /* Add messages to our internal queue */
-       iter = tny_list_create_iterator (headers);
-       while (!tny_iterator_is_done (iter)) {
-               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
-               _add_message (self, header); 
-               g_object_unref (header);                
-
-               tny_iterator_next (iter);
-       }
-
-       /* Reenable suspended items */
-       modest_tny_send_queue_wakeup (self);
-
-       /* Frees */
-       g_object_unref (headers);
-       g_object_unref (iter);
-
-       /* Do this at the end, because it'll call tny_send_queue_flush
-          which will call tny_send_queue_get_outbox and
-          tny_send_queue_get_sentbox */
-       tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self),
-                                                   account); 
+       headers = tny_simple_list_new ();
+       info = g_slice_new0 (GetHeadersInfo);
+       info->account = g_object_ref (account);
+       info->queue = g_object_ref (self);
+       tny_folder_get_headers_async (priv->outbox, headers, TRUE, 
+                                     new_queue_get_headers_async_cb, 
+                                     NULL, info);
 
        return self;
 }
@@ -572,6 +623,8 @@ _on_msg_has_been_sent (TnySendQueue *self,
 
        tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
 
+       tny_folder_sync_async (priv->sentbox, FALSE, NULL, NULL, NULL);
+
        /* Get status info */
        item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
 
@@ -730,19 +783,25 @@ modest_tny_all_send_queues_get_msg_status (TnyHeader *header)
        return status;
 }
 
-void   
-modest_tny_send_queue_wakeup (ModestTnySendQueue *self)
+static void
+wakeup_get_headers_async_cb (TnyFolder *folder, 
+                            gboolean cancelled, 
+                            TnyList *headers, 
+                            GError *err, 
+                            gpointer user_data)
 {
+       ModestTnySendQueue *self;
        ModestTnySendQueuePrivate *priv;
-       TnyList *headers;
        TnyIterator *iter;
 
-       g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
-
+       self = MODEST_TNY_SEND_QUEUE (user_data);
        priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
 
-       headers = tny_simple_list_new ();
-       tny_folder_get_headers (priv->outbox, headers, TRUE, NULL);
+       if (cancelled || err) {
+               g_debug ("Failed to wake up the headers of the send queue");
+               g_object_unref (self);
+               return;
+       }
 
        /* Wake up every single suspended header */
        iter = tny_list_create_iterator (headers);
@@ -778,7 +837,25 @@ modest_tny_send_queue_wakeup (ModestTnySendQueue *self)
 
        /* Frees */
        g_object_unref (iter);
-       g_object_unref (G_OBJECT (headers));
+       g_object_unref (headers);
+       g_object_unref (self);
+}
+
+
+void   
+modest_tny_send_queue_wakeup (ModestTnySendQueue *self)
+{
+       ModestTnySendQueuePrivate *priv;
+       TnyList *headers;
+
+       g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
+
+       priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
+
+       headers = tny_simple_list_new ();
+       tny_folder_get_headers_async (priv->outbox, headers, TRUE, 
+                                     wakeup_get_headers_async_cb, 
+                                     NULL, g_object_ref (self));
 }
 
 gboolean 
index 1c86dc9..32a51d5 100644 (file)
@@ -648,7 +648,6 @@ modest_ui_actions_on_accounts (GtkAction *action,
        } else {
                /* Show the list of accounts */
                GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
-               gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
                
                /* The accounts dialog must be modal */
                modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
@@ -945,17 +944,26 @@ open_msg_cb (ModestMailOperation *mail_op,
                if (from_header) {
                        GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
                        GSList *node = NULL;
+                       gchar *from_header_email;
+
+                       from_header_email = modest_text_utils_get_email_address ((const gchar *) from_header);
+
                        for (node = accounts; node != NULL; node = g_slist_next (node)) {
-                               gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
+                               gchar *from, *from_email;
                                
-                               if (from && (strcmp (from_header, from) == 0)) {
-                                       g_free (account);
-                                       account = g_strdup (node->data);
+                               from = modest_account_mgr_get_from_string (mgr, node->data);
+                               if (from) {
+                                       from_email = modest_text_utils_get_email_address ((const gchar *) from);
+                                       if (strcmp (from_header_email, from_email) == 0) {
+                                               g_free (account);
+                                               account = g_strdup (node->data);
+                                               g_free (from);
+                                               break;
+                                       }
                                        g_free (from);
-                                       break;
                                }
-                               g_free (from);
                        }
+                       g_free (from_header_email);
                        g_free (from_header);
                        g_slist_foreach (accounts, (GFunc) g_free, NULL);
                        g_slist_free (accounts);
index 8a9ba72..fe5ab9c 100644 (file)
@@ -1246,14 +1246,60 @@ on_account_inserted (TnyAccountStore *account_store,
 }
 
 
+static gboolean
+same_account_selected (ModestFolderView *self,
+                      TnyAccount *account)
+{
+       ModestFolderViewPrivate *priv;
+       gboolean same_account = FALSE;
+
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       if (priv->cur_folder_store) {
+               TnyAccount *selected_folder_account = NULL;
+
+               if (TNY_IS_FOLDER (priv->cur_folder_store)) {
+                       selected_folder_account = 
+                               tny_folder_get_account (TNY_FOLDER (priv->cur_folder_store));
+               } else {
+                       selected_folder_account = 
+                               TNY_ACCOUNT (g_object_ref (priv->cur_folder_store));
+               }
+
+               if (selected_folder_account == account)
+                       same_account = TRUE;
+
+               g_object_unref (selected_folder_account);
+       }
+       return same_account;
+}
+
+/**
+ *
+ * Selects the first inbox or the local account in an idle
+ */
+static gboolean
+on_idle_select_first_inbox_or_local (gpointer user_data)
+{
+       ModestFolderView *self = MODEST_FOLDER_VIEW (user_data);
+
+       gdk_threads_enter ();
+       modest_folder_view_select_first_inbox_or_local (self);
+       gdk_threads_leave ();
+
+       return FALSE;
+}
+
 static void
 on_account_changed (TnyAccountStore *account_store, 
                    TnyAccount *tny_account,
                    gpointer user_data)
 {
+       ModestFolderView *self;
        ModestFolderViewPrivate *priv;
        GtkTreeModel *sort_model, *filter_model;
        GtkTreeSelection *sel;
+       gboolean same_account;
 
        /* Ignore transport account insertions, we're not showing them
           in the folder view */
@@ -1265,7 +1311,7 @@ on_account_changed (TnyAccountStore *account_store,
                return;
        }
 
-
+       self = MODEST_FOLDER_VIEW (user_data);
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (user_data);
 
        /* Get the inner model */
@@ -1275,16 +1321,19 @@ on_account_changed (TnyAccountStore *account_store,
                return;
        }
 
-
        sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
        if (!GTK_IS_TREE_MODEL_SORT(sort_model)) {
                g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
                return;
        }
 
-       /* Unselect the folder, clear the header list */
-       sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (user_data));
-       gtk_tree_selection_unselect_all (sel);
+       /* Invalidate the cur_folder_store only if the selected folder
+          belongs to the account that is being removed */
+       same_account = same_account_selected (self, tny_account);
+       if (same_account) {
+               sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+               gtk_tree_selection_unselect_all (sel);
+       }
 
        /* Remove the account from the model */
        tny_list_remove (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
@@ -1296,25 +1345,13 @@ on_account_changed (TnyAccountStore *account_store,
 
        /* Refilter the model */
        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
-}
 
-/**
- *
- * Selects the first inbox or the local account in an idle
- */
-static gboolean
-on_idle_select_first_inbox_or_local (gpointer user_data)
-{
-       ModestFolderView *self = MODEST_FOLDER_VIEW (user_data);
-
-       gdk_threads_enter ();
-       modest_folder_view_select_first_inbox_or_local (self);
-       gdk_threads_leave ();
-
-       return FALSE;
+       /* Select the first INBOX if the currently selected folder
+          belongs to the account that is being deleted */
+       if (same_account)
+               g_idle_add (on_idle_select_first_inbox_or_local, self);
 }
 
-
 static void
 on_account_removed (TnyAccountStore *account_store, 
                    TnyAccount *account,
@@ -1324,7 +1361,7 @@ on_account_removed (TnyAccountStore *account_store,
        ModestFolderViewPrivate *priv;
        GtkTreeModel *sort_model, *filter_model;
        GtkTreeSelection *sel = NULL;
-       gboolean same_account_selected = FALSE;
+       gboolean same_account = FALSE;
 
        /* Ignore transport account removals, we're not showing them
           in the folder view */
@@ -1341,23 +1378,10 @@ on_account_removed (TnyAccountStore *account_store,
 
        /* Invalidate the cur_folder_store only if the selected folder
           belongs to the account that is being removed */
-       if (priv->cur_folder_store) {
-               TnyAccount *selected_folder_account = NULL;
-
-               if (TNY_IS_FOLDER (priv->cur_folder_store)) {
-                       selected_folder_account = 
-                               tny_folder_get_account (TNY_FOLDER (priv->cur_folder_store));
-               } else {
-                       selected_folder_account = 
-                               TNY_ACCOUNT (g_object_ref (priv->cur_folder_store));
-               }
-
-               if (selected_folder_account == account) {
-                       sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
-                       gtk_tree_selection_unselect_all (sel);
-                       same_account_selected = TRUE;
-               }
-               g_object_unref (selected_folder_account);
+       same_account = same_account_selected (self, account);
+       if (same_account) {
+               sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+               gtk_tree_selection_unselect_all (sel);
        }
 
        /* Invalidate row to select only if the folder to select
@@ -1408,7 +1432,7 @@ on_account_removed (TnyAccountStore *account_store,
 
        /* Select the first INBOX if the currently selected folder
           belongs to the account that is being deleted */
-       if (same_account_selected)
+       if (same_account)
                g_idle_add (on_idle_select_first_inbox_or_local, self);
 }
 
index cee8ad6..895ec95 100644 (file)
@@ -989,22 +989,19 @@ modest_header_view_get_folder (ModestHeaderView *self)
 }
 
 static void
-modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
+set_folder_intern_get_headers_async_cb (TnyFolder *folder, 
+                                       gboolean cancelled, 
+                                       TnyList *headers, 
+                                       GError *err, 
+                                       gpointer user_data)
 {
-       TnyFolderType type;
-       TnyList *headers;
+       ModestHeaderView *self;
        ModestHeaderViewPrivate *priv;
-       GList *cols, *cursor;
-       GtkTreeModel *filter_model, *sortable; 
-       guint sort_colid;
-       GtkSortType sort_type;
 
-       priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
-
-       headers = TNY_LIST (tny_gtk_header_list_model_new ());
+       g_return_if_fail (MODEST_IS_HEADER_VIEW (user_data));
 
-       tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL(headers),
-                                             folder, FALSE, NULL, NULL, NULL);
+       self = MODEST_HEADER_VIEW (user_data);
+       priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
 
        /* Add IDLE observer (monitor) and another folder observer for
           new messages (self) */
@@ -1017,6 +1014,39 @@ modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
        tny_folder_monitor_add_list (priv->monitor, TNY_LIST (headers));
        tny_folder_monitor_start (priv->monitor);
        g_mutex_unlock (priv->observers_lock);
+}
+
+static void
+modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
+{
+       TnyFolderType type;
+       TnyList *headers;
+       ModestHeaderViewPrivate *priv;
+       GList *cols, *cursor;
+       GtkTreeModel *filter_model, *sortable; 
+       guint sort_colid;
+       GtkSortType sort_type;
+
+       priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+       headers = TNY_LIST (tny_gtk_header_list_model_new ());
+
+       /* Start the monitor in the callback of the
+          tny_gtk_header_list_model_set_folder call. It's crucial to
+          do it there and not just after the call because we want the
+          monitor to observe only the headers returned by the
+          tny_folder_get_headers_async call that it's inside the
+          tny_gtk_header_list_model_set_folder call. This way the
+          monitor infrastructure could successfully cope with
+          duplicates. For example if a tny_folder_add_msg_async is
+          happening while tny_gtk_header_list_model_set_folder is
+          invoked, then the first call could add a header that will
+          be added again by tny_gtk_header_list_model_set_folder, so
+          we'd end up with duplicate headers. sergio */
+       tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL(headers),
+                                             folder, FALSE, 
+                                             set_folder_intern_get_headers_async_cb, 
+                                             NULL, self);
 
        sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(headers));
        g_object_unref (G_OBJECT (headers));