* Added an attribute sent to the msg edit window that specifies that the mail has...
[modest] / src / modest-ui-actions.c
index 71f925f..fa1d7b3 100644 (file)
@@ -97,6 +97,7 @@ typedef struct _ReplyForwardHelper {
        GtkWidget *parent_window;
 } ReplyForwardHelper;
 
+
 /*
  * The do_headers_action uses this kind of functions to perform some
  * action to each member of a list of headers
@@ -121,8 +122,6 @@ static void     reply_forward_cb       (ModestMailOperation *mail_op,
 
 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
 
-static gchar*   ask_for_folder_name    (GtkWindow *parent_window, const gchar *title);
-
 
 static void     _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
                                                   ModestMailOperationState *state,
@@ -263,9 +262,18 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
        gint response;
        gboolean found;
        ModestWindowMgr *mgr;
+       GtkWidget *header_view;
 
        g_return_if_fail (MODEST_IS_WINDOW(win));
 
+       /* Check first if the header view has the focus */
+       if (MODEST_IS_MAIN_WINDOW (win)) {
+               header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
+                                                                  MODEST_WIDGET_TYPE_HEADER_VIEW);
+               if (!gtk_widget_is_focus (header_view))
+                       return;
+       }
+
        header_list = get_selected_headers (win);
        if (!header_list) return;
 
@@ -297,16 +305,15 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
        }
 
        /* Select message */
-       if (tny_list_get_length(header_list) > 1)
-               message = g_strdup(_("emev_nc_delete_messages"));
-       else {
+       if (tny_list_get_length(header_list) == 1) {
                iter = tny_list_create_iterator (header_list);
                header = TNY_HEADER (tny_iterator_get_current (iter));
                desc = g_strdup_printf ("%s", tny_header_get_subject (header)); 
-               message = g_strdup_printf(_("emev_nc_delete_message"), desc);
                g_object_unref (header);
                g_object_unref (iter);
        }
+       message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages", 
+                                          tny_list_get_length(header_list)), desc);
 
        /* Confirmation dialog */               
        response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
@@ -338,10 +345,13 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
 void
 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
 {
-       #ifdef MODEST_PLATFORM_MAEMO
+#ifdef MODEST_PLATFORM_MAEMO
        modest_osso_save_state();
-       #endif /* MODEST_PLATFORM_MAEMO */
-       
+#endif /* MODEST_PLATFORM_MAEMO */
+
+       /* FIXME: we need to cancel all actions/threads here,
+        so we really quit */
+
        gtk_main_quit ();
 }
 
@@ -465,9 +475,9 @@ modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
        /* Show the window: */  
        gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
        gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
-    gtk_widget_show (specific_window);
+       gtk_widget_show (specific_window);
     
-    /* Save changes when the window is hidden: */
+       /* Save changes when the window is hidden: */
        g_signal_connect (specific_window, "hide", 
                G_CALLBACK (on_smtp_servers_window_hide), win);
 #endif /* MODEST_PLATFORM_MAEMO */
@@ -476,7 +486,7 @@ modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
 void
 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
 {
-       ModestWindow *msg_win;
+       ModestWindow *msg_win = NULL;
        TnyMsg *msg = NULL;
        TnyFolder *folder = NULL;
        gchar *account_name = NULL;
@@ -492,9 +502,9 @@ modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
                        return;
        }
        
-       account_name = g_strdup(modest_window_get_active_account (win));
+       account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
        if (!account_name)
-               account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
+               account_name = g_strdup (modest_window_get_active_account (win));
        if (!account_name) {
                g_printerr ("modest: no account found\n");
                goto cleanup;
@@ -552,6 +562,8 @@ cleanup:
        g_free (account_name);
        g_free (from_str);
        g_free (blank_and_signature);
+       if (msg_win)
+               g_object_unref (msg_win);
        if (account)
                g_object_unref (G_OBJECT(account));
        if (msg)
@@ -584,9 +596,9 @@ open_msg_cb (ModestMailOperation *mail_op,
        headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
 
        /* Get account */
-       account =  g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
+       account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
        if (!account)
-               account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
+               account =  g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
        
        /* Gets folder type (OUTBOX headers will be opened in edit window */
        if (modest_tny_folder_is_local_folder (folder))
@@ -642,6 +654,7 @@ open_msg_cb (ModestMailOperation *mail_op,
        if (win != NULL) {
                mgr = modest_runtime_get_window_mgr ();
                modest_window_mgr_register_window (mgr, win);
+               g_object_unref (win);
                gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
                gtk_widget_show_all (GTK_WIDGET(win));
        }
@@ -649,9 +662,9 @@ open_msg_cb (ModestMailOperation *mail_op,
 cleanup:
        /* Free */
        g_free(account);
+       g_object_unref (parent_win);
        g_object_unref (msg);
        g_object_unref (folder);
-       g_object_unref (header);
 }
 
 /*
@@ -670,6 +683,7 @@ modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
 
                modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
                                                        error->message);
+               g_object_unref (win);
        }
 }
 
@@ -715,11 +729,20 @@ _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
                                                                 modest_ui_actions_get_msgs_full_error_handler, 
                                                                 NULL);
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
-       modest_mail_operation_get_msgs_full (mail_op, 
-                                            not_opened_headers, 
-                                            open_msg_cb, 
-                                            NULL, 
-                                            NULL);
+       if (tny_list_get_length (not_opened_headers) > 1) {
+               modest_mail_operation_get_msgs_full (mail_op, 
+                                                    not_opened_headers, 
+                                                    open_msg_cb, 
+                                                    NULL, 
+                                                    NULL);
+       } else {
+               TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
+               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
+               modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
+               g_object_unref (header);
+               g_object_unref (iter);
+       }
+
        /* Clean */
        g_object_unref (not_opened_headers);
        g_object_unref (iter);
@@ -761,11 +784,11 @@ reply_forward_cb (ModestMailOperation *mail_op,
 {
        TnyMsg *new_msg;
        ReplyForwardHelper *rf_helper;
-       ModestWindow *msg_win;
+       ModestWindow *msg_win = NULL;
        ModestEditType edit_type;
-       gchar *from;
+       gchar *from = NULL;
        TnyAccount *account = NULL;
-       ModestWindowMgr *mgr;
+       ModestWindowMgr *mgr = NULL;
        gchar *signature = NULL;
                        
        g_return_if_fail (user_data != NULL);
@@ -836,6 +859,8 @@ reply_forward_cb (ModestMailOperation *mail_op,
        gtk_widget_show_all (GTK_WIDGET (msg_win));
 
 cleanup:
+       if (msg_win)
+               g_object_unref (msg_win);
        if (new_msg)
                g_object_unref (G_OBJECT (new_msg));
        if (account)
@@ -857,11 +882,11 @@ static gboolean
 download_uncached_messages (TnyList *header_list, GtkWindow *win)
 {
        TnyIterator *iter;
-       gboolean found, retval;
+       gboolean retval;
+       gint uncached_messages = 0;
 
        iter = tny_list_create_iterator (header_list);
-       found = FALSE;
-       while (!tny_iterator_is_done (iter) && !found) {
+       while (!tny_iterator_is_done (iter)) {
                TnyHeader *header;
                TnyHeaderFlags flags;
 
@@ -870,7 +895,8 @@ download_uncached_messages (TnyList *header_list, GtkWindow *win)
                /* TODO: is this the right flag?, it seems that some
                   headers that have been previously downloaded do not
                   come with it */
-               found = !(flags & TNY_HEADER_FLAG_CACHED);
+               if (! (flags & TNY_HEADER_FLAG_CACHED))
+                       uncached_messages ++;
                g_object_unref (header);
                tny_iterator_next (iter);
        }
@@ -878,11 +904,13 @@ download_uncached_messages (TnyList *header_list, GtkWindow *win)
 
        /* Ask for user permission to download the messages */
        retval = TRUE;
-       if (found) {
+       if (uncached_messages > 0) {
                GtkResponseType response;
                response = 
                        modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
-                                                                _("mcen_nc_get_multi_msg_txt"));
+                                                                ngettext("mcen_nc_get_msg",
+                                                                         "mcen_nc_get_msgs",
+                                                                        uncached_messages));
                if (response == GTK_RESPONSE_CANCEL)
                        retval = FALSE;
        }
@@ -1061,6 +1089,17 @@ modest_ui_actions_on_sort (GtkAction *action,
        }
 }
 
+static void
+new_messages_arrived (ModestMailOperation *self, 
+                     gint new_messages,
+                     gpointer user_data)
+{
+       if (new_messages == 0)
+               return;
+
+       modest_platform_on_new_msg ();
+}
+
 /*
  * This function performs the send & receive required actions. The
  * window is used to create the mail operation. Typically it should
@@ -1103,7 +1142,7 @@ modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
           internally, so the progress objects will receive the proper
           progress information */
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
-       modest_mail_operation_update_account (mail_op, acc_name);
+       modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
        g_object_unref (G_OBJECT (mail_op));
        
        /* Free */
@@ -1127,9 +1166,9 @@ modest_ui_actions_do_send_receive_all (ModestWindow *win)
                modest_ui_actions_do_send_receive ((const char*) iter->data, win);
                iter = g_slist_next (iter);
        }
-       
-       g_slist_foreach (account_names, (GFunc) g_free, NULL);
-       g_slist_free (account_names);
+
+       modest_account_mgr_free_account_names (account_names);
+       account_names = NULL;
 }
 
 /*
@@ -1195,9 +1234,13 @@ modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
        /* If no header has been selected then exit */
        if (!header)
                return;
-       
+
+       /* Update focus */
+       if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
+           gtk_widget_grab_focus (GTK_WIDGET(header_view));
+
        /* Update Main window title */
-       if (GTK_WIDGET_HAS_FOCUS (header_view)) {
+       if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
                const gchar *subject = tny_header_get_subject (header);
                if (subject && strlen(subject) > 0)
                        gtk_window_set_title (GTK_WINDOW (main_window), subject);
@@ -1255,7 +1298,6 @@ folder_refreshed_cb (const GObject *obj,
                     TnyFolder *folder, 
                     gpointer user_data)
 {
-       printf ("DEBUG: %s\n", __FUNCTION__);
        ModestMainWindow *win = NULL;
        GtkWidget *header_view;
 
@@ -1272,12 +1314,6 @@ folder_refreshed_cb (const GObject *obj,
                                                       MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
        } else {
                printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
-               /* Restore configuration. There is no need to set the
-                  contents style to headers because it was already
-                  being done in folder_selection_changed */
-               modest_widget_memory_restore (modest_runtime_get_conf (), 
-                                             G_OBJECT(header_view),
-                                             MODEST_CONF_HEADER_VIEW_KEY);
        }
 }
 
@@ -1300,28 +1336,28 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
        conf = modest_runtime_get_conf ();
 
        if (TNY_IS_ACCOUNT (folder_store)) {
-               /* Update active account */
-               set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
-               /* Show account details */
-               modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
+               if (selected) {
+                       /* Update active account */
+                       set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
+                       /* Show account details */
+                       modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
+               }
        } else {
                if (TNY_IS_FOLDER (folder_store) && selected) {
                        
-                       if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
-                               /* Update the active account */
-                               TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
+                       /* Update the active account */
+                       TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
+                       if (account) {
                                set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
                                g_object_unref (account);
+                               account = NULL;
                        }
 
-                       /* Set the header view, we could change it to
-                          the empty view after the refresh */
+                       /* Set the header style by default, it could
+                          be changed later by the refresh callback to
+                          empty */
                        modest_main_window_set_contents_style (main_window, 
                                                               MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
-                       
-                       modest_widget_memory_save (modest_runtime_get_conf(),
-                                                  G_OBJECT(header_view),
-                                                  MODEST_CONF_HEADER_VIEW_KEY);
 
                        /* Set folder on header view. This function
                           will call tny_folder_refresh_async so we
@@ -1332,13 +1368,24 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
                                                       TNY_FOLDER (folder_store),
                                                       folder_refreshed_cb,
                                                       main_window);
+                       
+                       /* Restore configuration. We need to do this
+                          *after* the set_folder because the widget
+                          memory asks the header view about its
+                          folder  */
+                       modest_widget_memory_restore (modest_runtime_get_conf (), 
+                                                     G_OBJECT(header_view),
+                                                     MODEST_CONF_HEADER_VIEW_KEY);
                } else {
                        /* Update the active account */
                        modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
-                       /* Do not show folder */
-                       modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
+                       /* Save only if we're seeing headers */
+                       if (modest_main_window_get_contents_style (main_window) ==
+                           MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
+                               modest_widget_memory_save (conf, G_OBJECT (header_view), 
+                                                          MODEST_CONF_HEADER_VIEW_KEY);
                        modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
-               }                       
+               }
        }
 
        /* Update toolbar dimming state */
@@ -1439,6 +1486,7 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
        MsgData *data;
        gchar *account_name, *from;
        ModestAccountMgr *account_mgr;
+       gchar *info_text = NULL;
 
        g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
        
@@ -1495,8 +1543,9 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
 
        modest_msg_edit_window_free_msg_data (edit_window, data);
 
-       /* Save settings and close the window */
-       gtk_widget_destroy (GTK_WIDGET (edit_window));
+       info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
+       modest_platform_information_banner (NULL, NULL, info_text);
+       g_free (info_text);
 }
 
 /* For instance, when clicking the Send toolbar button when editing a message: */
@@ -1568,6 +1617,8 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
                }
        }
 
+       modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
+
        /* Create the mail operation */
        ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
@@ -1592,6 +1643,7 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
        g_object_unref (G_OBJECT (mail_operation));
 
        modest_msg_edit_window_free_msg_data (edit_window, data);
+       modest_msg_edit_window_set_sent (edit_window, TRUE);
 
        /* Save settings and close the window: */
        gtk_widget_destroy (GTK_WIDGET (edit_window));
@@ -1742,46 +1794,6 @@ modest_ui_actions_on_remove_attachments (GtkAction *action,
        modest_msg_edit_window_remove_attachments (window, NULL);
 }
 
-/*
- * Shows a dialog with an entry that asks for some text. The returned
- * value must be freed by the caller. The dialog window title will be
- * set to @title.
- */
-static gchar *
-ask_for_folder_name (GtkWindow *parent_window,
-                    const gchar *title)
-{
-       GtkWidget *dialog, *entry;
-       gchar *folder_name = NULL;
-
-       /* Ask for folder name */
-       dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
-                                             parent_window,
-                                             GTK_DIALOG_MODAL,
-                                             GTK_STOCK_CANCEL,
-                                             GTK_RESPONSE_REJECT,
-                                             GTK_STOCK_OK,
-                                             GTK_RESPONSE_ACCEPT,
-                                             NULL);
-       gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
-                           gtk_label_new(title),
-                           FALSE, FALSE, 0);
-               
-       entry = gtk_entry_new_with_max_length (40);
-       gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
-                           entry,
-                           TRUE, FALSE, 0);    
-       
-       gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
-       
-       if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)         
-               folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
-
-       gtk_widget_destroy (dialog);
-
-       return folder_name;
-}
-
 void 
 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
 {
@@ -1861,10 +1873,14 @@ modest_ui_actions_on_rename_folder (GtkAction *action,
        
        if (folder && TNY_IS_FOLDER (folder)) {
                gchar *folder_name;
-               folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
-                                                  _("Please enter a new name for the folder"));
+               gint response;
+               const gchar *current_name;
 
-               if (folder_name != NULL && strlen (folder_name) > 0) {
+               current_name = tny_folder_get_name (TNY_FOLDER (folder));
+               response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
+                                                                    current_name, &folder_name);
+
+               if (response == GTK_RESPONSE_OK && strlen (folder_name) > 0) {
                        ModestMailOperation *mail_op;
 
                        mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
@@ -1892,6 +1908,7 @@ modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
 
        modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
                                                _("mail_in_ui_folder_delete_error"));
+       g_object_unref (win);
 }
 
 static void
@@ -2094,12 +2111,8 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
                        const gboolean username_was_changed = 
                                (strcmp (*username, initial_username) != 0);
                        if (username_was_changed) {
-                               /* To actually use a changed username, 
-                                * we must reset the connection, according to pvanhoof.
-                                * This _might_ be a sensible way to do that: */
-                                TnyDevice *device = modest_runtime_get_device();
-                                tny_device_force_offline (device);
-                                tny_device_force_online (device);
+                               g_warning ("%s: tinymail does not yet support changing the "
+                                       "username in the get_password() callback.\n", __FUNCTION__);
                        }
                }
                        
@@ -2157,6 +2170,10 @@ modest_ui_actions_on_cut (GtkAction *action,
                clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
                buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
                gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
+       } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
+               modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
+       } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
+               modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
        }
 }
 
@@ -2169,16 +2186,45 @@ modest_ui_actions_on_copy (GtkAction *action,
 
        clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
        focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
+
        if (GTK_IS_LABEL (focused_widget)) {
                gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
        } else if (GTK_IS_EDITABLE (focused_widget)) {
                gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
        } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
                GtkTextBuffer *buffer;
-
                buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
                gtk_text_buffer_copy_clipboard (buffer, clipboard);
-       }
+               modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
+       } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
+               TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
+               TnyIterator *iter = tny_list_create_iterator (header_list);
+               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
+               TnyFolder *folder = tny_header_get_folder (header);
+               TnyAccount *account = tny_folder_get_account (folder);
+               const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
+               /* If it's POP then ask */
+               gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
+                      MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
+               g_object_unref (account);
+               g_object_unref (folder);
+               g_object_unref (header);
+               g_object_unref (iter);
+               
+               /* Check that the messages have been previously downloaded */
+               gboolean continue_download = TRUE;
+               if (ask)
+                       continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
+               if (continue_download)
+                       modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
+               g_object_unref (header_list);
+       } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
+               modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
+       }    
+
+       /* Show information banner */
+       modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
+       
 }
 
 void
@@ -2197,6 +2243,7 @@ modest_ui_actions_on_paste (GtkAction *action,
                            ModestWindow *window)
 {
        GtkWidget *focused_widget;
+       ModestMailOperation *mail_op = NULL;
 
        focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
        if (GTK_IS_EDITABLE (focused_widget)) {
@@ -2208,6 +2255,52 @@ modest_ui_actions_on_paste (GtkAction *action,
                clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
                buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
                gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
+       } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
+               ModestEmailClipboard *clipboard = NULL;
+               TnyFolder *src_folder = NULL;
+               TnyFolderStore *folder_store = NULL;
+               TnyList *data = NULL;           
+               gboolean delete = FALSE;
+               
+               /* Check clipboard source */
+               clipboard = modest_runtime_get_email_clipboard ();
+               if (modest_email_clipboard_cleared (clipboard)) 
+                       return;
+               
+               /* Get elements to paste */
+               modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
+
+               /* Create a new mail operation */
+               mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
+               modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
+                                                mail_op);
+               
+               /* Get destination folder */
+               folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
+
+               /* transfer messages  */
+               if (data != NULL) {
+                       modest_mail_operation_xfer_msgs (mail_op, 
+                                                        data,
+                                                        TNY_FOLDER (folder_store),
+                                                        delete,
+                                                        NULL,
+                                                        NULL);
+                       
+               } else if (src_folder != NULL) {                        
+                       modest_mail_operation_xfer_folder (mail_op, 
+                                                          src_folder,
+                                                          folder_store,
+                                                          delete);
+               }
+
+               /* Free */
+               if (data != NULL) 
+                       g_object_unref (data);
+               if (src_folder != NULL) 
+                       g_object_unref (src_folder);
+               if (folder_store != NULL) 
+                       g_object_unref (folder_store);
        }
 }
 
@@ -2247,6 +2340,10 @@ modest_ui_actions_on_select_all (GtkAction *action,
                /* Select all messages */
                selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
                gtk_tree_selection_select_all (selection);
+
+               /* Set focuse on header view */
+               gtk_widget_grab_focus (header_view);
+
        } else if (GTK_IS_HTML (focused_widget)) {
                gtk_html_select_all (GTK_HTML (focused_widget));
        }
@@ -2441,15 +2538,20 @@ modest_ui_actions_on_details (GtkAction *action,
                folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
                if (gtk_widget_is_focus (folder_view)) {
-                       TnyFolder *folder;
-
-                       folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
-
+                       TnyFolderStore *folder_store
+                               = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
+                       if (!folder_store) {
+                               g_warning ("%s: No item was selected.\n", __FUNCTION__);
+                               return; 
+                       }
                        /* Show only when it's a folder */
-                       if (!folder || !TNY_IS_FOLDER (folder))
-                               return;
+                       /* This function should not be called for account items, 
+                        * because we dim the menu item for them. */
+                       if (TNY_IS_FOLDER (folder_store)) {
+                               show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
+                       }
 
-                       show_folder_details (folder, GTK_WINDOW (win));
+                       g_object_unref (folder_store);
 
                } else {
                        header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
@@ -2658,21 +2760,21 @@ msgs_move_to_confirmation (GtkWindow *win,
                g_object_unref (header);
                g_object_unref (iter);
 
+               /* if no src_folder, message may be an attahcment */
+               if (src_folder == NULL) 
+                       return GTK_RESPONSE_CANCEL;
+
                /* If the source is a remote folder */
                if (!modest_tny_folder_is_local_folder (src_folder)) {
                        const gchar *message;
                        
-                       if (tny_list_get_length (headers) == 1)
-                               if (has_retrieved_msgs (headers))
-                                       message = _("mcen_nc_move_retrieve");
-                               else
-                                       message = _("mcen_nc_move_header");
-                       else
-                               if (has_retrieved_msgs (headers))
-                                       message = _("mcen_nc_move_retrieves");
-                               else
-                                       message = _("mcen_nc_move_headers");
-                       
+                       if (has_retrieved_msgs (headers))
+                               message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
+                                                   tny_list_get_length (headers));
+                       else 
+                               message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
+                                                   tny_list_get_length (headers));
+
                        response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
                                                                            (const gchar *) message);
                }
@@ -2683,16 +2785,17 @@ msgs_move_to_confirmation (GtkWindow *win,
 
 
 static void
-tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
+transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
 {
        ModestMsgViewWindow *self = NULL;
-       gboolean found = FALSE;
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
        self = MODEST_MSG_VIEW_WINDOW (object);
 
-       found = modest_msg_view_window_select_first_message (self);
-       g_return_if_fail (found);
+       /* If there are not more messages don't do anything. The
+          viewer will show the same message */
+       if (!modest_msg_view_window_select_first_message (self))
+           return;
 }
 
 void
@@ -2704,6 +2807,7 @@ modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
        /* TODO: show error message */
        modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
                                                _("mail_in_ui_folder_move_target_error"));
+       g_object_unref (win);
 }
 
 /*
@@ -2801,8 +2905,9 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action,
                        g_object_unref (headers);
                }
        }
-       g_object_unref (folder_store);
  end:
+       if (folder_store != NULL)
+               g_object_unref (folder_store);
        gtk_widget_destroy (dialog);
 }
 
@@ -2842,6 +2947,7 @@ modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
 
                /* Create header list */
                header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
+                       
                headers = tny_simple_list_new ();
                tny_list_prepend (headers, G_OBJECT (header));
                g_object_unref (header);
@@ -2865,7 +2971,7 @@ modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
                                                         headers,
                                                         TNY_FOLDER (folder_store),
                                                         TRUE,
-                                                        tranasfer_msgs_from_viewer_cb,
+                                                        transfer_msgs_from_viewer_cb,
                                                         NULL);
                        g_object_unref (G_OBJECT (mail_op));
                }
@@ -2901,22 +3007,34 @@ do_headers_action (ModestWindow *win,
 {
        TnyList *headers_list;
        TnyIterator *iter;
+       TnyHeader *header;
+       TnyFolder *folder;
 
        /* Get headers */
        headers_list = get_selected_headers (win);
        if (!headers_list)
                return;
 
-       /* Call the function for each header */
+       /* Get the folder */
        iter = tny_list_create_iterator (headers_list);
-       while (!tny_iterator_is_done (iter)) {
-               TnyHeader *header;
+       header = TNY_HEADER (tny_iterator_get_current (iter));
+       folder = tny_header_get_folder (header);
+       g_object_unref (header);
 
+       /* Call the function for each header */
+       while (!tny_iterator_is_done (iter)) {
                header = TNY_HEADER (tny_iterator_get_current (iter));
                func (header, win, user_data);
                g_object_unref (header);
                tny_iterator_next (iter);
        }
+
+       /* Trick: do a poke status in order to speed up the signaling
+          of observers */
+       tny_folder_poke_status (folder);
+
+       /* Frees */
+       g_object_unref (folder);
        g_object_unref (iter);
        g_object_unref (headers_list);
 }
@@ -2950,7 +3068,7 @@ modest_ui_actions_remove_attachments (GtkAction *action,
                                      ModestWindow *window)
 {
        if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
-               modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
+               modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window));
        } else {
                /* not supported window for this action */
                g_return_if_reached ();
@@ -2965,7 +3083,7 @@ modest_ui_actions_on_settings (GtkAction *action,
 
        dialog = modest_platform_get_global_settings_dialog ();
        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
-       gtk_widget_show (dialog);
+       gtk_widget_show_all (dialog);
 
        gtk_dialog_run (GTK_DIALOG (dialog));
 
@@ -3016,6 +3134,7 @@ modest_ui_actions_on_help (GtkAction *action,
                                        help_id = NULL;
                                }
                        }
+                       g_object_unref (folder_store);
                } else {
                        help_id = "applications_email_mainview";        
                }
@@ -3178,3 +3297,5 @@ _on_send_receive_progress_changed (ModestMailOperation  *mail_op,
                modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
        
 }
+
+