24a70d24de2b897d9709dd8e75046dc1ca015a50
[modest] / src / modest-ui-actions.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved. 
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29  
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif /*HAVE_CONFIG_H*/
33
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
36 #include <string.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46 #include "modest-debug.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
51 #ifdef MODEST_TOOLKIT_HILDON2
52 #include <modest-accounts-window.h>
53 #include <hildon/hildon-pannable-area.h>
54 #include <hildon/hildon-gtk.h>
55 #include <modest-header-window.h>
56 #include <modest-folder-window.h>
57 #include <modest-maemo-utils.h>
58 #endif
59
60 #ifdef MODEST_PLATFORM_MAEMO
61 #include "maemo/modest-osso-state-saving.h"
62 #endif /* MODEST_PLATFORM_MAEMO */
63 #ifndef MODEST_TOOLKIT_GTK
64 #include "maemo/modest-hildon-includes.h"
65 #include "maemo/modest-connection-specific-smtp-window.h"
66 #endif /* !MODEST_TOOLKIT_GTK */
67 #include <modest-utils.h>
68
69 #include "widgets/modest-ui-constants.h"
70 #include <widgets/modest-main-window.h>
71 #include <widgets/modest-msg-view-window.h>
72 #include <widgets/modest-account-view-window.h>
73 #include <widgets/modest-details-dialog.h>
74 #include <widgets/modest-attachments-view.h>
75 #include "widgets/modest-folder-view.h"
76 #include "widgets/modest-global-settings-dialog.h"
77 #include "modest-account-mgr-helpers.h"
78 #include "modest-mail-operation.h"
79 #include "modest-text-utils.h"
80 #include <modest-widget-memory.h>
81 #include <tny-error.h>
82 #include <tny-simple-list.h>
83 #include <tny-msg-view.h>
84 #include <tny-device.h>
85 #include <tny-merge-folder.h>
86
87 #include <gtkhtml/gtkhtml.h>
88
89 #define MIN_FREE_SPACE 5 * 1024 * 1024
90 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
91
92 typedef struct _GetMsgAsyncHelper {     
93         ModestWindow *window;
94         ModestMailOperation *mail_op;
95         TnyIterator *iter;
96         guint num_ops;
97         GFunc func;     
98         gpointer user_data;
99 } GetMsgAsyncHelper;
100
101 typedef enum _ReplyForwardAction {
102         ACTION_REPLY,
103         ACTION_REPLY_TO_ALL,
104         ACTION_FORWARD
105 } ReplyForwardAction;
106
107 typedef struct _ReplyForwardHelper {
108         guint reply_forward_type;
109         ReplyForwardAction action;
110         gchar *account_name;
111         GtkWidget *parent_window;
112         TnyHeader *header;
113 } ReplyForwardHelper;
114
115 typedef struct _MoveToHelper {
116         GtkTreeRowReference *reference;
117         GtkWidget *banner;
118 } MoveToHelper;
119
120 typedef struct _PasteAsAttachmentHelper {
121         ModestMsgEditWindow *window;
122         GtkWidget *banner;
123 } PasteAsAttachmentHelper;
124
125 typedef struct {
126         TnyList *list;
127         ModestWindow *win;
128 } MoveToInfo;
129
130 /*
131  * The do_headers_action uses this kind of functions to perform some
132  * action to each member of a list of headers
133  */
134 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
135
136 static void     do_headers_action     (ModestWindow *win, 
137                                        HeadersFunc func,
138                                        gpointer user_data);
139
140 static void     open_msg_cb            (ModestMailOperation *mail_op, 
141                                         TnyHeader *header, 
142                                         gboolean canceled,
143                                         TnyMsg *msg,
144                                         GError *err,
145                                         gpointer user_data);
146
147 static void     reply_forward_cb       (ModestMailOperation *mail_op, 
148                                         TnyHeader *header, 
149                                         gboolean canceled,
150                                         TnyMsg *msg,
151                                         GError *err,
152                                         gpointer user_data);
153
154 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
155
156 static void     folder_refreshed_cb    (ModestMailOperation *mail_op, 
157                                         TnyFolder *folder, 
158                                         gpointer user_data);
159
160 static void     on_send_receive_finished (ModestMailOperation  *mail_op, 
161                                           gpointer user_data);
162
163 static gint header_list_count_uncached_msgs (TnyList *header_list);
164
165 static gboolean connect_to_get_msg (ModestWindow *win,
166                                     gint num_of_uncached_msgs,
167                                     TnyAccount *account);
168
169 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
170
171 static void     do_create_folder (GtkWindow *window, 
172                                   TnyFolderStore *parent_folder, 
173                                   const gchar *suggested_name);
174
175 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
176
177 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
178                                                       GtkWidget *folder_view,
179                                                       TnyFolderStore *dst_folder,
180                                                       ModestMainWindow *win);
181 #ifdef MODEST_TOOLKIT_HILDON2
182 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
183                                                         TnyFolderStore *dst_folder,
184                                                         TnyList *selection,
185                                                         GtkWindow *win);
186 #endif
187
188 static void modest_ui_actions_on_window_move_to (GtkAction *action,
189                                                  TnyList *list_to_move,
190                                                  TnyFolderStore *dst_folder,
191                                                  ModestWindow *win);
192
193 /*
194  * This function checks whether a TnyFolderStore is a pop account
195  */
196 static gboolean
197 remote_folder_has_leave_on_server (TnyFolderStore *folder)
198 {
199         TnyAccount *account;
200         gboolean result;
201
202         g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
203         
204         account = get_account_from_folder_store (folder);
205         result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
206                                                                               modest_tny_account_get_protocol_type (account)));
207         g_object_unref (account);
208
209         return result;
210 }
211
212 /* FIXME: this should be merged with the similar code in modest-account-view-window */
213 /* Show the account creation wizard dialog.
214  * returns: TRUE if an account was created. FALSE if the user cancelled.
215  */
216 gboolean
217 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
218 {
219         gboolean result = FALSE;
220         GtkWindow *wizard;
221         gint dialog_response;
222
223         /* there is no such wizard yet */
224         wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
225         modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
226
227 #ifndef MODEST_TOOLKIT_HILDON2
228         /* always present a main window in the background 
229          * we do it here, so we cannot end up with two wizards (as this
230          * function might be called in modest_window_mgr_get_main_window as well */
231         if (!win)
232                 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
233                                                          TRUE);  /* create if not existent */
234 #else
235         if (!win) {
236                 GList *window_list;
237                 ModestWindowMgr *mgr;
238
239                 mgr = modest_runtime_get_window_mgr ();
240
241                 window_list = modest_window_mgr_get_window_list (mgr);
242                 if (window_list == NULL) {
243                         ModestWindow *old_win;
244                         win = MODEST_WINDOW (modest_accounts_window_new ());
245                         if (modest_window_mgr_register_window (mgr, win, NULL)) {
246                                 gtk_widget_show_all (GTK_WIDGET (win));
247                         } else {
248                                 gtk_widget_destroy (GTK_WIDGET (win));
249                                 win = NULL;
250                         }
251
252                         old_win = win;
253                         win = MODEST_WINDOW (modest_folder_window_new (NULL));
254                         if (modest_window_mgr_register_window (mgr, win, NULL)) {
255                                 gtk_widget_show_all (GTK_WIDGET (win));
256                         } else {
257                                 gtk_widget_destroy (GTK_WIDGET (win));
258                                 win = old_win;
259                         }
260                 } else {
261                         g_list_free (window_list);
262                 }
263         }
264 #endif
265
266         if (win)
267                 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
268
269         /* make sure the mainwindow is visible. We need to present the
270            wizard again to give it the focus back. show_all are needed
271            in order to get the widgets properly drawn (MainWindow main
272            paned won't be in its right position and the dialog will be
273            missplaced */
274 #ifndef MODEST_TOOLKIT_HILDON2
275         gtk_widget_show_all (GTK_WIDGET (win));
276         gtk_widget_show_all (GTK_WIDGET (wizard));
277         gtk_window_present (GTK_WINDOW (win));
278         gtk_window_present (GTK_WINDOW (wizard));
279 #endif
280
281         dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
282         gtk_widget_destroy (GTK_WIDGET (wizard));
283         if (gtk_events_pending ())
284                 gtk_main_iteration ();
285
286         if (dialog_response == GTK_RESPONSE_CANCEL) {
287                 result = FALSE;
288         } else {
289                 /* Check whether an account was created: */
290                 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
291         }
292         return result;
293 }
294
295
296 void   
297 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
298 {
299         GtkWidget *about;
300         const gchar *authors[] = {
301                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
302                 NULL
303         };
304         about = gtk_about_dialog_new ();
305         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
306         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
307         gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
308                                         _("Copyright (c) 2006, Nokia Corporation\n"
309                                           "All rights reserved."));
310         gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
311                                        _("a modest e-mail client\n\n"
312                                          "design and implementation: Dirk-Jan C. Binnema\n"
313                                          "contributions from the fine people at KC and Ig\n"
314                                          "uses the tinymail email framework written by Philip van Hoof"));
315         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
316         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
317         gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
318         gtk_window_set_modal (GTK_WINDOW (about), TRUE);
319         
320         gtk_dialog_run (GTK_DIALOG (about));
321         gtk_widget_destroy(about);
322 }
323
324 /*
325  * Gets the list of currently selected messages. If the win is the
326  * main window, then it returns a newly allocated list of the headers
327  * selected in the header view. If win is the msg view window, then
328  * the value returned is a list with just a single header.
329  *
330  * The caller of this funcion must free the list.
331  */
332 static TnyList *
333 get_selected_headers (ModestWindow *win)
334 {
335         if (MODEST_IS_MAIN_WINDOW(win)) {
336                 GtkWidget *header_view;         
337                 
338                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
339                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
340                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
341                 
342         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
343                 /* for MsgViewWindows, we simply return a list with one element */
344                 TnyHeader *header;
345                 TnyList *list = NULL;
346                 
347                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
348                 if (header != NULL) {
349                         list = tny_simple_list_new ();
350                         tny_list_prepend (list, G_OBJECT(header));
351                         g_object_unref (G_OBJECT(header));
352                 }
353
354                 return list;
355
356 #ifdef MODEST_TOOLKIT_HILDON2
357         } else if (MODEST_IS_HEADER_WINDOW (win)) {
358                 GtkWidget *header_view;
359
360                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
361                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
362 #endif
363         } else
364                 return NULL;
365 }
366
367 static GtkTreeRowReference *
368 get_next_after_selected_headers (ModestHeaderView *header_view)
369 {
370         GtkTreeSelection *sel;
371         GList *selected_rows, *node;
372         GtkTreePath *path;
373         GtkTreeRowReference *result;
374         GtkTreeModel *model;
375
376         model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
377         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
378         selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
379
380         if (selected_rows == NULL)
381                 return NULL;
382
383         node = g_list_last (selected_rows);
384         path = gtk_tree_path_copy ((GtkTreePath *) node->data);
385         gtk_tree_path_next (path);
386
387         result = gtk_tree_row_reference_new (model, path);
388
389         gtk_tree_path_free (path);
390         g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
391         g_list_free (selected_rows);
392
393         return result;
394 }
395
396 static void
397 headers_action_mark_as_read (TnyHeader *header,
398                              ModestWindow *win,
399                              gpointer user_data)
400 {
401         TnyHeaderFlags flags;
402
403         g_return_if_fail (TNY_IS_HEADER(header));
404
405         flags = tny_header_get_flags (header);
406         if (flags & TNY_HEADER_FLAG_SEEN) return;
407         tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
408 }
409
410 static void
411 headers_action_mark_as_unread (TnyHeader *header,
412                                ModestWindow *win,
413                                gpointer user_data)
414 {
415         TnyHeaderFlags flags;
416
417         g_return_if_fail (TNY_IS_HEADER(header));
418
419         flags = tny_header_get_flags (header);
420         if (flags & TNY_HEADER_FLAG_SEEN)  {
421                 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
422         }
423 }
424
425 /** After deleing a message that is currently visible in a window, 
426  * show the next message from the list, or close the window if there are no more messages.
427  **/
428 void 
429 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
430 {
431         /* Close msg view window or select next */
432         if (!modest_msg_view_window_select_next_message (win) &&
433             !modest_msg_view_window_select_previous_message (win)) {
434                 gboolean ret_value;
435                 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);       
436         }
437 }
438
439
440 void
441 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
442 {
443         modest_ui_actions_on_edit_mode_delete_message (win);
444 }
445
446 gboolean
447 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
448 {
449         TnyList *header_list = NULL;
450         TnyIterator *iter = NULL;
451         TnyHeader *header = NULL;
452         gchar *message = NULL;
453         gchar *desc = NULL;
454         gint response;
455         ModestWindowMgr *mgr;
456         GtkWidget *header_view = NULL;
457         gboolean retval = TRUE;
458
459         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
460         
461         /* Check first if the header view has the focus */
462         if (MODEST_IS_MAIN_WINDOW (win)) {
463                 header_view = 
464                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
465                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
466                 if (!gtk_widget_is_focus (header_view))
467                         return FALSE;
468         }
469         
470         /* Get the headers, either from the header view (if win is the main window),
471          * or from the message view window: */
472         header_list = get_selected_headers (win);
473         if (!header_list) return FALSE;
474                         
475         /* Check if any of the headers are already opened, or in the process of being opened */
476         if (MODEST_IS_MAIN_WINDOW (win)) {
477                 gint opened_headers = 0;
478
479                 iter = tny_list_create_iterator (header_list);
480                 mgr = modest_runtime_get_window_mgr ();
481                 while (!tny_iterator_is_done (iter)) {
482                         header = TNY_HEADER (tny_iterator_get_current (iter));
483                         if (header) {
484                                 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
485                                         opened_headers++;
486                                 g_object_unref (header);
487                         }
488                         tny_iterator_next (iter);
489                 }
490                 g_object_unref (iter);
491
492                 if (opened_headers > 0) {
493                         gchar *msg;
494
495                         msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), 
496                                                opened_headers);
497
498                         modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
499                         
500                         g_free (msg);
501                         g_object_unref (header_list);
502                         return FALSE;
503                 }
504         }
505
506         /* Select message */
507         if (tny_list_get_length(header_list) == 1) {
508                 iter = tny_list_create_iterator (header_list);
509                 header = TNY_HEADER (tny_iterator_get_current (iter));
510                 if (header) {
511                         gchar *subject;
512                         subject = tny_header_dup_subject (header);
513                         if (!subject)
514                                 subject = g_strdup (_("mail_va_no_subject"));
515                         desc = g_strdup_printf ("%s", subject); 
516                         g_free (subject);
517                         g_object_unref (header);
518                 }
519
520                 g_object_unref (iter);
521         }
522         message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages", 
523                                            tny_list_get_length(header_list)), desc);
524
525         /* Confirmation dialog */
526         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
527                                                             message);
528         
529
530         if (response == GTK_RESPONSE_OK) {      
531                 ModestWindow *main_window = NULL;
532                 ModestWindowMgr *mgr = NULL;
533                 GtkTreeModel *model = NULL;
534                 GtkTreeSelection *sel = NULL;
535                 GList *sel_list = NULL, *tmp = NULL;
536                 GtkTreeRowReference *next_row_reference = NULL;
537                 GtkTreeRowReference *prev_row_reference = NULL;
538                 GtkTreePath *next_path = NULL;
539                 GtkTreePath *prev_path = NULL;
540                 ModestMailOperation *mail_op = NULL;
541
542                 /* Find last selected row */                    
543                 if (MODEST_IS_MAIN_WINDOW (win)) {
544                         model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
545                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
546                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
547                         for (tmp=sel_list; tmp; tmp=tmp->next) {
548                                 if (tmp->next == NULL) {
549                                         prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
550                                         next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
551
552                                         gtk_tree_path_prev (prev_path);
553                                         gtk_tree_path_next (next_path);
554
555                                         prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
556                                         next_row_reference = gtk_tree_row_reference_new (model, next_path);
557                                 }
558                         }
559                 }
560                 
561                 /* Disable window dimming management */
562                 modest_window_disable_dimming (MODEST_WINDOW(win));
563
564                 /* Remove each header. If it's a view window header_view == NULL */
565                 mail_op = modest_mail_operation_new ((GObject *) win);
566                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
567                                                  mail_op);
568                 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
569                 g_object_unref (mail_op);
570                 
571                 /* Enable window dimming management */
572                 if (sel != NULL) {
573                         gtk_tree_selection_unselect_all (sel);
574                 }
575                 modest_window_enable_dimming (MODEST_WINDOW(win));
576                 
577                 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
578                         modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
579                         
580                         /* Get main window */
581                         mgr = modest_runtime_get_window_mgr ();
582                         main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
583                 } else if (MODEST_IS_MAIN_WINDOW (win)) {
584                         /* Move cursor to next row */
585                         main_window = win; 
586
587                         /* Select next or previous row */
588                         if (gtk_tree_row_reference_valid (next_row_reference)) {
589                                 gtk_tree_selection_select_path (sel, next_path);
590                         }
591                         else if (gtk_tree_row_reference_valid (prev_row_reference)) {                           
592                                 gtk_tree_selection_select_path (sel, prev_path);
593                         }
594
595                         /* Free */
596                         if (gtk_tree_row_reference_valid (next_row_reference)) 
597                                 gtk_tree_row_reference_free (next_row_reference);
598                         if (next_path != NULL) 
599                                 gtk_tree_path_free (next_path);                         
600                         if (gtk_tree_row_reference_valid (prev_row_reference)) 
601                                 gtk_tree_row_reference_free (prev_row_reference);
602                         if (prev_path != NULL) 
603                                 gtk_tree_path_free (prev_path);
604                 }
605                 
606                 /* Update toolbar dimming state */
607                 if (main_window) {
608                         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
609                         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
610                 }
611
612                 /* Free */
613                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
614                 g_list_free (sel_list);
615                 retval = TRUE;
616         } else {
617                 retval = FALSE;
618         }
619
620         /* Free*/
621         g_free(message);
622         g_free(desc);
623         g_object_unref (header_list);
624
625         return retval;
626 }
627
628
629
630
631 /* delete either message or folder, based on where we are */
632 void
633 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
634 {
635         g_return_if_fail (MODEST_IS_WINDOW(win));
636         
637         /* Check first if the header view has the focus */
638         if (MODEST_IS_MAIN_WINDOW (win)) {
639                 GtkWidget *w;
640                 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
641                                                          MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
642                 if (gtk_widget_is_focus (w)) {
643                         modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
644                         return;
645                 }
646         }
647         modest_ui_actions_on_delete_message (action, win);
648 }
649
650 void
651 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
652 {       
653         ModestWindowMgr *mgr = NULL;
654         
655 #ifdef MODEST_PLATFORM_MAEMO
656         modest_osso_save_state();
657 #endif /* MODEST_PLATFORM_MAEMO */
658
659         g_debug ("closing down, clearing %d item(s) from operation queue",
660                  modest_mail_operation_queue_num_elements
661                  (modest_runtime_get_mail_operation_queue()));
662
663         /* cancel all outstanding operations */
664         modest_mail_operation_queue_cancel_all 
665                 (modest_runtime_get_mail_operation_queue());
666         
667         g_debug ("queue has been cleared");
668
669
670         /* Check if there are opened editing windows */ 
671         mgr = modest_runtime_get_window_mgr ();
672         modest_window_mgr_close_all_windows (mgr);
673
674         /* note: when modest-tny-account-store is finalized,
675            it will automatically set all network connections
676            to offline */
677
678 /*      gtk_main_quit (); */
679 }
680
681 void
682 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
683 {
684         gboolean ret_value;
685
686         g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
687
688 /*      if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
689 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
690 /*      } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
691 /*              gboolean ret_value; */
692 /*              g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
693 /*      } else if (MODEST_IS_WINDOW (win)) { */
694 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
695 /*      } else { */
696 /*              g_return_if_reached (); */
697 /*      } */
698 }
699
700 void
701 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
702 {
703        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
704        
705        modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
706 }
707
708 void
709 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
710 {
711         GtkClipboard *clipboard = NULL;
712         gchar *selection = NULL;
713
714         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
715         selection = gtk_clipboard_wait_for_text (clipboard);
716
717         /* Question: why is the clipboard being used here? 
718          * It doesn't really make a lot of sense. */
719
720         if (selection)
721         {
722                 modest_address_book_add_address (selection);
723                 g_free (selection);
724         }
725 }
726
727 void
728 modest_ui_actions_on_new_account (GtkAction *action,
729                                   ModestWindow *window)
730 {
731         modest_ui_actions_run_account_setup_wizard (window);
732 }
733
734 void
735 modest_ui_actions_on_accounts (GtkAction *action,
736                                ModestWindow *win)
737 {
738         /* This is currently only implemented for Maemo */
739         if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
740                 if (!modest_ui_actions_run_account_setup_wizard (win))
741                         g_debug ("%s: wizard was already running", __FUNCTION__);
742
743                 return;
744         } else {
745                 /* Show the list of accounts */
746                 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
747
748                 /* The accounts dialog must be modal */
749                 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
750                 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win)); 
751         }
752 }
753
754 void
755 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
756 {
757         /* This is currently only implemented for Maemo,
758          * because it requires an API (libconic) to detect different connection 
759          * possiblities.
760          */
761 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
762
763         /* Create the window if necessary: */
764         GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
765         modest_connection_specific_smtp_window_fill_with_connections (
766                 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), 
767                 modest_runtime_get_account_mgr());
768
769         /* Show the window: */
770         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
771                                      GTK_WINDOW (specific_window), (GtkWindow *) win);
772         gtk_widget_show (specific_window);
773 #endif /* !MODEST_TOOLKIT_GTK */
774 }
775
776 void
777 modest_ui_actions_compose_msg(ModestWindow *win,
778                               const gchar *to_str,
779                               const gchar *cc_str,
780                               const gchar *bcc_str,
781                               const gchar *subject_str,
782                               const gchar *body_str,
783                               GSList *attachments,
784                               gboolean set_as_modified)
785 {
786         gchar *account_name = NULL;
787         TnyMsg *msg = NULL;
788         TnyAccount *account = NULL;
789         TnyFolder *folder = NULL;
790         gchar *from_str = NULL, *signature = NULL, *body = NULL;
791         gboolean use_signature = FALSE;
792         ModestWindow *msg_win = NULL;
793         ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
794         ModestTnyAccountStore *store = modest_runtime_get_account_store();
795         GnomeVFSFileSize total_size, allowed_size;
796
797         /* we check for low-mem */
798         if (modest_platform_check_memory_low (win, TRUE))
799                 goto cleanup;
800
801 #ifdef MODEST_TOOLKIT_HILDON2
802         account_name = g_strdup (modest_window_get_active_account(win));
803 #endif
804         if (!account_name) {
805                 account_name = modest_account_mgr_get_default_account(mgr);
806         }
807         if (!account_name) {
808                 g_printerr ("modest: no account found\n");
809                 goto cleanup;
810         }
811         account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
812         if (!account) {
813                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
814                 goto cleanup;
815         }
816         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
817         if (!folder) {
818                 g_printerr ("modest: failed to find Drafts folder\n");
819                 goto cleanup;
820         }
821         from_str = modest_account_mgr_get_from_string (mgr, account_name);
822         if (!from_str) {
823                 g_printerr ("modest: failed get from string for '%s'\n", account_name);
824                 goto cleanup;
825         }
826
827         signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
828         if (body_str != NULL) {
829                 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
830         } else {
831                 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
832         }
833
834         msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
835         if (!msg) {
836                 g_printerr ("modest: failed to create new msg\n");
837                 goto cleanup;
838         }
839
840         /* Create and register edit window */
841         /* This is destroyed by TODO. */
842         total_size = 0;
843         allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
844         msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
845
846         if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
847                 gtk_widget_destroy (GTK_WIDGET (msg_win));
848                 goto cleanup;
849         }
850         modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
851         gtk_widget_show_all (GTK_WIDGET (msg_win));
852
853         while (attachments) {
854                 total_size +=
855                         modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
856                                                                attachments->data, allowed_size);
857
858                 if (total_size > allowed_size) {
859                         g_warning ("%s: total size: %u",
860                                    __FUNCTION__, (unsigned int)total_size);
861                         break;
862                 }
863                 allowed_size -= total_size;
864
865                 attachments = g_slist_next(attachments);
866         }
867
868 cleanup:
869         g_free (from_str);
870         g_free (signature);
871         g_free (body);
872         g_free (account_name);
873         if (account) 
874                 g_object_unref (G_OBJECT(account));
875         if (folder)
876                 g_object_unref (G_OBJECT(folder));
877         if (msg)
878                 g_object_unref (G_OBJECT(msg));
879 }
880
881 void
882 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
883 {
884         /* if there are no accounts yet, just show the wizard */
885         if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
886                 if (!modest_ui_actions_run_account_setup_wizard (win))
887                         return;
888                 
889         modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
890 }
891
892
893 gboolean 
894 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
895                                        TnyHeader *header,
896                                        TnyMsg *msg)
897 {
898         ModestMailOperationStatus status;
899
900         /* If there is no message or the operation was not successful */
901         status = modest_mail_operation_get_status (mail_op);
902         if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
903                 const GError *error;
904
905                 /* If it's a memory low issue, then show a banner */
906                 error = modest_mail_operation_get_error (mail_op);
907                 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
908                     error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
909                         GObject *source = modest_mail_operation_get_source (mail_op);
910                         modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
911                                                                 _KR("memr_ib_operation_disabled"),
912                                                                 TRUE);
913                         g_object_unref (source);
914                 }
915
916                 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
917                               error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
918                         gchar *subject, *msg, *format = NULL;
919                         TnyAccount *account;
920                         subject = tny_header_dup_subject (header);
921                         if (!subject)
922                                 subject = g_strdup (_("mail_va_no_subject"));
923
924                         account = modest_mail_operation_get_account (mail_op);
925                         if (account) {
926                                 ModestProtocol *protocol;
927                                 ModestProtocolType proto;
928                                 proto = modest_tny_account_get_protocol_type (account);
929                                 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
930                                 if (protocol)
931                                   format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
932                                 g_object_unref (account);
933                         }
934
935                         if (!format)
936                                 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
937
938                         msg = g_strdup_printf (format, subject);
939                         modest_platform_run_information_dialog (NULL, msg, FALSE);
940                         g_free (msg);
941                         g_free (format);
942                         g_free (subject);
943                 }
944
945                 /* Remove the header from the preregistered uids */
946                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),  
947                                                      header);
948
949                 return FALSE;
950         }
951
952         return TRUE;
953 }
954
955 typedef struct {
956         guint idle_handler;
957         gchar *message;
958         GtkWidget *banner;
959 } OpenMsgBannerInfo;
960
961 typedef struct {
962         GtkTreeModel *model;
963         TnyHeader *header;
964         OpenMsgBannerInfo *banner_info;
965         GtkTreeRowReference *rowref;
966 } OpenMsgHelper;
967
968 gboolean
969 open_msg_banner_idle (gpointer userdata)
970 {
971         OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
972
973         gdk_threads_enter ();
974         banner_info->idle_handler = 0;
975         banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
976         if (banner_info)
977                 g_object_ref (banner_info->banner);
978         
979         gdk_threads_leave ();
980
981         return FALSE;
982         
983 }
984
985 static GtkWidget *
986 get_header_view_from_window (ModestWindow *window)
987 {
988         GtkWidget *header_view;
989
990         if (MODEST_IS_MAIN_WINDOW (window)) {
991                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
992                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
993 #ifdef MODEST_TOOLKIT_HILDON2
994         } else if (MODEST_IS_HEADER_WINDOW (window)){
995                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
996 #endif
997         } else {
998                 header_view = NULL;
999         }
1000
1001         return header_view;
1002 }
1003
1004 static gchar *
1005 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1006 {
1007         TnyFolder *folder;
1008         gchar *account = NULL;
1009         TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1010
1011         *is_draft = FALSE;
1012         *can_open = TRUE;
1013
1014         folder = tny_header_get_folder (header);
1015         /* Gets folder type (OUTBOX headers will be opened in edit window */
1016         if (modest_tny_folder_is_local_folder (folder)) {
1017                 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1018                 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1019                         g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1020         }
1021
1022         if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1023                 TnyTransportAccount *traccount = NULL;
1024                 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1025                 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1026                 if (traccount) {
1027                         ModestTnySendQueue *send_queue = NULL;
1028                         ModestTnySendQueueStatus status;
1029                         gchar *msg_id;
1030                         account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1031                                                    TNY_ACCOUNT(traccount)));
1032                         send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1033                         if (TNY_IS_SEND_QUEUE (send_queue)) {
1034                                 msg_id = modest_tny_send_queue_get_msg_id (header);
1035                                 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1036                                 g_free (msg_id);
1037                                 /* Only open messages in outbox with the editor if they are in Failed state */
1038                                 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1039                                         *is_draft = TRUE;
1040                                 }
1041 #ifdef MODEST_TOOLKIT_HILDON2
1042                                 else {
1043                                         /* In Fremantle we can not
1044                                            open any message from
1045                                            outbox which is not in
1046                                            failed state */
1047                                         *can_open = FALSE;
1048                                 }
1049 #endif
1050                         }
1051                         g_object_unref(traccount);
1052                 } else {
1053                         g_warning("Cannot get transport account for message in outbox!!");
1054                 }
1055         } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1056                 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1057         }
1058
1059         if (!account) {
1060                 TnyAccount *acc = tny_folder_get_account (folder);
1061                 if (acc) {
1062                         account =
1063                                 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1064                         g_object_unref (acc);
1065                 }
1066         }
1067
1068         g_object_unref (folder);
1069
1070         return account;
1071 }
1072
1073 static void
1074 open_msg_cb (ModestMailOperation *mail_op, 
1075              TnyHeader *header,  
1076              gboolean canceled,
1077              TnyMsg *msg, 
1078              GError *err,
1079              gpointer user_data)
1080 {
1081         ModestWindowMgr *mgr = NULL;
1082         ModestWindow *parent_win = NULL;
1083         ModestWindow *win = NULL;
1084         gchar *account = NULL;
1085         gboolean open_in_editor = FALSE;
1086         gboolean can_open;
1087         OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1088
1089         /* Do nothing if there was any problem with the mail
1090            operation. The error will be shown by the error_handler of
1091            the mail operation */
1092         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1093                 return;
1094
1095         parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1096
1097         /* Mark header as read */
1098         headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1099
1100         account = get_info_from_header (header, &open_in_editor, &can_open);
1101
1102         /* Get account */
1103         if (!account)
1104                 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1105         if (!account)
1106                 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1107
1108         if (open_in_editor) {
1109                 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1110                 gchar *from_header = NULL, *acc_name;
1111
1112                 from_header = tny_header_dup_from (header);
1113
1114                 /* we cannot edit without a valid account... */
1115                 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1116                         if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1117                                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1118                                                                      header);
1119                                 g_free (from_header);
1120                                 goto cleanup;
1121                         }
1122                 }
1123
1124                 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1125                 g_free (from_header);
1126                 if (acc_name) {
1127                         g_free (account);
1128                         account = acc_name;
1129                 }
1130
1131                 win = modest_msg_edit_window_new (msg, account, TRUE);
1132         } else {
1133                 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1134
1135                 if (helper->rowref && helper->model) {
1136                         win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1137                                                                             helper->model, helper->rowref);
1138                 } else {
1139                         win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1140                 }
1141                 g_free (uid);
1142         }
1143
1144         /* Register and show new window */
1145         if (win != NULL) {
1146                 mgr = modest_runtime_get_window_mgr ();
1147                 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1148                         gtk_widget_destroy (GTK_WIDGET (win));
1149                         goto cleanup;
1150                 }
1151                 gtk_widget_show_all (GTK_WIDGET(win));
1152         }
1153
1154         /* Update toolbar dimming state */
1155         if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1156                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1157         }
1158
1159 cleanup:
1160         /* Free */
1161         g_free(account);
1162         g_object_unref (parent_win);
1163 }
1164
1165 static gboolean
1166 is_memory_full_error (GError *error)
1167 {
1168         gboolean enough_free_space = TRUE;
1169         GnomeVFSURI *cache_dir_uri;
1170         const gchar *cache_dir;
1171         GnomeVFSFileSize free_space;
1172
1173         cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1174         cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1175         if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1176                 if (free_space < MIN_FREE_SPACE)
1177                         enough_free_space = FALSE;
1178         }
1179         gnome_vfs_uri_unref (cache_dir_uri);
1180
1181         if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1182              /* When asking for a mail and no space left on device
1183                 tinymail returns this error */
1184              error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1185              /* When the folder summary could not be read or
1186                 written */
1187              error->code == TNY_IO_ERROR_WRITE ||
1188              error->code == TNY_IO_ERROR_READ) && 
1189             !enough_free_space) {
1190                 return TRUE;
1191         } else {
1192                 return FALSE;
1193         }
1194 }
1195
1196 static gboolean
1197 check_memory_full_error (GtkWidget *parent_window, GError *err)
1198 {
1199         if (err == NULL)
1200                 return FALSE;
1201
1202         if (is_memory_full_error (err))
1203                 modest_platform_information_banner (parent_window,
1204                                                     NULL, _KR("cerm_device_memory_full"));
1205         else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1206                 /* If the account was created in memory full
1207                    conditions then tinymail won't be able to
1208                    connect so it'll return this error code */
1209                 modest_platform_information_banner (parent_window,
1210                                                     NULL, _("emev_ui_imap_inbox_select_error"));
1211         else
1212                 return FALSE;
1213
1214         return TRUE;
1215 }
1216
1217 void
1218 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1219                                                  gpointer user_data)
1220 {
1221         const GError *error;
1222         GObject *win = NULL;
1223         ModestMailOperationStatus status;
1224
1225         win = modest_mail_operation_get_source (mail_op);
1226         error = modest_mail_operation_get_error (mail_op);
1227         status = modest_mail_operation_get_status (mail_op);
1228
1229         /* If the mail op has been cancelled then it's not an error:
1230            don't show any message */
1231         if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1232                 if (is_memory_full_error ((GError *) error)) {
1233                         modest_platform_information_banner ((GtkWidget *) win,
1234                                                             NULL, _KR("cerm_device_memory_full"));
1235                 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1236                         modest_platform_information_banner ((GtkWidget *) win,
1237                                                             NULL, _("emev_ui_imap_inbox_select_error"));
1238                 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1239                            error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1240                         modest_platform_information_banner ((GtkWidget *) win,
1241                                                             NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1242                 } else if (user_data) {
1243                         modest_platform_information_banner ((GtkWidget *) win, 
1244                                                             NULL, user_data);
1245                 }
1246         }
1247
1248         if (win)
1249                 g_object_unref (win);
1250 }
1251
1252 /**
1253  * Returns the account a list of headers belongs to. It returns a
1254  * *new* reference so don't forget to unref it
1255  */
1256 static TnyAccount*
1257 get_account_from_header_list (TnyList *headers)
1258 {
1259         TnyAccount *account = NULL;
1260
1261         if (tny_list_get_length (headers) > 0) {
1262                 TnyIterator *iter = tny_list_create_iterator (headers);
1263                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1264                 TnyFolder *folder = tny_header_get_folder (header);
1265                 
1266                 if (!folder) {
1267                         g_object_unref (header);
1268                         
1269                         while (!tny_iterator_is_done (iter)) {
1270                                 header = TNY_HEADER (tny_iterator_get_current (iter));
1271                                 folder = tny_header_get_folder (header);
1272                                 if (folder) 
1273                                         break;
1274                                 g_object_unref (header);
1275                                 header = NULL;
1276                                 tny_iterator_next (iter);
1277                         }
1278                 }
1279
1280                 if (folder) {
1281                         account = tny_folder_get_account (folder);
1282                         g_object_unref (folder);
1283                 }
1284                 
1285                 if (header)
1286                         g_object_unref (header);
1287                 
1288                 g_object_unref (iter);
1289         }
1290         return account;
1291 }
1292
1293 static TnyAccount*
1294 get_account_from_header (TnyHeader *header)
1295 {
1296         TnyAccount *account = NULL;
1297         TnyFolder *folder;
1298
1299         folder = tny_header_get_folder (header);
1300                 
1301         if (folder) {
1302                 account = tny_folder_get_account (folder);
1303                 g_object_unref (folder);
1304         }
1305         return account;
1306 }
1307
1308 static void
1309 open_msg_helper_destroyer (gpointer user_data)
1310 {
1311         OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1312
1313         if (helper->banner_info) {
1314                 g_free (helper->banner_info->message);
1315                 if (helper->banner_info->idle_handler > 0) {
1316                         g_source_remove (helper->banner_info->idle_handler);
1317                         helper->banner_info->idle_handler = 0;
1318                 }
1319                 if (helper->banner_info->banner != NULL) {
1320                         gtk_widget_destroy (helper->banner_info->banner);
1321                         g_object_unref (helper->banner_info->banner);
1322                         helper->banner_info->banner = NULL;
1323                 }
1324                 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1325                 helper->banner_info = NULL;
1326         }
1327         g_object_unref (helper->model);
1328         g_object_unref (helper->header);
1329         gtk_tree_row_reference_free (helper->rowref);
1330         g_slice_free (OpenMsgHelper, helper);
1331 }
1332
1333 static void
1334 open_msg_performer(gboolean canceled, 
1335                     GError *err,
1336                     GtkWindow *parent_window,
1337                     TnyAccount *account,
1338                     gpointer user_data)
1339 {
1340         ModestMailOperation *mail_op = NULL;
1341         gchar *error_msg;
1342         ModestProtocolType proto;
1343         TnyConnectionStatus status;
1344         OpenMsgHelper *helper = NULL;
1345         ModestProtocol *protocol;
1346         ModestProtocolRegistry *protocol_registry;
1347         gchar *subject;
1348
1349         helper = (OpenMsgHelper *) user_data;
1350
1351         status = tny_account_get_connection_status (account);
1352         if (err || canceled) {
1353                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1354                 /* Free the helper */
1355                 open_msg_helper_destroyer (helper);
1356
1357                 /* In memory full conditions we could get this error here */
1358                 check_memory_full_error ((GtkWidget *) parent_window, err);
1359
1360                 goto clean;
1361         }
1362
1363         /* Get the error message depending on the protocol */
1364         proto = modest_tny_account_get_protocol_type (account);
1365         if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1366                 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1367         }
1368
1369         protocol_registry = modest_runtime_get_protocol_registry ();
1370         subject = tny_header_dup_subject (helper->header);
1371
1372         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1373         error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1374         if (subject)
1375                 g_free (subject);
1376
1377         if (error_msg == NULL) {
1378                 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1379         }
1380
1381 #ifndef MODEST_TOOLKIT_HILDON2
1382         gboolean show_open_draft = FALSE;
1383         if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1384                                                             proto,
1385                                                             MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) { 
1386                 TnyFolder *folder;
1387                 TnyFolderType folder_type;
1388
1389                 folder = tny_header_get_folder (helper->header);
1390                 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1391                 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1392                 g_object_unref (folder);
1393         }
1394 #endif
1395
1396 #ifdef MODEST_TOOLKIT_HILDON2
1397         gboolean is_draft;
1398         gboolean can_open;
1399         gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1400
1401         if (!can_open) {
1402                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1403                 g_free (account_name);
1404                 open_msg_helper_destroyer (helper);
1405                 goto clean;
1406         }
1407
1408         if (!is_draft) {
1409                 ModestWindow *window;
1410                 GtkWidget *header_view;
1411                 gchar *uid;
1412
1413                 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1414                 uid = modest_tny_folder_get_header_unique_id (helper->header);
1415                 if (header_view) {
1416                         window = modest_msg_view_window_new_from_header_view 
1417                                 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1418                         if (window != NULL) {
1419                                 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1420                                                                         window, NULL)) {
1421                                         gtk_widget_destroy (GTK_WIDGET (window));
1422                                 } else {
1423                                         gtk_widget_show_all (GTK_WIDGET(window));
1424                                 }
1425                         }
1426                 }
1427                 g_free (account_name);
1428                 g_free (uid);
1429                 open_msg_helper_destroyer (helper);
1430                 goto clean;
1431         }
1432         g_free (account_name);
1433 #endif
1434         /* Create the mail operation */
1435         mail_op = 
1436                 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1437                                                                modest_ui_actions_disk_operations_error_handler,
1438                                                                error_msg, g_free);
1439         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1440                                          mail_op);
1441
1442
1443 #ifndef MODEST_TOOLKIT_HILDON2
1444         if (show_open_draft) {
1445                 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1446                 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1447                 helper->banner_info->banner = NULL;
1448                 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle, 
1449                                                                    helper->banner_info);
1450         }
1451 #endif
1452
1453
1454         TnyList *headers;
1455         headers = TNY_LIST (tny_simple_list_new ());
1456         tny_list_prepend (headers, G_OBJECT (helper->header));
1457         modest_mail_operation_get_msgs_full (mail_op,
1458                                              headers,
1459                                              open_msg_cb,
1460                                              helper,
1461                                              open_msg_helper_destroyer);
1462         g_object_unref (headers);
1463
1464         /* Frees */
1465  clean:
1466         if (mail_op)
1467                 g_object_unref (mail_op);
1468         g_object_unref (account);
1469 }
1470
1471 /*
1472  * This function is used by both modest_ui_actions_on_open and
1473  * modest_ui_actions_on_header_activated. This way we always do the
1474  * same when trying to open messages.
1475  */
1476 static void
1477 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1478 {
1479         ModestWindowMgr *mgr = NULL;
1480         TnyAccount *account;
1481         gboolean cached = FALSE;
1482         gboolean found;
1483         GtkWidget *header_view = NULL;
1484         OpenMsgHelper *helper;
1485         ModestWindow *window;
1486
1487         g_return_if_fail (header != NULL && rowref != NULL);
1488
1489         mgr = modest_runtime_get_window_mgr ();
1490
1491         /* get model */
1492         header_view = get_header_view_from_window (MODEST_WINDOW (win));
1493         if (header_view == NULL)
1494                 return;
1495
1496         /* Get the account */
1497         account = get_account_from_header (header);
1498         if (!account)
1499                 return;
1500
1501         window = NULL;
1502         found = modest_window_mgr_find_registered_header (mgr, header, &window);
1503
1504         /* Do not open again the message and present the
1505            window to the user */
1506         if (found) {
1507                 if (window) {
1508 #ifndef MODEST_TOOLKIT_HILDON2
1509                         gtk_window_present (GTK_WINDOW (window));
1510 #endif
1511                 } else {
1512                         /* the header has been registered already, we don't do
1513                          * anything but wait for the window to come up*/
1514                         g_debug ("header %p already registered, waiting for window", header);
1515                 }
1516                 goto cleanup;
1517         }
1518
1519         /* Open each message */
1520         cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1521         if (!cached) {
1522                 /* Allways download if we are online. */
1523                 if (!tny_device_is_online (modest_runtime_get_device ())) {
1524                         gint response;
1525
1526                         /* If ask for user permission to download the messages */
1527                         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1528                                                                             _("mcen_nc_get_msg"));
1529
1530                         /* End if the user does not want to continue */
1531                         if (response == GTK_RESPONSE_CANCEL) {
1532                                 goto cleanup;
1533                         }
1534                 }
1535         }
1536
1537         /* We register the window for opening */
1538         modest_window_mgr_register_header (mgr, header, NULL);
1539
1540         /* Create the helper. We need to get a reference to the model
1541            here because it could change while the message is readed
1542            (the user could switch between folders) */
1543         helper = g_slice_new (OpenMsgHelper);
1544         helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1545         helper->header = g_object_ref (header);
1546         helper->rowref = gtk_tree_row_reference_copy (rowref);
1547         helper->banner_info = NULL;
1548
1549         /* Connect to the account and perform */
1550         if (!cached) {
1551                 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account), 
1552                                                      open_msg_performer, helper);
1553         } else {
1554                 /* Call directly the performer, do not need to connect */
1555                 open_msg_performer (FALSE, NULL, (GtkWindow *) win, 
1556                                     g_object_ref (account), helper);
1557         }
1558 cleanup:
1559         /* Clean */
1560         if (account)
1561                 g_object_unref (account);
1562 }
1563
1564 void
1565 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1566 {
1567         TnyList *headers;
1568         TnyHeader *header;
1569         gint headers_count;
1570         TnyIterator *iter;
1571         
1572         /* we check for low-mem; in that case, show a warning, and don't allow
1573          * opening
1574          */
1575         if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1576                 return;
1577
1578         /* Get headers */
1579         headers = get_selected_headers (win);
1580         if (!headers)
1581                 return;
1582
1583         headers_count = tny_list_get_length (headers);
1584         if (headers_count != 1) {
1585                 if (headers_count > 1) {
1586                         /* Don't allow activation if there are more than one message selected */
1587                         modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1588                 }
1589
1590                 g_object_unref (headers);
1591                 return;
1592         }
1593
1594         iter = tny_list_create_iterator (headers);
1595         header = TNY_HEADER (tny_iterator_get_current (iter));
1596         g_object_unref (iter);
1597
1598         /* Open them */
1599         if (header) {
1600                 open_msg_from_header (header, NULL, win);
1601                 g_object_unref (header);
1602         }
1603
1604         g_object_unref(headers);
1605 }
1606
1607 static void
1608 rf_helper_window_closed (gpointer data,
1609                          GObject *object)
1610 {
1611         ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1612
1613         helper->parent_window = NULL;
1614 }
1615
1616 static ReplyForwardHelper*
1617 create_reply_forward_helper (ReplyForwardAction action, 
1618                              ModestWindow *win,
1619                              guint reply_forward_type,
1620                              TnyHeader *header)
1621 {
1622         ReplyForwardHelper *rf_helper = NULL;
1623         const gchar *active_acc = modest_window_get_active_account (win);
1624
1625         rf_helper = g_slice_new0 (ReplyForwardHelper);
1626         rf_helper->reply_forward_type = reply_forward_type;
1627         rf_helper->action = action;
1628         rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1629         rf_helper->header = (header) ? g_object_ref (header) : NULL;
1630         rf_helper->account_name = (active_acc) ? 
1631                 g_strdup (active_acc) :
1632                 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1633
1634         /* Note that window could be destroyed just AFTER calling
1635            register_window so we must ensure that this pointer does
1636            not hold invalid references */
1637         if (rf_helper->parent_window)
1638                 g_object_weak_ref (G_OBJECT (rf_helper->parent_window), 
1639                                    rf_helper_window_closed, rf_helper);
1640
1641         return rf_helper;
1642 }
1643
1644 static void
1645 free_reply_forward_helper (gpointer data)
1646 {
1647         ReplyForwardHelper *helper;
1648
1649         helper = (ReplyForwardHelper *) data;
1650         g_free (helper->account_name);
1651         if (helper->header)
1652                 g_object_unref (helper->header);
1653         if (helper->parent_window) 
1654                 g_object_weak_unref (G_OBJECT (helper->parent_window), 
1655                                      rf_helper_window_closed, helper);
1656         g_slice_free (ReplyForwardHelper, helper);
1657 }
1658
1659 static void
1660 reply_forward_cb (ModestMailOperation *mail_op,  
1661                   TnyHeader *header, 
1662                   gboolean canceled,
1663                   TnyMsg *msg,
1664                   GError *err,
1665                   gpointer user_data)
1666 {
1667         TnyMsg *new_msg = NULL;
1668         ReplyForwardHelper *rf_helper;
1669         ModestWindow *msg_win = NULL;
1670         ModestEditType edit_type;
1671         gchar *from = NULL;
1672         TnyAccount *account = NULL;
1673         ModestWindowMgr *mgr = NULL;
1674         gchar *signature = NULL;
1675         gboolean use_signature;
1676
1677         /* If there was any error. The mail operation could be NULL,
1678            this means that we already have the message downloaded and
1679            that we didn't do a mail operation to retrieve it */
1680         rf_helper = (ReplyForwardHelper *) user_data;
1681         if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1682                 goto cleanup;
1683
1684         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1685                                                    rf_helper->account_name);
1686         signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(), 
1687                                                       rf_helper->account_name, 
1688                                                       &use_signature);
1689
1690         /* Create reply mail */
1691         switch (rf_helper->action) {
1692         case ACTION_REPLY:
1693                 new_msg = 
1694                         modest_tny_msg_create_reply_msg (msg, header, from, 
1695                                                          (use_signature) ? signature : NULL,
1696                                                          rf_helper->reply_forward_type,
1697                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
1698                 break;
1699         case ACTION_REPLY_TO_ALL:
1700                 new_msg = 
1701                         modest_tny_msg_create_reply_msg (msg, header, from, 
1702                                                          (use_signature) ? signature : NULL, 
1703                                                          rf_helper->reply_forward_type,
1704                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
1705                 edit_type = MODEST_EDIT_TYPE_REPLY;
1706                 break;
1707         case ACTION_FORWARD:
1708                 new_msg = 
1709                         modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL, 
1710                                                            rf_helper->reply_forward_type);
1711                 edit_type = MODEST_EDIT_TYPE_FORWARD;
1712                 break;
1713         default:
1714                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1715                                                      header);
1716                 g_return_if_reached ();
1717                 return;
1718         }
1719
1720         g_free (from);
1721         g_free (signature);
1722
1723         if (!new_msg) {
1724                 g_warning ("%s: failed to create message\n", __FUNCTION__);
1725                 goto cleanup;
1726         }
1727
1728         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1729                                                                        rf_helper->account_name,
1730                                                                        TNY_ACCOUNT_TYPE_STORE);
1731         if (!account) {
1732                 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1733                 goto cleanup;
1734         }
1735
1736         /* Create and register the windows */
1737         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1738         mgr = modest_runtime_get_window_mgr ();
1739         modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1740
1741         /* Note that register_window could have deleted the account */
1742         if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1743                 gdouble parent_zoom;
1744
1745                 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1746                 modest_window_set_zoom (msg_win, parent_zoom);
1747         }
1748
1749         /* Show edit window */
1750         gtk_widget_show_all (GTK_WIDGET (msg_win));
1751
1752 cleanup:
1753         /* We always unregister the header because the message is
1754            forwarded or replied so the original one is no longer
1755            opened */
1756         modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1757                                              header);
1758         if (new_msg)
1759                 g_object_unref (G_OBJECT (new_msg));
1760         if (account)
1761                 g_object_unref (G_OBJECT (account));
1762         free_reply_forward_helper (rf_helper);
1763 }
1764
1765 /* Checks a list of headers. If any of them are not currently
1766  * downloaded (CACHED) then returns TRUE else returns FALSE.
1767  */
1768 static gint
1769 header_list_count_uncached_msgs (TnyList *header_list)
1770 {
1771         TnyIterator *iter;
1772         gint uncached_messages = 0;
1773
1774         iter = tny_list_create_iterator (header_list);
1775         while (!tny_iterator_is_done (iter)) {
1776                 TnyHeader *header;
1777
1778                 header = TNY_HEADER (tny_iterator_get_current (iter));
1779                 if (header) {
1780                         if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1781                                 uncached_messages ++;
1782                         g_object_unref (header);
1783                 }
1784
1785                 tny_iterator_next (iter);
1786         }
1787         g_object_unref (iter);
1788
1789         return uncached_messages;
1790 }
1791
1792 /* Returns FALSE if the user does not want to download the
1793  * messages. Returns TRUE if the user allowed the download.
1794  */
1795 static gboolean
1796 connect_to_get_msg (ModestWindow *win,
1797                     gint num_of_uncached_msgs,
1798                     TnyAccount *account)
1799 {
1800         GtkResponseType response;
1801
1802         /* Allways download if we are online. */
1803         if (tny_device_is_online (modest_runtime_get_device ()))
1804                 return TRUE;
1805
1806         /* If offline, then ask for user permission to download the messages */
1807         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1808                         ngettext("mcen_nc_get_msg",
1809                         "mcen_nc_get_msgs",
1810                         num_of_uncached_msgs));
1811
1812         if (response == GTK_RESPONSE_CANCEL)
1813                 return FALSE;
1814
1815         return modest_platform_connect_and_wait((GtkWindow *) win, account);
1816 }
1817
1818 static void
1819 reply_forward_performer (gboolean canceled, 
1820                          GError *err,
1821                          GtkWindow *parent_window, 
1822                          TnyAccount *account, 
1823                          gpointer user_data)
1824 {
1825         ReplyForwardHelper *rf_helper = NULL;
1826         ModestMailOperation *mail_op;
1827
1828         rf_helper = (ReplyForwardHelper *) user_data;
1829
1830         if (canceled || err) {
1831                 free_reply_forward_helper (rf_helper);
1832                 return;
1833         }
1834
1835         /* Retrieve the message */
1836         modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1837         mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1838                                                                  modest_ui_actions_disk_operations_error_handler,
1839                                                                  NULL, NULL);
1840         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1841         modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1842
1843         /* Frees */
1844         g_object_unref(mail_op);
1845 }
1846
1847 /*
1848  * Common code for the reply and forward actions
1849  */
1850 static void
1851 reply_forward (ReplyForwardAction action, ModestWindow *win)
1852 {
1853         ReplyForwardHelper *rf_helper = NULL;
1854         guint reply_forward_type;
1855
1856         g_return_if_fail (MODEST_IS_WINDOW(win));
1857
1858         /* we check for low-mem; in that case, show a warning, and don't allow
1859          * reply/forward (because it could potentially require a lot of memory */
1860         if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1861                 return;
1862
1863
1864         /* we need an account when editing */
1865         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1866                 if (!modest_ui_actions_run_account_setup_wizard (win))
1867                         return;
1868         }
1869
1870         reply_forward_type =
1871                 modest_conf_get_int (modest_runtime_get_conf (),
1872                                      (action == ACTION_FORWARD) ?
1873                                      MODEST_CONF_FORWARD_TYPE :
1874                                      MODEST_CONF_REPLY_TYPE,
1875                                      NULL);
1876
1877         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1878                 TnyMsg *msg = NULL;
1879                 TnyHeader *header = NULL;
1880                 /* Get header and message. Do not free them here, the
1881                    reply_forward_cb must do it */
1882                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1883                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1884
1885                 if (msg && header) {
1886                         /* Create helper */
1887                         rf_helper = create_reply_forward_helper (action, win,
1888                                                                  reply_forward_type, header);
1889                         reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1890                 } else {
1891                         g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1892                 }
1893
1894                 if (msg)
1895                         g_object_unref (msg);
1896                 if (header)
1897                         g_object_unref (header);
1898         } else {
1899                 TnyHeader *header = NULL;
1900                 TnyIterator *iter;
1901                 gboolean do_retrieve = TRUE;
1902                 TnyList *header_list = NULL;
1903
1904                 header_list = get_selected_headers (win);
1905                 if (!header_list)
1906                         return;
1907                 /* Check that only one message is selected for replying */
1908                 if (tny_list_get_length (header_list) != 1) {
1909                         modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1910                                                             NULL, _("mcen_ib_select_one_message"));
1911                         g_object_unref (header_list);
1912                         return;
1913                 }
1914
1915                 /* Only reply/forward to one message */
1916                 iter = tny_list_create_iterator (header_list);
1917                 header = TNY_HEADER (tny_iterator_get_current (iter));
1918                 g_object_unref (iter);
1919
1920                 /* Retrieve messages */
1921                 do_retrieve = (action == ACTION_FORWARD) ||
1922                         (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1923
1924                 if (do_retrieve) {
1925                         TnyAccount *account = NULL;
1926                         TnyFolder *folder = NULL;
1927                         gdouble download = TRUE;
1928                         guint uncached_msgs = 0;
1929
1930                         folder = tny_header_get_folder (header);
1931                         if (!folder)
1932                                 goto do_retrieve_frees;
1933                         account = tny_folder_get_account (folder);
1934                         if (!account)
1935                                 goto do_retrieve_frees;
1936
1937                         uncached_msgs = header_list_count_uncached_msgs (header_list);
1938
1939                         if (uncached_msgs > 0) {
1940                                 /* Allways download if we are online. */
1941                                 if (!tny_device_is_online (modest_runtime_get_device ())) {
1942                                         gint response;
1943
1944                                         /* If ask for user permission to download the messages */
1945                                         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1946                                                                                             ngettext("mcen_nc_get_msg",
1947                                                                                                      "mcen_nc_get_msgs",
1948                                                                                                      uncached_msgs));
1949
1950                                         /* End if the user does not want to continue */
1951                                         if (response == GTK_RESPONSE_CANCEL)
1952                                                 download = FALSE;
1953                                 }
1954                         }
1955
1956                         if (download) {
1957                                 /* Create helper */
1958                                 rf_helper = create_reply_forward_helper (action, win, 
1959                                                                          reply_forward_type, header);
1960                                 if (uncached_msgs > 0) {
1961                                         modest_platform_connect_and_perform (GTK_WINDOW (win), 
1962                                                                              TRUE, account, 
1963                                                                              reply_forward_performer, 
1964                                                                              rf_helper);
1965                                 } else {
1966                                         reply_forward_performer (FALSE, NULL, GTK_WINDOW (win), 
1967                                                                  account, rf_helper);
1968                                 }
1969                         }
1970                 do_retrieve_frees:
1971                         if (account)
1972                                 g_object_unref (account);
1973                         if (folder)
1974                                 g_object_unref (folder);
1975                 } else {
1976                         reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1977                 }
1978                 /* Frees */
1979                 g_object_unref (header_list);
1980                 g_object_unref (header);
1981         }
1982 }
1983
1984 void
1985 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1986 {
1987         g_return_if_fail (MODEST_IS_WINDOW(win));
1988
1989         reply_forward (ACTION_REPLY, win);
1990 }
1991
1992 void
1993 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1994 {
1995         g_return_if_fail (MODEST_IS_WINDOW(win));
1996
1997         reply_forward (ACTION_FORWARD, win);
1998 }
1999
2000 void
2001 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2002 {
2003         g_return_if_fail (MODEST_IS_WINDOW(win));
2004
2005         reply_forward (ACTION_REPLY_TO_ALL, win);
2006 }
2007
2008 void 
2009 modest_ui_actions_on_next (GtkAction *action, 
2010                            ModestWindow *window)
2011 {
2012         if (MODEST_IS_MAIN_WINDOW (window)) {
2013                 GtkWidget *header_view;
2014
2015                 header_view = modest_main_window_get_child_widget (
2016                                 MODEST_MAIN_WINDOW(window),
2017                                 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2018                 if (!header_view)
2019                         return;
2020         
2021                 modest_header_view_select_next (
2022                                 MODEST_HEADER_VIEW(header_view)); 
2023         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2024                 modest_msg_view_window_select_next_message (
2025                                 MODEST_MSG_VIEW_WINDOW (window));
2026         } else {
2027                 g_return_if_reached ();
2028         }
2029 }
2030
2031 void 
2032 modest_ui_actions_on_prev (GtkAction *action, 
2033                            ModestWindow *window)
2034 {
2035         g_return_if_fail (MODEST_IS_WINDOW(window));
2036
2037         if (MODEST_IS_MAIN_WINDOW (window)) {
2038                 GtkWidget *header_view;
2039                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2040                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2041                 if (!header_view)
2042                         return;
2043                 
2044                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
2045         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2046                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2047         } else {
2048                 g_return_if_reached ();
2049         }
2050 }
2051
2052 void 
2053 modest_ui_actions_on_sort (GtkAction *action, 
2054                            ModestWindow *window)
2055 {
2056         GtkWidget *header_view = NULL;
2057
2058         g_return_if_fail (MODEST_IS_WINDOW(window));
2059
2060         if (MODEST_IS_MAIN_WINDOW (window)) {
2061                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2062                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2063 #ifdef MODEST_TOOLKIT_HILDON2
2064         } else if (MODEST_IS_HEADER_WINDOW (window)) {
2065                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2066 #endif
2067         }
2068
2069         if (!header_view) {
2070                 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2071                 
2072                 return;
2073         }
2074
2075         /* Show sorting dialog */
2076         modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);        
2077 }
2078
2079 static void
2080 new_messages_arrived (ModestMailOperation *self, 
2081                       TnyList *new_headers,
2082                       gpointer user_data)
2083 {
2084         GObject *source;
2085         gboolean show_visual_notifications;
2086
2087         source = modest_mail_operation_get_source (self);
2088         show_visual_notifications = (source) ? FALSE : TRUE;
2089         if (source)
2090                 g_object_unref (source);
2091
2092         /* Notify new messages have been downloaded. If the
2093            send&receive was invoked by the user then do not show any
2094            visual notification, only play a sound and activate the LED
2095            (for the Maemo version) */
2096         if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2097                 modest_platform_on_new_headers_received (new_headers, 
2098                                                          show_visual_notifications);
2099
2100 }
2101
2102 gboolean
2103 retrieve_all_messages_cb (GObject *source,
2104                           guint num_msgs,
2105                           guint retrieve_limit)
2106 {
2107         GtkWindow *window;
2108         gchar *msg;
2109         gint response;
2110
2111         window = GTK_WINDOW (source);
2112         msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"), 
2113                                num_msgs, retrieve_limit);
2114
2115         /* Ask the user if they want to retrieve all the messages */
2116         response = 
2117                 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2118                                                                       _("mcen_bd_get_all"),
2119                                                                       _("mcen_bd_newest_only"));
2120         /* Free and return */
2121         g_free (msg);
2122         return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2123 }
2124
2125 typedef struct {
2126         TnyAccount *account;
2127         ModestWindow *win;
2128         gchar *account_name;
2129         gboolean poke_status;
2130         gboolean interactive;
2131         ModestMailOperation *mail_op;
2132 } SendReceiveInfo;
2133
2134 static void
2135 do_send_receive_performer (gboolean canceled, 
2136                            GError *err,
2137                            GtkWindow *parent_window, 
2138                            TnyAccount *account, 
2139                            gpointer user_data)
2140 {
2141         SendReceiveInfo *info;
2142
2143         info = (SendReceiveInfo *) user_data;
2144
2145         if (err || canceled) {
2146                 /* In memory full conditions we could get this error here */
2147                 check_memory_full_error ((GtkWidget *) parent_window, err);
2148
2149                 if (info->mail_op) {
2150                         modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2151                                                             info->mail_op);
2152                 }
2153                 goto clean;
2154         }
2155
2156         /* Set send/receive operation in progress */    
2157         if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2158                 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2159         }
2160
2161         if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2162                 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished", 
2163                                   G_CALLBACK (on_send_receive_finished), 
2164                                   info->win);
2165
2166         /* Send & receive. */
2167         modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2168                                               (info->win) ? retrieve_all_messages_cb : NULL, 
2169                                               new_messages_arrived, info->win);
2170         
2171  clean:
2172         /* Frees */
2173         if (info->mail_op)
2174                 g_object_unref (G_OBJECT (info->mail_op));
2175         if (info->account_name)
2176                 g_free (info->account_name);
2177         if (info->win)
2178                 g_object_unref (info->win);
2179         if (info->account)
2180                 g_object_unref (info->account);
2181         g_slice_free (SendReceiveInfo, info);
2182 }
2183
2184 /*
2185  * This function performs the send & receive required actions. The
2186  * window is used to create the mail operation. Typically it should
2187  * always be the main window, but we pass it as argument in order to
2188  * be more flexible.
2189  */
2190 void
2191 modest_ui_actions_do_send_receive (const gchar *account_name, 
2192                                    gboolean force_connection,
2193                                    gboolean poke_status,
2194                                    gboolean interactive,
2195                                    ModestWindow *win)
2196 {
2197         gchar *acc_name = NULL;
2198         SendReceiveInfo *info;
2199         ModestTnyAccountStore *acc_store;
2200
2201         /* If no account name was provided then get the current account, and if
2202            there is no current account then pick the default one: */
2203         if (!account_name) {
2204                 if (win)
2205                         acc_name = g_strdup (modest_window_get_active_account (win));
2206                 if (!acc_name)
2207                         acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2208                 if (!acc_name) {
2209                         g_printerr ("modest: cannot get default account\n");
2210                         return;
2211                 }
2212         } else {
2213                 acc_name = g_strdup (account_name);
2214         }
2215
2216         acc_store = modest_runtime_get_account_store ();
2217
2218         /* Create the info for the connect and perform */
2219         info = g_slice_new (SendReceiveInfo);
2220         info->account_name = acc_name;
2221         info->win = (win) ? g_object_ref (win) : NULL;
2222         info->poke_status = poke_status;
2223         info->interactive = interactive;
2224         info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2225                                                                      TNY_ACCOUNT_TYPE_STORE);
2226         /* We need to create the operation here, because otherwise it
2227            could happen that the queue emits the queue-empty signal
2228            while we're trying to connect the account */
2229         info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2230                                                                        modest_ui_actions_disk_operations_error_handler,
2231                                                                        NULL, NULL);
2232         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2233
2234         /* Invoke the connect and perform */
2235         modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL, 
2236                                              force_connection, info->account, 
2237                                              do_send_receive_performer, info);
2238 }
2239
2240
2241 static void
2242 modest_ui_actions_do_cancel_send (const gchar *account_name,  
2243                                   ModestWindow *win)
2244 {
2245         TnyTransportAccount *transport_account;
2246         TnySendQueue *send_queue = NULL;
2247         GError *error = NULL;
2248
2249         /* Get transport account */
2250         transport_account =
2251                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2252                                       (modest_runtime_get_account_store(),
2253                                        account_name,
2254                                        TNY_ACCOUNT_TYPE_TRANSPORT));
2255         if (!transport_account) {
2256                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2257                 goto frees;
2258         }
2259
2260         /* Get send queue*/
2261         send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2262         if (!TNY_IS_SEND_QUEUE(send_queue)) {
2263                 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2264                              MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2265                              "modest: could not find send queue for account\n");
2266         } else {
2267                 /* Cancel the current send */
2268                 tny_account_cancel (TNY_ACCOUNT (transport_account));
2269
2270                 /* Suspend all pending messages */
2271                 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2272         }
2273
2274  frees:
2275         if (transport_account != NULL) 
2276                 g_object_unref (G_OBJECT (transport_account));
2277 }
2278
2279 static void
2280 modest_ui_actions_cancel_send_all (ModestWindow *win) 
2281 {
2282         GSList *account_names, *iter;
2283
2284         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
2285                                                           TRUE);
2286
2287         iter = account_names;
2288         while (iter) {                  
2289                 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2290                 iter = g_slist_next (iter);
2291         }
2292
2293         modest_account_mgr_free_account_names (account_names);
2294         account_names = NULL;
2295 }
2296
2297 void
2298 modest_ui_actions_cancel_send (GtkAction *action,  ModestWindow *win)
2299
2300 {
2301         /* Check if accounts exist */
2302         gboolean accounts_exist = 
2303                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2304         
2305         /* If not, allow the user to create an account before trying to send/receive. */
2306         if (!accounts_exist)
2307                 modest_ui_actions_on_accounts (NULL, win);
2308         
2309         /* Cancel all sending operaitons */     
2310         modest_ui_actions_cancel_send_all (win);
2311 }
2312
2313 /*
2314  * Refreshes all accounts. This function will be used by automatic
2315  * updates
2316  */
2317 void
2318 modest_ui_actions_do_send_receive_all (ModestWindow *win, 
2319                                        gboolean force_connection,
2320                                        gboolean poke_status,
2321                                        gboolean interactive)
2322 {
2323         GSList *account_names, *iter;
2324
2325         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
2326                                                           TRUE);
2327
2328         iter = account_names;
2329         while (iter) {                  
2330                 modest_ui_actions_do_send_receive ((const char*) iter->data, 
2331                                                    force_connection, 
2332                                                    poke_status, interactive, win);
2333                 iter = g_slist_next (iter);
2334         }
2335
2336         modest_account_mgr_free_account_names (account_names);
2337         account_names = NULL;
2338 }
2339
2340 /*
2341  * Handler of the click on Send&Receive button in the main toolbar
2342  */
2343 void
2344 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2345 {
2346         /* Check if accounts exist */
2347         gboolean accounts_exist;
2348
2349         accounts_exist =
2350                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2351         
2352         /* If not, allow the user to create an account before trying to send/receive. */
2353         if (!accounts_exist)
2354                 modest_ui_actions_on_accounts (NULL, win);
2355         
2356         /* Refresh the current folder. The if is always TRUE it's just an extra check */
2357         if (MODEST_IS_MAIN_WINDOW (win)) {
2358                 GtkWidget *folder_view;
2359                 TnyFolderStore *folder_store;
2360
2361                 folder_view = 
2362                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), 
2363                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2364                 if (!folder_view)
2365                         return;
2366                 
2367                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2368         
2369                 if (folder_store)
2370                         g_object_unref (folder_store);
2371                 /* Refresh the active account. Force the connection if needed
2372                    and poke the status of all folders */
2373                 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2374 #ifdef MODEST_TOOLKIT_HILDON2
2375         } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2376                 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2377 #endif
2378         } else {
2379                 const gchar *active_account;
2380                 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2381
2382                 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2383         } 
2384         
2385 }
2386
2387
2388 void
2389 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2390 {
2391         ModestConf *conf;
2392         GtkWidget *header_view;
2393         
2394         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2395
2396         header_view = modest_main_window_get_child_widget (main_window,
2397                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2398         if (!header_view)
2399                 return;
2400
2401         conf = modest_runtime_get_conf ();
2402         
2403         /* what is saved/restored is depending on the style; thus; we save with
2404          * old style, then update the style, and restore for this new style
2405          */
2406         modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2407         
2408         if (modest_header_view_get_style
2409             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2410                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2411                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
2412         else
2413                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2414                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
2415
2416         modest_widget_memory_restore (conf, G_OBJECT(header_view),
2417                                       MODEST_CONF_HEADER_VIEW_KEY);
2418 }
2419
2420
2421 void 
2422 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
2423                                       TnyHeader *header,
2424                                       ModestMainWindow *main_window)
2425 {
2426         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2427         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2428         
2429         /* in the case the folder is empty, show the empty folder message and focus
2430          * folder view */
2431         if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2432                 if (modest_header_view_is_empty (header_view)) {
2433                         TnyFolder *folder = modest_header_view_get_folder (header_view);
2434                         GtkWidget *folder_view = 
2435                                 modest_main_window_get_child_widget (main_window,
2436                                                                      MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2437                         if (folder != NULL) {
2438                                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2439                                 g_object_unref (folder);
2440                         }
2441                         gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2442                         return;
2443                 }
2444         }
2445         /* If no header has been selected then exit */
2446         if (!header)
2447                 return;
2448
2449         /* Update focus */
2450         if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2451             gtk_widget_grab_focus (GTK_WIDGET(header_view));
2452
2453         /* Update toolbar dimming state */
2454         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2455         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2456 }
2457
2458 void
2459 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2460                                        TnyHeader *header,
2461                                        GtkTreePath *path,
2462                                        ModestWindow *window)
2463 {
2464         GtkWidget *open_widget;
2465         GtkTreeRowReference *rowref;
2466
2467         g_return_if_fail (MODEST_IS_WINDOW(window));
2468         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2469         g_return_if_fail (TNY_IS_HEADER (header));
2470
2471         if (modest_header_view_count_selected_headers (header_view) > 1) {
2472                 /* Don't allow activation if there are more than one message selected */
2473                 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2474                 return;
2475         }
2476
2477         /* we check for low-mem; in that case, show a warning, and don't allow
2478          * activating headers
2479          */
2480         if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2481                 return;
2482
2483         if (MODEST_IS_MAIN_WINDOW (window)) {
2484                 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2485                 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2486                 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2487                         return;
2488         }
2489
2490         rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2491         open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2492         gtk_tree_row_reference_free (rowref);
2493 }
2494
2495 static void
2496 set_active_account_from_tny_account (TnyAccount *account,
2497                                      ModestWindow *window)
2498 {
2499         const gchar *server_acc_name = tny_account_get_id (account);
2500         
2501         /* We need the TnyAccount provided by the
2502            account store because that is the one that
2503            knows the name of the Modest account */
2504         TnyAccount *modest_server_account = modest_server_account = 
2505                 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2506                                                              MODEST_TNY_ACCOUNT_STORE_QUERY_ID, 
2507                                                              server_acc_name);
2508         if (!modest_server_account) {
2509                 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2510                 return;
2511         }
2512
2513         /* Update active account, but only if it's not a pseudo-account */
2514         if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2515             (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2516                 const gchar *modest_acc_name = 
2517                         modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2518                 if (modest_acc_name)
2519                         modest_window_set_active_account (window, modest_acc_name);
2520         }
2521         
2522         g_object_unref (modest_server_account);
2523 }
2524
2525
2526 static void
2527 folder_refreshed_cb (ModestMailOperation *mail_op, 
2528                      TnyFolder *folder, 
2529                      gpointer user_data)
2530 {
2531         ModestMainWindow *win = NULL;
2532         GtkWidget *folder_view;
2533         const GError *error;
2534
2535         g_return_if_fail (TNY_IS_FOLDER (folder));
2536
2537         win = MODEST_MAIN_WINDOW (user_data);
2538
2539         /* Check if the operation failed due to memory low conditions */
2540         error = modest_mail_operation_get_error (mail_op);
2541         if (error && error->domain == MODEST_MAIL_OPERATION_ERROR && 
2542             error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2543                 modest_platform_run_information_dialog (GTK_WINDOW (win),
2544                                                         _KR("memr_ib_operation_disabled"),
2545                                                         TRUE);
2546                 return;
2547         }
2548
2549         folder_view = 
2550                 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2551
2552         if (folder_view) {
2553                 TnyFolderStore *current_folder;
2554
2555                 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2556                 if (current_folder) {
2557                         gboolean different = ((TnyFolderStore *) folder != current_folder);
2558                         g_object_unref (current_folder);
2559                         if (different)
2560                                 return;
2561                 }
2562         }
2563
2564         /* Check if folder is empty and set headers view contents style */
2565         if (tny_folder_get_all_count (folder) == 0)
2566                 modest_main_window_set_contents_style (win,
2567                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2568
2569 }
2570
2571 void 
2572 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2573                                                TnyFolderStore *folder_store, 
2574                                                gboolean selected,
2575                                                ModestMainWindow *main_window)
2576 {
2577         ModestConf *conf;
2578         GtkWidget *header_view;
2579
2580         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2581
2582         header_view = modest_main_window_get_child_widget(main_window,
2583                                                           MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2584         if (!header_view)
2585                 return;
2586         
2587         conf = modest_runtime_get_conf ();
2588
2589         if (TNY_IS_ACCOUNT (folder_store)) {
2590                 if (selected) {
2591                         set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2592                         
2593                         /* Show account details */
2594                         modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2595                 }
2596         } else {
2597                 if (TNY_IS_FOLDER (folder_store) && selected) {
2598                         TnyAccount *account;
2599                         const gchar *account_name = NULL;
2600
2601                         /* Update the active account */
2602                         account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2603                         if (account) {
2604                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2605                                 account_name = 
2606                                         modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2607                                 g_object_unref (account);
2608                                 account = NULL;
2609                         }
2610
2611                         /* Set the header style by default, it could
2612                            be changed later by the refresh callback to
2613                            empty */
2614                         modest_main_window_set_contents_style (main_window, 
2615                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2616
2617                         /* Set folder on header view. This function
2618                            will call tny_folder_refresh_async so we
2619                            pass a callback that will be called when
2620                            finished. We use that callback to set the
2621                            empty view if there are no messages */
2622                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2623                                                        TNY_FOLDER (folder_store),
2624                                                        TRUE,
2625                                                        MODEST_WINDOW (main_window),
2626                                                        folder_refreshed_cb,
2627                                                        main_window);
2628                         
2629                         /* Restore configuration. We need to do this
2630                            *after* the set_folder because the widget
2631                            memory asks the header view about its
2632                            folder  */
2633                         modest_widget_memory_restore (modest_runtime_get_conf (), 
2634                                                       G_OBJECT(header_view),
2635                                                       MODEST_CONF_HEADER_VIEW_KEY);
2636                 } else {
2637                         /* No need to save the header view
2638                            configuration for Maemo because it only
2639                            saves the sorting stuff and that it's
2640                            already being done by the sort
2641                            dialog. Remove it when the GNOME version
2642                            has the same behaviour */
2643 #ifdef MODEST_TOOLKIT_GTK
2644                         if (modest_main_window_get_contents_style (main_window) ==
2645                             MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2646                                 modest_widget_memory_save (conf, G_OBJECT (header_view), 
2647                                                            MODEST_CONF_HEADER_VIEW_KEY);
2648 #endif
2649                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2650                 }
2651         }
2652
2653         /* Update dimming state */
2654         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2655         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2656 }
2657
2658 void 
2659 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2660                                      ModestWindow *win)
2661 {
2662         GtkWidget *dialog;
2663         gchar *txt, *item;
2664         gboolean online;
2665
2666         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2667         
2668         online = tny_device_is_online (modest_runtime_get_device());
2669
2670         if (online) {
2671                 /* already online -- the item is simply not there... */
2672                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2673                                                  GTK_DIALOG_MODAL,
2674                                                  GTK_MESSAGE_WARNING,
2675                                                  GTK_BUTTONS_NONE,
2676                                                  _("The %s you selected cannot be found"),
2677                                                  item);
2678                 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2679                 gtk_dialog_run (GTK_DIALOG(dialog));
2680         } else {
2681                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2682                                                       GTK_WINDOW (win),
2683                                                       GTK_DIALOG_MODAL,
2684                                                       _("mcen_bd_dialog_cancel"),
2685                                                       GTK_RESPONSE_REJECT,
2686                                                       _("mcen_bd_dialog_ok"),
2687                                                       GTK_RESPONSE_ACCEPT,
2688                                                       NULL);
2689                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2690                                          "Do you want to get online?"), item);
2691                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
2692                                     gtk_label_new (txt), FALSE, FALSE, 0);
2693                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2694                 g_free (txt);
2695
2696                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2697                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2698                         /* TODO: Comment about why is this commented out: */
2699                         /* modest_platform_connect_and_wait (); */
2700                 }
2701         }
2702         gtk_widget_destroy (dialog);
2703 }
2704
2705 void
2706 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2707                                      ModestWindow *win)
2708 {
2709         /* g_message ("%s %s", __FUNCTION__, link); */
2710 }       
2711
2712
2713 void
2714 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2715                                         ModestWindow *win)
2716 {
2717         modest_platform_activate_uri (link);
2718 }
2719
2720 void
2721 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2722                                           ModestWindow *win)
2723 {
2724         modest_platform_show_uri_popup (link);
2725 }
2726
2727 void
2728 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2729                                              ModestWindow *win)
2730 {
2731         /* we check for low-mem; in that case, show a warning, and don't allow
2732          * viewing attachments
2733          */
2734         if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2735                 return;
2736
2737         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2738 }
2739
2740 void
2741 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2742                                           const gchar *address,
2743                                           ModestWindow *win)
2744 {
2745         /* g_message ("%s %s", __FUNCTION__, address); */
2746 }
2747
2748 static void
2749 on_save_to_drafts_cb (ModestMailOperation *mail_op, 
2750                       TnyMsg *saved_draft,
2751                       gpointer user_data)
2752 {
2753         ModestMsgEditWindow *edit_window;
2754
2755         /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2756 #ifndef MODEST_TOOLKIT_HILDON2
2757         ModestMainWindow *win;
2758
2759         /* FIXME. Make the header view sensitive again. This is a
2760          * temporary hack. See modest_ui_actions_on_save_to_drafts()
2761          * for details */
2762         win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2763                                          modest_runtime_get_window_mgr(), FALSE));
2764         if (win != NULL) {
2765                 GtkWidget *hdrview = modest_main_window_get_child_widget(
2766                         win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2767                 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2768         }
2769 #endif
2770
2771         edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2772
2773         /* Set draft is there was no error */
2774         if (!modest_mail_operation_get_error (mail_op))
2775                 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2776
2777         g_object_unref(edit_window);
2778 }
2779
2780 static gboolean
2781 enough_space_for_message (ModestMsgEditWindow *edit_window,
2782                           MsgData *data)
2783 {
2784         TnyAccountStore *acc_store;
2785         guint64 available_disk, expected_size;
2786         gint parts_count;
2787         guint64 parts_size;
2788
2789         /* Check size */
2790         acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2791         available_disk = modest_utils_get_available_space (NULL);
2792         modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2793         expected_size = modest_tny_msg_estimate_size (data->plain_body,
2794                                                       data->html_body,
2795                                                       parts_count,
2796                                                       parts_size);
2797
2798         /* Double check: memory full condition or message too big */
2799         if (available_disk < MIN_FREE_SPACE || 
2800             expected_size > available_disk) {
2801
2802                 modest_platform_information_banner (NULL, NULL, 
2803                                                     _KR("cerm_device_memory_full"));
2804                 return FALSE;
2805         }
2806
2807         /*
2808          * djcb: if we're in low-memory state, we only allow for
2809          * saving messages smaller than
2810          * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2811          * should still allow for sending anything critical...
2812          */
2813         if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2814             modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2815                 return FALSE;
2816
2817         /*
2818          * djcb: we also make sure that the attachments are smaller than the max size
2819          * this is for the case where we'd try to forward a message with attachments 
2820          * bigger than our max allowed size, or sending an message from drafts which
2821          * somehow got past our checks when attaching.
2822          */
2823         if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2824                 modest_platform_run_information_dialog (
2825                         GTK_WINDOW(edit_window),
2826                         _KR("memr_ib_operation_disabled"),
2827                         TRUE);
2828                 return FALSE;
2829         }
2830
2831         return TRUE;
2832 }
2833
2834 gboolean
2835 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2836 {
2837         TnyTransportAccount *transport_account;
2838         ModestMailOperation *mail_operation;
2839         MsgData *data;
2840         gchar *account_name, *from;
2841         ModestAccountMgr *account_mgr;
2842         gboolean had_error = FALSE;
2843         ModestMainWindow *win = NULL;
2844
2845         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2846         
2847         data = modest_msg_edit_window_get_msg_data (edit_window);
2848
2849         /* Check size */
2850         if (!enough_space_for_message (edit_window, data)) {
2851                 modest_msg_edit_window_free_msg_data (edit_window, data);
2852                 return FALSE;
2853         }
2854
2855         account_name = g_strdup (data->account_name);
2856         account_mgr = modest_runtime_get_account_mgr();
2857         if (!account_name)
2858                 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2859         if (!account_name) 
2860                 account_name = modest_account_mgr_get_default_account (account_mgr);
2861         if (!account_name) {
2862                 g_printerr ("modest: no account found\n");
2863                 modest_msg_edit_window_free_msg_data (edit_window, data);
2864                 return FALSE;
2865         }
2866
2867         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2868                 account_name = g_strdup (data->account_name);
2869         }
2870
2871         transport_account =
2872                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2873                                       (modest_runtime_get_account_store (),
2874                                        account_name,
2875                                        TNY_ACCOUNT_TYPE_TRANSPORT));
2876         if (!transport_account) {
2877                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2878                 g_free (account_name);
2879                 modest_msg_edit_window_free_msg_data (edit_window, data);
2880                 return FALSE;
2881         }
2882         from = modest_account_mgr_get_from_string (account_mgr, account_name);
2883
2884         /* Create the mail operation */         
2885         mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2886                                                                         NULL, NULL);
2887         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2888
2889         modest_mail_operation_save_to_drafts (mail_operation,
2890                                               transport_account,
2891                                               data->draft_msg,
2892                                               from,
2893                                               data->to, 
2894                                               data->cc, 
2895                                               data->bcc,
2896                                               data->subject, 
2897                                               data->plain_body, 
2898                                               data->html_body,
2899                                               data->attachments,
2900                                               data->images,
2901                                               data->priority_flags,
2902                                               on_save_to_drafts_cb,
2903                                               g_object_ref(edit_window));
2904
2905 #ifdef MODEST_TOOLKIT_HILDON2
2906         /* In hildon2 we always show the information banner on saving to drafts.
2907          * It will be a system information banner in this case.
2908          */
2909         gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2910         modest_platform_information_banner (NULL, NULL, text);
2911         g_free (text);
2912 #else
2913         /* Use the main window as the parent of the banner, if the
2914            main window does not exist it won't be shown, if the parent
2915            window exists then it's properly shown. We don't use the
2916            editor window because it could be closed (save to drafts
2917            could happen after closing the window */
2918         win = (ModestMainWindow *)
2919                 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2920         if (win) {
2921                 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2922                 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2923                 g_free (text);
2924         }
2925 #endif
2926         modest_msg_edit_window_set_modified (edit_window, FALSE);
2927
2928         /* Frees */
2929         g_free (from);
2930         g_free (account_name);
2931         g_object_unref (G_OBJECT (transport_account));
2932         g_object_unref (G_OBJECT (mail_operation));
2933
2934         modest_msg_edit_window_free_msg_data (edit_window, data);
2935
2936         /* ** FIXME **
2937          * If the drafts folder is selected then make the header view
2938          * insensitive while the message is being saved to drafts
2939          * (it'll be sensitive again in on_save_to_drafts_cb()). This
2940          * is not very clean but it avoids letting the drafts folder
2941          * in an inconsistent state: the user could edit the message
2942          * being saved and undesirable things would happen.
2943          * In the average case the user won't notice anything at
2944          * all. In the worst case (the user is editing a really big
2945          * file from Drafts) the header view will be insensitive
2946          * during the saving process (10 or 20 seconds, depending on
2947          * the message). Anyway this is just a quick workaround: once
2948          * we find a better solution it should be removed
2949          * See NB#65125 (commend #18) for details.
2950          */
2951         if (!had_error && win != NULL) {
2952                 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2953                         win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2954                 if (view != NULL) {
2955                         TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2956                         if (folder) {
2957                                 if (modest_tny_folder_is_local_folder(folder)) {
2958                                         TnyFolderType folder_type;
2959                                         folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2960                                         if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2961                                                 GtkWidget *hdrview = modest_main_window_get_child_widget(
2962                                                         win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2963                                                 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2964                                         }
2965                                 }
2966                         }
2967                         if (folder != NULL) g_object_unref(folder);
2968                 }
2969         }
2970
2971         return !had_error;
2972 }
2973
2974 /* For instance, when clicking the Send toolbar button when editing a message: */
2975 gboolean
2976 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2977 {
2978         TnyTransportAccount *transport_account = NULL;
2979         gboolean had_error = FALSE;
2980         MsgData *data;
2981         ModestAccountMgr *account_mgr;
2982         gchar *account_name;
2983         gchar *from;
2984         ModestMailOperation *mail_operation;
2985
2986         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2987
2988         if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2989                 return TRUE;
2990         
2991         data = modest_msg_edit_window_get_msg_data (edit_window);
2992
2993         /* Check size */
2994         if (!enough_space_for_message (edit_window, data)) {
2995                 modest_msg_edit_window_free_msg_data (edit_window, data);
2996                 return FALSE;
2997         }
2998
2999         account_mgr = modest_runtime_get_account_mgr();
3000         account_name = g_strdup (data->account_name);
3001         if (!account_name)
3002                 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3003
3004         if (!account_name) 
3005                 account_name = modest_account_mgr_get_default_account (account_mgr);
3006                 
3007         if (!account_name) {
3008                 modest_msg_edit_window_free_msg_data (edit_window, data);
3009                 /* Run account setup wizard */
3010                 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3011                         return TRUE;
3012                 }
3013         }
3014         
3015         /* Get the currently-active transport account for this modest account: */
3016         if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3017                 transport_account = 
3018                         TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3019                                               (modest_runtime_get_account_store (), 
3020                                                account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3021         }
3022         
3023         if (!transport_account) {
3024                 modest_msg_edit_window_free_msg_data (edit_window, data);
3025                 /* Run account setup wizard */
3026                 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3027                         return TRUE;
3028         }
3029         
3030
3031         /* Create the mail operation */
3032         from = modest_account_mgr_get_from_string (account_mgr, account_name);
3033         mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3034         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3035
3036         modest_mail_operation_send_new_mail (mail_operation,
3037                                              transport_account,
3038                                              data->draft_msg,
3039                                              from,
3040                                              data->to,
3041                                              data->cc, 
3042                                              data->bcc,
3043                                              data->subject, 
3044                                              data->plain_body, 
3045                                              data->html_body,
3046                                              data->attachments,
3047                                              data->images,
3048                                              data->priority_flags);
3049
3050         if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3051                 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3052
3053
3054         if (modest_mail_operation_get_error (mail_operation) != NULL) {
3055                 const GError *error = modest_mail_operation_get_error (mail_operation);
3056                 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3057                     error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3058                         g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3059                         modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3060                         had_error = TRUE;
3061                 }
3062         }
3063                                              
3064         /* Free data: */
3065         g_free (from);
3066         g_free (account_name);
3067         g_object_unref (G_OBJECT (transport_account));
3068         g_object_unref (G_OBJECT (mail_operation));
3069
3070         modest_msg_edit_window_free_msg_data (edit_window, data);
3071
3072         if (!had_error) {
3073                 modest_msg_edit_window_set_sent (edit_window, TRUE);
3074
3075                 /* Save settings and close the window: */
3076                 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3077         }
3078
3079         return !had_error;
3080 }
3081
3082 void 
3083 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3084                                   ModestMsgEditWindow *window)
3085 {
3086         ModestMsgEditFormatState *format_state = NULL;
3087
3088         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3089         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3090
3091         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3092                 return;
3093
3094         format_state = modest_msg_edit_window_get_format_state (window);
3095         g_return_if_fail (format_state != NULL);
3096
3097         format_state->bold = gtk_toggle_action_get_active (action);
3098         modest_msg_edit_window_set_format_state (window, format_state);
3099         g_free (format_state);
3100         
3101 }
3102
3103 void 
3104 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3105                                      ModestMsgEditWindow *window)
3106 {
3107         ModestMsgEditFormatState *format_state = NULL;
3108
3109         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3110         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3111
3112         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3113                 return;
3114
3115         format_state = modest_msg_edit_window_get_format_state (window);
3116         g_return_if_fail (format_state != NULL);
3117
3118         format_state->italics = gtk_toggle_action_get_active (action);
3119         modest_msg_edit_window_set_format_state (window, format_state);
3120         g_free (format_state);
3121         
3122 }
3123
3124 void 
3125 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3126                                      ModestMsgEditWindow *window)
3127 {
3128         ModestMsgEditFormatState *format_state = NULL;
3129
3130         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3131         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3132
3133         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3134                 return;
3135
3136         format_state = modest_msg_edit_window_get_format_state (window);
3137         g_return_if_fail (format_state != NULL);
3138
3139         format_state->bullet = gtk_toggle_action_get_active (action);
3140         modest_msg_edit_window_set_format_state (window, format_state);
3141         g_free (format_state);
3142         
3143 }
3144
3145 void 
3146 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3147                                      GtkRadioAction *selected,
3148                                      ModestMsgEditWindow *window)
3149 {
3150         ModestMsgEditFormatState *format_state = NULL;
3151         GtkJustification value;
3152
3153         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3154
3155         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3156                 return;
3157
3158         value = gtk_radio_action_get_current_value (selected);
3159
3160         format_state = modest_msg_edit_window_get_format_state (window);
3161         g_return_if_fail (format_state != NULL);
3162
3163         format_state->justification = value;
3164         modest_msg_edit_window_set_format_state (window, format_state);
3165         g_free (format_state);
3166 }
3167
3168 void 
3169 modest_ui_actions_on_select_editor_color (GtkAction *action,
3170                                           ModestMsgEditWindow *window)
3171 {
3172         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3173         g_return_if_fail (GTK_IS_ACTION (action));
3174
3175         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3176                 return;
3177
3178         modest_msg_edit_window_select_color (window);
3179 }
3180
3181 void 
3182 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3183                                                      ModestMsgEditWindow *window)
3184 {
3185         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3186         g_return_if_fail (GTK_IS_ACTION (action));
3187
3188         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3189                 return;
3190
3191         modest_msg_edit_window_select_background_color (window);
3192 }
3193
3194 void 
3195 modest_ui_actions_on_insert_image (GObject *object,
3196                                    ModestMsgEditWindow *window)
3197 {
3198         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3199
3200
3201         if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3202                 return;
3203
3204         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3205                 return;
3206
3207         modest_msg_edit_window_insert_image (window);
3208 }
3209
3210 void 
3211 modest_ui_actions_on_attach_file (GtkAction *action,
3212                                   ModestMsgEditWindow *window)
3213 {
3214         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3215         g_return_if_fail (GTK_IS_ACTION (action));
3216
3217         if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3218                 return;
3219         
3220         modest_msg_edit_window_offer_attach_file (window);
3221 }
3222
3223 void 
3224 modest_ui_actions_on_remove_attachments (GtkAction *action,
3225                                          ModestMsgEditWindow *window)
3226 {
3227         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3228
3229         modest_msg_edit_window_remove_attachments (window, NULL);
3230 }
3231
3232
3233 #ifndef MODEST_TOOLKIT_GTK
3234 typedef struct {
3235         guint handler;
3236         gchar *name;
3237         GtkWindow *win;
3238         TnyFolderStore *folder;
3239 } CreateFolderHelper;
3240
3241 static gboolean
3242 show_create_folder_in_timeout (gpointer data)
3243 {
3244         CreateFolderHelper *helper = (CreateFolderHelper *) data;
3245
3246         /* Remove the timeout ASAP, we can not wait until the dialog
3247            is shown because it could take a lot of time and so the
3248            timeout could be called twice or more times */
3249         g_source_remove (helper->handler);
3250
3251         gdk_threads_enter ();
3252         do_create_folder (helper->win, helper->folder, helper->name);
3253         gdk_threads_leave ();
3254
3255         g_object_unref (helper->win);
3256         g_object_unref (helper->folder);
3257         g_free (helper->name);
3258         g_slice_free (CreateFolderHelper, helper);
3259
3260         return FALSE;
3261 }
3262 #endif
3263
3264 static void
3265 do_create_folder_cb (ModestMailOperation *mail_op,
3266                      TnyFolderStore *parent_folder, 
3267                      TnyFolder *new_folder,
3268                      gpointer user_data)
3269 {
3270         gchar *suggested_name = (gchar *) user_data;
3271         GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3272
3273         if (modest_mail_operation_get_error (mail_op)) {
3274
3275                 /* Show an error. If there was some problem writing to
3276                    disk, show it, otherwise show the generic folder
3277                    create error. We do it here and not in an error
3278                    handler because the call to do_create_folder will
3279                    stop the main loop in a gtk_dialog_run and then,
3280                    the message won't be shown until that dialog is
3281                    closed */
3282                 modest_ui_actions_disk_operations_error_handler (mail_op,
3283                                                                  _("mail_in_ui_folder_create_error"));
3284
3285                 /* Try again. Do *NOT* show any error because the mail
3286                    operations system will do it for us because we
3287                    created the mail_op with new_with_error_handler */
3288 #ifndef MODEST_TOOLKIT_GTK
3289                 CreateFolderHelper *helper;
3290                 helper = g_slice_new0 (CreateFolderHelper);
3291                 helper->name = g_strdup (suggested_name);
3292                 helper->folder = g_object_ref (parent_folder);
3293                 helper->win = g_object_ref (source_win);
3294
3295                 /* Ugly but neccesary stuff. The problem is that the
3296                    dialog when is shown calls a function that destroys
3297                    all the temporary windows, so the banner is
3298                    destroyed */
3299                 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3300 #else
3301                 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3302 #endif
3303         } else {
3304                 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3305                  * FIXME: any other? */
3306                 GtkWidget *folder_view;
3307
3308                 if (MODEST_IS_MAIN_WINDOW(source_win)) 
3309                         folder_view = 
3310                                 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3311                                                                      MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3312                 else
3313                         folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3314                                                                     MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3315
3316                 /* Select the newly created folder. It could happen
3317                    that the widget is no longer there (i.e. the window
3318                    has been destroyed, so we need to check this */
3319                 if (folder_view)
3320                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3321                                                           new_folder, FALSE);
3322                 g_object_unref (new_folder);
3323         }
3324         /* Free. Note that the first time it'll be NULL so noop */
3325         g_free (suggested_name);
3326         g_object_unref (source_win);
3327 }
3328
3329 typedef struct {
3330         gchar *folder_name;
3331         TnyFolderStore *parent;
3332 } CreateFolderConnect;
3333
3334 static void
3335 do_create_folder_performer (gboolean canceled, 
3336                          GError *err,
3337                          GtkWindow *parent_window, 
3338                          TnyAccount *account, 
3339                          gpointer user_data)
3340 {
3341         CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3342         ModestMailOperation *mail_op;
3343
3344         if (canceled || err) {
3345                 /* In memory full conditions we could get this error here */
3346                 check_memory_full_error ((GtkWidget *) parent_window, err);
3347                 goto frees;
3348         }
3349
3350         mail_op  = modest_mail_operation_new ((GObject *) parent_window);
3351         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
3352                                          mail_op);
3353         modest_mail_operation_create_folder (mail_op,
3354                                              helper->parent,
3355                                              (const gchar *) helper->folder_name,
3356                                              do_create_folder_cb,
3357                                              g_strdup (helper->folder_name));
3358         g_object_unref (mail_op);
3359
3360  frees:
3361         if (helper->parent)
3362                 g_object_unref (helper->parent);
3363         if (helper->folder_name)
3364                 g_free (helper->folder_name);
3365         g_slice_free (CreateFolderConnect, helper);
3366 }
3367
3368
3369 static void
3370 do_create_folder (GtkWindow *parent_window, 
3371                   TnyFolderStore *suggested_parent, 
3372                   const gchar *suggested_name)
3373 {
3374         gint result;
3375         gchar *folder_name = NULL;
3376         TnyFolderStore *parent_folder = NULL;
3377
3378         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3379                                                         suggested_parent,
3380                                                         (gchar *) suggested_name,
3381                                                         &folder_name,
3382                                                         &parent_folder);
3383
3384         if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3385                 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderHelper);
3386                 helper->folder_name = g_strdup (folder_name);
3387                 helper->parent = g_object_ref (parent_folder);
3388
3389                 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3390                                                                TRUE,
3391                                                                parent_folder,
3392                                                                do_create_folder_performer,
3393                                                                helper);
3394         }
3395
3396         if (folder_name)
3397                 g_free (folder_name);
3398         if (parent_folder)
3399                 g_object_unref (parent_folder);
3400 }
3401
3402 static void
3403 modest_ui_actions_create_folder(GtkWidget *parent_window,
3404                                 GtkWidget *folder_view)
3405 {
3406         TnyFolderStore *parent_folder;
3407
3408 #ifdef MODEST_TOOLKIT_HILDON2
3409         ModestTnyAccountStore *acc_store;
3410
3411         acc_store = modest_runtime_get_account_store ();
3412
3413         parent_folder = (TnyFolderStore *) 
3414                 modest_tny_account_store_get_local_folders_account (acc_store);
3415 #else
3416         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3417 #endif
3418
3419         if (parent_folder)
3420                 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3421 }
3422
3423 void
3424 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3425 {
3426
3427         g_return_if_fail (MODEST_IS_WINDOW(window));
3428
3429         if (MODEST_IS_MAIN_WINDOW (window)) {
3430                 GtkWidget *folder_view;
3431
3432                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3433                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3434                 if (!folder_view)
3435                         return;
3436
3437                 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3438 #ifdef MODEST_TOOLKIT_HILDON2
3439         } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3440                 GtkWidget *folder_view;
3441
3442                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3443                 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3444 #endif
3445         } else {
3446                 g_assert_not_reached ();
3447         }
3448 }
3449
3450 static void
3451 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3452                                                gpointer user_data)
3453 {
3454         const GError *error = NULL;
3455         const gchar *message = NULL;
3456         
3457         /* Get error message */
3458         error = modest_mail_operation_get_error (mail_op);
3459         if (!error)
3460                 g_return_if_reached ();
3461
3462         if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3463             error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3464                 message = _CS("ckdg_ib_folder_already_exists");
3465         } else if (error->domain == TNY_ERROR_DOMAIN &&
3466                    error->code == TNY_SERVICE_ERROR_STATE) {
3467                 /* This means that the folder is already in use (a
3468                    message is opened for example */
3469                 message = _("emev_ni_internal_error");
3470         } else {
3471                 message = _CS("ckdg_ib_unable_to_rename");
3472         }
3473
3474         /* We don't set a parent for the dialog because the dialog
3475            will be destroyed so the banner won't appear */
3476         modest_platform_information_banner (NULL, NULL, message);
3477 }
3478
3479 typedef struct {
3480         TnyFolderStore *folder;
3481         gchar *new_name;
3482 } RenameFolderInfo;
3483
3484 static void
3485 on_rename_folder_cb (ModestMailOperation *mail_op, 
3486                      TnyFolder *new_folder,
3487                      gpointer user_data)
3488 {
3489         ModestFolderView *folder_view;
3490
3491         /* If the window was closed when renaming a folder, or if
3492          * it's not a main window this will happen */
3493         if (!MODEST_IS_FOLDER_VIEW (user_data))
3494                 return;
3495
3496         folder_view = MODEST_FOLDER_VIEW (user_data);
3497         /* Note that if the rename fails new_folder will be NULL */
3498         if (new_folder) {
3499                 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3500         } else {
3501                 modest_folder_view_select_first_inbox_or_local (folder_view);
3502         }
3503         gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3504 }
3505
3506 static void
3507 on_rename_folder_performer (gboolean canceled, 
3508                             GError *err, 
3509                             GtkWindow *parent_window, 
3510                             TnyAccount *account, 
3511                             gpointer user_data)
3512 {
3513         ModestMailOperation *mail_op = NULL;
3514         GtkTreeSelection *sel = NULL;
3515         GtkWidget *folder_view = NULL;
3516         RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3517
3518         if (canceled || err) {
3519                 /* In memory full conditions we could get this error here */
3520                 check_memory_full_error ((GtkWidget *) parent_window, err);
3521         } else {
3522
3523                 mail_op =
3524                         modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3525                                         modest_ui_actions_rename_folder_error_handler,
3526                                         parent_window, NULL);
3527
3528                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3529                                 mail_op);
3530
3531                 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3532
3533                         folder_view = modest_main_window_get_child_widget (
3534                                 MODEST_MAIN_WINDOW (parent_window),
3535                                 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3536                 } 
3537 #ifdef MODEST_TOOLKIT_HILDON2
3538                 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3539                         ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3540                         folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3541                 }
3542 #endif
3543
3544                 /* Clear the folders view */
3545                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3546                 gtk_tree_selection_unselect_all (sel);
3547
3548                 /* Actually rename the folder */
3549                 modest_mail_operation_rename_folder (mail_op,
3550                                                      TNY_FOLDER (data->folder),
3551                                                      (const gchar *) (data->new_name),
3552                                                      on_rename_folder_cb,
3553                                                      folder_view);
3554                 g_object_unref (mail_op);
3555         }
3556
3557         g_object_unref (data->folder);
3558         g_free (data->new_name);
3559         g_free (data);
3560 }
3561
3562 void 
3563 modest_ui_actions_on_rename_folder (GtkAction *action,
3564                                      ModestWindow *window)
3565 {
3566         modest_ui_actions_on_edit_mode_rename_folder (window);
3567 }
3568
3569 gboolean 
3570 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3571 {
3572         TnyFolderStore *folder;
3573         GtkWidget *folder_view;
3574         gboolean do_rename = TRUE;
3575
3576         g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3577
3578         if (MODEST_IS_MAIN_WINDOW (window)) {
3579                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3580                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3581                 if (!folder_view)
3582                         return FALSE;
3583
3584 #ifdef MODEST_TOOLKIT_HILDON2
3585         } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3586                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3587 #endif
3588         } else {
3589                 return FALSE;
3590         }
3591
3592         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3593
3594         if (!folder)
3595                 return FALSE;
3596
3597         if (TNY_IS_FOLDER (folder)) {
3598                 gchar *folder_name = NULL;
3599                 gint response;
3600                 const gchar *current_name;
3601                 TnyFolderStore *parent;
3602
3603                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3604                 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3605                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3606                                                                      parent, current_name, 
3607                                                                      &folder_name);
3608                 g_object_unref (parent);
3609
3610                 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3611                         do_rename = FALSE;
3612                 } else {
3613                         RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3614                         rename_folder_data->folder = g_object_ref (folder);
3615                         rename_folder_data->new_name = folder_name;
3616                         modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3617                                         folder, on_rename_folder_performer, rename_folder_data);
3618                 }
3619         }
3620         g_object_unref (folder);
3621         return do_rename;
3622 }
3623
3624 static void
3625 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3626                                                gpointer user_data)
3627 {
3628         GObject *win = modest_mail_operation_get_source (mail_op);
3629
3630         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3631                                                 _("mail_in_ui_folder_delete_error"),
3632                                                 FALSE);
3633         g_object_unref (win);
3634 }
3635
3636 typedef struct {
3637         TnyFolderStore *folder;
3638         gboolean move_to_trash;
3639 } DeleteFolderInfo;
3640
3641 static void
3642 on_delete_folder_cb (gboolean canceled, 
3643                   GError *err,
3644                   GtkWindow *parent_window, 
3645                   TnyAccount *account, 
3646                   gpointer user_data)
3647 {
3648         DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3649         GtkWidget *folder_view;
3650         ModestMailOperation *mail_op;
3651         GtkTreeSelection *sel;
3652         
3653         if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3654                 g_object_unref (G_OBJECT (info->folder));
3655                 g_free (info);
3656                 return;
3657         }
3658         
3659         if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3660                 folder_view = modest_main_window_get_child_widget (
3661                         MODEST_MAIN_WINDOW (parent_window),
3662                         MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3663 #ifdef MODEST_TOOLKIT_HILDON2
3664         } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3665                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3666 #endif
3667         } else {
3668                 g_object_unref (G_OBJECT (info->folder));
3669                 g_free (info);
3670                 return;
3671         }
3672
3673         /* Unselect the folder before deleting it to free the headers */
3674         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3675         gtk_tree_selection_unselect_all (sel);
3676
3677         /* Create the mail operation */
3678         mail_op =
3679                 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3680                                 modest_ui_actions_delete_folder_error_handler,
3681                                 NULL, NULL);
3682
3683         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3684                         mail_op);
3685         modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3686         
3687         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3688
3689         g_object_unref (G_OBJECT (mail_op));
3690         g_object_unref (G_OBJECT (info->folder));
3691         g_free (info);
3692 }
3693
3694 static gboolean
3695 delete_folder (ModestWindow *window, gboolean move_to_trash)
3696 {
3697         TnyFolderStore *folder;
3698         GtkWidget *folder_view;
3699         gint response;
3700         gchar *message;
3701         
3702         g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3703
3704         if (MODEST_IS_MAIN_WINDOW (window)) {
3705
3706                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3707                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3708 #ifdef MODEST_TOOLKIT_HILDON2
3709         } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3710                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3711 #endif
3712         } else {
3713                 return FALSE;
3714         }
3715         if (!folder_view)
3716                 return FALSE;
3717
3718         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3719
3720         if (!folder)
3721                 return FALSE;
3722
3723         /* Show an error if it's an account */
3724         if (!TNY_IS_FOLDER (folder)) {
3725                 modest_platform_run_information_dialog (GTK_WINDOW (window),
3726                                                         _("mail_in_ui_folder_delete_error"),
3727                                                         FALSE);
3728                 g_object_unref (G_OBJECT (folder));
3729                 return FALSE;
3730         }
3731
3732         /* Ask the user */
3733         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
3734                                     tny_folder_get_name (TNY_FOLDER (folder)));
3735         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3736                                                             (const gchar *) message);
3737         g_free (message);
3738
3739         if (response == GTK_RESPONSE_OK) {
3740                 DeleteFolderInfo *info;
3741                 info = g_new0(DeleteFolderInfo, 1);
3742                 info->folder = folder;
3743                 info->move_to_trash = move_to_trash;
3744                 g_object_ref (G_OBJECT (info->folder));
3745                 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3746                 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window), 
3747                                                                TRUE,
3748                                                                TNY_FOLDER_STORE (account), 
3749                                                                on_delete_folder_cb, info);
3750                 g_object_unref (account);
3751                 return TRUE;
3752         } else {
3753                 return FALSE;
3754         }
3755         g_object_unref (G_OBJECT (folder));
3756 }
3757
3758 void
3759 modest_ui_actions_on_delete_folder (GtkAction *action,
3760                                     ModestWindow *window)
3761 {
3762         modest_ui_actions_on_edit_mode_delete_folder (window);
3763 }
3764
3765 gboolean
3766 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3767 {
3768         g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3769         
3770         return delete_folder (window, FALSE);
3771 }
3772
3773 void 
3774 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3775 {
3776         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3777         
3778         delete_folder (MODEST_WINDOW (main_window), TRUE);
3779 }
3780
3781
3782 typedef struct _PasswordDialogFields {
3783         GtkWidget *username;
3784         GtkWidget *password;
3785         GtkWidget *dialog;
3786 } PasswordDialogFields;
3787
3788 static void
3789 password_dialog_check_field (GtkEditable *editable,
3790                              PasswordDialogFields *fields)
3791 {
3792         const gchar *value;
3793         gboolean any_value_empty = FALSE;
3794
3795 #ifdef MODEST_TOOLKIT_HILDON2
3796         value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3797 #else
3798         value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3799 #endif
3800         if ((value == NULL) || value[0] == '\0') {
3801                 any_value_empty = TRUE;
3802         }
3803 #ifdef MODEST_TOOLKIT_HILDON2
3804         value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3805 #else
3806         value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3807 #endif
3808         if ((value == NULL) || value[0] == '\0') {
3809                 any_value_empty = TRUE;
3810         }
3811         gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3812 }
3813
3814 void
3815 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3816                                          const gchar* server_account_name,
3817                                          gchar **username,
3818                                          gchar **password,
3819                                          gboolean *cancel,
3820                                          gboolean *remember,
3821                                          ModestMainWindow *main_window)
3822 {
3823         g_return_if_fail(server_account_name);
3824         gboolean completed = FALSE;
3825         PasswordDialogFields *fields = NULL;
3826
3827         /* Initalize output parameters: */
3828         if (cancel)
3829                 *cancel = FALSE;
3830
3831         if (remember)
3832                 *remember = TRUE;
3833
3834 #ifndef MODEST_TOOLKIT_GTK
3835         /* Maemo uses a different (awkward) button order,
3836          * It should probably just use gtk_alternative_dialog_button_order ().
3837          */
3838 #ifdef MODEST_TOOLKIT_HILDON2
3839         GtkWidget *dialog =
3840                 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3841                                              NULL,
3842                                              GTK_DIALOG_MODAL,
3843                                              _HL("wdgt_bd_done"),
3844                                              GTK_RESPONSE_ACCEPT,
3845                                              NULL);
3846         gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 
3847                                         HILDON_MARGIN_DOUBLE);
3848 #else
3849         GtkWidget *dialog =
3850                 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3851                                              NULL,
3852                                              GTK_DIALOG_MODAL,
3853                                              _("mcen_bd_dialog_ok"),
3854                                              GTK_RESPONSE_ACCEPT,
3855                                              _("mcen_bd_dialog_cancel"),
3856                                              GTK_RESPONSE_REJECT,
3857                                              NULL);
3858 #endif /* MODEST_TOOLKIT_HILDON2 */
3859 #else
3860         GtkWidget *dialog = 
3861                 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3862                                              NULL,
3863                                              GTK_DIALOG_MODAL,
3864                                              GTK_STOCK_CANCEL,
3865                                              GTK_RESPONSE_REJECT,
3866                                              GTK_STOCK_OK,
3867                                              GTK_RESPONSE_ACCEPT,
3868                                              NULL);
3869 #endif /* MODEST_TOOLKIT_GTK */
3870
3871         modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3872
3873         gchar *server_name = modest_account_mgr_get_server_account_hostname (
3874                 modest_runtime_get_account_mgr(), server_account_name);
3875         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3876                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3877                 if (cancel)
3878                         *cancel = TRUE;
3879                 gtk_widget_destroy (dialog);
3880                 return;
3881         }
3882
3883         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3884         GtkWidget *label = gtk_label_new (txt);
3885         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3886         g_free (txt);
3887         g_free (server_name);
3888         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3889                             FALSE, FALSE, 0);
3890         server_name = NULL;
3891
3892         /* username: */
3893         gchar *initial_username = modest_account_mgr_get_server_account_username (
3894                 modest_runtime_get_account_mgr(), server_account_name);
3895
3896 #ifdef MODEST_TOOLKIT_HILDON2
3897         GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3898         if (initial_username)
3899                 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3900 #else
3901         GtkWidget *entry_username = gtk_entry_new ();
3902         if (initial_username)
3903                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3904 #endif
3905         /* Dim this if a connection has ever succeeded with this username,
3906          * as per the UI spec: */
3907         /* const gboolean username_known =  */
3908         /*      modest_account_mgr_get_server_account_username_has_succeeded( */
3909         /*              modest_runtime_get_account_mgr(), server_account_name); */
3910         /* gtk_widget_set_sensitive (entry_username, !username_known); */
3911
3912         /* We drop the username sensitive code and disallow changing it here
3913          * as tinymail does not support really changing the username in the callback
3914          */
3915         gtk_widget_set_sensitive (entry_username, FALSE);
3916
3917 #ifndef MODEST_TOOLKIT_GTK
3918         /* Auto-capitalization is the default, so let's turn it off: */
3919         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3920
3921         /* Create a size group to be used by all captions.
3922          * Note that HildonCaption does not create a default size group if we do not specify one.
3923          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3924         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3925
3926 #ifdef MODEST_TOOLKIT_HILDON2
3927         GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL, 
3928                                                                   _("mail_fi_username"), FALSE,
3929                                                                   entry_username);
3930 #else
3931         GtkWidget *caption = hildon_caption_new (sizegroup, 
3932                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3933 #endif
3934         gtk_widget_show (entry_username);
3935         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
3936                 FALSE, FALSE, MODEST_MARGIN_HALF);
3937         gtk_widget_show (caption);
3938 #else
3939         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3940                             TRUE, FALSE, 0);
3941 #endif /* !MODEST_TOOLKIT_GTK */
3942
3943         /* password: */
3944 #ifdef MODEST_TOOLKIT_HILDON2
3945         GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3946 #else
3947         GtkWidget *entry_password = gtk_entry_new ();
3948 #endif
3949         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3950         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3951
3952 #ifndef MODEST_TOOLKIT_GTK
3953         /* Auto-capitalization is the default, so let's turn it off: */
3954         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3955                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3956
3957 #ifdef MODEST_TOOLKIT_HILDON2
3958         caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3959                                                        _("mail_fi_password"), FALSE,
3960                                                        entry_password);
3961 #else
3962         caption = hildon_caption_new (sizegroup,
3963                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3964 #endif
3965         gtk_widget_show (entry_password);
3966         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3967                 FALSE, FALSE, MODEST_MARGIN_HALF);
3968         gtk_widget_show (caption);
3969         g_object_unref (sizegroup);
3970 #else
3971         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3972                             TRUE, FALSE, 0);
3973 #endif /* !MODEST_TOOLKIT_GTK */
3974
3975         if (initial_username != NULL)
3976                 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3977
3978 /* This is not in the Maemo UI spec:
3979         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3980         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3981                             TRUE, FALSE, 0);
3982 */
3983
3984         fields = g_slice_new0 (PasswordDialogFields);
3985         fields->username = entry_username;
3986         fields->password = entry_password;
3987         fields->dialog = dialog;
3988
3989         g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3990         g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3991         password_dialog_check_field (NULL, fields);
3992
3993         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3994
3995         while (!completed) {
3996
3997                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3998                         if (username) {
3999 #ifdef MODEST_TOOLKIT_HILDON2
4000                                 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4001 #else
4002                                 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4003 #endif
4004
4005                                 /* Note that an empty field becomes the "" string */
4006                                 if (*username && strlen (*username) > 0) {
4007                                         modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(), 
4008                                                                                         server_account_name, 
4009                                                                                         *username);
4010                                         completed = TRUE;
4011
4012                                         const gboolean username_was_changed = 
4013                                                 (strcmp (*username, initial_username) != 0);
4014                                         if (username_was_changed) {
4015                                                 g_warning ("%s: tinymail does not yet support changing the "
4016                                                            "username in the get_password() callback.\n", __FUNCTION__);
4017                                         }
4018                                 } else {
4019                                         g_free (*username);
4020                                         *username = NULL;
4021                                         /* Show error */
4022                                         modest_platform_information_banner (GTK_WIDGET (dialog), NULL, 
4023                                                                             _("mcen_ib_username_pw_incorrect"));
4024                                         completed = FALSE;
4025                                 }
4026                         }
4027
4028                         if (password) {
4029 #ifdef MODEST_TOOLKIT_HILDON2
4030                                 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4031 #else
4032                                 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4033 #endif
4034
4035                                 /* We do not save the password in the configuration, 
4036                                  * because this function is only called for passwords that should 
4037                                  * not be remembered:
4038                                  modest_server_account_set_password (
4039                                  modest_runtime_get_account_mgr(), server_account_name, 
4040                                  *password);
4041                                  */
4042                         }
4043                         if (cancel)
4044                                 *cancel   = FALSE;
4045                 } else {
4046 #ifndef MODEST_TOOLKIT_HILDON2
4047                         /* Set parent to NULL or the banner will disappear with its parent dialog */
4048                         modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4049 #endif
4050                         completed = TRUE;
4051                         if (username)
4052                                 *username = NULL;
4053                         if (password)
4054                                 *password = NULL;
4055                         if (cancel)
4056                                 *cancel   = TRUE;
4057                 }
4058         }
4059
4060 /* This is not in the Maemo UI spec:
4061         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4062                 *remember = TRUE;
4063         else
4064                 *remember = FALSE;
4065 */
4066
4067         g_free (initial_username);
4068         gtk_widget_destroy (dialog);
4069         g_slice_free (PasswordDialogFields, fields);
4070         
4071         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4072 }
4073
4074 void
4075 modest_ui_actions_on_cut (GtkAction *action,
4076                           ModestWindow *window)
4077 {
4078         GtkWidget *focused_widget;
4079         GtkClipboard *clipboard;
4080
4081         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4082         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4083         if (GTK_IS_EDITABLE (focused_widget)) {
4084                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4085                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4086                 gtk_clipboard_store (clipboard);
4087         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4088                 GtkTextBuffer *buffer;
4089
4090                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4091                 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4092                         gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4093                         gtk_clipboard_set_can_store (clipboard, NULL, 0);
4094                         gtk_clipboard_store (clipboard);
4095                 }
4096         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4097                 TnyList *header_list = modest_header_view_get_selected_headers (
4098                                 MODEST_HEADER_VIEW (focused_widget));
4099                 gboolean continue_download = FALSE;
4100                 gint num_of_unc_msgs;
4101
4102                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4103
4104                 if (num_of_unc_msgs) {
4105                         TnyAccount *account = get_account_from_header_list (header_list);
4106                         if (account) {
4107                                 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4108                                 g_object_unref (account);
4109                         }
4110                 }
4111
4112                 if (num_of_unc_msgs == 0 || continue_download) {
4113 /*                      modest_platform_information_banner (
4114                                         NULL, NULL, _CS("mcen_ib_getting_items"));*/
4115                         modest_header_view_cut_selection (
4116                                         MODEST_HEADER_VIEW (focused_widget));
4117                 }
4118
4119                 g_object_unref (header_list);
4120         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4121                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4122         }
4123 }
4124
4125 void
4126 modest_ui_actions_on_copy (GtkAction *action,
4127                            ModestWindow *window)
4128 {
4129         GtkClipboard *clipboard;
4130         GtkWidget *focused_widget;
4131         gboolean copied = TRUE;
4132
4133         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4134         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4135
4136         if (GTK_IS_LABEL (focused_widget)) {
4137                 gchar *selection;
4138                 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4139                 gtk_clipboard_set_text (clipboard, selection, -1);
4140                 g_free (selection);
4141                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4142                 gtk_clipboard_store (clipboard);
4143         } else if (GTK_IS_EDITABLE (focused_widget)) {
4144                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4145                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4146                 gtk_clipboard_store (clipboard);
4147         } else if (GTK_IS_HTML (focused_widget)) {
4148                 const gchar *sel;
4149                 int len = -1;
4150                 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4151                 if ((sel == NULL) || (sel[0] == '\0')) {
4152                         copied = FALSE;
4153                 } else {
4154                         gtk_html_copy (GTK_HTML (focused_widget));
4155                         gtk_clipboard_set_can_store (clipboard, NULL, 0);
4156                         gtk_clipboard_store (clipboard);
4157                 }
4158         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4159                 GtkTextBuffer *buffer;
4160                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4161                 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4162                         gtk_text_buffer_copy_clipboard (buffer, clipboard);
4163                         gtk_clipboard_set_can_store (clipboard, NULL, 0);
4164                         gtk_clipboard_store (clipboard);
4165                 }
4166         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4167                 TnyList *header_list = modest_header_view_get_selected_headers (
4168                                 MODEST_HEADER_VIEW (focused_widget));
4169                 gboolean continue_download = FALSE;
4170                 gint num_of_unc_msgs;
4171
4172                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4173
4174                 if (num_of_unc_msgs) {
4175                         TnyAccount *account = get_account_from_header_list (header_list);
4176                         if (account) {
4177                                 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4178                                 g_object_unref (account);
4179                         }
4180                 }
4181
4182                 if (num_of_unc_msgs == 0 || continue_download) {
4183                         modest_platform_information_banner (
4184                                         NULL, NULL, _CS("mcen_ib_getting_items"));
4185                         modest_header_view_copy_selection (
4186                                         MODEST_HEADER_VIEW (focused_widget));
4187                 } else
4188                         copied = FALSE;
4189
4190                 g_object_unref (header_list);
4191
4192         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4193                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4194         }
4195
4196         /* Show information banner if there was a copy to clipboard */
4197         if(copied)
4198                 modest_platform_information_banner (
4199                                 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4200 }
4201
4202 void
4203 modest_ui_actions_on_undo (GtkAction *action,
4204                            ModestWindow *window)
4205 {
4206         ModestEmailClipboard *clipboard = NULL;
4207
4208         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4209                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4210         } else if (MODEST_IS_MAIN_WINDOW (window)) {
4211                 /* Clear clipboard source */
4212                 clipboard = modest_runtime_get_email_clipboard ();
4213                 modest_email_clipboard_clear (clipboard);               
4214         }
4215         else {
4216                 g_return_if_reached ();
4217         }
4218 }
4219
4220 void
4221 modest_ui_actions_on_redo (GtkAction *action,
4222                            ModestWindow *window)
4223 {
4224         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4225                 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4226         }
4227         else {
4228                 g_return_if_reached ();
4229         }
4230 }
4231
4232
4233 static void
4234 destroy_information_note (ModestMailOperation *mail_op, 
4235                           gpointer user_data)
4236 {
4237         /* destroy information note */
4238         gtk_widget_destroy (GTK_WIDGET(user_data));
4239 }
4240
4241 static void
4242 destroy_folder_information_note (ModestMailOperation *mail_op, 
4243                                  TnyFolder *new_folder,
4244                                  gpointer user_data)
4245 {
4246         /* destroy information note */
4247         gtk_widget_destroy (GTK_WIDGET(user_data));
4248 }
4249
4250
4251 static void
4252 paste_as_attachment_free (gpointer data)
4253 {
4254         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4255
4256         if (helper->banner) {
4257                 gtk_widget_destroy (helper->banner);
4258                 g_object_unref (helper->banner);
4259         }
4260         g_free (helper);
4261 }
4262
4263 static void
4264 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4265                             TnyHeader *header,
4266                             TnyMsg *msg,
4267                             gpointer userdata)
4268 {
4269         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4270         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4271
4272         if (msg == NULL)
4273                 return;
4274
4275         modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4276         
4277 }
4278
4279 void
4280 modest_ui_actions_on_paste (GtkAction *action,
4281                             ModestWindow *window)
4282 {
4283         GtkWidget *focused_widget = NULL;
4284         GtkWidget *inf_note = NULL;
4285         ModestMailOperation *mail_op = NULL;
4286
4287         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4288         if (GTK_IS_EDITABLE (focused_widget)) {
4289                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4290         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4291                 ModestEmailClipboard *e_clipboard = NULL;
4292                 e_clipboard = modest_runtime_get_email_clipboard ();
4293                 if (modest_email_clipboard_cleared (e_clipboard)) {
4294                         GtkTextBuffer *buffer;
4295                         GtkClipboard *clipboard;
4296
4297                         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4298                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4299                         gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4300                 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4301                         ModestMailOperation *mail_op;
4302                         TnyFolder *src_folder = NULL;
4303                         TnyList *data = NULL;
4304                         gboolean delete;
4305                         PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4306                         helper->window = MODEST_MSG_EDIT_WINDOW (window);
4307                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4308                                                                            _CS("ckct_nw_pasting"));
4309                         modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4310                         mail_op = modest_mail_operation_new (G_OBJECT (window));
4311                         if (helper->banner != NULL) {
4312                                 g_object_ref (G_OBJECT (helper->banner));
4313                                 gtk_widget_show (GTK_WIDGET (helper->banner));
4314                         }
4315
4316                         if (data != NULL) {
4317                                 modest_mail_operation_get_msgs_full (mail_op, 
4318                                                                      data,
4319                                                                      (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4320                                                                      helper,
4321                                                                      paste_as_attachment_free);
4322                         }
4323                         /* Free */
4324                         if (data) 
4325                                 g_object_unref (data);
4326                         if (src_folder) 
4327                                 g_object_unref (src_folder);
4328
4329                 }
4330         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4331                 ModestEmailClipboard *clipboard = NULL;
4332                 TnyFolder *src_folder = NULL;
4333                 TnyFolderStore *folder_store = NULL;
4334                 TnyList *data = NULL;           
4335                 gboolean delete = FALSE;
4336                 
4337                 /* Check clipboard source */
4338                 clipboard = modest_runtime_get_email_clipboard ();
4339                 if (modest_email_clipboard_cleared (clipboard)) 
4340                         return;
4341                 
4342                 /* Get elements to paste */
4343                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4344
4345                 /* Create a new mail operation */
4346                 mail_op = modest_mail_operation_new (G_OBJECT(window));
4347                 
4348                 /* Get destination folder */
4349                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4350
4351                 /* transfer messages  */
4352                 if (data != NULL) {
4353                         gint response = 0;
4354
4355                         /* Ask for user confirmation */
4356                         response = 
4357                                 modest_ui_actions_msgs_move_to_confirmation (window, 
4358                                                                              TNY_FOLDER (folder_store), 
4359                                                                              delete,
4360                                                                              data);
4361                         
4362                         if (response == GTK_RESPONSE_OK) {
4363                                 /* Launch notification */
4364                                 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
4365                                                                              _CS("ckct_nw_pasting"));
4366                                 if (inf_note != NULL)  {
4367                                         gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4368                                         gtk_widget_show (GTK_WIDGET(inf_note));
4369                                 }
4370
4371                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4372                                 modest_mail_operation_xfer_msgs (mail_op, 
4373                                                                  data,
4374                                                                  TNY_FOLDER (folder_store),
4375                                                                  delete,
4376                                                                  destroy_information_note,
4377                                                                  inf_note);                             
4378                         } else {
4379                                 g_object_unref (mail_op);
4380                         }
4381                         
4382                 } else if (src_folder != NULL) {                        
4383                         /* Launch notification */
4384                         inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
4385                                                                      _CS("ckct_nw_pasting"));
4386                         if (inf_note != NULL)  {
4387                                 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4388                                 gtk_widget_show (GTK_WIDGET(inf_note));
4389                         }
4390                         
4391                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4392                         modest_mail_operation_xfer_folder (mail_op, 
4393                                                            src_folder,
4394                                                            folder_store,
4395                                                            delete,
4396                                                            destroy_folder_information_note,
4397                                                            inf_note);
4398                 }
4399
4400                 /* Free */
4401                 if (data != NULL) 
4402                         g_object_unref (data);
4403                 if (src_folder != NULL) 
4404                         g_object_unref (src_folder);
4405                 if (folder_store != NULL) 
4406                         g_object_unref (folder_store);
4407         }
4408 }
4409
4410
4411 void
4412 modest_ui_actions_on_select_all (GtkAction *action,
4413                                  ModestWindow *window)
4414 {
4415         GtkWidget *focused_widget;
4416
4417         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4418         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4419                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4420         } else if (GTK_IS_LABEL (focused_widget)) {
4421                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4422         } else if (GTK_IS_EDITABLE (focused_widget)) {
4423                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4424         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4425                 GtkTextBuffer *buffer;
4426                 GtkTextIter start, end;
4427
4428                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4429                 gtk_text_buffer_get_start_iter (buffer, &start);
4430                 gtk_text_buffer_get_end_iter (buffer, &end);
4431                 gtk_text_buffer_select_range (buffer, &start, &end);
4432         } else if (GTK_IS_HTML (focused_widget)) {
4433                 gtk_html_select_all (GTK_HTML (focused_widget));
4434         } else if (MODEST_IS_MAIN_WINDOW (window)) {
4435                 GtkWidget *header_view = focused_widget;
4436                 GtkTreeSelection *selection = NULL;
4437                 
4438                 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4439                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4440                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4441                 }
4442                                 
4443                 /* Disable window dimming management */
4444                 modest_window_disable_dimming (MODEST_WINDOW(window));
4445                 
4446                 /* Select all messages */
4447                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4448                 gtk_tree_selection_select_all (selection);
4449
4450                 /* Set focuse on header view */
4451                 gtk_widget_grab_focus (header_view);
4452
4453                 /* Enable window dimming management */
4454                 modest_window_enable_dimming (MODEST_WINDOW(window));
4455                 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4456                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4457         }
4458
4459 }
4460
4461 void
4462 modest_ui_actions_on_mark_as_read (GtkAction *action,
4463                                    ModestWindow *window)
4464 {       
4465         g_return_if_fail (MODEST_IS_WINDOW(window));
4466                 
4467         /* Mark each header as read */
4468         do_headers_action (window, headers_action_mark_as_read, NULL);
4469 }
4470
4471 void
4472 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4473                                      ModestWindow *window)
4474 {       
4475         g_return_if_fail (MODEST_IS_WINDOW(window));
4476                 
4477         /* Mark each header as read */
4478         do_headers_action (window, headers_action_mark_as_unread, NULL);
4479 }
4480
4481 void
4482 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4483                                   GtkRadioAction *selected,
4484                                   ModestWindow *window)
4485 {
4486         gint value;
4487
4488         value = gtk_radio_action_get_current_value (selected);
4489         if (MODEST_IS_WINDOW (window)) {
4490                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4491         }
4492 }
4493
4494 void
4495 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4496                                                GtkRadioAction *selected,
4497                                                ModestWindow *window)
4498 {
4499         TnyHeaderFlags flags;
4500         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4501
4502         flags = gtk_radio_action_get_current_value (selected);
4503         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4504 }
4505
4506 void
4507 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4508                                                   GtkRadioAction *selected,
4509                                                   ModestWindow *window)
4510 {
4511         gint file_format;
4512
4513         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4514
4515         file_format = gtk_radio_action_get_current_value (selected);
4516         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4517 }
4518
4519
4520 void
4521 modest_ui_actions_on_zoom_plus (GtkAction *action,
4522                                 ModestWindow *window)
4523 {
4524         g_return_if_fail (MODEST_IS_WINDOW (window));
4525
4526         modest_window_zoom_plus (MODEST_WINDOW (window));
4527 }
4528
4529 void     
4530 modest_ui_actions_on_zoom_minus (GtkAction *action,
4531                                  ModestWindow *window)
4532 {
4533         g_return_if_fail (MODEST_IS_WINDOW (window));
4534
4535         modest_window_zoom_minus (MODEST_WINDOW (window));
4536 }
4537
4538 void     
4539 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
4540                                            ModestWindow *window)
4541 {
4542         ModestWindowMgr *mgr;
4543         gboolean fullscreen, active;
4544         g_return_if_fail (MODEST_IS_WINDOW (window));
4545
4546         mgr = modest_runtime_get_window_mgr ();
4547
4548         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4549         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4550
4551         if (active != fullscreen) {
4552                 modest_window_mgr_set_fullscreen_mode (mgr, active);
4553 #ifndef MODEST_TOOLKIT_HILDON2
4554                 gtk_window_present (GTK_WINDOW (window));
4555 #endif
4556         }
4557 }
4558
4559 void
4560 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4561                                         ModestWindow *window)
4562 {
4563         ModestWindowMgr *mgr;
4564         gboolean fullscreen;
4565
4566         g_return_if_fail (MODEST_IS_WINDOW (window));
4567
4568         mgr = modest_runtime_get_window_mgr ();
4569         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4570         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4571
4572 #ifndef MODEST_TOOLKIT_HILDON2
4573         gtk_window_present (GTK_WINDOW (window));
4574 #endif
4575 }
4576
4577 /* 
4578  * Used by modest_ui_actions_on_details to call do_headers_action 
4579  */
4580 static void
4581 headers_action_show_details (TnyHeader *header,
4582                              ModestWindow *window,
4583                              gpointer user_data)
4584
4585 {
4586         modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4587 }
4588
4589 /*
4590  * Show the header details in a ModestDetailsDialog widget
4591  */
4592 void
4593 modest_ui_actions_on_details (GtkAction *action,
4594                               ModestWindow *win)
4595 {
4596         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4597                 TnyMsg *msg;
4598                 TnyHeader *header;
4599
4600                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4601                 if (!msg)
4602                         return;
4603
4604                 header = tny_msg_get_header (msg);
4605                 if (header) {
4606                         headers_action_show_details (header, win, NULL);
4607                         g_object_unref (header);
4608                 }
4609                 g_object_unref (msg);
4610
4611         } else if (MODEST_IS_MAIN_WINDOW (win)) {
4612                 GtkWidget *folder_view, *header_view;
4613
4614                 /* Check which widget has the focus */
4615                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4616                                                                     MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4617                 if (gtk_widget_is_focus (folder_view)) {
4618                         TnyFolderStore *folder_store
4619                                 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4620                         if (!folder_store) {
4621                                 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4622                                 return; 
4623                         }
4624                         /* Show only when it's a folder */
4625                         /* This function should not be called for account items, 
4626                          * because we dim the menu item for them. */
4627                         if (TNY_IS_FOLDER (folder_store)) {
4628                                 modest_platform_run_folder_details_dialog (GTK_WINDOW (win), 
4629                                                                            TNY_FOLDER (folder_store));
4630                         }
4631
4632                         g_object_unref (folder_store);
4633
4634                 } else {
4635                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4636                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4637                         /* Show details of each header */
4638                         do_headers_action (win, headers_action_show_details, header_view);
4639                 }
4640 #ifdef MODEST_TOOLKIT_HILDON2
4641         } else if (MODEST_IS_HEADER_WINDOW (win)) {
4642                 TnyFolder *folder;
4643                 GtkWidget *header_view;
4644
4645                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4646                 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4647                 if (folder) {
4648                         modest_platform_run_folder_details_dialog (GTK_WINDOW (win), 
4649                                                                    folder);
4650                         g_object_unref (folder);
4651                 }
4652 #endif
4653         }
4654 }
4655
4656 void     
4657 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4658                                      ModestMsgEditWindow *window)
4659 {
4660         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4661
4662         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4663 }
4664
4665 void     
4666 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4667                                       ModestMsgEditWindow *window)
4668 {
4669         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4670
4671         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4672 }
4673
4674 void
4675 modest_ui_actions_toggle_folders_view (GtkAction *action, 
4676                                        ModestMainWindow *main_window)
4677 {
4678         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4679
4680         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4681                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4682         else
4683                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4684 }
4685
4686 void 
4687 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
4688                                      ModestWindow *window)
4689 {
4690         gboolean active, fullscreen = FALSE;
4691         ModestWindowMgr *mgr;
4692
4693         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4694
4695         /* Check if we want to toggle the toolbar view in fullscreen
4696            or normal mode */
4697         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
4698                      "ViewShowToolbarFullScreen")) {
4699                 fullscreen = TRUE;
4700         }
4701
4702         /* Toggle toolbar */
4703         mgr = modest_runtime_get_window_mgr ();
4704         modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4705 }
4706
4707 void     
4708 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4709                                            ModestMsgEditWindow *window)
4710 {
4711         modest_msg_edit_window_select_font (window);
4712 }
4713
4714
4715 void
4716 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4717                                                   const gchar *display_name,
4718                                                   GtkWindow *window)
4719 {
4720         /* don't update the display name if it was already set;
4721          * updating the display name apparently is expensive */
4722         const gchar* old_name = gtk_window_get_title (window);
4723
4724         if (display_name == NULL)
4725                 display_name = " ";
4726
4727         if (old_name && display_name && strcmp (old_name, display_name) == 0)
4728                 return; /* don't do anything */
4729
4730         /* This is usually used to change the title of the main window, which
4731          * is the one that holds the folder view. Note that this change can
4732          * happen even when the widget doesn't have the focus. */
4733         gtk_window_set_title (window, display_name);
4734
4735 }
4736
4737 void
4738 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4739 {
4740         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4741         modest_msg_edit_window_select_contacts (window);
4742 }
4743
4744 void
4745 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4746 {
4747         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4748         modest_msg_edit_window_check_names (window, FALSE);
4749 }
4750
4751 #ifndef MODEST_TOOLKIT_HILDON2
4752 /*
4753  * This function is used to track changes in the selection of the
4754  * folder view that is inside the "move to" dialog to enable/disable
4755  * the OK button because we do not want the user to select a disallowed
4756  * destination for a folder.
4757  * The user also not desired to be able to use NEW button on items where
4758  * folder creation is not possibel.
4759  */
4760 static void
4761 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4762                                             TnyFolderStore *folder_store,
4763                                             gboolean selected,
4764                                             gpointer user_data)
4765 {
4766         GtkWidget *dialog = NULL;
4767         gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4768         gboolean moving_folder = FALSE;
4769         gboolean is_local_account = TRUE;
4770         GtkWidget *folder_view = NULL;
4771         ModestTnyFolderRules rules;
4772
4773         g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4774
4775         if (!selected)
4776                 return;
4777
4778         dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4779         if (!dialog)
4780                 return;
4781
4782         /* check if folder_store is an remote account */
4783         if (TNY_IS_ACCOUNT (folder_store)) {
4784                 TnyAccount *local_account = NULL;
4785                 TnyAccount *mmc_account = NULL;
4786                 ModestTnyAccountStore *account_store = NULL;
4787
4788                 account_store = modest_runtime_get_account_store ();
4789                 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4790                 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4791
4792                 if ((gpointer) local_account != (gpointer) folder_store &&
4793                     (gpointer) mmc_account != (gpointer) folder_store) {
4794                         ModestProtocolType proto;
4795                         proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4796                         if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4797                                 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4798                         }
4799                         is_local_account = FALSE;
4800                         /* New button should be dimmed on remote
4801                            POP account root */
4802                         new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4803                                                                                          proto,
4804                                                                                          MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4805                 }
4806                 g_object_unref (local_account);
4807
4808                 /* It could not exist */
4809                 if (mmc_account)
4810                         g_object_unref (mmc_account);
4811         }
4812
4813         /* Check the target folder rules */
4814         if (TNY_IS_FOLDER (folder_store)) {
4815                 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4816                 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4817                         ok_sensitive = FALSE;
4818                         new_sensitive = FALSE;
4819                         goto end;
4820                 }
4821         }
4822
4823         /* Check if we're moving a folder */
4824         if (MODEST_IS_MAIN_WINDOW (user_data)) {
4825                 /* Get the widgets */
4826                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4827                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4828                 if (gtk_widget_is_focus (folder_view))
4829                         moving_folder = TRUE;
4830         }
4831
4832         if (moving_folder) {
4833                 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4834
4835                 /* Get the folder to move */
4836                 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4837
4838                 /* Check that we're not moving to the same folder */
4839                 if (TNY_IS_FOLDER (moved_folder)) {
4840                         parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4841                         if (parent == folder_store)
4842                                 ok_sensitive = FALSE;
4843                         g_object_unref (parent);
4844                 }
4845
4846                 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4847                         /* Do not allow to move to an account unless it's the
4848                            local folders account */
4849                         if (!is_local_account)
4850                                 ok_sensitive = FALSE;
4851                 }
4852
4853                 if (ok_sensitive && (moved_folder == folder_store)) {
4854                         /* Do not allow to move to itself */
4855                         ok_sensitive = FALSE;
4856                 }
4857                 g_object_unref (moved_folder);
4858         } else {
4859                 TnyFolder *src_folder = NULL;
4860
4861                 /* Moving a message */
4862                 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4863
4864                         TnyHeader *header = NULL;
4865                         header = modest_msg_view_window_get_header
4866                                 (MODEST_MSG_VIEW_WINDOW (user_data));
4867                         if (!TNY_IS_HEADER(header))
4868                                 g_warning ("%s: could not get source header", __FUNCTION__);
4869                         else
4870                                 src_folder = tny_header_get_folder (header);
4871
4872                         if (header)
4873                                 g_object_unref (header);
4874                 } else {
4875                         src_folder = 
4876                                 TNY_FOLDER (modest_folder_view_get_selected
4877                                             (MODEST_FOLDER_VIEW (folder_view)));
4878                 }
4879
4880                 if (TNY_IS_FOLDER(src_folder)) {
4881                         /* Do not allow to move the msg to the same folder */
4882                         /* Do not allow to move the msg to an account */
4883                         if ((gpointer) src_folder == (gpointer) folder_store ||
4884                             TNY_IS_ACCOUNT (folder_store))
4885                                 ok_sensitive = FALSE;
4886                         g_object_unref (src_folder);
4887                 } else
4888                         g_warning ("%s: could not get source folder", __FUNCTION__);
4889         }
4890
4891  end:
4892         /* Set sensitivity of the OK and NEW button */
4893         gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4894         gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4895 }
4896 #endif
4897
4898 static void
4899 on_move_to_dialog_response (GtkDialog *dialog,
4900                             gint       response,
4901                             gpointer   user_data)
4902 {
4903         GtkWidget *parent_win;
4904         MoveToInfo *helper = NULL;
4905         ModestFolderView *folder_view;
4906
4907         helper = (MoveToInfo *) user_data;
4908
4909         parent_win = (GtkWidget *) helper->win;
4910         folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4911                                                              MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4912
4913         switch (response) {
4914                 TnyFolderStore *dst_folder;
4915
4916         case MODEST_GTK_RESPONSE_NEW_FOLDER:
4917                 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view));
4918                 return;
4919         case GTK_RESPONSE_NONE:
4920         case GTK_RESPONSE_CANCEL:
4921         case GTK_RESPONSE_DELETE_EVENT:
4922                 break;
4923         case GTK_RESPONSE_OK:
4924                 dst_folder = modest_folder_view_get_selected (folder_view);
4925
4926                 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4927                         /* Clean list to move used for filtering */
4928                         modest_folder_view_set_list_to_move (folder_view, NULL);
4929
4930                         modest_ui_actions_on_main_window_move_to (NULL,
4931                                                                   GTK_WIDGET (folder_view),
4932                                                                   dst_folder,
4933                                                                   MODEST_MAIN_WINDOW (parent_win));
4934 #ifdef MODEST_TOOLKIT_HILDON2
4935                 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4936                         /* Clean list to move used for filtering */
4937                         modest_folder_view_set_list_to_move (folder_view, NULL);
4938
4939                         modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4940                                                                     dst_folder,
4941                                                                     helper->list,
4942                                                                     GTK_WINDOW (parent_win));
4943 #endif
4944                 } else {
4945                         /* if the user selected a root folder
4946                            (account) then do not perform any action */
4947                         if (TNY_IS_ACCOUNT (dst_folder)) {
4948                                 g_signal_stop_emission_by_name (dialog, "response");
4949                                 return;
4950                         }
4951
4952                         /* Clean list to move used for filtering */
4953                         modest_folder_view_set_list_to_move (folder_view, NULL);
4954
4955                         /* Moving from headers window in edit mode */
4956                         modest_ui_actions_on_window_move_to (NULL, helper->list,
4957                                                              dst_folder, 
4958                                                              MODEST_WINDOW (parent_win));
4959                 }
4960
4961                 if (dst_folder)
4962                         g_object_unref (dst_folder);
4963
4964                 break;
4965         default:
4966                 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4967         }
4968
4969         /* Free the helper and exit */
4970         if (helper->list)
4971                 g_object_unref (helper->list);
4972         g_slice_free (MoveToInfo, helper);
4973         gtk_widget_destroy (GTK_WIDGET (dialog));
4974 }
4975
4976 static GtkWidget*
4977 create_move_to_dialog (GtkWindow *win,
4978                        GtkWidget *folder_view,
4979                        TnyList *list_to_move)
4980 {
4981         GtkWidget *dialog, *tree_view = NULL;
4982
4983         dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4984
4985 #ifndef MODEST_TOOLKIT_HILDON2
4986         /* Track changes in the selection to
4987          * disable the OK button whenever "Move to" is not possible
4988          * disbale NEW button whenever New is not possible */
4989         g_signal_connect (tree_view,
4990                           "folder_selection_changed",
4991                           G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4992                           win);
4993 #endif
4994
4995         /* It could happen that we're trying to move a message from a
4996            window (msg window for example) after the main window was
4997            closed, so we can not just get the model of the folder
4998            view */
4999         if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5000                 const gchar *visible_id = NULL;
5001
5002                 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5003                                               MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5004                 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view), 
5005                                                MODEST_FOLDER_VIEW(tree_view));
5006
5007                 visible_id = 
5008                         modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5009
5010                 /* Show the same account than the one that is shown in the main window */
5011                 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5012                                                                              visible_id);
5013         } else {
5014                 const gchar *active_account_name = NULL;
5015                 ModestAccountMgr *mgr = NULL;
5016                 ModestAccountSettings *settings = NULL;
5017                 ModestServerAccountSettings *store_settings = NULL;
5018
5019                 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5020                                               MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5021                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5022                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5023
5024                 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5025                 mgr = modest_runtime_get_account_mgr ();
5026                 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5027
5028                 if (settings) {
5029                         const gchar *store_account_name;
5030                         store_settings = modest_account_settings_get_store_settings (settings);
5031                         store_account_name = modest_server_account_settings_get_account_name (store_settings);
5032
5033                         modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5034                                                                                      store_account_name);
5035                         g_object_unref (store_settings);
5036                         g_object_unref (settings);
5037                 }
5038         }
5039
5040         /* we keep a pointer to the embedded folder view, so we can
5041          *   retrieve it with get_folder_view_from_move_to_dialog (see
5042          *   above) later (needed for focus handling)
5043          */
5044         g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5045
5046         /* Hide special folders */
5047         modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5048         if (list_to_move)
5049                 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5050 #ifndef MODEST_TOOLKIT_HILDON2
5051         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5052 #endif
5053
5054         gtk_widget_show (GTK_WIDGET (tree_view));
5055
5056         return dialog;
5057 }
5058
5059 /*
5060  * Shows a confirmation dialog to the user when we're moving messages
5061  * from a remote server to the local storage. Returns the dialog
5062  * response. If it's other kind of movement then it always returns
5063  * GTK_RESPONSE_OK
5064  *
5065  * This one is used by the next functions:
5066  *      modest_ui_actions_on_paste                      - commented out
5067  *      drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5068  */
5069 gint
5070 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5071                                              TnyFolder *dest_folder,
5072                                              gboolean delete,
5073                                              TnyList *headers)
5074 {
5075         gint response = GTK_RESPONSE_OK;
5076         TnyAccount *account = NULL;
5077         TnyFolder *src_folder = NULL;
5078         TnyIterator *iter = NULL;
5079         TnyHeader *header = NULL;
5080
5081         /* return with OK if the destination is a remote folder */
5082         if (modest_tny_folder_is_remote_folder (dest_folder))
5083                 return GTK_RESPONSE_OK;
5084
5085         /* Get source folder */
5086         iter = tny_list_create_iterator (headers);
5087         header = TNY_HEADER (tny_iterator_get_current (iter));
5088         if (header) {
5089                 src_folder = tny_header_get_folder (header);
5090                 g_object_unref (header);
5091         }
5092         g_object_unref (iter);
5093
5094         /* if no src_folder, message may be an attahcment */
5095         if (src_folder == NULL) 
5096                 return GTK_RESPONSE_CANCEL;
5097
5098         /* If the source is a local or MMC folder */
5099         if (!modest_tny_folder_is_remote_folder (src_folder)) {
5100                 g_object_unref (src_folder);
5101                 return GTK_RESPONSE_OK;
5102         }
5103
5104         /* Get the account */
5105         account = tny_folder_get_account (src_folder);
5106
5107         /* now if offline we ask the user */
5108         if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5109                 response = GTK_RESPONSE_OK;
5110         else
5111                 response = GTK_RESPONSE_CANCEL;
5112
5113         /* Frees */
5114         g_object_unref (src_folder);
5115         g_object_unref (account);
5116
5117         return response;
5118 }
5119
5120 static void
5121 move_to_helper_destroyer (gpointer user_data)
5122 {
5123         MoveToHelper *helper = (MoveToHelper *) user_data;
5124
5125         /* Close the "Pasting" information banner */
5126         if (helper->banner) {
5127                 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5128                 g_object_unref (helper->banner);
5129         }
5130         if (gtk_tree_row_reference_valid (helper->reference)) {
5131                 gtk_tree_row_reference_free (helper->reference);
5132                 helper->reference = NULL;
5133         }
5134         g_free (helper);
5135 }
5136
5137 static void
5138 move_to_cb (ModestMailOperation *mail_op, 
5139             gpointer user_data)
5140 {
5141         MoveToHelper *helper = (MoveToHelper *) user_data;
5142         GObject *object = modest_mail_operation_get_source (mail_op);
5143
5144         /* Note that the operation could have failed, in that case do
5145            nothing */
5146         if (modest_mail_operation_get_status (mail_op) != 
5147             MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5148                 goto frees;
5149
5150         if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5151                 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5152
5153                 if (!modest_msg_view_window_select_next_message (self) &&
5154                     !modest_msg_view_window_select_previous_message (self)) {
5155                         /* No more messages to view, so close this window */
5156                         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5157                 }
5158         } else if (MODEST_IS_MAIN_WINDOW (object) && 
5159                    gtk_tree_row_reference_valid (helper->reference)) {
5160                 GtkWidget *header_view;
5161                 GtkTreePath *path;
5162                 GtkTreeSelection *sel;
5163
5164                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5165                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5166                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5167                 path = gtk_tree_row_reference_get_path (helper->reference);
5168                 /* We need to unselect the previous one
5169                    because we could be copying instead of
5170                    moving */
5171                 gtk_tree_selection_unselect_all (sel);
5172                 gtk_tree_selection_select_path (sel, path);
5173                 gtk_tree_path_free (path);
5174         }
5175         g_object_unref (object);
5176
5177  frees:
5178         /* Destroy the helper */
5179         move_to_helper_destroyer (helper);
5180 }
5181
5182 static void
5183 folder_move_to_cb (ModestMailOperation *mail_op, 
5184                    TnyFolder *new_folder,
5185                    gpointer user_data)
5186 {
5187         GtkWidget *folder_view;
5188         GObject *object;
5189
5190         object = modest_mail_operation_get_source (mail_op);
5191         if (MODEST_IS_MAIN_WINDOW (object)) {
5192                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5193                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5194                 g_object_ref (folder_view);
5195                 g_object_unref (object);
5196                 move_to_cb (mail_op, user_data);
5197                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5198                 g_object_unref (folder_view);
5199         } else {
5200                 move_to_cb (mail_op, user_data);
5201         }
5202 }
5203
5204 static void
5205 msgs_move_to_cb (ModestMailOperation *mail_op, 
5206                  gpointer user_data)
5207 {
5208         move_to_cb (mail_op, user_data);
5209 }
5210
5211 void
5212 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
5213                                              gpointer user_data)
5214 {
5215         GObject *win = NULL;
5216
5217 #ifndef MODEST_TOOLKIT_HILDON2
5218         ModestWindow *main_window = NULL;
5219
5220         /* Disable next automatic folder selection */
5221         main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5222                                                          FALSE); /* don't create */
5223         if (main_window) {
5224                 GtkWidget *folder_view = NULL;
5225
5226                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5227                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW); 
5228                 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5229
5230                 if (user_data && TNY_IS_FOLDER (user_data)) {
5231                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), 
5232                                                           TNY_FOLDER (user_data), FALSE);
5233                 }
5234         }
5235 #endif
5236         /* Show notification dialog only if the main window exists */
5237         win = modest_mail_operation_get_source (mail_op);
5238         modest_platform_run_information_dialog ((GtkWindow *) win, 
5239                                                 _("mail_in_ui_folder_move_target_error"), 
5240                                                 FALSE);
5241         if (win)
5242                 g_object_unref (win);
5243 }
5244
5245 static void
5246 open_msg_for_purge_cb (ModestMailOperation *mail_op, 
5247                        TnyHeader *header, 
5248                        gboolean canceled,
5249                        TnyMsg *msg, 
5250                        GError *err,
5251                        gpointer user_data)
5252 {
5253         TnyList *parts;
5254         TnyIterator *iter;
5255         gint pending_purges = 0;
5256         gboolean some_purged = FALSE;
5257         ModestWindow *win = MODEST_WINDOW (user_data);
5258         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5259
5260         /* If there was any error */
5261         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5262                 modest_window_mgr_unregister_header (mgr, header);
5263                 return;
5264         }
5265
5266         /* Once the message has been retrieved for purging, we check if
5267          * it's all ok for purging */
5268
5269         parts = tny_simple_list_new ();
5270         tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5271         iter = tny_list_create_iterator (parts);
5272
5273         while (!tny_iterator_is_done (iter)) {
5274                 TnyMimePart *part;
5275                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5276                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5277                         if (tny_mime_part_is_purged (part))
5278                                 some_purged = TRUE;
5279                         else
5280                                 pending_purges++;
5281                 }
5282
5283                 if (part)
5284                         g_object_unref (part);
5285
5286                 tny_iterator_next (iter);
5287         }
5288         g_object_unref (iter);
5289         
5290
5291         if (pending_purges>0) {
5292                 gint response;
5293                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5294
5295                 if (response == GTK_RESPONSE_OK) {
5296                         GtkWidget *info;
5297                         info =
5298                                 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5299                         iter = tny_list_create_iterator (parts);
5300                         while (!tny_iterator_is_done (iter)) {
5301                                 TnyMimePart *part;
5302                                 
5303                                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5304                                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5305                                         tny_mime_part_set_purged (part);
5306
5307                                 if (part)
5308                                         g_object_unref (part);
5309
5310                                 tny_iterator_next (iter);
5311                         }
5312                         g_object_unref (iter);
5313                         
5314                         tny_msg_rewrite_cache (msg);
5315
5316                         gtk_widget_destroy (info);
5317                 }
5318         }
5319
5320         modest_window_mgr_unregister_header (mgr, header);
5321
5322         g_object_unref (parts);
5323 }
5324
5325 static void
5326 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5327                                                      ModestMainWindow *win)
5328 {
5329         GtkWidget *header_view;
5330         TnyList *header_list;
5331         TnyHeader *header;
5332         TnyHeaderFlags flags;
5333         ModestWindow *msg_view_window =  NULL;
5334         gboolean found;
5335
5336         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5337
5338         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5339                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5340
5341         header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5342         if (!header_list) {
5343                 g_warning ("%s: no header selected", __FUNCTION__);
5344                 return;
5345         }
5346         
5347         if (tny_list_get_length (header_list) == 1) {
5348                 TnyIterator *iter = tny_list_create_iterator (header_list);
5349                 header = TNY_HEADER (tny_iterator_get_current (iter));
5350                 g_object_unref (iter);
5351         } else
5352                 return;
5353         
5354         if (!header || !TNY_IS_HEADER(header)) {
5355                 g_warning ("%s: header is not valid", __FUNCTION__);
5356                 return;
5357         }
5358         
5359         found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5360                                                           header, &msg_view_window);
5361         flags = tny_header_get_flags (header);
5362         if (!(flags & TNY_HEADER_FLAG_CACHED))
5363                 return;
5364         if (found) {
5365                 if (msg_view_window != NULL) 
5366                         modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5367                 else {
5368                         /* do nothing; uid was registered before, so window is probably on it's way */
5369                         g_warning ("debug: header %p has already been registered", header);
5370                 }
5371         } else {
5372                 ModestMailOperation *mail_op = NULL;
5373                 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5374                 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5375                                                                          modest_ui_actions_disk_operations_error_handler,
5376                                                                          NULL, NULL);
5377                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5378                 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5379                 
5380                 g_object_unref (mail_op);
5381         }
5382         if (header)
5383                 g_object_unref (header);
5384         if (header_list)
5385                 g_object_unref (header_list);
5386 }
5387
5388 /*
5389  * Checks if we need a connection to do the transfer and if the user
5390  * wants to connect to complete it
5391  */
5392 static void
5393 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5394                                        TnyFolderStore *src_folder,
5395                                        TnyList *headers,
5396                                        TnyFolder *dst_folder,
5397                                        gboolean delete_originals,
5398                                        gboolean *need_connection,
5399                                        gboolean *do_xfer)
5400 {
5401         TnyAccount *src_account;
5402         gint uncached_msgs = 0;
5403
5404         /* We don't need any further check if
5405          *
5406          * 1- the source folder is local OR
5407          * 2- the device is already online
5408          */
5409         if (!modest_tny_folder_store_is_remote (src_folder) ||
5410             tny_device_is_online (modest_runtime_get_device())) {
5411                 *need_connection = FALSE;
5412                 *do_xfer = TRUE;
5413                 return;
5414         }
5415
5416         /* We must ask for a connection when
5417          *
5418          *   - the message(s) is not already cached   OR 
5419          *   - the message(s) is cached but the leave_on_server setting
5420          * is FALSE (because we need to sync the source folder to
5421          * delete the message from the server (for IMAP we could do it
5422          * offline, it'll take place the next time we get a
5423          * connection)
5424          */
5425         uncached_msgs = header_list_count_uncached_msgs (headers);
5426         src_account = get_account_from_folder_store (src_folder);
5427         if (uncached_msgs > 0) {
5428                 guint num_headers;
5429                 const gchar *msg;
5430
5431                 *need_connection = TRUE;
5432                 num_headers = tny_list_get_length (headers);
5433                 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5434
5435                 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5436                     GTK_RESPONSE_CANCEL) {
5437                         *do_xfer = FALSE;
5438                 } else {
5439                         *do_xfer = TRUE;
5440                 }
5441         } else {
5442                 /* The transfer is possible and the user wants to */
5443                 *do_xfer = TRUE;
5444
5445                 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5446                         const gchar *account_name;
5447                         gboolean leave_on_server;
5448
5449                         account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5450                         leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5451                                                                                   account_name);
5452
5453                         if (leave_on_server == TRUE) {
5454                                 *need_connection = FALSE;
5455                         } else {
5456                                 *need_connection = TRUE;
5457                         }
5458                 } else {
5459                         *need_connection = FALSE;
5460                 }
5461         }
5462
5463         /* Frees */
5464         g_object_unref (src_account);
5465 }
5466
5467 static void
5468 xfer_messages_error_handler (ModestMailOperation *mail_op, 
5469                              gpointer user_data)
5470 {
5471         GObject *win;
5472         const GError *error;
5473
5474         win = modest_mail_operation_get_source (mail_op);
5475         error = modest_mail_operation_get_error (mail_op);
5476
5477         if (error && is_memory_full_error ((GError *) error))
5478                 modest_platform_information_banner ((GtkWidget *) win,
5479                                                     NULL, _KR("cerm_device_memory_full"));
5480         else
5481                 modest_platform_run_information_dialog ((GtkWindow *) win, 
5482                                                         _("mail_in_ui_folder_move_target_error"), 
5483                                                         FALSE);
5484         if (win)
5485                 g_object_unref (win);
5486 }
5487
5488 typedef struct {
5489         TnyFolderStore *dst_folder;
5490         TnyList *headers;
5491 } XferMsgsHelper;
5492
5493 /**
5494  * Utility function that transfer messages from both the main window
5495  * and the msg view window when using the "Move to" dialog
5496  */
5497 static void
5498 xfer_messages_performer  (gboolean canceled, 
5499                           GError *err,
5500                           GtkWindow *parent_window, 
5501                           TnyAccount *account, 
5502                           gpointer user_data)
5503 {
5504         ModestWindow *win = MODEST_WINDOW (parent_window);
5505         TnyAccount *dst_account = NULL;
5506         gboolean dst_forbids_message_add = FALSE;
5507         XferMsgsHelper *helper;
5508         MoveToHelper *movehelper;
5509         ModestMailOperation *mail_op;
5510
5511         helper = (XferMsgsHelper *) user_data;
5512
5513         if (canceled || err) {
5514                 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5515                         /* Show the proper error message */
5516                         modest_ui_actions_on_account_connection_error (parent_window, account);
5517                 }
5518                 goto end;
5519         }
5520
5521         dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5522
5523         /* tinymail will return NULL for local folders it seems */
5524         dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5525                                                                                   modest_tny_account_get_protocol_type (dst_account),
5526                                                                                   MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5527         g_object_unref (dst_account);
5528
5529         if (dst_forbids_message_add) {
5530                 modest_platform_information_banner (GTK_WIDGET (win),
5531                                                     NULL,
5532                                                     ngettext("mail_in_ui_folder_move_target_error",
5533                                                              "mail_in_ui_folder_move_targets_error",
5534                                                              tny_list_get_length (helper->headers)));
5535                 goto end;
5536         }
5537
5538         movehelper = g_new0 (MoveToHelper, 1);
5539
5540 #ifndef MODEST_TOOLKIT_HILDON2
5541         movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5542                                                                _CS("ckct_nw_pasting"));
5543         if (movehelper->banner != NULL)  {
5544                 g_object_ref (movehelper->banner);
5545                 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5546         }
5547 #endif
5548
5549         if (MODEST_IS_MAIN_WINDOW (win)) {
5550                 GtkWidget *header_view = 
5551                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5552                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5553                 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5554         }
5555
5556         /* Perform the mail operation */
5557         mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5558                                                                  xfer_messages_error_handler,
5559                                                                  movehelper, NULL);
5560         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
5561                                          mail_op);
5562
5563         modest_mail_operation_xfer_msgs (mail_op, 
5564                                          helper->headers,
5565                                          TNY_FOLDER (helper->dst_folder),
5566                                          TRUE,
5567                                          msgs_move_to_cb,
5568                                          movehelper);
5569
5570         g_object_unref (G_OBJECT (mail_op));
5571  end:
5572         g_object_unref (helper->dst_folder);
5573         g_object_unref (helper->headers);
5574         g_slice_free (XferMsgsHelper, helper);
5575 }
5576
5577 typedef struct {
5578         TnyFolder *src_folder;
5579         TnyFolderStore *dst_folder;
5580         gboolean delete_original;
5581         GtkWidget *folder_view;
5582 } MoveFolderInfo;
5583
5584 static void
5585 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window, 
5586                 TnyAccount *account, gpointer user_data)
5587 {
5588         MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5589         GtkTreeSelection *sel;
5590         ModestMailOperation *mail_op = NULL;
5591
5592         if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5593                 g_object_unref (G_OBJECT (info->src_folder));
5594                 g_object_unref (G_OBJECT (info->dst_folder));
5595                 g_free (info);
5596                 return;
5597         }
5598
5599         MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5600 #ifndef MODEST_TOOLKIT_HILDON2
5601         helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5602                         _CS("ckct_nw_pasting"));
5603         if (helper->banner != NULL)  {
5604                 g_object_ref (helper->banner);
5605                 gtk_widget_show (GTK_WIDGET(helper->banner));
5606         }
5607 #endif
5608         /* Clean folder on header view before moving it */
5609         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5610         gtk_tree_selection_unselect_all (sel);
5611
5612         /* Let gtk events run. We need that the folder
5613            view frees its reference to the source
5614            folder *before* issuing the mail operation
5615            so we need the signal handler of selection
5616            changed to happen before the mail
5617            operation 
5618         while (gtk_events_pending ())
5619                 gtk_main_iteration ();   */
5620
5621         mail_op =
5622                 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5623                                 modest_ui_actions_move_folder_error_handler,
5624                                 info->src_folder, NULL);
5625         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5626                         mail_op);
5627
5628         /* Select *after* the changes */
5629         /* TODO: this function hangs UI after transfer */ 
5630         /*                      modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5631         /*                                                        TNY_FOLDER (src_folder), TRUE); */
5632
5633         if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5634                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5635                                                   TNY_FOLDER (info->dst_folder), TRUE);
5636         }
5637         modest_mail_operation_xfer_folder (mail_op,
5638                         TNY_FOLDER (info->src_folder),
5639                         info->dst_folder,
5640                         info->delete_original, 
5641                         folder_move_to_cb, 
5642                         helper);
5643         g_object_unref (G_OBJECT (info->src_folder));
5644
5645         /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {        */
5646         /* } */
5647         
5648         /* Unref mail operation */
5649         g_object_unref (G_OBJECT (mail_op));
5650         g_object_unref (G_OBJECT (info->dst_folder));
5651         g_free (user_data);
5652 }
5653
5654 static TnyAccount *
5655 get_account_from_folder_store (TnyFolderStore *folder_store) 
5656 {
5657         if (TNY_IS_ACCOUNT (folder_store))
5658                 return g_object_ref (folder_store);
5659         else
5660                 return tny_folder_get_account (TNY_FOLDER (folder_store));
5661 }
5662
5663 /*
5664  * UI handler for the "Move to" action when invoked from the
5665  * ModestMainWindow
5666  */
5667 static void 
5668 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
5669                                           GtkWidget *folder_view,
5670                                           TnyFolderStore *dst_folder,
5671                                           ModestMainWindow *win)
5672 {
5673         ModestHeaderView *header_view = NULL;
5674         TnyFolderStore *src_folder = NULL;
5675
5676         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5677
5678         /* Get the source folder */
5679         src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5680
5681         /* Get header view */
5682         header_view = (ModestHeaderView *)
5683                 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5684
5685         /* Get folder or messages to transfer */
5686         if (gtk_widget_is_focus (folder_view)) {
5687                 gboolean do_xfer = TRUE;
5688
5689                 /* Allow only to transfer folders to the local root folder */
5690                 if (TNY_IS_ACCOUNT (dst_folder) && 
5691                     !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5692                     !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5693                         do_xfer = FALSE;
5694                 } else if (!TNY_IS_FOLDER (src_folder)) {
5695                         g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5696                         do_xfer = FALSE;
5697                 }
5698
5699                 if (do_xfer) {
5700                         MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5701                         DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5702
5703                         info->src_folder = g_object_ref (src_folder);
5704                         info->dst_folder = g_object_ref (dst_folder);
5705                         info->delete_original = TRUE;
5706                         info->folder_view = folder_view;
5707
5708                         connect_info->callback = on_move_folder_cb;
5709                         connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5710                         connect_info->data = info;
5711
5712                         modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5713                                                                    TNY_FOLDER_STORE (src_folder), 
5714                                                                    connect_info);
5715                 }
5716         } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5717                 TnyList *headers;
5718
5719                 headers = modest_header_view_get_selected_headers(header_view);
5720
5721                 /* Transfer the messages */
5722                 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder), 
5723                                                             headers, TNY_FOLDER (dst_folder));
5724
5725                 g_object_unref (headers);
5726         }
5727
5728         /* Frees */
5729         g_object_unref (src_folder);
5730 }
5731
5732 #ifdef MODEST_TOOLKIT_HILDON2
5733 /*
5734  * UI handler for the "Move to" action when invoked from the
5735  * ModestFolderWindow
5736  */
5737 static void 
5738 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5739                                             TnyFolderStore *dst_folder,
5740                                             TnyList *selection,
5741                                             GtkWindow *win)
5742 {
5743         TnyFolderStore *src_folder = NULL;
5744         TnyIterator *iterator;
5745
5746         if (tny_list_get_length (selection) != 1)
5747                 return;
5748
5749         iterator = tny_list_create_iterator (selection);
5750         src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5751         g_object_unref (iterator);
5752
5753
5754         gboolean do_xfer = TRUE;
5755
5756         /* Allow only to transfer folders to the local root folder */
5757         if (TNY_IS_ACCOUNT (dst_folder) && 
5758             !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5759             !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5760                 do_xfer = FALSE;
5761                 /* Show an error */
5762                 modest_platform_run_information_dialog (win,
5763                                                         _("mail_in_ui_folder_move_target_error"),
5764                                                         FALSE);
5765         } else if (!TNY_IS_FOLDER (src_folder)) {
5766                 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5767                 do_xfer = FALSE;
5768         }
5769
5770         if (do_xfer) {
5771                 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5772                 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5773
5774                 info->src_folder = g_object_ref (src_folder);
5775                 info->dst_folder = g_object_ref (dst_folder);
5776                 info->delete_original = TRUE;
5777                 info->folder_view = folder_view;
5778
5779                 connect_info->callback = on_move_folder_cb;
5780                 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5781                 connect_info->data = info;
5782
5783                 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5784                                                            TNY_FOLDER_STORE (src_folder), 
5785                                                            connect_info);
5786         }
5787
5788         /* Frees */
5789         g_object_unref (src_folder);
5790 }
5791 #endif
5792
5793
5794 void
5795 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5796                                             TnyFolder *src_folder,
5797                                             TnyList *headers,
5798                                             TnyFolder *dst_folder)
5799 {
5800         gboolean need_connection = TRUE;
5801         gboolean do_xfer = TRUE;
5802         XferMsgsHelper *helper;
5803
5804         g_return_if_fail (TNY_IS_FOLDER (src_folder));
5805         g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5806         g_return_if_fail (TNY_IS_LIST (headers));
5807         
5808         modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder), 
5809                                                headers, TNY_FOLDER (dst_folder),
5810                                                TRUE, &need_connection, 
5811                                                &do_xfer);
5812
5813         /* If we don't want to transfer just return */
5814         if (!do_xfer)
5815                 return;
5816
5817         /* Create the helper */
5818         helper = g_slice_new (XferMsgsHelper);
5819         helper->dst_folder = g_object_ref (dst_folder);
5820         helper->headers = g_object_ref (headers);
5821
5822         if (need_connection) {
5823                 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5824                 connect_info->callback = xfer_messages_performer;
5825                 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5826                 connect_info->data = helper;
5827                 
5828                 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5829                                                            TNY_FOLDER_STORE (src_folder), 
5830                                                            connect_info);
5831         } else {
5832                 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5833                 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5834                                          src_account, helper);
5835                 g_object_unref (src_account);
5836         }
5837 }
5838
5839 /*
5840  * UI handler for the "Move to" action when invoked from the
5841  * ModestMsgViewWindow
5842  */
5843 static void
5844 modest_ui_actions_on_window_move_to (GtkAction *action,
5845                                      TnyList *headers,
5846                                      TnyFolderStore *dst_folder,
5847                                      ModestWindow *win)
5848 {
5849         TnyFolder *src_folder = NULL;
5850
5851         g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5852
5853         if (headers) {
5854                 TnyHeader *header = NULL;
5855                 TnyIterator *iter;
5856
5857                 iter = tny_list_create_iterator (headers);
5858                 header = (TnyHeader *) tny_iterator_get_current (iter);
5859                 src_folder = tny_header_get_folder (header);
5860
5861                 /* Transfer the messages */
5862                 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, 
5863                                                             headers,
5864                                                             TNY_FOLDER (dst_folder));
5865
5866                 /* Frees */
5867                 g_object_unref (header);
5868                 g_object_unref (iter);
5869                 g_object_unref (src_folder);
5870         }
5871 }
5872
5873 void 
5874 modest_ui_actions_on_move_to (GtkAction *action, 
5875                               ModestWindow *win)
5876 {
5877         modest_ui_actions_on_edit_mode_move_to (win);
5878 }
5879
5880 gboolean 
5881 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5882 {
5883         GtkWidget *dialog = NULL;
5884         MoveToInfo *helper = NULL;
5885         TnyList *list_to_move;
5886
5887         g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5888
5889 #ifndef MODEST_TOOLKIT_HILDON2
5890         /* Get the main window if exists */
5891         ModestMainWindow *main_window;
5892         if (MODEST_IS_MAIN_WINDOW (win))
5893                 main_window = MODEST_MAIN_WINDOW (win);
5894         else
5895                 main_window = 
5896                         MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5897                                                                                FALSE)); /* don't create */
5898 #endif
5899
5900         list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5901
5902         if (!list_to_move)
5903                 return FALSE;
5904
5905         if (tny_list_get_length (list_to_move) < 1) {
5906                 g_object_unref (list_to_move);
5907                 return FALSE;
5908         }
5909
5910         /* Create and run the dialog */
5911         dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5912         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
5913                                      GTK_WINDOW (dialog), 
5914                                      (GtkWindow *) win);
5915
5916         /* Create helper */
5917         helper = g_slice_new0 (MoveToInfo);
5918         helper->list = list_to_move;
5919         helper->win = win;
5920
5921         /* Listen to response signal */
5922         g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5923
5924         /* Show the dialog */
5925         gtk_widget_show (dialog);
5926
5927         return TRUE;
5928 }
5929
5930 /*
5931  * Calls #HeadersFunc for each header already selected in the main
5932  * window or the message currently being shown in the msg view window
5933  */
5934 static void
5935 do_headers_action (ModestWindow *win, 
5936                    HeadersFunc func,
5937                    gpointer user_data)
5938 {
5939         TnyList *headers_list = NULL;
5940         TnyIterator *iter = NULL;
5941         TnyHeader *header = NULL;
5942         TnyFolder *folder = NULL;
5943
5944         /* Get headers */
5945         headers_list = get_selected_headers (win);
5946         if (!headers_list)
5947                 return;
5948
5949         /* Get the folder */
5950         iter = tny_list_create_iterator (headers_list);
5951         header = TNY_HEADER (tny_iterator_get_current (iter));
5952         if (header) {
5953                 folder = tny_header_get_folder (header);
5954                 g_object_unref (header);
5955         }
5956
5957         /* Call the function for each header */
5958         while (!tny_iterator_is_done (iter)) {
5959                 header = TNY_HEADER (tny_iterator_get_current (iter));
5960                 func (header, win, user_data);
5961                 g_object_unref (header);
5962                 tny_iterator_next (iter);
5963         }
5964
5965         /* Trick: do a poke status in order to speed up the signaling
5966            of observers */
5967         if (folder) {
5968                 tny_folder_poke_status (folder);
5969                 g_object_unref (folder);
5970         }
5971
5972         /* Frees */
5973         g_object_unref (iter);
5974         g_object_unref (headers_list);
5975 }
5976
5977 void 
5978 modest_ui_actions_view_attachment (GtkAction *action,
5979                                    ModestWindow *window)
5980 {
5981         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5982                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5983         } else {
5984                 /* not supported window for this action */
5985                 g_return_if_reached ();
5986         }
5987 }
5988
5989 void
5990 modest_ui_actions_save_attachments (GtkAction *action,
5991                                     ModestWindow *window)
5992 {
5993         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5994
5995                 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5996                         return;
5997
5998                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5999         } else {
6000                 /* not supported window for this action */
6001                 g_return_if_reached ();
6002         }
6003 }
6004
6005 void
6006 modest_ui_actions_remove_attachments (GtkAction *action,
6007                                       ModestWindow *window)
6008 {
6009         if (MODEST_IS_MAIN_WINDOW (window)) {
6010                 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6011         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6012                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6013         } else {
6014                 /* not supported window for this action */
6015                 g_return_if_reached ();
6016         }
6017 }
6018
6019 void 
6020 modest_ui_actions_on_settings (GtkAction *action, 
6021                                ModestWindow *win)
6022 {
6023         GtkWidget *dialog;
6024
6025         dialog = modest_platform_get_global_settings_dialog ();
6026         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6027         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6028         gtk_widget_show_all (dialog);
6029
6030         gtk_dialog_run (GTK_DIALOG (dialog));
6031
6032         gtk_widget_destroy (dialog);
6033 }
6034
6035 void 
6036 modest_ui_actions_on_help (GtkAction *action, 
6037                            GtkWindow *win)
6038 {
6039         /* Help app is not available at all in fremantle */
6040 #ifndef MODEST_TOOLKIT_HILDON2
6041         const gchar *help_id;
6042
6043         g_return_if_fail (win && GTK_IS_WINDOW(win));
6044         
6045         help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6046
6047         if (help_id)
6048                 modest_platform_show_help (GTK_WINDOW (win), help_id);
6049 #endif
6050 }
6051
6052 void 
6053 modest_ui_actions_on_csm_help (GtkAction *action, 
6054                                GtkWindow *win)
6055 {
6056         /* Help app is not available at all in fremantle */
6057 #ifndef MODEST_TOOLKIT_HILDON2
6058
6059         const gchar* help_id = NULL;
6060         GtkWidget *folder_view;
6061         TnyFolderStore *folder_store;
6062
6063         g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6064
6065         /* Get selected folder */
6066         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6067                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6068         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6069
6070         /* Switch help_id */
6071         if (folder_store && TNY_IS_FOLDER (folder_store))
6072                 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6073
6074         if (folder_store)
6075                 g_object_unref (folder_store);
6076
6077         if (help_id)
6078                 modest_platform_show_help (GTK_WINDOW (win), help_id);
6079         else
6080                 modest_ui_actions_on_help (action, win);
6081 #endif
6082 }
6083
6084 static void     
6085 retrieve_contents_cb (ModestMailOperation *mail_op, 
6086                       TnyHeader *header, 
6087                       gboolean canceled,
6088                       TnyMsg *msg,
6089                       GError *err,
6090                       gpointer user_data)
6091 {
6092         /* We only need this callback to show an error in case of
6093            memory low condition */
6094         modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
6095 }
6096
6097 static void
6098 retrieve_msg_contents_performer (gboolean canceled, 
6099                                  GError *err,
6100                                  GtkWindow *parent_window, 
6101                                  TnyAccount *account, 
6102                                  gpointer user_data)
6103 {
6104         ModestMailOperation *mail_op;
6105         TnyList *headers = TNY_LIST (user_data);
6106
6107         if (err || canceled) {
6108                 check_memory_full_error ((GtkWidget *) parent_window, err);
6109                 goto out;
6110         }
6111
6112         /* Create mail operation */
6113         mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6114                                                                  modest_ui_actions_disk_operations_error_handler, 
6115                                                                  NULL, NULL);
6116         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6117         modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6118
6119         /* Frees */
6120         g_object_unref (mail_op);
6121  out:
6122         g_object_unref (headers);
6123         g_object_unref (account);
6124 }
6125
6126 void 
6127 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6128                                             ModestWindow *window)
6129 {
6130         TnyList *headers = NULL;
6131         TnyAccount *account = NULL;
6132         TnyIterator *iter = NULL;
6133         TnyHeader *header = NULL;
6134         TnyFolder *folder = NULL;
6135
6136         /* Get headers */
6137         headers = get_selected_headers (window);
6138         if (!headers)
6139                 return;
6140
6141         /* Pick the account */
6142         iter = tny_list_create_iterator (headers);
6143         header = TNY_HEADER (tny_iterator_get_current (iter));
6144         folder = tny_header_get_folder (header);
6145         account = tny_folder_get_account (folder);
6146         g_object_unref (folder);
6147         g_object_unref (header);
6148         g_object_unref (iter);
6149
6150         /* Connect and perform the message retrieval */
6151         modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6152                                              g_object_ref (account), 
6153                                              retrieve_msg_contents_performer, 
6154                                              g_object_ref (headers));
6155
6156         /* Frees */
6157         g_object_unref (account);
6158         g_object_unref (headers);
6159 }
6160
6161 void
6162 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6163 {
6164         g_return_if_fail (MODEST_IS_WINDOW (window));
6165
6166         /* Update dimmed */
6167         modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6168 }
6169
6170 void
6171 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6172 {
6173         g_return_if_fail (MODEST_IS_WINDOW (window));
6174
6175         /* Update dimmed */
6176         modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6177 }
6178
6179 void
6180 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6181                                           ModestWindow *window)
6182 {
6183         g_return_if_fail (MODEST_IS_WINDOW (window));
6184         
6185         /* Update dimmed */
6186         modest_ui_actions_check_menu_dimming_rules (window);
6187 }
6188
6189 void
6190 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6191                                           ModestWindow *window)
6192 {
6193         g_return_if_fail (MODEST_IS_WINDOW (window));
6194
6195         /* Update dimmed */
6196         modest_ui_actions_check_menu_dimming_rules (window);
6197 }
6198
6199 void
6200 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6201                                           ModestWindow *window)
6202 {
6203         g_return_if_fail (MODEST_IS_WINDOW (window));
6204
6205         /* Update dimmed */
6206         modest_ui_actions_check_menu_dimming_rules (window);
6207 }
6208
6209 void
6210 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6211                                             ModestWindow *window)
6212 {
6213         g_return_if_fail (MODEST_IS_WINDOW (window));
6214
6215         /* Update dimmed */
6216         modest_ui_actions_check_menu_dimming_rules (window);
6217 }
6218
6219 void
6220 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6221                                           ModestWindow *window)
6222 {
6223         g_return_if_fail (MODEST_IS_WINDOW (window));
6224
6225         /* Update dimmed */
6226         modest_ui_actions_check_menu_dimming_rules (window);
6227 }
6228
6229 void
6230 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6231                                           ModestWindow *window)
6232 {
6233         g_return_if_fail (MODEST_IS_WINDOW (window));
6234
6235         /* Update dimmed */
6236         modest_ui_actions_check_menu_dimming_rules (window);
6237 }
6238
6239 void
6240 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6241                                                  ModestWindow *window)
6242 {
6243         g_return_if_fail (MODEST_IS_WINDOW (window));
6244
6245         /* Update dimmed */
6246         modest_ui_actions_check_menu_dimming_rules (window);
6247 }
6248
6249 void
6250 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6251                                                      ModestWindow *window)
6252 {
6253         g_return_if_fail (MODEST_IS_WINDOW (window));
6254
6255         /* Update dimmed */
6256         modest_ui_actions_check_menu_dimming_rules (window);
6257 }
6258
6259 void
6260 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6261                                                      ModestWindow *window)
6262 {
6263         g_return_if_fail (MODEST_IS_WINDOW (window));
6264
6265         /* Update dimmed */
6266         modest_ui_actions_check_menu_dimming_rules (window);
6267 }
6268
6269 void
6270 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6271 {
6272         g_return_if_fail (MODEST_IS_WINDOW (window));
6273
6274         /* we check for low-mem; in that case, show a warning, and don't allow
6275          * searching
6276          */
6277         if (modest_platform_check_memory_low (window, TRUE))
6278                 return;
6279         
6280         modest_platform_show_search_messages (GTK_WINDOW (window));
6281 }
6282
6283 void     
6284 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6285 {
6286         g_return_if_fail (MODEST_IS_WINDOW (win));
6287
6288
6289         /* we check for low-mem; in that case, show a warning, and don't allow
6290          * for the addressbook
6291          */
6292         if (modest_platform_check_memory_low (win, TRUE))
6293                 return;
6294
6295
6296         modest_platform_show_addressbook (GTK_WINDOW (win));
6297 }
6298
6299
6300 void
6301 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6302                                           ModestWindow *window)
6303 {
6304         gboolean active;
6305         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6306
6307         if (GTK_IS_TOGGLE_ACTION (action))
6308                 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6309         else
6310                 active = TRUE;
6311
6312         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), 
6313                                                     active);
6314 }
6315
6316 static void 
6317 on_send_receive_finished (ModestMailOperation  *mail_op, 
6318                            gpointer user_data)
6319 {
6320         GtkWidget *header_view, *folder_view;
6321         TnyFolderStore *folder_store;
6322         ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6323
6324         /* Set send/receive operation finished */       
6325         modest_main_window_notify_send_receive_completed (main_win);
6326
6327         /* Don't refresh the current folder if there were any errors */
6328         if (modest_mail_operation_get_status (mail_op) !=
6329             MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6330                 return;
6331         
6332         /* Refresh the current folder if we're viewing a window. We do
6333            this because the user won't be able to see the new mails in
6334            the selected folder after a Send&Receive because it only
6335            performs a poke_status, i.e, only the number of read/unread
6336            messages is updated, but the new headers are not
6337            downloaded */
6338         folder_view = modest_main_window_get_child_widget (main_win, 
6339                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6340         if (!folder_view)
6341                 return;
6342
6343         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6344         
6345         /* Do not need to refresh INBOX again because the
6346            update_account does it always automatically */
6347         if (folder_store && TNY_IS_FOLDER (folder_store) && 
6348             tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6349                 ModestMailOperation *refresh_op;
6350
6351                 header_view = modest_main_window_get_child_widget (main_win,
6352                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6353                 
6354                 /* We do not need to set the contents style
6355                    because it hasn't changed. We also do not
6356                    need to save the widget status. Just force
6357                    a refresh */
6358                 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6359                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6360                 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6361                                                       folder_refreshed_cb, main_win);
6362                 g_object_unref (refresh_op);
6363         }
6364         
6365         if (folder_store)
6366                 g_object_unref (folder_store);
6367 }
6368
6369
6370 void
6371 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self, 
6372                                                 TnyHeader *header, 
6373                                                 TnyMsg *msg, 
6374                                                 GError *err, 
6375                                                 gpointer user_data)
6376 {
6377         const gchar* server_name = NULL;
6378         TnyTransportAccount *server_account;
6379         gchar *message = NULL;
6380
6381         /* Don't show anything if the user cancelled something or the
6382          * send receive request is not interactive. Authentication
6383          * errors are managed by the account store so no need to show
6384          * a dialog here again */
6385         if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6386             err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6387             !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6388                 return;
6389
6390
6391         /* Get the server name: */
6392         server_account =
6393                 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6394         if (server_account)
6395                 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6396         else
6397                 g_return_if_reached ();
6398
6399         /* Show the appropriate message text for the GError: */
6400         switch (err->code) {
6401         case TNY_SERVICE_ERROR_CONNECT:
6402                 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6403                 break;
6404         case TNY_SERVICE_ERROR_SEND:
6405                 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6406                 break;
6407         case TNY_SERVICE_ERROR_UNAVAILABLE:
6408                 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6409                 break;
6410         default:
6411                 g_warning ("%s: unexpected ERROR %d",
6412                            __FUNCTION__, err->code);
6413                 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6414                 break;
6415         }
6416
6417         modest_platform_run_information_dialog (NULL, message, FALSE);
6418         g_free (message);
6419         g_object_unref (server_account);
6420 }
6421
6422 void
6423 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6424                                                 gchar *msg_id, 
6425                                                 guint status,
6426                                                 gpointer user_data)
6427 {
6428         ModestWindow *top_window = NULL;
6429         ModestWindowMgr *mgr = NULL;
6430         GtkWidget *header_view = NULL;
6431         TnyFolder *selected_folder = NULL;
6432         TnyFolderType folder_type;
6433
6434         mgr = modest_runtime_get_window_mgr ();
6435         top_window = modest_window_mgr_get_current_top (mgr);
6436
6437         if (!top_window)
6438                 return;
6439
6440 #ifndef MODEST_TOOLKIT_HILDON2
6441         if (MODEST_IS_MAIN_WINDOW (top_window)) {
6442                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6443                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6444         }
6445 #else
6446         if (MODEST_IS_HEADER_WINDOW (top_window)) {
6447                 header_view = (GtkWidget *)
6448                         modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6449         }
6450 #endif
6451
6452         /* Get selected folder */
6453         selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6454         if (!selected_folder)
6455                 return;
6456
6457         /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6458 #if GTK_CHECK_VERSION(2, 8, 0)
6459         folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6460         if (folder_type ==  TNY_FOLDER_TYPE_OUTBOX) {
6461                 GtkTreeViewColumn *tree_column;
6462
6463                 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6464                                                         TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6465                 if (tree_column)
6466                         gtk_tree_view_column_queue_resize (tree_column);
6467                 }
6468 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6469         gtk_widget_queue_draw (header_view);
6470 #endif
6471
6472 #ifndef MODEST_TOOLKIT_HILDON2
6473         /* Rerun dimming rules, because the message could become deletable for example */
6474         modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6475                                                  MODEST_DIMMING_RULES_TOOLBAR);
6476         modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6477                                                  MODEST_DIMMING_RULES_MENU);
6478 #endif
6479
6480         /* Free */
6481         g_object_unref (selected_folder);
6482 }
6483
6484 void
6485 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6486                                                TnyAccount *account)
6487 {
6488         ModestProtocolType protocol_type;
6489         ModestProtocol *protocol;
6490         gchar *error_note = NULL;
6491
6492         protocol_type = modest_tny_account_get_protocol_type (account);
6493         protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6494                                                                   protocol_type);
6495
6496         error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6497         if (error_note == NULL) {
6498                 g_warning ("%s: This should not be reached", __FUNCTION__);
6499         } else {
6500                 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6501                 g_free (error_note);
6502         }
6503 }
6504
6505 gchar *
6506 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6507 {
6508         gchar *msg = NULL;
6509         gchar *subject;
6510         TnyFolderStore *folder = NULL;
6511         TnyAccount *account = NULL;
6512         ModestProtocolType proto;
6513         ModestProtocol *protocol;
6514         TnyHeader *header = NULL;
6515
6516         if (MODEST_IS_MAIN_WINDOW (win)) {
6517                 GtkWidget *header_view;
6518                 TnyList* headers = NULL;
6519                 TnyIterator *iter;
6520                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6521                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6522                 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6523                 if (!headers || tny_list_get_length (headers) == 0) {
6524                         if (headers)
6525                                 g_object_unref (headers);
6526                         return NULL;
6527                 }
6528                 iter = tny_list_create_iterator (headers);
6529                 header = TNY_HEADER (tny_iterator_get_current (iter));
6530                 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6531                 g_object_unref (iter);
6532                 g_object_unref (headers);
6533 #ifdef MODEST_TOOLKIT_HILDON2
6534         } else if (MODEST_IS_HEADER_WINDOW (win)) {
6535                 GtkWidget *header_view;
6536                 TnyList* headers = NULL;
6537                 TnyIterator *iter;
6538                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6539                 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6540                 if (!headers || tny_list_get_length (headers) == 0) {
6541                         if (headers)
6542                                 g_object_unref (headers);
6543                         return NULL;
6544                 }
6545                 iter = tny_list_create_iterator (headers);
6546                 header = TNY_HEADER (tny_iterator_get_current (iter));
6547                 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6548                 g_object_unref (iter);
6549                 g_object_unref (headers);
6550 #endif
6551         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6552                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6553                 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6554         }
6555
6556         /* Get the account type */
6557         account = tny_folder_get_account (TNY_FOLDER (folder));
6558         proto = modest_tny_account_get_protocol_type (account);
6559         protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6560                                                                   proto);
6561
6562         subject = tny_header_dup_subject (header);
6563         msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6564         if (subject)
6565                 g_free (subject);
6566         if (msg == NULL) {
6567                 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6568         }
6569
6570         /* Frees */
6571         g_object_unref (account);
6572         g_object_unref (folder);
6573         g_object_unref (header);
6574
6575         return msg;
6576 }
6577
6578 gboolean
6579 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6580                                      const gchar *account_name,
6581                                      const gchar *account_title)
6582 {
6583         ModestAccountMgr *account_mgr;
6584         gchar *txt = NULL;
6585         gint response;
6586         ModestProtocol *protocol;
6587         gboolean removed = FALSE;
6588
6589         g_return_val_if_fail (account_name, FALSE);
6590         g_return_val_if_fail (account_title, FALSE);
6591
6592         account_mgr = modest_runtime_get_account_mgr();
6593
6594         /* The warning text depends on the account type: */
6595         protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6596                                                                   modest_account_mgr_get_store_protocol (account_mgr,
6597                                                                                                          account_name));
6598         txt = modest_protocol_get_translation (protocol,
6599                                                MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6600                                                account_title);
6601         if (txt == NULL)
6602                 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6603
6604         response = modest_platform_run_confirmation_dialog (parent_window, txt);
6605         g_free (txt);
6606         txt = NULL;
6607
6608         if (response == GTK_RESPONSE_OK) {
6609                 /* Remove account. If it succeeds then it also removes
6610                    the account from the ModestAccountView: */
6611                 gboolean is_default = FALSE;
6612                 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6613                 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6614                         is_default = TRUE;
6615                 g_free (default_account_name);
6616
6617                 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6618                 if (!removed)
6619                         g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6620         }
6621         return removed;
6622 }