* Fixes NB#100011, just created folders now appear in the folder list after closing...
[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                 g_object_unref (parent_folder);
3423         }
3424 }
3425
3426 void
3427 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3428 {
3429
3430         g_return_if_fail (MODEST_IS_WINDOW(window));
3431
3432         if (MODEST_IS_MAIN_WINDOW (window)) {
3433                 GtkWidget *folder_view;
3434
3435                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3436                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3437                 if (!folder_view)
3438                         return;
3439
3440                 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3441 #ifdef MODEST_TOOLKIT_HILDON2
3442         } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3443                 GtkWidget *folder_view;
3444
3445                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3446                 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3447 #endif
3448         } else {
3449                 g_assert_not_reached ();
3450         }
3451 }
3452
3453 static void
3454 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3455                                                gpointer user_data)
3456 {
3457         const GError *error = NULL;
3458         const gchar *message = NULL;
3459         
3460         /* Get error message */
3461         error = modest_mail_operation_get_error (mail_op);
3462         if (!error)
3463                 g_return_if_reached ();
3464
3465         if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3466             error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3467                 message = _CS("ckdg_ib_folder_already_exists");
3468         } else if (error->domain == TNY_ERROR_DOMAIN &&
3469                    error->code == TNY_SERVICE_ERROR_STATE) {
3470                 /* This means that the folder is already in use (a
3471                    message is opened for example */
3472                 message = _("emev_ni_internal_error");
3473         } else {
3474                 message = _CS("ckdg_ib_unable_to_rename");
3475         }
3476
3477         /* We don't set a parent for the dialog because the dialog
3478            will be destroyed so the banner won't appear */
3479         modest_platform_information_banner (NULL, NULL, message);
3480 }
3481
3482 typedef struct {
3483         TnyFolderStore *folder;
3484         gchar *new_name;
3485 } RenameFolderInfo;
3486
3487 static void
3488 on_rename_folder_cb (ModestMailOperation *mail_op, 
3489                      TnyFolder *new_folder,
3490                      gpointer user_data)
3491 {
3492         ModestFolderView *folder_view;
3493
3494         /* If the window was closed when renaming a folder, or if
3495          * it's not a main window this will happen */
3496         if (!MODEST_IS_FOLDER_VIEW (user_data))
3497                 return;
3498
3499         folder_view = MODEST_FOLDER_VIEW (user_data);
3500         /* Note that if the rename fails new_folder will be NULL */
3501         if (new_folder) {
3502                 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3503         } else {
3504                 modest_folder_view_select_first_inbox_or_local (folder_view);
3505         }
3506         gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3507 }
3508
3509 static void
3510 on_rename_folder_performer (gboolean canceled, 
3511                             GError *err, 
3512                             GtkWindow *parent_window, 
3513                             TnyAccount *account, 
3514                             gpointer user_data)
3515 {
3516         ModestMailOperation *mail_op = NULL;
3517         GtkTreeSelection *sel = NULL;
3518         GtkWidget *folder_view = NULL;
3519         RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3520
3521         if (canceled || err) {
3522                 /* In memory full conditions we could get this error here */
3523                 check_memory_full_error ((GtkWidget *) parent_window, err);
3524         } else {
3525
3526                 mail_op =
3527                         modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3528                                         modest_ui_actions_rename_folder_error_handler,
3529                                         parent_window, NULL);
3530
3531                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3532                                 mail_op);
3533
3534                 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3535
3536                         folder_view = modest_main_window_get_child_widget (
3537                                 MODEST_MAIN_WINDOW (parent_window),
3538                                 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3539                 } 
3540 #ifdef MODEST_TOOLKIT_HILDON2
3541                 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3542                         ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3543                         folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3544                 }
3545 #endif
3546
3547                 /* Clear the folders view */
3548                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3549                 gtk_tree_selection_unselect_all (sel);
3550
3551                 /* Actually rename the folder */
3552                 modest_mail_operation_rename_folder (mail_op,
3553                                                      TNY_FOLDER (data->folder),
3554                                                      (const gchar *) (data->new_name),
3555                                                      on_rename_folder_cb,
3556                                                      folder_view);
3557                 g_object_unref (mail_op);
3558         }
3559
3560         g_object_unref (data->folder);
3561         g_free (data->new_name);
3562         g_free (data);
3563 }
3564
3565 void 
3566 modest_ui_actions_on_rename_folder (GtkAction *action,
3567                                      ModestWindow *window)
3568 {
3569         modest_ui_actions_on_edit_mode_rename_folder (window);
3570 }
3571
3572 gboolean 
3573 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3574 {
3575         TnyFolderStore *folder;
3576         GtkWidget *folder_view;
3577         gboolean do_rename = TRUE;
3578
3579         g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3580
3581         if (MODEST_IS_MAIN_WINDOW (window)) {
3582                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3583                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3584                 if (!folder_view)
3585                         return FALSE;
3586
3587 #ifdef MODEST_TOOLKIT_HILDON2
3588         } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3589                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3590 #endif
3591         } else {
3592                 return FALSE;
3593         }
3594
3595         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3596
3597         if (!folder)
3598                 return FALSE;
3599
3600         if (TNY_IS_FOLDER (folder)) {
3601                 gchar *folder_name = NULL;
3602                 gint response;
3603                 const gchar *current_name;
3604                 TnyFolderStore *parent;
3605
3606                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3607                 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3608                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3609                                                                      parent, current_name, 
3610                                                                      &folder_name);
3611                 g_object_unref (parent);
3612
3613                 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3614                         do_rename = FALSE;
3615                 } else {
3616                         RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3617                         rename_folder_data->folder = g_object_ref (folder);
3618                         rename_folder_data->new_name = folder_name;
3619                         modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3620                                         folder, on_rename_folder_performer, rename_folder_data);
3621                 }
3622         }
3623         g_object_unref (folder);
3624         return do_rename;
3625 }
3626
3627 static void
3628 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3629                                                gpointer user_data)
3630 {
3631         GObject *win = modest_mail_operation_get_source (mail_op);
3632
3633         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3634                                                 _("mail_in_ui_folder_delete_error"),
3635                                                 FALSE);
3636         g_object_unref (win);
3637 }
3638
3639 typedef struct {
3640         TnyFolderStore *folder;
3641         gboolean move_to_trash;
3642 } DeleteFolderInfo;
3643
3644 static void
3645 on_delete_folder_cb (gboolean canceled, 
3646                   GError *err,
3647                   GtkWindow *parent_window, 
3648                   TnyAccount *account, 
3649                   gpointer user_data)
3650 {
3651         DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3652         GtkWidget *folder_view;
3653         ModestMailOperation *mail_op;
3654         GtkTreeSelection *sel;
3655         
3656         if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3657                 g_object_unref (G_OBJECT (info->folder));
3658                 g_free (info);
3659                 return;
3660         }
3661         
3662         if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3663                 folder_view = modest_main_window_get_child_widget (
3664                         MODEST_MAIN_WINDOW (parent_window),
3665                         MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3666 #ifdef MODEST_TOOLKIT_HILDON2
3667         } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3668                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3669 #endif
3670         } else {
3671                 g_object_unref (G_OBJECT (info->folder));
3672                 g_free (info);
3673                 return;
3674         }
3675
3676         /* Unselect the folder before deleting it to free the headers */
3677         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3678         gtk_tree_selection_unselect_all (sel);
3679
3680         /* Create the mail operation */
3681         mail_op =
3682                 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3683                                 modest_ui_actions_delete_folder_error_handler,
3684                                 NULL, NULL);
3685
3686         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3687                         mail_op);
3688         modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3689         
3690         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3691
3692         g_object_unref (G_OBJECT (mail_op));
3693         g_object_unref (G_OBJECT (info->folder));
3694         g_free (info);
3695 }
3696
3697 static gboolean
3698 delete_folder (ModestWindow *window, gboolean move_to_trash)
3699 {
3700         TnyFolderStore *folder;
3701         GtkWidget *folder_view;
3702         gint response;
3703         gchar *message;
3704         
3705         g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3706
3707         if (MODEST_IS_MAIN_WINDOW (window)) {
3708
3709                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3710                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3711 #ifdef MODEST_TOOLKIT_HILDON2
3712         } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3713                 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3714 #endif
3715         } else {
3716                 return FALSE;
3717         }
3718         if (!folder_view)
3719                 return FALSE;
3720
3721         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3722
3723         if (!folder)
3724                 return FALSE;
3725
3726         /* Show an error if it's an account */
3727         if (!TNY_IS_FOLDER (folder)) {
3728                 modest_platform_run_information_dialog (GTK_WINDOW (window),
3729                                                         _("mail_in_ui_folder_delete_error"),
3730                                                         FALSE);
3731                 g_object_unref (G_OBJECT (folder));
3732                 return FALSE;
3733         }
3734
3735         /* Ask the user */
3736         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
3737                                     tny_folder_get_name (TNY_FOLDER (folder)));
3738         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3739                                                             (const gchar *) message);
3740         g_free (message);
3741
3742         if (response == GTK_RESPONSE_OK) {
3743                 DeleteFolderInfo *info;
3744                 info = g_new0(DeleteFolderInfo, 1);
3745                 info->folder = folder;
3746                 info->move_to_trash = move_to_trash;
3747                 g_object_ref (G_OBJECT (info->folder));
3748                 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3749                 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window), 
3750                                                                TRUE,
3751                                                                TNY_FOLDER_STORE (account), 
3752                                                                on_delete_folder_cb, info);
3753                 g_object_unref (account);
3754                 return TRUE;
3755         } else {
3756                 return FALSE;
3757         }
3758         g_object_unref (G_OBJECT (folder));
3759 }
3760
3761 void
3762 modest_ui_actions_on_delete_folder (GtkAction *action,
3763                                     ModestWindow *window)
3764 {
3765         modest_ui_actions_on_edit_mode_delete_folder (window);
3766 }
3767
3768 gboolean
3769 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3770 {
3771         g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3772         
3773         return delete_folder (window, FALSE);
3774 }
3775
3776 void 
3777 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3778 {
3779         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3780         
3781         delete_folder (MODEST_WINDOW (main_window), TRUE);
3782 }
3783
3784
3785 typedef struct _PasswordDialogFields {
3786         GtkWidget *username;
3787         GtkWidget *password;
3788         GtkWidget *dialog;
3789 } PasswordDialogFields;
3790
3791 static void
3792 password_dialog_check_field (GtkEditable *editable,
3793                              PasswordDialogFields *fields)
3794 {
3795         const gchar *value;
3796         gboolean any_value_empty = FALSE;
3797
3798 #ifdef MODEST_TOOLKIT_HILDON2
3799         value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3800 #else
3801         value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3802 #endif
3803         if ((value == NULL) || value[0] == '\0') {
3804                 any_value_empty = TRUE;
3805         }
3806 #ifdef MODEST_TOOLKIT_HILDON2
3807         value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3808 #else
3809         value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3810 #endif
3811         if ((value == NULL) || value[0] == '\0') {
3812                 any_value_empty = TRUE;
3813         }
3814         gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3815 }
3816
3817 void
3818 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3819                                          const gchar* server_account_name,
3820                                          gchar **username,
3821                                          gchar **password,
3822                                          gboolean *cancel,
3823                                          gboolean *remember,
3824                                          ModestMainWindow *main_window)
3825 {
3826         g_return_if_fail(server_account_name);
3827         gboolean completed = FALSE;
3828         PasswordDialogFields *fields = NULL;
3829
3830         /* Initalize output parameters: */
3831         if (cancel)
3832                 *cancel = FALSE;
3833
3834         if (remember)
3835                 *remember = TRUE;
3836
3837 #ifndef MODEST_TOOLKIT_GTK
3838         /* Maemo uses a different (awkward) button order,
3839          * It should probably just use gtk_alternative_dialog_button_order ().
3840          */
3841 #ifdef MODEST_TOOLKIT_HILDON2
3842         GtkWidget *dialog =
3843                 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3844                                              NULL,
3845                                              GTK_DIALOG_MODAL,
3846                                              _HL("wdgt_bd_done"),
3847                                              GTK_RESPONSE_ACCEPT,
3848                                              NULL);
3849         gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 
3850                                         HILDON_MARGIN_DOUBLE);
3851 #else
3852         GtkWidget *dialog =
3853                 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3854                                              NULL,
3855                                              GTK_DIALOG_MODAL,
3856                                              _("mcen_bd_dialog_ok"),
3857                                              GTK_RESPONSE_ACCEPT,
3858                                              _("mcen_bd_dialog_cancel"),
3859                                              GTK_RESPONSE_REJECT,
3860                                              NULL);
3861 #endif /* MODEST_TOOLKIT_HILDON2 */
3862 #else
3863         GtkWidget *dialog = 
3864                 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3865                                              NULL,
3866                                              GTK_DIALOG_MODAL,
3867                                              GTK_STOCK_CANCEL,
3868                                              GTK_RESPONSE_REJECT,
3869                                              GTK_STOCK_OK,
3870                                              GTK_RESPONSE_ACCEPT,
3871                                              NULL);
3872 #endif /* MODEST_TOOLKIT_GTK */
3873
3874         modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3875
3876         gchar *server_name = modest_account_mgr_get_server_account_hostname (
3877                 modest_runtime_get_account_mgr(), server_account_name);
3878         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3879                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3880                 if (cancel)
3881                         *cancel = TRUE;
3882                 gtk_widget_destroy (dialog);
3883                 return;
3884         }
3885
3886         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3887         GtkWidget *label = gtk_label_new (txt);
3888         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3889         g_free (txt);
3890         g_free (server_name);
3891         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3892                             FALSE, FALSE, 0);
3893         server_name = NULL;
3894
3895         /* username: */
3896         gchar *initial_username = modest_account_mgr_get_server_account_username (
3897                 modest_runtime_get_account_mgr(), server_account_name);
3898
3899 #ifdef MODEST_TOOLKIT_HILDON2
3900         GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3901         if (initial_username)
3902                 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3903 #else
3904         GtkWidget *entry_username = gtk_entry_new ();
3905         if (initial_username)
3906                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3907 #endif
3908         /* Dim this if a connection has ever succeeded with this username,
3909          * as per the UI spec: */
3910         /* const gboolean username_known =  */
3911         /*      modest_account_mgr_get_server_account_username_has_succeeded( */
3912         /*              modest_runtime_get_account_mgr(), server_account_name); */
3913         /* gtk_widget_set_sensitive (entry_username, !username_known); */
3914
3915         /* We drop the username sensitive code and disallow changing it here
3916          * as tinymail does not support really changing the username in the callback
3917          */
3918         gtk_widget_set_sensitive (entry_username, FALSE);
3919
3920 #ifndef MODEST_TOOLKIT_GTK
3921         /* Auto-capitalization is the default, so let's turn it off: */
3922         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3923
3924         /* Create a size group to be used by all captions.
3925          * Note that HildonCaption does not create a default size group if we do not specify one.
3926          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3927         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3928
3929 #ifdef MODEST_TOOLKIT_HILDON2
3930         GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL, 
3931                                                                   _("mail_fi_username"), FALSE,
3932                                                                   entry_username);
3933 #else
3934         GtkWidget *caption = hildon_caption_new (sizegroup, 
3935                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3936 #endif
3937         gtk_widget_show (entry_username);
3938         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
3939                 FALSE, FALSE, MODEST_MARGIN_HALF);
3940         gtk_widget_show (caption);
3941 #else
3942         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3943                             TRUE, FALSE, 0);
3944 #endif /* !MODEST_TOOLKIT_GTK */
3945
3946         /* password: */
3947 #ifdef MODEST_TOOLKIT_HILDON2
3948         GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3949 #else
3950         GtkWidget *entry_password = gtk_entry_new ();
3951 #endif
3952         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3953         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3954
3955 #ifndef MODEST_TOOLKIT_GTK
3956         /* Auto-capitalization is the default, so let's turn it off: */
3957         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3958                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3959
3960 #ifdef MODEST_TOOLKIT_HILDON2
3961         caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3962                                                        _("mail_fi_password"), FALSE,
3963                                                        entry_password);
3964 #else
3965         caption = hildon_caption_new (sizegroup,
3966                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3967 #endif
3968         gtk_widget_show (entry_password);
3969         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3970                 FALSE, FALSE, MODEST_MARGIN_HALF);
3971         gtk_widget_show (caption);
3972         g_object_unref (sizegroup);
3973 #else
3974         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3975                             TRUE, FALSE, 0);
3976 #endif /* !MODEST_TOOLKIT_GTK */
3977
3978         if (initial_username != NULL)
3979                 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3980
3981 /* This is not in the Maemo UI spec:
3982         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3983         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3984                             TRUE, FALSE, 0);
3985 */
3986
3987         fields = g_slice_new0 (PasswordDialogFields);
3988         fields->username = entry_username;
3989         fields->password = entry_password;
3990         fields->dialog = dialog;
3991
3992         g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3993         g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3994         password_dialog_check_field (NULL, fields);
3995
3996         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3997
3998         while (!completed) {
3999
4000                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4001                         if (username) {
4002 #ifdef MODEST_TOOLKIT_HILDON2
4003                                 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4004 #else
4005                                 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4006 #endif
4007
4008                                 /* Note that an empty field becomes the "" string */
4009                                 if (*username && strlen (*username) > 0) {
4010                                         modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(), 
4011                                                                                         server_account_name, 
4012                                                                                         *username);
4013                                         completed = TRUE;
4014
4015                                         const gboolean username_was_changed = 
4016                                                 (strcmp (*username, initial_username) != 0);
4017                                         if (username_was_changed) {
4018                                                 g_warning ("%s: tinymail does not yet support changing the "
4019                                                            "username in the get_password() callback.\n", __FUNCTION__);
4020                                         }
4021                                 } else {
4022                                         g_free (*username);
4023                                         *username = NULL;
4024                                         /* Show error */
4025                                         modest_platform_information_banner (GTK_WIDGET (dialog), NULL, 
4026                                                                             _("mcen_ib_username_pw_incorrect"));
4027                                         completed = FALSE;
4028                                 }
4029                         }
4030
4031                         if (password) {
4032 #ifdef MODEST_TOOLKIT_HILDON2
4033                                 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4034 #else
4035                                 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4036 #endif
4037
4038                                 /* We do not save the password in the configuration, 
4039                                  * because this function is only called for passwords that should 
4040                                  * not be remembered:
4041                                  modest_server_account_set_password (
4042                                  modest_runtime_get_account_mgr(), server_account_name, 
4043                                  *password);
4044                                  */
4045                         }
4046                         if (cancel)
4047                                 *cancel   = FALSE;
4048                 } else {
4049 #ifndef MODEST_TOOLKIT_HILDON2
4050                         /* Set parent to NULL or the banner will disappear with its parent dialog */
4051                         modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4052 #endif
4053                         completed = TRUE;
4054                         if (username)
4055                                 *username = NULL;
4056                         if (password)
4057                                 *password = NULL;
4058                         if (cancel)
4059                                 *cancel   = TRUE;
4060                 }
4061         }
4062
4063 /* This is not in the Maemo UI spec:
4064         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4065                 *remember = TRUE;
4066         else
4067                 *remember = FALSE;
4068 */
4069
4070         g_free (initial_username);
4071         gtk_widget_destroy (dialog);
4072         g_slice_free (PasswordDialogFields, fields);
4073         
4074         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4075 }
4076
4077 void
4078 modest_ui_actions_on_cut (GtkAction *action,
4079                           ModestWindow *window)
4080 {
4081         GtkWidget *focused_widget;
4082         GtkClipboard *clipboard;
4083
4084         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4085         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4086         if (GTK_IS_EDITABLE (focused_widget)) {
4087                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4088                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4089                 gtk_clipboard_store (clipboard);
4090         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4091                 GtkTextBuffer *buffer;
4092
4093                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4094                 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4095                         gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4096                         gtk_clipboard_set_can_store (clipboard, NULL, 0);
4097                         gtk_clipboard_store (clipboard);
4098                 }
4099         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4100                 TnyList *header_list = modest_header_view_get_selected_headers (
4101                                 MODEST_HEADER_VIEW (focused_widget));
4102                 gboolean continue_download = FALSE;
4103                 gint num_of_unc_msgs;
4104
4105                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4106
4107                 if (num_of_unc_msgs) {
4108                         TnyAccount *account = get_account_from_header_list (header_list);
4109                         if (account) {
4110                                 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4111                                 g_object_unref (account);
4112                         }
4113                 }
4114
4115                 if (num_of_unc_msgs == 0 || continue_download) {
4116 /*                      modest_platform_information_banner (
4117                                         NULL, NULL, _CS("mcen_ib_getting_items"));*/
4118                         modest_header_view_cut_selection (
4119                                         MODEST_HEADER_VIEW (focused_widget));
4120                 }
4121
4122                 g_object_unref (header_list);
4123         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4124                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4125         }
4126 }
4127
4128 void
4129 modest_ui_actions_on_copy (GtkAction *action,
4130                            ModestWindow *window)
4131 {
4132         GtkClipboard *clipboard;
4133         GtkWidget *focused_widget;
4134         gboolean copied = TRUE;
4135
4136         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4137         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4138
4139         if (GTK_IS_LABEL (focused_widget)) {
4140                 gchar *selection;
4141                 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4142                 gtk_clipboard_set_text (clipboard, selection, -1);
4143                 g_free (selection);
4144                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4145                 gtk_clipboard_store (clipboard);
4146         } else if (GTK_IS_EDITABLE (focused_widget)) {
4147                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4148                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4149                 gtk_clipboard_store (clipboard);
4150         } else if (GTK_IS_HTML (focused_widget)) {
4151                 const gchar *sel;
4152                 int len = -1;
4153                 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4154                 if ((sel == NULL) || (sel[0] == '\0')) {
4155                         copied = FALSE;
4156                 } else {
4157                         gtk_html_copy (GTK_HTML (focused_widget));
4158                         gtk_clipboard_set_can_store (clipboard, NULL, 0);
4159                         gtk_clipboard_store (clipboard);
4160                 }
4161         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4162                 GtkTextBuffer *buffer;
4163                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4164                 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4165                         gtk_text_buffer_copy_clipboard (buffer, clipboard);
4166                         gtk_clipboard_set_can_store (clipboard, NULL, 0);
4167                         gtk_clipboard_store (clipboard);
4168                 }
4169         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4170                 TnyList *header_list = modest_header_view_get_selected_headers (
4171                                 MODEST_HEADER_VIEW (focused_widget));
4172                 gboolean continue_download = FALSE;
4173                 gint num_of_unc_msgs;
4174
4175                 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4176
4177                 if (num_of_unc_msgs) {
4178                         TnyAccount *account = get_account_from_header_list (header_list);
4179                         if (account) {
4180                                 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4181                                 g_object_unref (account);
4182                         }
4183                 }
4184
4185                 if (num_of_unc_msgs == 0 || continue_download) {
4186                         modest_platform_information_banner (
4187                                         NULL, NULL, _CS("mcen_ib_getting_items"));
4188                         modest_header_view_copy_selection (
4189                                         MODEST_HEADER_VIEW (focused_widget));
4190                 } else
4191                         copied = FALSE;
4192
4193                 g_object_unref (header_list);
4194
4195         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4196                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4197         }
4198
4199         /* Show information banner if there was a copy to clipboard */
4200         if(copied)
4201                 modest_platform_information_banner (
4202                                 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4203 }
4204
4205 void
4206 modest_ui_actions_on_undo (GtkAction *action,
4207                            ModestWindow *window)
4208 {
4209         ModestEmailClipboard *clipboard = NULL;
4210
4211         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4212                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4213         } else if (MODEST_IS_MAIN_WINDOW (window)) {
4214                 /* Clear clipboard source */
4215                 clipboard = modest_runtime_get_email_clipboard ();
4216                 modest_email_clipboard_clear (clipboard);               
4217         }
4218         else {
4219                 g_return_if_reached ();
4220         }
4221 }
4222
4223 void
4224 modest_ui_actions_on_redo (GtkAction *action,
4225                            ModestWindow *window)
4226 {
4227         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4228                 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4229         }
4230         else {
4231                 g_return_if_reached ();
4232         }
4233 }
4234
4235
4236 static void
4237 destroy_information_note (ModestMailOperation *mail_op, 
4238                           gpointer user_data)
4239 {
4240         /* destroy information note */
4241         gtk_widget_destroy (GTK_WIDGET(user_data));
4242 }
4243
4244 static void
4245 destroy_folder_information_note (ModestMailOperation *mail_op, 
4246                                  TnyFolder *new_folder,
4247                                  gpointer user_data)
4248 {
4249         /* destroy information note */
4250         gtk_widget_destroy (GTK_WIDGET(user_data));
4251 }
4252
4253
4254 static void
4255 paste_as_attachment_free (gpointer data)
4256 {
4257         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4258
4259         if (helper->banner) {
4260                 gtk_widget_destroy (helper->banner);
4261                 g_object_unref (helper->banner);
4262         }
4263         g_free (helper);
4264 }
4265
4266 static void
4267 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4268                             TnyHeader *header,
4269                             TnyMsg *msg,
4270                             gpointer userdata)
4271 {
4272         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4273         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4274
4275         if (msg == NULL)
4276                 return;
4277
4278         modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4279         
4280 }
4281
4282 void
4283 modest_ui_actions_on_paste (GtkAction *action,
4284                             ModestWindow *window)
4285 {
4286         GtkWidget *focused_widget = NULL;
4287         GtkWidget *inf_note = NULL;
4288         ModestMailOperation *mail_op = NULL;
4289
4290         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4291         if (GTK_IS_EDITABLE (focused_widget)) {
4292                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4293         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4294                 ModestEmailClipboard *e_clipboard = NULL;
4295                 e_clipboard = modest_runtime_get_email_clipboard ();
4296                 if (modest_email_clipboard_cleared (e_clipboard)) {
4297                         GtkTextBuffer *buffer;
4298                         GtkClipboard *clipboard;
4299
4300                         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4301                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4302                         gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4303                 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4304                         ModestMailOperation *mail_op;
4305                         TnyFolder *src_folder = NULL;
4306                         TnyList *data = NULL;
4307                         gboolean delete;
4308                         PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4309                         helper->window = MODEST_MSG_EDIT_WINDOW (window);
4310                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4311                                                                            _CS("ckct_nw_pasting"));
4312                         modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4313                         mail_op = modest_mail_operation_new (G_OBJECT (window));
4314                         if (helper->banner != NULL) {
4315                                 g_object_ref (G_OBJECT (helper->banner));
4316                                 gtk_widget_show (GTK_WIDGET (helper->banner));
4317                         }
4318
4319                         if (data != NULL) {
4320                                 modest_mail_operation_get_msgs_full (mail_op, 
4321                                                                      data,
4322                                                                      (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4323                                                                      helper,
4324                                                                      paste_as_attachment_free);
4325                         }
4326                         /* Free */
4327                         if (data) 
4328                                 g_object_unref (data);
4329                         if (src_folder) 
4330                                 g_object_unref (src_folder);
4331
4332                 }
4333         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4334                 ModestEmailClipboard *clipboard = NULL;
4335                 TnyFolder *src_folder = NULL;
4336                 TnyFolderStore *folder_store = NULL;
4337                 TnyList *data = NULL;           
4338                 gboolean delete = FALSE;
4339                 
4340                 /* Check clipboard source */
4341                 clipboard = modest_runtime_get_email_clipboard ();
4342                 if (modest_email_clipboard_cleared (clipboard)) 
4343                         return;
4344                 
4345                 /* Get elements to paste */
4346                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4347
4348                 /* Create a new mail operation */
4349                 mail_op = modest_mail_operation_new (G_OBJECT(window));
4350                 
4351                 /* Get destination folder */
4352                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4353
4354                 /* transfer messages  */
4355                 if (data != NULL) {
4356                         gint response = 0;
4357
4358                         /* Ask for user confirmation */
4359                         response = 
4360                                 modest_ui_actions_msgs_move_to_confirmation (window, 
4361                                                                              TNY_FOLDER (folder_store), 
4362                                                                              delete,
4363                                                                              data);
4364                         
4365                         if (response == GTK_RESPONSE_OK) {
4366                                 /* Launch notification */
4367                                 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
4368                                                                              _CS("ckct_nw_pasting"));
4369                                 if (inf_note != NULL)  {
4370                                         gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4371                                         gtk_widget_show (GTK_WIDGET(inf_note));
4372                                 }
4373
4374                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4375                                 modest_mail_operation_xfer_msgs (mail_op, 
4376                                                                  data,
4377                                                                  TNY_FOLDER (folder_store),
4378                                                                  delete,
4379                                                                  destroy_information_note,
4380                                                                  inf_note);                             
4381                         } else {
4382                                 g_object_unref (mail_op);
4383                         }
4384                         
4385                 } else if (src_folder != NULL) {                        
4386                         /* Launch notification */
4387                         inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
4388                                                                      _CS("ckct_nw_pasting"));
4389                         if (inf_note != NULL)  {
4390                                 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4391                                 gtk_widget_show (GTK_WIDGET(inf_note));
4392                         }
4393                         
4394                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4395                         modest_mail_operation_xfer_folder (mail_op, 
4396                                                            src_folder,
4397                                                            folder_store,
4398                                                            delete,
4399                                                            destroy_folder_information_note,
4400                                                            inf_note);
4401                 }
4402
4403                 /* Free */
4404                 if (data != NULL) 
4405                         g_object_unref (data);
4406                 if (src_folder != NULL) 
4407                         g_object_unref (src_folder);
4408                 if (folder_store != NULL) 
4409                         g_object_unref (folder_store);
4410         }
4411 }
4412
4413
4414 void
4415 modest_ui_actions_on_select_all (GtkAction *action,
4416                                  ModestWindow *window)
4417 {
4418         GtkWidget *focused_widget;
4419
4420         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4421         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4422                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4423         } else if (GTK_IS_LABEL (focused_widget)) {
4424                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4425         } else if (GTK_IS_EDITABLE (focused_widget)) {
4426                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4427         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4428                 GtkTextBuffer *buffer;
4429                 GtkTextIter start, end;
4430
4431                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4432                 gtk_text_buffer_get_start_iter (buffer, &start);
4433                 gtk_text_buffer_get_end_iter (buffer, &end);
4434                 gtk_text_buffer_select_range (buffer, &start, &end);
4435         } else if (GTK_IS_HTML (focused_widget)) {
4436                 gtk_html_select_all (GTK_HTML (focused_widget));
4437         } else if (MODEST_IS_MAIN_WINDOW (window)) {
4438                 GtkWidget *header_view = focused_widget;
4439                 GtkTreeSelection *selection = NULL;
4440                 
4441                 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4442                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4443                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4444                 }
4445                                 
4446                 /* Disable window dimming management */
4447                 modest_window_disable_dimming (MODEST_WINDOW(window));
4448                 
4449                 /* Select all messages */
4450                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4451                 gtk_tree_selection_select_all (selection);
4452
4453                 /* Set focuse on header view */
4454                 gtk_widget_grab_focus (header_view);
4455
4456                 /* Enable window dimming management */
4457                 modest_window_enable_dimming (MODEST_WINDOW(window));
4458                 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4459                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4460         }
4461
4462 }
4463
4464 void
4465 modest_ui_actions_on_mark_as_read (GtkAction *action,
4466                                    ModestWindow *window)
4467 {       
4468         g_return_if_fail (MODEST_IS_WINDOW(window));
4469                 
4470         /* Mark each header as read */
4471         do_headers_action (window, headers_action_mark_as_read, NULL);
4472 }
4473
4474 void
4475 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4476                                      ModestWindow *window)
4477 {       
4478         g_return_if_fail (MODEST_IS_WINDOW(window));
4479                 
4480         /* Mark each header as read */
4481         do_headers_action (window, headers_action_mark_as_unread, NULL);
4482 }
4483
4484 void
4485 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4486                                   GtkRadioAction *selected,
4487                                   ModestWindow *window)
4488 {
4489         gint value;
4490
4491         value = gtk_radio_action_get_current_value (selected);
4492         if (MODEST_IS_WINDOW (window)) {
4493                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4494         }
4495 }
4496
4497 void
4498 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4499                                                GtkRadioAction *selected,
4500                                                ModestWindow *window)
4501 {
4502         TnyHeaderFlags flags;
4503         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4504
4505         flags = gtk_radio_action_get_current_value (selected);
4506         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4507 }
4508
4509 void
4510 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4511                                                   GtkRadioAction *selected,
4512                                                   ModestWindow *window)
4513 {
4514         gint file_format;
4515
4516         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4517
4518         file_format = gtk_radio_action_get_current_value (selected);
4519         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4520 }
4521
4522
4523 void
4524 modest_ui_actions_on_zoom_plus (GtkAction *action,
4525                                 ModestWindow *window)
4526 {
4527         g_return_if_fail (MODEST_IS_WINDOW (window));
4528
4529         modest_window_zoom_plus (MODEST_WINDOW (window));
4530 }
4531
4532 void     
4533 modest_ui_actions_on_zoom_minus (GtkAction *action,
4534                                  ModestWindow *window)
4535 {
4536         g_return_if_fail (MODEST_IS_WINDOW (window));
4537
4538         modest_window_zoom_minus (MODEST_WINDOW (window));
4539 }
4540
4541 void     
4542 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
4543                                            ModestWindow *window)
4544 {
4545         ModestWindowMgr *mgr;
4546         gboolean fullscreen, active;
4547         g_return_if_fail (MODEST_IS_WINDOW (window));
4548
4549         mgr = modest_runtime_get_window_mgr ();
4550
4551         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4552         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4553
4554         if (active != fullscreen) {
4555                 modest_window_mgr_set_fullscreen_mode (mgr, active);
4556 #ifndef MODEST_TOOLKIT_HILDON2
4557                 gtk_window_present (GTK_WINDOW (window));
4558 #endif
4559         }
4560 }
4561
4562 void
4563 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4564                                         ModestWindow *window)
4565 {
4566         ModestWindowMgr *mgr;
4567         gboolean fullscreen;
4568
4569         g_return_if_fail (MODEST_IS_WINDOW (window));
4570
4571         mgr = modest_runtime_get_window_mgr ();
4572         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4573         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4574
4575 #ifndef MODEST_TOOLKIT_HILDON2
4576         gtk_window_present (GTK_WINDOW (window));
4577 #endif
4578 }
4579
4580 /* 
4581  * Used by modest_ui_actions_on_details to call do_headers_action 
4582  */
4583 static void
4584 headers_action_show_details (TnyHeader *header,
4585                              ModestWindow *window,
4586                              gpointer user_data)
4587
4588 {
4589         modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4590 }
4591
4592 /*
4593  * Show the header details in a ModestDetailsDialog widget
4594  */
4595 void
4596 modest_ui_actions_on_details (GtkAction *action,
4597                               ModestWindow *win)
4598 {
4599         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4600                 TnyMsg *msg;
4601                 TnyHeader *header;
4602
4603                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4604                 if (!msg)
4605                         return;
4606
4607                 header = tny_msg_get_header (msg);
4608                 if (header) {
4609                         headers_action_show_details (header, win, NULL);
4610                         g_object_unref (header);
4611                 }
4612                 g_object_unref (msg);
4613
4614         } else if (MODEST_IS_MAIN_WINDOW (win)) {
4615                 GtkWidget *folder_view, *header_view;
4616
4617                 /* Check which widget has the focus */
4618                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4619                                                                     MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4620                 if (gtk_widget_is_focus (folder_view)) {
4621                         TnyFolderStore *folder_store
4622                                 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4623                         if (!folder_store) {
4624                                 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4625                                 return; 
4626                         }
4627                         /* Show only when it's a folder */
4628                         /* This function should not be called for account items, 
4629                          * because we dim the menu item for them. */
4630                         if (TNY_IS_FOLDER (folder_store)) {
4631                                 modest_platform_run_folder_details_dialog (GTK_WINDOW (win), 
4632                                                                            TNY_FOLDER (folder_store));
4633                         }
4634
4635                         g_object_unref (folder_store);
4636
4637                 } else {
4638                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4639                                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4640                         /* Show details of each header */
4641                         do_headers_action (win, headers_action_show_details, header_view);
4642                 }
4643 #ifdef MODEST_TOOLKIT_HILDON2
4644         } else if (MODEST_IS_HEADER_WINDOW (win)) {
4645                 TnyFolder *folder;
4646                 GtkWidget *header_view;
4647
4648                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4649                 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4650                 if (folder) {
4651                         modest_platform_run_folder_details_dialog (GTK_WINDOW (win), 
4652                                                                    folder);
4653                         g_object_unref (folder);
4654                 }
4655 #endif
4656         }
4657 }
4658
4659 void     
4660 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4661                                      ModestMsgEditWindow *window)
4662 {
4663         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4664
4665         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4666 }
4667
4668 void     
4669 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4670                                       ModestMsgEditWindow *window)
4671 {
4672         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4673
4674         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4675 }
4676
4677 void
4678 modest_ui_actions_toggle_folders_view (GtkAction *action, 
4679                                        ModestMainWindow *main_window)
4680 {
4681         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4682
4683         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4684                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4685         else
4686                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4687 }
4688
4689 void 
4690 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
4691                                      ModestWindow *window)
4692 {
4693         gboolean active, fullscreen = FALSE;
4694         ModestWindowMgr *mgr;
4695
4696         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4697
4698         /* Check if we want to toggle the toolbar view in fullscreen
4699            or normal mode */
4700         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
4701                      "ViewShowToolbarFullScreen")) {
4702                 fullscreen = TRUE;
4703         }
4704
4705         /* Toggle toolbar */
4706         mgr = modest_runtime_get_window_mgr ();
4707         modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4708 }
4709
4710 void     
4711 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4712                                            ModestMsgEditWindow *window)
4713 {
4714         modest_msg_edit_window_select_font (window);
4715 }
4716
4717
4718 void
4719 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4720                                                   const gchar *display_name,
4721                                                   GtkWindow *window)
4722 {
4723         /* don't update the display name if it was already set;
4724          * updating the display name apparently is expensive */
4725         const gchar* old_name = gtk_window_get_title (window);
4726
4727         if (display_name == NULL)
4728                 display_name = " ";
4729
4730         if (old_name && display_name && strcmp (old_name, display_name) == 0)
4731                 return; /* don't do anything */
4732
4733         /* This is usually used to change the title of the main window, which
4734          * is the one that holds the folder view. Note that this change can
4735          * happen even when the widget doesn't have the focus. */
4736         gtk_window_set_title (window, display_name);
4737
4738 }
4739
4740 void
4741 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4742 {
4743         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4744         modest_msg_edit_window_select_contacts (window);
4745 }
4746
4747 void
4748 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4749 {
4750         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4751         modest_msg_edit_window_check_names (window, FALSE);
4752 }
4753
4754 #ifndef MODEST_TOOLKIT_HILDON2
4755 /*
4756  * This function is used to track changes in the selection of the
4757  * folder view that is inside the "move to" dialog to enable/disable
4758  * the OK button because we do not want the user to select a disallowed
4759  * destination for a folder.
4760  * The user also not desired to be able to use NEW button on items where
4761  * folder creation is not possibel.
4762  */
4763 static void
4764 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4765                                             TnyFolderStore *folder_store,
4766                                             gboolean selected,
4767                                             gpointer user_data)
4768 {
4769         GtkWidget *dialog = NULL;
4770         gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4771         gboolean moving_folder = FALSE;
4772         gboolean is_local_account = TRUE;
4773         GtkWidget *folder_view = NULL;
4774         ModestTnyFolderRules rules;
4775
4776         g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4777
4778         if (!selected)
4779                 return;
4780
4781         dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4782         if (!dialog)
4783                 return;
4784
4785         /* check if folder_store is an remote account */
4786         if (TNY_IS_ACCOUNT (folder_store)) {
4787                 TnyAccount *local_account = NULL;
4788                 TnyAccount *mmc_account = NULL;
4789                 ModestTnyAccountStore *account_store = NULL;
4790
4791                 account_store = modest_runtime_get_account_store ();
4792                 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4793                 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4794
4795                 if ((gpointer) local_account != (gpointer) folder_store &&
4796                     (gpointer) mmc_account != (gpointer) folder_store) {
4797                         ModestProtocolType proto;
4798                         proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4799                         if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4800                                 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4801                         }
4802                         is_local_account = FALSE;
4803                         /* New button should be dimmed on remote
4804                            POP account root */
4805                         new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4806                                                                                          proto,
4807                                                                                          MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4808                 }
4809                 g_object_unref (local_account);
4810
4811                 /* It could not exist */
4812                 if (mmc_account)
4813                         g_object_unref (mmc_account);
4814         }
4815
4816         /* Check the target folder rules */
4817         if (TNY_IS_FOLDER (folder_store)) {
4818                 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4819                 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4820                         ok_sensitive = FALSE;
4821                         new_sensitive = FALSE;
4822                         goto end;
4823                 }
4824         }
4825
4826         /* Check if we're moving a folder */
4827         if (MODEST_IS_MAIN_WINDOW (user_data)) {
4828                 /* Get the widgets */
4829                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4830                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4831                 if (gtk_widget_is_focus (folder_view))
4832                         moving_folder = TRUE;
4833         }
4834
4835         if (moving_folder) {
4836                 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4837
4838                 /* Get the folder to move */
4839                 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4840
4841                 /* Check that we're not moving to the same folder */
4842                 if (TNY_IS_FOLDER (moved_folder)) {
4843                         parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4844                         if (parent == folder_store)
4845                                 ok_sensitive = FALSE;
4846                         g_object_unref (parent);
4847                 }
4848
4849                 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4850                         /* Do not allow to move to an account unless it's the
4851                            local folders account */
4852                         if (!is_local_account)
4853                                 ok_sensitive = FALSE;
4854                 }
4855
4856                 if (ok_sensitive && (moved_folder == folder_store)) {
4857                         /* Do not allow to move to itself */
4858                         ok_sensitive = FALSE;
4859                 }
4860                 g_object_unref (moved_folder);
4861         } else {
4862                 TnyFolder *src_folder = NULL;
4863
4864                 /* Moving a message */
4865                 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4866
4867                         TnyHeader *header = NULL;
4868                         header = modest_msg_view_window_get_header
4869                                 (MODEST_MSG_VIEW_WINDOW (user_data));
4870                         if (!TNY_IS_HEADER(header))
4871                                 g_warning ("%s: could not get source header", __FUNCTION__);
4872                         else
4873                                 src_folder = tny_header_get_folder (header);
4874
4875                         if (header)
4876                                 g_object_unref (header);
4877                 } else {
4878                         src_folder = 
4879                                 TNY_FOLDER (modest_folder_view_get_selected
4880                                             (MODEST_FOLDER_VIEW (folder_view)));
4881                 }
4882
4883                 if (TNY_IS_FOLDER(src_folder)) {
4884                         /* Do not allow to move the msg to the same folder */
4885                         /* Do not allow to move the msg to an account */
4886                         if ((gpointer) src_folder == (gpointer) folder_store ||
4887                             TNY_IS_ACCOUNT (folder_store))
4888                                 ok_sensitive = FALSE;
4889                         g_object_unref (src_folder);
4890                 } else
4891                         g_warning ("%s: could not get source folder", __FUNCTION__);
4892         }
4893
4894  end:
4895         /* Set sensitivity of the OK and NEW button */
4896         gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4897         gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4898 }
4899 #endif
4900
4901 static void
4902 on_move_to_dialog_response (GtkDialog *dialog,
4903                             gint       response,
4904                             gpointer   user_data)
4905 {
4906         GtkWidget *parent_win;
4907         MoveToInfo *helper = NULL;
4908         ModestFolderView *folder_view;
4909
4910         helper = (MoveToInfo *) user_data;
4911
4912         parent_win = (GtkWidget *) helper->win;
4913         folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4914                                                              MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4915
4916         switch (response) {
4917                 TnyFolderStore *dst_folder;
4918
4919         case MODEST_GTK_RESPONSE_NEW_FOLDER:
4920                 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view));
4921                 return;
4922         case GTK_RESPONSE_NONE:
4923         case GTK_RESPONSE_CANCEL:
4924         case GTK_RESPONSE_DELETE_EVENT:
4925                 break;
4926         case GTK_RESPONSE_OK:
4927                 dst_folder = modest_folder_view_get_selected (folder_view);
4928
4929                 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4930                         /* Clean list to move used for filtering */
4931                         modest_folder_view_set_list_to_move (folder_view, NULL);
4932
4933                         modest_ui_actions_on_main_window_move_to (NULL,
4934                                                                   GTK_WIDGET (folder_view),
4935                                                                   dst_folder,
4936                                                                   MODEST_MAIN_WINDOW (parent_win));
4937 #ifdef MODEST_TOOLKIT_HILDON2
4938                 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4939                         /* Clean list to move used for filtering */
4940                         modest_folder_view_set_list_to_move (folder_view, NULL);
4941
4942                         modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4943                                                                     dst_folder,
4944                                                                     helper->list,
4945                                                                     GTK_WINDOW (parent_win));
4946 #endif
4947                 } else {
4948                         /* if the user selected a root folder
4949                            (account) then do not perform any action */
4950                         if (TNY_IS_ACCOUNT (dst_folder)) {
4951                                 g_signal_stop_emission_by_name (dialog, "response");
4952                                 return;
4953                         }
4954
4955                         /* Clean list to move used for filtering */
4956                         modest_folder_view_set_list_to_move (folder_view, NULL);
4957
4958                         /* Moving from headers window in edit mode */
4959                         modest_ui_actions_on_window_move_to (NULL, helper->list,
4960                                                              dst_folder, 
4961                                                              MODEST_WINDOW (parent_win));
4962                 }
4963
4964                 if (dst_folder)
4965                         g_object_unref (dst_folder);
4966
4967                 break;
4968         default:
4969                 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4970         }
4971
4972         /* Free the helper and exit */
4973         if (helper->list)
4974                 g_object_unref (helper->list);
4975         g_slice_free (MoveToInfo, helper);
4976         gtk_widget_destroy (GTK_WIDGET (dialog));
4977 }
4978
4979 static GtkWidget*
4980 create_move_to_dialog (GtkWindow *win,
4981                        GtkWidget *folder_view,
4982                        TnyList *list_to_move)
4983 {
4984         GtkWidget *dialog, *tree_view = NULL;
4985
4986         dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4987
4988 #ifndef MODEST_TOOLKIT_HILDON2
4989         /* Track changes in the selection to
4990          * disable the OK button whenever "Move to" is not possible
4991          * disbale NEW button whenever New is not possible */
4992         g_signal_connect (tree_view,
4993                           "folder_selection_changed",
4994                           G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4995                           win);
4996 #endif
4997
4998         /* It could happen that we're trying to move a message from a
4999            window (msg window for example) after the main window was
5000            closed, so we can not just get the model of the folder
5001            view */
5002         if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5003                 const gchar *visible_id = NULL;
5004
5005                 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5006                                               MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5007                 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view), 
5008                                                MODEST_FOLDER_VIEW(tree_view));
5009
5010                 visible_id = 
5011                         modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5012
5013                 /* Show the same account than the one that is shown in the main window */
5014                 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5015                                                                              visible_id);
5016         } else {
5017                 const gchar *active_account_name = NULL;
5018                 ModestAccountMgr *mgr = NULL;
5019                 ModestAccountSettings *settings = NULL;
5020                 ModestServerAccountSettings *store_settings = NULL;
5021
5022                 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5023                                               MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5024                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5025                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5026
5027                 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5028                 mgr = modest_runtime_get_account_mgr ();
5029                 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5030
5031                 if (settings) {
5032                         const gchar *store_account_name;
5033                         store_settings = modest_account_settings_get_store_settings (settings);
5034                         store_account_name = modest_server_account_settings_get_account_name (store_settings);
5035
5036                         modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5037                                                                                      store_account_name);
5038                         g_object_unref (store_settings);
5039                         g_object_unref (settings);
5040                 }
5041         }
5042
5043         /* we keep a pointer to the embedded folder view, so we can
5044          *   retrieve it with get_folder_view_from_move_to_dialog (see
5045          *   above) later (needed for focus handling)
5046          */
5047         g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5048
5049         /* Hide special folders */
5050         modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5051         if (list_to_move)
5052                 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5053 #ifndef MODEST_TOOLKIT_HILDON2
5054         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5055 #endif
5056
5057         gtk_widget_show (GTK_WIDGET (tree_view));
5058
5059         return dialog;
5060 }
5061
5062 /*
5063  * Shows a confirmation dialog to the user when we're moving messages
5064  * from a remote server to the local storage. Returns the dialog
5065  * response. If it's other kind of movement then it always returns
5066  * GTK_RESPONSE_OK
5067  *
5068  * This one is used by the next functions:
5069  *      modest_ui_actions_on_paste                      - commented out
5070  *      drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5071  */
5072 gint
5073 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5074                                              TnyFolder *dest_folder,
5075                                              gboolean delete,
5076                                              TnyList *headers)
5077 {
5078         gint response = GTK_RESPONSE_OK;
5079         TnyAccount *account = NULL;
5080         TnyFolder *src_folder = NULL;
5081         TnyIterator *iter = NULL;
5082         TnyHeader *header = NULL;
5083
5084         /* return with OK if the destination is a remote folder */
5085         if (modest_tny_folder_is_remote_folder (dest_folder))
5086                 return GTK_RESPONSE_OK;
5087
5088         /* Get source folder */
5089         iter = tny_list_create_iterator (headers);
5090         header = TNY_HEADER (tny_iterator_get_current (iter));
5091         if (header) {
5092                 src_folder = tny_header_get_folder (header);
5093                 g_object_unref (header);
5094         }
5095         g_object_unref (iter);
5096
5097         /* if no src_folder, message may be an attahcment */
5098         if (src_folder == NULL) 
5099                 return GTK_RESPONSE_CANCEL;
5100
5101         /* If the source is a local or MMC folder */
5102         if (!modest_tny_folder_is_remote_folder (src_folder)) {
5103                 g_object_unref (src_folder);
5104                 return GTK_RESPONSE_OK;
5105         }
5106
5107         /* Get the account */
5108         account = tny_folder_get_account (src_folder);
5109
5110         /* now if offline we ask the user */
5111         if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5112                 response = GTK_RESPONSE_OK;
5113         else
5114                 response = GTK_RESPONSE_CANCEL;
5115
5116         /* Frees */
5117         g_object_unref (src_folder);
5118         g_object_unref (account);
5119
5120         return response;
5121 }
5122
5123 static void
5124 move_to_helper_destroyer (gpointer user_data)
5125 {
5126         MoveToHelper *helper = (MoveToHelper *) user_data;
5127
5128         /* Close the "Pasting" information banner */
5129         if (helper->banner) {
5130                 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5131                 g_object_unref (helper->banner);
5132         }
5133         if (gtk_tree_row_reference_valid (helper->reference)) {
5134                 gtk_tree_row_reference_free (helper->reference);
5135                 helper->reference = NULL;
5136         }
5137         g_free (helper);
5138 }
5139
5140 static void
5141 move_to_cb (ModestMailOperation *mail_op, 
5142             gpointer user_data)
5143 {
5144         MoveToHelper *helper = (MoveToHelper *) user_data;
5145         GObject *object = modest_mail_operation_get_source (mail_op);
5146
5147         /* Note that the operation could have failed, in that case do
5148            nothing */
5149         if (modest_mail_operation_get_status (mail_op) != 
5150             MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5151                 goto frees;
5152
5153         if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5154                 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5155
5156                 if (!modest_msg_view_window_select_next_message (self) &&
5157                     !modest_msg_view_window_select_previous_message (self)) {
5158                         /* No more messages to view, so close this window */
5159                         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5160                 }
5161         } else if (MODEST_IS_MAIN_WINDOW (object) && 
5162                    gtk_tree_row_reference_valid (helper->reference)) {
5163                 GtkWidget *header_view;
5164                 GtkTreePath *path;
5165                 GtkTreeSelection *sel;
5166
5167                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5168                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5169                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5170                 path = gtk_tree_row_reference_get_path (helper->reference);
5171                 /* We need to unselect the previous one
5172                    because we could be copying instead of
5173                    moving */
5174                 gtk_tree_selection_unselect_all (sel);
5175                 gtk_tree_selection_select_path (sel, path);
5176                 gtk_tree_path_free (path);
5177         }
5178         g_object_unref (object);
5179
5180  frees:
5181         /* Destroy the helper */
5182         move_to_helper_destroyer (helper);
5183 }
5184
5185 static void
5186 folder_move_to_cb (ModestMailOperation *mail_op, 
5187                    TnyFolder *new_folder,
5188                    gpointer user_data)
5189 {
5190         GtkWidget *folder_view;
5191         GObject *object;
5192
5193         object = modest_mail_operation_get_source (mail_op);
5194         if (MODEST_IS_MAIN_WINDOW (object)) {
5195                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5196                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5197                 g_object_ref (folder_view);
5198                 g_object_unref (object);
5199                 move_to_cb (mail_op, user_data);
5200                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5201                 g_object_unref (folder_view);
5202         } else {
5203                 move_to_cb (mail_op, user_data);
5204         }
5205 }
5206
5207 static void
5208 msgs_move_to_cb (ModestMailOperation *mail_op, 
5209                  gpointer user_data)
5210 {
5211         move_to_cb (mail_op, user_data);
5212 }
5213
5214 void
5215 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
5216                                              gpointer user_data)
5217 {
5218         GObject *win = NULL;
5219
5220 #ifndef MODEST_TOOLKIT_HILDON2
5221         ModestWindow *main_window = NULL;
5222
5223         /* Disable next automatic folder selection */
5224         main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5225                                                          FALSE); /* don't create */
5226         if (main_window) {
5227                 GtkWidget *folder_view = NULL;
5228
5229                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5230                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW); 
5231                 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5232
5233                 if (user_data && TNY_IS_FOLDER (user_data)) {
5234                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), 
5235                                                           TNY_FOLDER (user_data), FALSE);
5236                 }
5237         }
5238 #endif
5239         /* Show notification dialog only if the main window exists */
5240         win = modest_mail_operation_get_source (mail_op);
5241         modest_platform_run_information_dialog ((GtkWindow *) win, 
5242                                                 _("mail_in_ui_folder_move_target_error"), 
5243                                                 FALSE);
5244         if (win)
5245                 g_object_unref (win);
5246 }
5247
5248 static void
5249 open_msg_for_purge_cb (ModestMailOperation *mail_op, 
5250                        TnyHeader *header, 
5251                        gboolean canceled,
5252                        TnyMsg *msg, 
5253                        GError *err,
5254                        gpointer user_data)
5255 {
5256         TnyList *parts;
5257         TnyIterator *iter;
5258         gint pending_purges = 0;
5259         gboolean some_purged = FALSE;
5260         ModestWindow *win = MODEST_WINDOW (user_data);
5261         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5262
5263         /* If there was any error */
5264         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5265                 modest_window_mgr_unregister_header (mgr, header);
5266                 return;
5267         }
5268
5269         /* Once the message has been retrieved for purging, we check if
5270          * it's all ok for purging */
5271
5272         parts = tny_simple_list_new ();
5273         tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5274         iter = tny_list_create_iterator (parts);
5275
5276         while (!tny_iterator_is_done (iter)) {
5277                 TnyMimePart *part;
5278                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5279                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5280                         if (tny_mime_part_is_purged (part))
5281                                 some_purged = TRUE;
5282                         else
5283                                 pending_purges++;
5284                 }
5285
5286                 if (part)
5287                         g_object_unref (part);
5288
5289                 tny_iterator_next (iter);
5290         }
5291         g_object_unref (iter);
5292         
5293
5294         if (pending_purges>0) {
5295                 gint response;
5296                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5297
5298                 if (response == GTK_RESPONSE_OK) {
5299                         GtkWidget *info;
5300                         info =
5301                                 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5302                         iter = tny_list_create_iterator (parts);
5303                         while (!tny_iterator_is_done (iter)) {
5304                                 TnyMimePart *part;
5305                                 
5306                                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5307                                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5308                                         tny_mime_part_set_purged (part);
5309
5310                                 if (part)
5311                                         g_object_unref (part);
5312
5313                                 tny_iterator_next (iter);
5314                         }
5315                         g_object_unref (iter);
5316                         
5317                         tny_msg_rewrite_cache (msg);
5318
5319                         gtk_widget_destroy (info);
5320                 }
5321         }
5322
5323         modest_window_mgr_unregister_header (mgr, header);
5324
5325         g_object_unref (parts);
5326 }
5327
5328 static void
5329 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5330                                                      ModestMainWindow *win)
5331 {
5332         GtkWidget *header_view;
5333         TnyList *header_list;
5334         TnyHeader *header;
5335         TnyHeaderFlags flags;
5336         ModestWindow *msg_view_window =  NULL;
5337         gboolean found;
5338
5339         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5340
5341         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5342                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5343
5344         header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5345         if (!header_list) {
5346                 g_warning ("%s: no header selected", __FUNCTION__);
5347                 return;
5348         }
5349         
5350         if (tny_list_get_length (header_list) == 1) {
5351                 TnyIterator *iter = tny_list_create_iterator (header_list);
5352                 header = TNY_HEADER (tny_iterator_get_current (iter));
5353                 g_object_unref (iter);
5354         } else
5355                 return;
5356         
5357         if (!header || !TNY_IS_HEADER(header)) {
5358                 g_warning ("%s: header is not valid", __FUNCTION__);
5359                 return;
5360         }
5361         
5362         found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5363                                                           header, &msg_view_window);
5364         flags = tny_header_get_flags (header);
5365         if (!(flags & TNY_HEADER_FLAG_CACHED))
5366                 return;
5367         if (found) {
5368                 if (msg_view_window != NULL) 
5369                         modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5370                 else {
5371                         /* do nothing; uid was registered before, so window is probably on it's way */
5372                         g_warning ("debug: header %p has already been registered", header);
5373                 }
5374         } else {
5375                 ModestMailOperation *mail_op = NULL;
5376                 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5377                 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5378                                                                          modest_ui_actions_disk_operations_error_handler,
5379                                                                          NULL, NULL);
5380                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5381                 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5382                 
5383                 g_object_unref (mail_op);
5384         }
5385         if (header)
5386                 g_object_unref (header);
5387         if (header_list)
5388                 g_object_unref (header_list);
5389 }
5390
5391 /*
5392  * Checks if we need a connection to do the transfer and if the user
5393  * wants to connect to complete it
5394  */
5395 static void
5396 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5397                                        TnyFolderStore *src_folder,
5398                                        TnyList *headers,
5399                                        TnyFolder *dst_folder,
5400                                        gboolean delete_originals,
5401                                        gboolean *need_connection,
5402                                        gboolean *do_xfer)
5403 {
5404         TnyAccount *src_account;
5405         gint uncached_msgs = 0;
5406
5407         /* We don't need any further check if
5408          *
5409          * 1- the source folder is local OR
5410          * 2- the device is already online
5411          */
5412         if (!modest_tny_folder_store_is_remote (src_folder) ||
5413             tny_device_is_online (modest_runtime_get_device())) {
5414                 *need_connection = FALSE;
5415                 *do_xfer = TRUE;
5416                 return;
5417         }
5418
5419         /* We must ask for a connection when
5420          *
5421          *   - the message(s) is not already cached   OR 
5422          *   - the message(s) is cached but the leave_on_server setting
5423          * is FALSE (because we need to sync the source folder to
5424          * delete the message from the server (for IMAP we could do it
5425          * offline, it'll take place the next time we get a
5426          * connection)
5427          */
5428         uncached_msgs = header_list_count_uncached_msgs (headers);
5429         src_account = get_account_from_folder_store (src_folder);
5430         if (uncached_msgs > 0) {
5431                 guint num_headers;
5432                 const gchar *msg;
5433
5434                 *need_connection = TRUE;
5435                 num_headers = tny_list_get_length (headers);
5436                 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5437
5438                 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5439                     GTK_RESPONSE_CANCEL) {
5440                         *do_xfer = FALSE;
5441                 } else {
5442                         *do_xfer = TRUE;
5443                 }
5444         } else {
5445                 /* The transfer is possible and the user wants to */
5446                 *do_xfer = TRUE;
5447
5448                 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5449                         const gchar *account_name;
5450                         gboolean leave_on_server;
5451
5452                         account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5453                         leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5454                                                                                   account_name);
5455
5456                         if (leave_on_server == TRUE) {
5457                                 *need_connection = FALSE;
5458                         } else {
5459                                 *need_connection = TRUE;
5460                         }
5461                 } else {
5462                         *need_connection = FALSE;
5463                 }
5464         }
5465
5466         /* Frees */
5467         g_object_unref (src_account);
5468 }
5469
5470 static void
5471 xfer_messages_error_handler (ModestMailOperation *mail_op, 
5472                              gpointer user_data)
5473 {
5474         GObject *win;
5475         const GError *error;
5476
5477         win = modest_mail_operation_get_source (mail_op);
5478         error = modest_mail_operation_get_error (mail_op);
5479
5480         if (error && is_memory_full_error ((GError *) error))
5481                 modest_platform_information_banner ((GtkWidget *) win,
5482                                                     NULL, _KR("cerm_device_memory_full"));
5483         else
5484                 modest_platform_run_information_dialog ((GtkWindow *) win, 
5485                                                         _("mail_in_ui_folder_move_target_error"), 
5486                                                         FALSE);
5487         if (win)
5488                 g_object_unref (win);
5489 }
5490
5491 typedef struct {
5492         TnyFolderStore *dst_folder;
5493         TnyList *headers;
5494 } XferMsgsHelper;
5495
5496 /**
5497  * Utility function that transfer messages from both the main window
5498  * and the msg view window when using the "Move to" dialog
5499  */
5500 static void
5501 xfer_messages_performer  (gboolean canceled, 
5502                           GError *err,
5503                           GtkWindow *parent_window, 
5504                           TnyAccount *account, 
5505                           gpointer user_data)
5506 {
5507         ModestWindow *win = MODEST_WINDOW (parent_window);
5508         TnyAccount *dst_account = NULL;
5509         gboolean dst_forbids_message_add = FALSE;
5510         XferMsgsHelper *helper;
5511         MoveToHelper *movehelper;
5512         ModestMailOperation *mail_op;
5513
5514         helper = (XferMsgsHelper *) user_data;
5515
5516         if (canceled || err) {
5517                 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5518                         /* Show the proper error message */
5519                         modest_ui_actions_on_account_connection_error (parent_window, account);
5520                 }
5521                 goto end;
5522         }
5523
5524         dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5525
5526         /* tinymail will return NULL for local folders it seems */
5527         dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5528                                                                                   modest_tny_account_get_protocol_type (dst_account),
5529                                                                                   MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5530         g_object_unref (dst_account);
5531
5532         if (dst_forbids_message_add) {
5533                 modest_platform_information_banner (GTK_WIDGET (win),
5534                                                     NULL,
5535                                                     ngettext("mail_in_ui_folder_move_target_error",
5536                                                              "mail_in_ui_folder_move_targets_error",
5537                                                              tny_list_get_length (helper->headers)));
5538                 goto end;
5539         }
5540
5541         movehelper = g_new0 (MoveToHelper, 1);
5542
5543 #ifndef MODEST_TOOLKIT_HILDON2
5544         movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5545                                                                _CS("ckct_nw_pasting"));
5546         if (movehelper->banner != NULL)  {
5547                 g_object_ref (movehelper->banner);
5548                 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5549         }
5550 #endif
5551
5552         if (MODEST_IS_MAIN_WINDOW (win)) {
5553                 GtkWidget *header_view = 
5554                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5555                                                              MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5556                 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5557         }
5558
5559         /* Perform the mail operation */
5560         mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5561                                                                  xfer_messages_error_handler,
5562                                                                  movehelper, NULL);
5563         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
5564                                          mail_op);
5565
5566         modest_mail_operation_xfer_msgs (mail_op, 
5567                                          helper->headers,
5568                                          TNY_FOLDER (helper->dst_folder),
5569                                          TRUE,
5570                                          msgs_move_to_cb,
5571                                          movehelper);
5572
5573         g_object_unref (G_OBJECT (mail_op));
5574  end:
5575         g_object_unref (helper->dst_folder);
5576         g_object_unref (helper->headers);
5577         g_slice_free (XferMsgsHelper, helper);
5578 }
5579
5580 typedef struct {
5581         TnyFolder *src_folder;
5582         TnyFolderStore *dst_folder;
5583         gboolean delete_original;
5584         GtkWidget *folder_view;
5585 } MoveFolderInfo;
5586
5587 static void
5588 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window, 
5589                 TnyAccount *account, gpointer user_data)
5590 {
5591         MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5592         GtkTreeSelection *sel;
5593         ModestMailOperation *mail_op = NULL;
5594
5595         if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5596                 g_object_unref (G_OBJECT (info->src_folder));
5597                 g_object_unref (G_OBJECT (info->dst_folder));
5598                 g_free (info);
5599                 return;
5600         }
5601
5602         MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5603 #ifndef MODEST_TOOLKIT_HILDON2
5604         helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5605                         _CS("ckct_nw_pasting"));
5606         if (helper->banner != NULL)  {
5607                 g_object_ref (helper->banner);
5608                 gtk_widget_show (GTK_WIDGET(helper->banner));
5609         }
5610 #endif
5611         /* Clean folder on header view before moving it */
5612         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5613         gtk_tree_selection_unselect_all (sel);
5614
5615         /* Let gtk events run. We need that the folder
5616            view frees its reference to the source
5617            folder *before* issuing the mail operation
5618            so we need the signal handler of selection
5619            changed to happen before the mail
5620            operation 
5621         while (gtk_events_pending ())
5622                 gtk_main_iteration ();   */
5623
5624         mail_op =
5625                 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5626                                 modest_ui_actions_move_folder_error_handler,
5627                                 info->src_folder, NULL);
5628         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5629                         mail_op);
5630
5631         /* Select *after* the changes */
5632         /* TODO: this function hangs UI after transfer */ 
5633         /*                      modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5634         /*                                                        TNY_FOLDER (src_folder), TRUE); */
5635
5636         if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5637                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5638                                                   TNY_FOLDER (info->dst_folder), TRUE);
5639         }
5640         modest_mail_operation_xfer_folder (mail_op,
5641                         TNY_FOLDER (info->src_folder),
5642                         info->dst_folder,
5643                         info->delete_original, 
5644                         folder_move_to_cb, 
5645                         helper);
5646         g_object_unref (G_OBJECT (info->src_folder));
5647
5648         /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {        */
5649         /* } */
5650         
5651         /* Unref mail operation */
5652         g_object_unref (G_OBJECT (mail_op));
5653         g_object_unref (G_OBJECT (info->dst_folder));
5654         g_free (user_data);
5655 }
5656
5657 static TnyAccount *
5658 get_account_from_folder_store (TnyFolderStore *folder_store) 
5659 {
5660         if (TNY_IS_ACCOUNT (folder_store))
5661                 return g_object_ref (folder_store);
5662         else
5663                 return tny_folder_get_account (TNY_FOLDER (folder_store));
5664 }
5665
5666 /*
5667  * UI handler for the "Move to" action when invoked from the
5668  * ModestMainWindow
5669  */
5670 static void 
5671 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
5672                                           GtkWidget *folder_view,
5673                                           TnyFolderStore *dst_folder,
5674                                           ModestMainWindow *win)
5675 {
5676         ModestHeaderView *header_view = NULL;
5677         TnyFolderStore *src_folder = NULL;
5678
5679         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5680
5681         /* Get the source folder */
5682         src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5683
5684         /* Get header view */
5685         header_view = (ModestHeaderView *)
5686                 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5687
5688         /* Get folder or messages to transfer */
5689         if (gtk_widget_is_focus (folder_view)) {
5690                 gboolean do_xfer = TRUE;
5691
5692                 /* Allow only to transfer folders to the local root folder */
5693                 if (TNY_IS_ACCOUNT (dst_folder) && 
5694                     !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5695                     !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5696                         do_xfer = FALSE;
5697                 } else if (!TNY_IS_FOLDER (src_folder)) {
5698                         g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5699                         do_xfer = FALSE;
5700                 }
5701
5702                 if (do_xfer) {
5703                         MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5704                         DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5705
5706                         info->src_folder = g_object_ref (src_folder);
5707                         info->dst_folder = g_object_ref (dst_folder);
5708                         info->delete_original = TRUE;
5709                         info->folder_view = folder_view;
5710
5711                         connect_info->callback = on_move_folder_cb;
5712                         connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5713                         connect_info->data = info;
5714
5715                         modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5716                                                                    TNY_FOLDER_STORE (src_folder), 
5717                                                                    connect_info);
5718                 }
5719         } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5720                 TnyList *headers;
5721
5722                 headers = modest_header_view_get_selected_headers(header_view);
5723
5724                 /* Transfer the messages */
5725                 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder), 
5726                                                             headers, TNY_FOLDER (dst_folder));
5727
5728                 g_object_unref (headers);
5729         }
5730
5731         /* Frees */
5732         g_object_unref (src_folder);
5733 }
5734
5735 #ifdef MODEST_TOOLKIT_HILDON2
5736 /*
5737  * UI handler for the "Move to" action when invoked from the
5738  * ModestFolderWindow
5739  */
5740 static void 
5741 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5742                                             TnyFolderStore *dst_folder,
5743                                             TnyList *selection,
5744                                             GtkWindow *win)
5745 {
5746         TnyFolderStore *src_folder = NULL;
5747         TnyIterator *iterator;
5748
5749         if (tny_list_get_length (selection) != 1)
5750                 return;
5751
5752         iterator = tny_list_create_iterator (selection);
5753         src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5754         g_object_unref (iterator);
5755
5756
5757         gboolean do_xfer = TRUE;
5758
5759         /* Allow only to transfer folders to the local root folder */
5760         if (TNY_IS_ACCOUNT (dst_folder) && 
5761             !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5762             !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5763                 do_xfer = FALSE;
5764                 /* Show an error */
5765                 modest_platform_run_information_dialog (win,
5766                                                         _("mail_in_ui_folder_move_target_error"),
5767                                                         FALSE);
5768         } else if (!TNY_IS_FOLDER (src_folder)) {
5769                 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5770                 do_xfer = FALSE;
5771         }
5772
5773         if (do_xfer) {
5774                 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5775                 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5776
5777                 info->src_folder = g_object_ref (src_folder);
5778                 info->dst_folder = g_object_ref (dst_folder);
5779                 info->delete_original = TRUE;
5780                 info->folder_view = folder_view;
5781
5782                 connect_info->callback = on_move_folder_cb;
5783                 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5784                 connect_info->data = info;
5785
5786                 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5787                                                            TNY_FOLDER_STORE (src_folder), 
5788                                                            connect_info);
5789         }
5790
5791         /* Frees */
5792         g_object_unref (src_folder);
5793 }
5794 #endif
5795
5796
5797 void
5798 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5799                                             TnyFolder *src_folder,
5800                                             TnyList *headers,
5801                                             TnyFolder *dst_folder)
5802 {
5803         gboolean need_connection = TRUE;
5804         gboolean do_xfer = TRUE;
5805         XferMsgsHelper *helper;
5806
5807         g_return_if_fail (TNY_IS_FOLDER (src_folder));
5808         g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5809         g_return_if_fail (TNY_IS_LIST (headers));
5810         
5811         modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder), 
5812                                                headers, TNY_FOLDER (dst_folder),
5813                                                TRUE, &need_connection, 
5814                                                &do_xfer);
5815
5816         /* If we don't want to transfer just return */
5817         if (!do_xfer)
5818                 return;
5819
5820         /* Create the helper */
5821         helper = g_slice_new (XferMsgsHelper);
5822         helper->dst_folder = g_object_ref (dst_folder);
5823         helper->headers = g_object_ref (headers);
5824
5825         if (need_connection) {
5826                 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5827                 connect_info->callback = xfer_messages_performer;
5828                 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5829                 connect_info->data = helper;
5830                 
5831                 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5832                                                            TNY_FOLDER_STORE (src_folder), 
5833                                                            connect_info);
5834         } else {
5835                 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5836                 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5837                                          src_account, helper);
5838                 g_object_unref (src_account);
5839         }
5840 }
5841
5842 /*
5843  * UI handler for the "Move to" action when invoked from the
5844  * ModestMsgViewWindow
5845  */
5846 static void
5847 modest_ui_actions_on_window_move_to (GtkAction *action,
5848                                      TnyList *headers,
5849                                      TnyFolderStore *dst_folder,
5850                                      ModestWindow *win)
5851 {
5852         TnyFolder *src_folder = NULL;
5853
5854         g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5855
5856         if (headers) {
5857                 TnyHeader *header = NULL;
5858                 TnyIterator *iter;
5859
5860                 iter = tny_list_create_iterator (headers);
5861                 header = (TnyHeader *) tny_iterator_get_current (iter);
5862                 src_folder = tny_header_get_folder (header);
5863
5864                 /* Transfer the messages */
5865                 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, 
5866                                                             headers,
5867                                                             TNY_FOLDER (dst_folder));
5868
5869                 /* Frees */
5870                 g_object_unref (header);
5871                 g_object_unref (iter);
5872                 g_object_unref (src_folder);
5873         }
5874 }
5875
5876 void 
5877 modest_ui_actions_on_move_to (GtkAction *action, 
5878                               ModestWindow *win)
5879 {
5880         modest_ui_actions_on_edit_mode_move_to (win);
5881 }
5882
5883 gboolean 
5884 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5885 {
5886         GtkWidget *dialog = NULL;
5887         MoveToInfo *helper = NULL;
5888         TnyList *list_to_move;
5889
5890         g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5891
5892 #ifndef MODEST_TOOLKIT_HILDON2
5893         /* Get the main window if exists */
5894         ModestMainWindow *main_window;
5895         if (MODEST_IS_MAIN_WINDOW (win))
5896                 main_window = MODEST_MAIN_WINDOW (win);
5897         else
5898                 main_window = 
5899                         MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5900                                                                                FALSE)); /* don't create */
5901 #endif
5902
5903         list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5904
5905         if (!list_to_move)
5906                 return FALSE;
5907
5908         if (tny_list_get_length (list_to_move) < 1) {
5909                 g_object_unref (list_to_move);
5910                 return FALSE;
5911         }
5912
5913         /* Create and run the dialog */
5914         dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5915         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), 
5916                                      GTK_WINDOW (dialog), 
5917                                      (GtkWindow *) win);
5918
5919         /* Create helper */
5920         helper = g_slice_new0 (MoveToInfo);
5921         helper->list = list_to_move;
5922         helper->win = win;
5923
5924         /* Listen to response signal */
5925         g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5926
5927         /* Show the dialog */
5928         gtk_widget_show (dialog);
5929
5930         return TRUE;
5931 }
5932
5933 /*
5934  * Calls #HeadersFunc for each header already selected in the main
5935  * window or the message currently being shown in the msg view window
5936  */
5937 static void
5938 do_headers_action (ModestWindow *win, 
5939                    HeadersFunc func,
5940                    gpointer user_data)
5941 {
5942         TnyList *headers_list = NULL;
5943         TnyIterator *iter = NULL;
5944         TnyHeader *header = NULL;
5945         TnyFolder *folder = NULL;
5946
5947         /* Get headers */
5948         headers_list = get_selected_headers (win);
5949         if (!headers_list)
5950                 return;
5951
5952         /* Get the folder */
5953         iter = tny_list_create_iterator (headers_list);
5954         header = TNY_HEADER (tny_iterator_get_current (iter));
5955         if (header) {
5956                 folder = tny_header_get_folder (header);
5957                 g_object_unref (header);
5958         }
5959
5960         /* Call the function for each header */
5961         while (!tny_iterator_is_done (iter)) {
5962                 header = TNY_HEADER (tny_iterator_get_current (iter));
5963                 func (header, win, user_data);
5964                 g_object_unref (header);
5965                 tny_iterator_next (iter);
5966         }
5967
5968         /* Trick: do a poke status in order to speed up the signaling
5969            of observers */
5970         if (folder) {
5971                 tny_folder_poke_status (folder);
5972                 g_object_unref (folder);
5973         }
5974
5975         /* Frees */
5976         g_object_unref (iter);
5977         g_object_unref (headers_list);
5978 }
5979
5980 void 
5981 modest_ui_actions_view_attachment (GtkAction *action,
5982                                    ModestWindow *window)
5983 {
5984         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5985                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5986         } else {
5987                 /* not supported window for this action */
5988                 g_return_if_reached ();
5989         }
5990 }
5991
5992 void
5993 modest_ui_actions_save_attachments (GtkAction *action,
5994                                     ModestWindow *window)
5995 {
5996         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5997
5998                 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5999                         return;
6000
6001                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6002         } else {
6003                 /* not supported window for this action */
6004                 g_return_if_reached ();
6005         }
6006 }
6007
6008 void
6009 modest_ui_actions_remove_attachments (GtkAction *action,
6010                                       ModestWindow *window)
6011 {
6012         if (MODEST_IS_MAIN_WINDOW (window)) {
6013                 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6014         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6015                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6016         } else {
6017                 /* not supported window for this action */
6018                 g_return_if_reached ();
6019         }
6020 }
6021
6022 void 
6023 modest_ui_actions_on_settings (GtkAction *action, 
6024                                ModestWindow *win)
6025 {
6026         GtkWidget *dialog;
6027
6028         dialog = modest_platform_get_global_settings_dialog ();
6029         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6030         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6031         gtk_widget_show_all (dialog);
6032
6033         gtk_dialog_run (GTK_DIALOG (dialog));
6034
6035         gtk_widget_destroy (dialog);
6036 }
6037
6038 void 
6039 modest_ui_actions_on_help (GtkAction *action, 
6040                            GtkWindow *win)
6041 {
6042         /* Help app is not available at all in fremantle */
6043 #ifndef MODEST_TOOLKIT_HILDON2
6044         const gchar *help_id;
6045
6046         g_return_if_fail (win && GTK_IS_WINDOW(win));
6047         
6048         help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6049
6050         if (help_id)
6051                 modest_platform_show_help (GTK_WINDOW (win), help_id);
6052 #endif
6053 }
6054
6055 void 
6056 modest_ui_actions_on_csm_help (GtkAction *action, 
6057                                GtkWindow *win)
6058 {
6059         /* Help app is not available at all in fremantle */
6060 #ifndef MODEST_TOOLKIT_HILDON2
6061
6062         const gchar* help_id = NULL;
6063         GtkWidget *folder_view;
6064         TnyFolderStore *folder_store;
6065
6066         g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6067
6068         /* Get selected folder */
6069         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6070                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6071         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6072
6073         /* Switch help_id */
6074         if (folder_store && TNY_IS_FOLDER (folder_store))
6075                 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6076
6077         if (folder_store)
6078                 g_object_unref (folder_store);
6079
6080         if (help_id)
6081                 modest_platform_show_help (GTK_WINDOW (win), help_id);
6082         else
6083                 modest_ui_actions_on_help (action, win);
6084 #endif
6085 }
6086
6087 static void     
6088 retrieve_contents_cb (ModestMailOperation *mail_op, 
6089                       TnyHeader *header, 
6090                       gboolean canceled,
6091                       TnyMsg *msg,
6092                       GError *err,
6093                       gpointer user_data)
6094 {
6095         /* We only need this callback to show an error in case of
6096            memory low condition */
6097         modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
6098 }
6099
6100 static void
6101 retrieve_msg_contents_performer (gboolean canceled, 
6102                                  GError *err,
6103                                  GtkWindow *parent_window, 
6104                                  TnyAccount *account, 
6105                                  gpointer user_data)
6106 {
6107         ModestMailOperation *mail_op;
6108         TnyList *headers = TNY_LIST (user_data);
6109
6110         if (err || canceled) {
6111                 check_memory_full_error ((GtkWidget *) parent_window, err);
6112                 goto out;
6113         }
6114
6115         /* Create mail operation */
6116         mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6117                                                                  modest_ui_actions_disk_operations_error_handler, 
6118                                                                  NULL, NULL);
6119         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6120         modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6121
6122         /* Frees */
6123         g_object_unref (mail_op);
6124  out:
6125         g_object_unref (headers);
6126         g_object_unref (account);
6127 }
6128
6129 void 
6130 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6131                                             ModestWindow *window)
6132 {
6133         TnyList *headers = NULL;
6134         TnyAccount *account = NULL;
6135         TnyIterator *iter = NULL;
6136         TnyHeader *header = NULL;
6137         TnyFolder *folder = NULL;
6138
6139         /* Get headers */
6140         headers = get_selected_headers (window);
6141         if (!headers)
6142                 return;
6143
6144         /* Pick the account */
6145         iter = tny_list_create_iterator (headers);
6146         header = TNY_HEADER (tny_iterator_get_current (iter));
6147         folder = tny_header_get_folder (header);
6148         account = tny_folder_get_account (folder);
6149         g_object_unref (folder);
6150         g_object_unref (header);
6151         g_object_unref (iter);
6152
6153         /* Connect and perform the message retrieval */
6154         modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6155                                              g_object_ref (account), 
6156                                              retrieve_msg_contents_performer, 
6157                                              g_object_ref (headers));
6158
6159         /* Frees */
6160         g_object_unref (account);
6161         g_object_unref (headers);
6162 }
6163
6164 void
6165 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6166 {
6167         g_return_if_fail (MODEST_IS_WINDOW (window));
6168
6169         /* Update dimmed */
6170         modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6171 }
6172
6173 void
6174 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6175 {
6176         g_return_if_fail (MODEST_IS_WINDOW (window));
6177
6178         /* Update dimmed */
6179         modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6180 }
6181
6182 void
6183 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6184                                           ModestWindow *window)
6185 {
6186         g_return_if_fail (MODEST_IS_WINDOW (window));
6187         
6188         /* Update dimmed */
6189         modest_ui_actions_check_menu_dimming_rules (window);
6190 }
6191
6192 void
6193 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6194                                           ModestWindow *window)
6195 {
6196         g_return_if_fail (MODEST_IS_WINDOW (window));
6197
6198         /* Update dimmed */
6199         modest_ui_actions_check_menu_dimming_rules (window);
6200 }
6201
6202 void
6203 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6204                                           ModestWindow *window)
6205 {
6206         g_return_if_fail (MODEST_IS_WINDOW (window));
6207
6208         /* Update dimmed */
6209         modest_ui_actions_check_menu_dimming_rules (window);
6210 }
6211
6212 void
6213 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6214                                             ModestWindow *window)
6215 {
6216         g_return_if_fail (MODEST_IS_WINDOW (window));
6217
6218         /* Update dimmed */
6219         modest_ui_actions_check_menu_dimming_rules (window);
6220 }
6221
6222 void
6223 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6224                                           ModestWindow *window)
6225 {
6226         g_return_if_fail (MODEST_IS_WINDOW (window));
6227
6228         /* Update dimmed */
6229         modest_ui_actions_check_menu_dimming_rules (window);
6230 }
6231
6232 void
6233 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6234                                           ModestWindow *window)
6235 {
6236         g_return_if_fail (MODEST_IS_WINDOW (window));
6237
6238         /* Update dimmed */
6239         modest_ui_actions_check_menu_dimming_rules (window);
6240 }
6241
6242 void
6243 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6244                                                  ModestWindow *window)
6245 {
6246         g_return_if_fail (MODEST_IS_WINDOW (window));
6247
6248         /* Update dimmed */
6249         modest_ui_actions_check_menu_dimming_rules (window);
6250 }
6251
6252 void
6253 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6254                                                      ModestWindow *window)
6255 {
6256         g_return_if_fail (MODEST_IS_WINDOW (window));
6257
6258         /* Update dimmed */
6259         modest_ui_actions_check_menu_dimming_rules (window);
6260 }
6261
6262 void
6263 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6264                                                      ModestWindow *window)
6265 {
6266         g_return_if_fail (MODEST_IS_WINDOW (window));
6267
6268         /* Update dimmed */
6269         modest_ui_actions_check_menu_dimming_rules (window);
6270 }
6271
6272 void
6273 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6274 {
6275         g_return_if_fail (MODEST_IS_WINDOW (window));
6276
6277         /* we check for low-mem; in that case, show a warning, and don't allow
6278          * searching
6279          */
6280         if (modest_platform_check_memory_low (window, TRUE))
6281                 return;
6282         
6283         modest_platform_show_search_messages (GTK_WINDOW (window));
6284 }
6285
6286 void     
6287 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6288 {
6289         g_return_if_fail (MODEST_IS_WINDOW (win));
6290
6291
6292         /* we check for low-mem; in that case, show a warning, and don't allow
6293          * for the addressbook
6294          */
6295         if (modest_platform_check_memory_low (win, TRUE))
6296                 return;
6297
6298
6299         modest_platform_show_addressbook (GTK_WINDOW (win));
6300 }
6301
6302
6303 void
6304 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6305                                           ModestWindow *window)
6306 {
6307         gboolean active;
6308         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6309
6310         if (GTK_IS_TOGGLE_ACTION (action))
6311                 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6312         else
6313                 active = TRUE;
6314
6315         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), 
6316                                                     active);
6317 }
6318
6319 static void 
6320 on_send_receive_finished (ModestMailOperation  *mail_op, 
6321                            gpointer user_data)
6322 {
6323         GtkWidget *header_view, *folder_view;
6324         TnyFolderStore *folder_store;
6325         ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6326
6327         /* Set send/receive operation finished */       
6328         modest_main_window_notify_send_receive_completed (main_win);
6329
6330         /* Don't refresh the current folder if there were any errors */
6331         if (modest_mail_operation_get_status (mail_op) !=
6332             MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6333                 return;
6334         
6335         /* Refresh the current folder if we're viewing a window. We do
6336            this because the user won't be able to see the new mails in
6337            the selected folder after a Send&Receive because it only
6338            performs a poke_status, i.e, only the number of read/unread
6339            messages is updated, but the new headers are not
6340            downloaded */
6341         folder_view = modest_main_window_get_child_widget (main_win, 
6342                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6343         if (!folder_view)
6344                 return;
6345
6346         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6347         
6348         /* Do not need to refresh INBOX again because the
6349            update_account does it always automatically */
6350         if (folder_store && TNY_IS_FOLDER (folder_store) && 
6351             tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6352                 ModestMailOperation *refresh_op;
6353
6354                 header_view = modest_main_window_get_child_widget (main_win,
6355                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6356                 
6357                 /* We do not need to set the contents style
6358                    because it hasn't changed. We also do not
6359                    need to save the widget status. Just force
6360                    a refresh */
6361                 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6362                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6363                 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6364                                                       folder_refreshed_cb, main_win);
6365                 g_object_unref (refresh_op);
6366         }
6367         
6368         if (folder_store)
6369                 g_object_unref (folder_store);
6370 }
6371
6372
6373 void
6374 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self, 
6375                                                 TnyHeader *header, 
6376                                                 TnyMsg *msg, 
6377                                                 GError *err, 
6378                                                 gpointer user_data)
6379 {
6380         const gchar* server_name = NULL;
6381         TnyTransportAccount *server_account;
6382         gchar *message = NULL;
6383
6384         /* Don't show anything if the user cancelled something or the
6385          * send receive request is not interactive. Authentication
6386          * errors are managed by the account store so no need to show
6387          * a dialog here again */
6388         if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6389             err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6390             !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6391                 return;
6392
6393
6394         /* Get the server name: */
6395         server_account =
6396                 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6397         if (server_account)
6398                 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6399         else
6400                 g_return_if_reached ();
6401
6402         /* Show the appropriate message text for the GError: */
6403         switch (err->code) {
6404         case TNY_SERVICE_ERROR_CONNECT:
6405                 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6406                 break;
6407         case TNY_SERVICE_ERROR_SEND:
6408                 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6409                 break;
6410         case TNY_SERVICE_ERROR_UNAVAILABLE:
6411                 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6412                 break;
6413         default:
6414                 g_warning ("%s: unexpected ERROR %d",
6415                            __FUNCTION__, err->code);
6416                 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6417                 break;
6418         }
6419
6420         modest_platform_run_information_dialog (NULL, message, FALSE);
6421         g_free (message);
6422         g_object_unref (server_account);
6423 }
6424
6425 void
6426 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6427                                                 gchar *msg_id, 
6428                                                 guint status,
6429                                                 gpointer user_data)
6430 {
6431         ModestWindow *top_window = NULL;
6432         ModestWindowMgr *mgr = NULL;
6433         GtkWidget *header_view = NULL;
6434         TnyFolder *selected_folder = NULL;
6435         TnyFolderType folder_type;
6436
6437         mgr = modest_runtime_get_window_mgr ();
6438         top_window = modest_window_mgr_get_current_top (mgr);
6439
6440         if (!top_window)
6441                 return;
6442
6443 #ifndef MODEST_TOOLKIT_HILDON2
6444         if (MODEST_IS_MAIN_WINDOW (top_window)) {
6445                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6446                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6447         }
6448 #else
6449         if (MODEST_IS_HEADER_WINDOW (top_window)) {
6450                 header_view = (GtkWidget *)
6451                         modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6452         }
6453 #endif
6454
6455         /* Get selected folder */
6456         selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6457         if (!selected_folder)
6458                 return;
6459
6460         /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6461 #if GTK_CHECK_VERSION(2, 8, 0)
6462         folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6463         if (folder_type ==  TNY_FOLDER_TYPE_OUTBOX) {
6464                 GtkTreeViewColumn *tree_column;
6465
6466                 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6467                                                         TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6468                 if (tree_column)
6469                         gtk_tree_view_column_queue_resize (tree_column);
6470                 }
6471 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6472         gtk_widget_queue_draw (header_view);
6473 #endif
6474
6475 #ifndef MODEST_TOOLKIT_HILDON2
6476         /* Rerun dimming rules, because the message could become deletable for example */
6477         modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6478                                                  MODEST_DIMMING_RULES_TOOLBAR);
6479         modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6480                                                  MODEST_DIMMING_RULES_MENU);
6481 #endif
6482
6483         /* Free */
6484         g_object_unref (selected_folder);
6485 }
6486
6487 void
6488 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6489                                                TnyAccount *account)
6490 {
6491         ModestProtocolType protocol_type;
6492         ModestProtocol *protocol;
6493         gchar *error_note = NULL;
6494
6495         protocol_type = modest_tny_account_get_protocol_type (account);
6496         protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6497                                                                   protocol_type);
6498
6499         error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6500         if (error_note == NULL) {
6501                 g_warning ("%s: This should not be reached", __FUNCTION__);
6502         } else {
6503                 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6504                 g_free (error_note);
6505         }
6506 }
6507
6508 gchar *
6509 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6510 {
6511         gchar *msg = NULL;
6512         gchar *subject;
6513         TnyFolderStore *folder = NULL;
6514         TnyAccount *account = NULL;
6515         ModestProtocolType proto;
6516         ModestProtocol *protocol;
6517         TnyHeader *header = NULL;
6518
6519         if (MODEST_IS_MAIN_WINDOW (win)) {
6520                 GtkWidget *header_view;
6521                 TnyList* headers = NULL;
6522                 TnyIterator *iter;
6523                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6524                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6525                 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6526                 if (!headers || tny_list_get_length (headers) == 0) {
6527                         if (headers)
6528                                 g_object_unref (headers);
6529                         return NULL;
6530                 }
6531                 iter = tny_list_create_iterator (headers);
6532                 header = TNY_HEADER (tny_iterator_get_current (iter));
6533                 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6534                 g_object_unref (iter);
6535                 g_object_unref (headers);
6536 #ifdef MODEST_TOOLKIT_HILDON2
6537         } else if (MODEST_IS_HEADER_WINDOW (win)) {
6538                 GtkWidget *header_view;
6539                 TnyList* headers = NULL;
6540                 TnyIterator *iter;
6541                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6542                 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6543                 if (!headers || tny_list_get_length (headers) == 0) {
6544                         if (headers)
6545                                 g_object_unref (headers);
6546                         return NULL;
6547                 }
6548                 iter = tny_list_create_iterator (headers);
6549                 header = TNY_HEADER (tny_iterator_get_current (iter));
6550                 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6551                 g_object_unref (iter);
6552                 g_object_unref (headers);
6553 #endif
6554         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6555                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6556                 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6557         }
6558
6559         /* Get the account type */
6560         account = tny_folder_get_account (TNY_FOLDER (folder));
6561         proto = modest_tny_account_get_protocol_type (account);
6562         protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6563                                                                   proto);
6564
6565         subject = tny_header_dup_subject (header);
6566         msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6567         if (subject)
6568                 g_free (subject);
6569         if (msg == NULL) {
6570                 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6571         }
6572
6573         /* Frees */
6574         g_object_unref (account);
6575         g_object_unref (folder);
6576         g_object_unref (header);
6577
6578         return msg;
6579 }
6580
6581 gboolean
6582 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6583                                      const gchar *account_name,
6584                                      const gchar *account_title)
6585 {
6586         ModestAccountMgr *account_mgr;
6587         gchar *txt = NULL;
6588         gint response;
6589         ModestProtocol *protocol;
6590         gboolean removed = FALSE;
6591
6592         g_return_val_if_fail (account_name, FALSE);
6593         g_return_val_if_fail (account_title, FALSE);
6594
6595         account_mgr = modest_runtime_get_account_mgr();
6596
6597         /* The warning text depends on the account type: */
6598         protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6599                                                                   modest_account_mgr_get_store_protocol (account_mgr,
6600                                                                                                          account_name));
6601         txt = modest_protocol_get_translation (protocol,
6602                                                MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6603                                                account_title);
6604         if (txt == NULL)
6605                 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6606
6607         response = modest_platform_run_confirmation_dialog (parent_window, txt);
6608         g_free (txt);
6609         txt = NULL;
6610
6611         if (response == GTK_RESPONSE_OK) {
6612                 /* Remove account. If it succeeds then it also removes
6613                    the account from the ModestAccountView: */
6614                 gboolean is_default = FALSE;
6615                 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6616                 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6617                         is_default = TRUE;
6618                 g_free (default_account_name);
6619
6620                 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6621                 if (!removed)
6622                         g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6623         }
6624         return removed;
6625 }