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