* Fixes NB#58331, INBOX must not be moveable
[modest] / src / modest-ui-actions.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29  
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif /*HAVE_CONFIG_H*/
33
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
36 #include <string.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47
48 #ifdef MODEST_PLATFORM_MAEMO
49 #include "maemo/modest-osso-state-saving.h"
50 #endif /* MODEST_PLATFORM_MAEMO */
51
52 #include "widgets/modest-ui-constants.h"
53 #include <widgets/modest-main-window.h>
54 #include <widgets/modest-msg-view-window.h>
55 #include <widgets/modest-account-view-window.h>
56 #include <widgets/modest-details-dialog.h>
57 #include <widgets/modest-attachments-view.h>
58 #include "widgets/modest-folder-view.h"
59 #include "widgets/modest-global-settings-dialog.h"
60 #include "modest-connection-specific-smtp-window.h"
61 #include "modest-account-mgr-helpers.h"
62 #include "modest-mail-operation.h"
63 #include "modest-text-utils.h"
64
65 #ifdef MODEST_HAVE_EASYSETUP
66 #include "easysetup/modest-easysetup-wizard.h"
67 #endif /* MODEST_HAVE_EASYSETUP */
68
69 #include <modest-widget-memory.h>
70 #include <tny-error.h>
71 #include <tny-simple-list.h>
72 #include <tny-msg-view.h>
73 #include <tny-device.h>
74 #include <tny-merge-folder.h>
75
76 #include <gtkhtml/gtkhtml.h>
77
78 typedef struct _GetMsgAsyncHelper {     
79         ModestWindow *window;
80         ModestMailOperation *mail_op;
81         TnyIterator *iter;
82         guint num_ops;
83         GFunc func;     
84         gpointer user_data;
85 } GetMsgAsyncHelper;
86
87 typedef enum _ReplyForwardAction {
88         ACTION_REPLY,
89         ACTION_REPLY_TO_ALL,
90         ACTION_FORWARD
91 } ReplyForwardAction;
92
93 typedef struct _ReplyForwardHelper {
94         guint reply_forward_type;
95         ReplyForwardAction action;
96         gchar *account_name;
97         GtkWidget *parent_window;
98 } ReplyForwardHelper;
99
100 /*
101  * The do_headers_action uses this kind of functions to perform some
102  * action to each member of a list of headers
103  */
104 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
105
106 static void
107 do_headers_action (ModestWindow *win, 
108                    HeadersFunc func,
109                    gpointer user_data);
110
111
112 static void     open_msg_cb            (ModestMailOperation *mail_op, 
113                                         TnyHeader *header, 
114                                         TnyMsg *msg,
115                                         gpointer user_data);
116
117 static void     reply_forward_cb       (ModestMailOperation *mail_op, 
118                                         TnyHeader *header, 
119                                         TnyMsg *msg,
120                                         gpointer user_data);
121
122 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
123
124 static gchar*   ask_for_folder_name    (GtkWindow *parent_window, const gchar *title);
125
126
127 static void     _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
128                                                    ModestMailOperationState *state,
129                                                    gpointer user_data);
130
131
132
133 static void
134 run_account_setup_wizard (ModestWindow *win)
135 {
136         ModestEasysetupWizardDialog *wizard;
137
138         g_return_if_fail (MODEST_IS_WINDOW(win));
139         
140         wizard = modest_easysetup_wizard_dialog_new ();
141         gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
142         gtk_dialog_run (GTK_DIALOG (wizard));
143         gtk_widget_destroy (GTK_WIDGET (wizard));
144 }
145
146
147 void   
148 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
149 {
150         GtkWidget *about;
151         const gchar *authors[] = {
152                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
153                 NULL
154         };
155         about = gtk_about_dialog_new ();
156         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
157         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
158         gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
159                                         _("Copyright (c) 2006, Nokia Corporation\n"
160                                           "All rights reserved."));
161         gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
162                                        _("a modest e-mail client\n\n"
163                                          "design and implementation: Dirk-Jan C. Binnema\n"
164                                          "contributions from the fine people at KC and Ig\n"
165                                          "uses the tinymail email framework written by Philip van Hoof"));
166         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
167         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
168         
169         gtk_dialog_run (GTK_DIALOG (about));
170         gtk_widget_destroy(about);
171 }
172
173 /*
174  * Gets the list of currently selected messages. If the win is the
175  * main window, then it returns a newly allocated list of the headers
176  * selected in the header view. If win is the msg view window, then
177  * the value returned is a list with just a single header.
178  *
179  * The caller of this funcion must free the list.
180  */
181 static TnyList *
182 get_selected_headers (ModestWindow *win)
183 {
184         if (MODEST_IS_MAIN_WINDOW(win)) {
185                 GtkWidget *header_view;         
186                 
187                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
188                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
189                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
190                 
191         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
192                 /* for MsgViewWindows, we simply return a list with one element */
193                 TnyHeader *header;
194                 TnyList *list = NULL;
195                 
196                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
197                 if (header != NULL) {
198                         list = tny_simple_list_new ();
199                         tny_list_prepend (list, G_OBJECT(header));
200                         g_object_unref (G_OBJECT(header));
201                 }
202
203                 return list;
204
205         } else
206                 return NULL;
207 }
208
209 static void
210 headers_action_mark_as_read (TnyHeader *header,
211                              ModestWindow *win,
212                              gpointer user_data)
213 {
214         TnyHeaderFlags flags;
215
216         g_return_if_fail (TNY_IS_HEADER(header));
217
218         flags = tny_header_get_flags (header);
219         if (flags & TNY_HEADER_FLAG_SEEN) return;
220         tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
221 }
222
223 static void
224 headers_action_mark_as_unread (TnyHeader *header,
225                                ModestWindow *win,
226                                gpointer user_data)
227 {
228         TnyHeaderFlags flags;
229
230         g_return_if_fail (TNY_IS_HEADER(header));
231
232         flags = tny_header_get_flags (header);
233         if (flags & TNY_HEADER_FLAG_SEEN)  {
234                 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
235         }
236 }
237
238
239 static void
240 headers_action_delete (TnyHeader *header,
241                        ModestWindow *win,
242                        gpointer user_data)
243 {
244         ModestMailOperation *mail_op = NULL;
245
246         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
247         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
248                                          mail_op);
249         
250         /* Always delete. TODO: Move to trash still not supported */
251         modest_mail_operation_remove_msg (mail_op, header, FALSE);
252         g_object_unref (G_OBJECT (mail_op));
253 }
254
255 void
256 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
257 {
258         TnyList *header_list = NULL;
259         TnyIterator *iter = NULL;
260         TnyHeader *header = NULL;
261         gchar *message = NULL;
262         gchar *desc = NULL;
263         gint response;
264         gboolean found;
265         ModestWindowMgr *mgr;
266
267         g_return_if_fail (MODEST_IS_WINDOW(win));
268
269         header_list = get_selected_headers (win);
270         if (!header_list) return;
271
272         /* Check if any of the headers is already opened */
273         iter = tny_list_create_iterator (header_list);
274         found = FALSE;
275         mgr = modest_runtime_get_window_mgr ();
276         while (!tny_iterator_is_done (iter) && !found) {
277                 header = TNY_HEADER (tny_iterator_get_current (iter));
278                 if (modest_window_mgr_find_window_by_header (mgr, header))
279                         found = TRUE;
280                 g_object_unref (header);
281                 tny_iterator_next (iter);
282         }
283         g_object_unref (iter);
284
285         if (found) {
286                 gchar *num, *msg;
287
288                 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
289                 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
290
291                 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
292
293                 g_free (msg);
294                 g_free (num);
295                 g_object_unref (header_list);
296                 return;
297         }
298
299         /* Select message */
300         if (tny_list_get_length(header_list) > 1)
301                 message = g_strdup(_("emev_nc_delete_messages"));
302         else {
303                 iter = tny_list_create_iterator (header_list);
304                 header = TNY_HEADER (tny_iterator_get_current (iter));
305                 desc = g_strdup_printf ("%s", tny_header_get_subject (header)); 
306                 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
307                 g_object_unref (header);
308                 g_object_unref (iter);
309         }
310
311         /* Confirmation dialog */               
312         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
313                                                             message);
314         
315
316         if (response == GTK_RESPONSE_OK) {
317                 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
318                         gboolean ret_value;
319                         g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
320                         return;
321                 }
322                 
323                 /* Remove each header */
324                 do_headers_action (win, headers_action_delete, NULL);
325
326                 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
327                         gtk_widget_destroy (GTK_WIDGET(win));
328                 } 
329         }
330
331         /* free */
332         g_free(message);
333         g_free(desc);
334         g_object_unref (header_list);
335 }
336
337
338 void
339 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
340 {
341         #ifdef MODEST_PLATFORM_MAEMO
342         modest_osso_save_state();
343         #endif /* MODEST_PLATFORM_MAEMO */
344         
345         gtk_main_quit ();
346 }
347
348 void
349 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
350 {
351         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
352                 gtk_widget_destroy (GTK_WIDGET (win));
353         } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
354                 gboolean ret_value;
355                 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
356         } else if (MODEST_IS_WINDOW (win)) {
357                 gtk_widget_destroy (GTK_WIDGET (win));
358         } else {
359                 g_return_if_reached ();
360         }
361 }
362
363 void
364 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
365 {
366         GtkClipboard *clipboard = NULL;
367         gchar *selection = NULL;
368
369         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
370         selection = gtk_clipboard_wait_for_text (clipboard);
371
372         /* Question: why is the clipboard being used here? 
373          * It doesn't really make a lot of sense. */
374
375         if (selection)
376         {
377                 modest_address_book_add_address (selection);
378                 g_free (selection);
379         }
380 }
381
382 void
383 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
384 {
385         /* This is currently only implemented for Maemo */
386 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
387         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
388                 run_account_setup_wizard (win);
389                 return;
390         } else  {
391                 /* Show the list of accounts: */
392                 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
393                 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
394                 gtk_dialog_run (account_win);
395                 gtk_widget_destroy (GTK_WIDGET(account_win));
396         }
397 #else
398         GtkWidget *dialog, *label;
399         
400         /* Create the widgets */
401         
402         dialog = gtk_dialog_new_with_buttons ("Message",
403                                               GTK_WINDOW(win),
404                                               GTK_DIALOG_DESTROY_WITH_PARENT,
405                                               GTK_STOCK_OK,
406                                               GTK_RESPONSE_NONE,
407                                               NULL);
408         label = gtk_label_new ("Hello World!");
409         
410         /* Ensure that the dialog box is destroyed when the user responds. */
411         
412         g_signal_connect_swapped (dialog, "response", 
413                                   G_CALLBACK (gtk_widget_destroy),
414                                   dialog);
415         
416         /* Add the label, and show everything we've added to the dialog. */
417         
418         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
419                            label);
420         gtk_widget_show_all (dialog);
421 #endif /* MODEST_PLATFORM_MAEMO */
422 }
423
424 static void
425 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
426 {
427         ModestWindow *main_window = MODEST_WINDOW (user_data);
428         
429         /* Save any changes. */
430         modest_connection_specific_smtp_window_save_server_accounts (
431                         MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window), 
432                         modest_window_get_active_account (main_window));
433         gtk_widget_destroy (GTK_WIDGET (window));
434 }
435
436
437
438 void
439 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
440 {
441         /* This is currently only implemented for Maemo,
442          * because it requires an API (libconic) to detect different connection 
443          * possiblities.
444          */
445 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
446         
447         /* Create the window if necessary: */
448         const gchar *active_account_name = modest_window_get_active_account (win);
449         
450         /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
451          * or show the default account?
452          * If we show the default account then the account name should be shown in 
453          * the window when we show it. */
454         if (!active_account_name) {
455                 g_warning ("%s: No account is active.", __FUNCTION__);
456                 return;
457         }
458                 
459         GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
460         modest_connection_specific_smtp_window_fill_with_connections (
461                 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), 
462                 modest_runtime_get_account_mgr(), 
463                 active_account_name);
464
465         /* Show the window: */  
466         gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
467         gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
468     gtk_widget_show (specific_window);
469     
470     /* Save changes when the window is hidden: */
471         g_signal_connect (specific_window, "hide", 
472                 G_CALLBACK (on_smtp_servers_window_hide), win);
473 #endif /* MODEST_PLATFORM_MAEMO */
474 }
475
476 void
477 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
478 {
479         ModestWindow *msg_win;
480         TnyMsg *msg = NULL;
481         TnyFolder *folder = NULL;
482         gchar *account_name = NULL;
483         gchar *from_str = NULL;
484 /*      GError *err = NULL; */
485         TnyAccount *account = NULL;
486         ModestWindowMgr *mgr;
487         gchar *signature = NULL, *blank_and_signature = NULL;
488
489         /* if there are no accounts yet, just show the wizard */
490         if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
491                         run_account_setup_wizard (win);
492                         return;
493         }
494         
495         account_name = g_strdup(modest_window_get_active_account (win));
496         if (!account_name)
497                 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
498         if (!account_name) {
499                 g_printerr ("modest: no account found\n");
500                 goto cleanup;
501         }
502         
503         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
504                                                                        account_name,
505                                                                        TNY_ACCOUNT_TYPE_STORE);
506         if (!account) {
507                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
508                 goto cleanup;
509         }
510
511         from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
512         if (!from_str) {
513                 g_printerr ("modest: failed get from string for '%s'\n", account_name);
514                 goto cleanup;
515         }
516
517         if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
518                                          MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
519                 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
520                                                            MODEST_ACCOUNT_SIGNATURE, FALSE);
521                 blank_and_signature = g_strconcat ("\n", signature, NULL);
522                 g_free (signature);
523         } else {
524                 blank_and_signature = g_strdup ("");
525         }
526
527         msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
528         if (!msg) {
529                 g_printerr ("modest: failed to create new msg\n");
530                 goto cleanup;
531         }
532         
533         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
534         if (!folder) {
535                 g_printerr ("modest: failed to find Drafts folder\n");
536                 goto cleanup;
537         }
538         
539
540         /* Create and register edit window */
541         /* This is destroyed by TOOD. */
542         msg_win = modest_msg_edit_window_new (msg, account_name);
543         mgr = modest_runtime_get_window_mgr ();
544         modest_window_mgr_register_window (mgr, msg_win);
545
546         if (win)
547                 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
548                                               GTK_WINDOW (win));        
549         gtk_widget_show_all (GTK_WIDGET (msg_win));
550
551 cleanup:
552         g_free (account_name);
553         g_free (from_str);
554         g_free (blank_and_signature);
555         if (account)
556                 g_object_unref (G_OBJECT(account));
557         if (msg)
558                 g_object_unref (G_OBJECT(msg));
559         if (folder)
560                 g_object_unref (G_OBJECT(folder));
561 }
562
563 static void
564 open_msg_cb (ModestMailOperation *mail_op, 
565              TnyHeader *header, 
566              TnyMsg *msg, 
567              gpointer user_data)
568 {
569         ModestWindowMgr *mgr = NULL;
570         ModestWindow *parent_win = NULL;
571         ModestWindow *win = NULL;
572         TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
573         gchar *account = NULL;
574         TnyFolder *folder;
575         
576         /* TODO: Show an error? (review the specs) */
577         if (!msg)
578                 return;
579
580         parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
581         folder = tny_header_get_folder (header);
582
583         /* Mark header as read */
584         headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
585
586         /* Get account */
587         account =  g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
588         if (!account)
589                 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
590         
591         /* Gets folder type (OUTBOX headers will be opened in edit window */
592         if (modest_tny_folder_is_local_folder (folder))
593                 folder_type = modest_tny_folder_get_local_folder_type (folder);
594
595         /* If the header is in the drafts folder then open the editor,
596            else the message view window */
597         if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
598                 /* we cannot edit without a valid account... */
599                 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
600                         run_account_setup_wizard(parent_win);
601                         goto cleanup;
602                 }
603                 win = modest_msg_edit_window_new (msg, account);
604         } else {
605                 gchar *uid = modest_tny_folder_get_header_unique_id (header);
606
607                 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
608                         GtkWidget *header_view;
609                         GtkTreeSelection *sel;
610                         GList *sel_list = NULL;
611                         GtkTreeModel *model;
612                 
613                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
614                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
615
616                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
617                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
618
619                         if (sel_list != NULL) {
620                                 GtkTreeRowReference *row_reference;
621
622                                 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
623                                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
624                                 g_list_free (sel_list);
625                                 
626                                 win = modest_msg_view_window_new_with_header_model (msg, 
627                                                                                     account,
628                                                                                     (const gchar*) uid,
629                                                                                     model, 
630                                                                                     row_reference);
631                                 gtk_tree_row_reference_free (row_reference);
632                         } else {
633                                 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
634                         }
635                 } else {
636                         win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
637                 }
638                 g_free (uid);
639         }
640         
641         /* Register and show new window */
642         if (win != NULL) {
643                 mgr = modest_runtime_get_window_mgr ();
644                 modest_window_mgr_register_window (mgr, win);
645                 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
646                 gtk_widget_show_all (GTK_WIDGET(win));
647         }
648
649 cleanup:
650         /* Free */
651         g_free(account);
652         g_object_unref (msg);
653         g_object_unref (folder);
654         g_object_unref (header);
655 }
656
657 /*
658  * This function is the error handler of the
659  * modest_mail_operation_get_msgs_full operation
660  */
661 static void
662 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
663                                                gpointer user_data)
664 {
665         const GError *error;
666
667         error = modest_mail_operation_get_error (mail_op);
668         if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
669                 GObject *win = modest_mail_operation_get_source (mail_op);
670
671                 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
672                                                         error->message);
673         }
674 }
675
676 /*
677  * This function is used by both modest_ui_actions_on_open and
678  * modest_ui_actions_on_header_activated. This way we always do the
679  * same when trying to open messages.
680  */
681 static void
682 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
683 {
684         ModestWindowMgr *mgr;
685         TnyIterator *iter;
686         ModestMailOperation *mail_op;
687         TnyList *not_opened_headers;
688
689         /* Look if we already have a message view for each header. If
690            true, then remove the header from the list of headers to
691            open */
692         mgr = modest_runtime_get_window_mgr ();
693         iter = tny_list_create_iterator (headers);
694         not_opened_headers = tny_simple_list_new ();
695         while (!tny_iterator_is_done (iter)) {
696                 ModestWindow *window;
697                 TnyHeader *header;
698                 
699                 header = TNY_HEADER (tny_iterator_get_current (iter));
700                 window = modest_window_mgr_find_window_by_header (mgr, header);
701                 /* Do not open again the message and present the
702                    window to the user */
703                 if (window)
704                         gtk_window_present (GTK_WINDOW (window));
705                 else
706                         tny_list_append (not_opened_headers, G_OBJECT (header));
707
708                 g_object_unref (header);
709                 tny_iterator_next (iter);
710         }
711         
712         /* Open each message */
713         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
714                                                                  G_OBJECT (win), 
715                                                                  modest_ui_actions_get_msgs_full_error_handler, 
716                                                                  NULL);
717         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
718         modest_mail_operation_get_msgs_full (mail_op, 
719                                              not_opened_headers, 
720                                              open_msg_cb, 
721                                              NULL, 
722                                              NULL);
723         /* Clean */
724         g_object_unref (not_opened_headers);
725         g_object_unref (iter);
726         g_object_unref (mail_op);
727 }
728
729 void
730 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
731 {
732         TnyList *headers;
733
734         /* Get headers */
735         headers = get_selected_headers (win);
736         if (!headers)
737                 return;
738
739         /* Open them */
740         _modest_ui_actions_open (headers, win);
741
742         g_object_unref(headers);
743 }
744
745
746 static void
747 free_reply_forward_helper (gpointer data)
748 {
749         ReplyForwardHelper *helper;
750
751         helper = (ReplyForwardHelper *) data;
752         g_free (helper->account_name);
753         g_slice_free (ReplyForwardHelper, helper);
754 }
755
756 static void
757 reply_forward_cb (ModestMailOperation *mail_op, 
758                   TnyHeader *header, 
759                   TnyMsg *msg,
760                   gpointer user_data)
761 {
762         TnyMsg *new_msg;
763         ReplyForwardHelper *rf_helper;
764         ModestWindow *msg_win;
765         ModestEditType edit_type;
766         gchar *from;
767         TnyAccount *account = NULL;
768         ModestWindowMgr *mgr;
769         gchar *signature = NULL;
770                         
771         g_return_if_fail (user_data != NULL);
772         rf_helper = (ReplyForwardHelper *) user_data;
773
774         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
775                                                    rf_helper->account_name);
776         if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
777                                          rf_helper->account_name,
778                                          MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
779                 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
780                                                            rf_helper->account_name,
781                                                            MODEST_ACCOUNT_SIGNATURE, FALSE);
782         }
783
784         /* Create reply mail */
785         switch (rf_helper->action) {
786         case ACTION_REPLY:
787                 new_msg = 
788                         modest_tny_msg_create_reply_msg (msg,  from, signature,
789                                                          rf_helper->reply_forward_type,
790                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
791                 break;
792         case ACTION_REPLY_TO_ALL:
793                 new_msg = 
794                         modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
795                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
796                 edit_type = MODEST_EDIT_TYPE_REPLY;
797                 break;
798         case ACTION_FORWARD:
799                 new_msg = 
800                         modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
801                 edit_type = MODEST_EDIT_TYPE_FORWARD;
802                 break;
803         default:
804                 g_return_if_reached ();
805                 return;
806         }
807
808         g_free (signature);
809
810         if (!new_msg) {
811                 g_printerr ("modest: failed to create message\n");
812                 goto cleanup;
813         }
814
815         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
816                                                                        rf_helper->account_name,
817                                                                        TNY_ACCOUNT_TYPE_STORE);
818         if (!account) {
819                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
820                 goto cleanup;
821         }
822
823         /* Create and register the windows */
824         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
825         mgr = modest_runtime_get_window_mgr ();
826         modest_window_mgr_register_window (mgr, msg_win);
827
828         if (rf_helper->parent_window != NULL) {
829                 gdouble parent_zoom;
830
831                 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
832                 modest_window_set_zoom (msg_win, parent_zoom);
833         }
834
835         /* Show edit window */
836         gtk_widget_show_all (GTK_WIDGET (msg_win));
837
838 cleanup:
839         if (new_msg)
840                 g_object_unref (G_OBJECT (new_msg));
841         if (account)
842                 g_object_unref (G_OBJECT (account));
843         g_object_unref (msg);
844         g_object_unref (header);
845 }
846
847 /*
848  * Checks a list of headers. If any of them are not currently
849  * downloaded (CACHED) then it asks the user for permission to
850  * download them.
851  *
852  * Returns FALSE if the user does not want to download the
853  * messages. Returns TRUE if the user allowed the download or if all
854  * of them are currently downloaded
855  */
856 static gboolean
857 download_uncached_messages (TnyList *header_list, GtkWindow *win)
858 {
859         TnyIterator *iter;
860         gboolean found, retval;
861
862         iter = tny_list_create_iterator (header_list);
863         found = FALSE;
864         while (!tny_iterator_is_done (iter) && !found) {
865                 TnyHeader *header;
866                 TnyHeaderFlags flags;
867
868                 header = TNY_HEADER (tny_iterator_get_current (iter));
869                 flags = tny_header_get_flags (header);
870                 /* TODO: is this the right flag?, it seems that some
871                    headers that have been previously downloaded do not
872                    come with it */
873                 found = !(flags & TNY_HEADER_FLAG_CACHED);
874                 g_object_unref (header);
875                 tny_iterator_next (iter);
876         }
877         g_object_unref (iter);
878
879         /* Ask for user permission to download the messages */
880         retval = TRUE;
881         if (found) {
882                 GtkResponseType response;
883                 response = 
884                         modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
885                                                                  _("mcen_nc_get_multi_msg_txt"));
886                 if (response == GTK_RESPONSE_CANCEL)
887                         retval = FALSE;
888         }
889         return retval;
890 }
891
892
893 /*
894  * Common code for the reply and forward actions
895  */
896 static void
897 reply_forward (ReplyForwardAction action, ModestWindow *win)
898 {
899         ModestMailOperation *mail_op = NULL;
900         TnyList *header_list = NULL;
901         ReplyForwardHelper *rf_helper = NULL;
902         guint reply_forward_type;
903         gboolean continue_download;
904         
905         g_return_if_fail (MODEST_IS_WINDOW(win));
906
907         /* we need an account when editing */
908         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
909                 run_account_setup_wizard (win);
910                 return;
911         }
912         
913         header_list = get_selected_headers (win);
914         if (!header_list)
915                 return;
916
917         /* Check that the messages have been previously downloaded */
918         continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
919         if (!continue_download) {
920                 g_object_unref (header_list);
921                 return;
922         }
923         
924         reply_forward_type = 
925                 modest_conf_get_int (modest_runtime_get_conf (),
926                                      (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
927                                      NULL);
928         /* We assume that we can only select messages of the
929            same folder and that we reply all of them from the
930            same account. In fact the interface currently only
931            allows single selection */
932         
933         /* Fill helpers */
934         rf_helper = g_slice_new0 (ReplyForwardHelper);
935         rf_helper->reply_forward_type = reply_forward_type;
936         rf_helper->action = action;
937         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
938         if ((win != NULL) && (MODEST_IS_WINDOW (win)))
939                 rf_helper->parent_window = GTK_WIDGET (win);
940         if (!rf_helper->account_name)
941                 rf_helper->account_name =
942                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
943
944         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
945                 TnyMsg *msg;
946                 TnyHeader *header;
947                 /* Get header and message. Do not free them here, the
948                    reply_forward_cb must do it */
949                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
950                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
951                 if (!msg || !header) {
952                         if (msg)
953                                 g_object_unref (msg);
954                         if (header)
955                                 g_object_unref (header);
956                         g_printerr ("modest: no message found\n");
957                         return;
958                 } else
959                         reply_forward_cb (NULL, header, msg, rf_helper);
960         } else {
961                 /* Retrieve messages */
962                 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
963                                                                          G_OBJECT(win),
964                                                                          modest_ui_actions_get_msgs_full_error_handler, 
965                                                                          NULL);
966                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
967                 modest_mail_operation_get_msgs_full (mail_op, 
968                                                      header_list, 
969                                                      reply_forward_cb, 
970                                                      rf_helper, 
971                                                      free_reply_forward_helper);
972
973                 /* Clean */
974                 g_object_unref(mail_op);
975         }
976
977         /* Free */
978         g_object_unref (header_list);
979 }
980
981 void
982 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
983 {
984         g_return_if_fail (MODEST_IS_WINDOW(win));
985
986         reply_forward (ACTION_REPLY, win);
987 }
988
989 void
990 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
991 {
992         g_return_if_fail (MODEST_IS_WINDOW(win));
993
994         reply_forward (ACTION_FORWARD, win);
995 }
996
997 void
998 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
999 {
1000         g_return_if_fail (MODEST_IS_WINDOW(win));
1001
1002         reply_forward (ACTION_REPLY_TO_ALL, win);
1003 }
1004
1005 void 
1006 modest_ui_actions_on_next (GtkAction *action, 
1007                            ModestWindow *window)
1008 {
1009         if (MODEST_IS_MAIN_WINDOW (window)) {
1010                 GtkWidget *header_view;
1011
1012                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1013                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1014                 if (!header_view)
1015                         return;
1016         
1017                 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); 
1018         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1019                 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1020         } else {
1021                 g_return_if_reached ();
1022         }
1023 }
1024
1025 void 
1026 modest_ui_actions_on_prev (GtkAction *action, 
1027                            ModestWindow *window)
1028 {
1029         g_return_if_fail (MODEST_IS_WINDOW(window));
1030
1031         if (MODEST_IS_MAIN_WINDOW (window)) {
1032                 GtkWidget *header_view;
1033                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1034                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1035                 if (!header_view)
1036                         return;
1037                 
1038                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
1039         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1040                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1041         } else {
1042                 g_return_if_reached ();
1043         }
1044 }
1045
1046 void 
1047 modest_ui_actions_on_sort (GtkAction *action, 
1048                            ModestWindow *window)
1049 {
1050         g_return_if_fail (MODEST_IS_WINDOW(window));
1051
1052         if (MODEST_IS_MAIN_WINDOW (window)) {
1053                 GtkWidget *header_view;
1054                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1055                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1056                 if (!header_view)
1057                         return;
1058
1059                 /* Show sorting dialog */
1060                 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);     
1061         }
1062 }
1063
1064 /*
1065  * This function performs the send & receive required actions. The
1066  * window is used to create the mail operation. Typically it should
1067  * always be the main window, but we pass it as argument in order to
1068  * be more flexible.
1069  */
1070 void
1071 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1072 {
1073         gchar *acc_name = NULL;
1074         ModestMailOperation *mail_op;
1075
1076         /* If no account name was provided then get the current account, and if
1077            there is no current account then pick the default one: */
1078         if (!account_name) {
1079                 acc_name = g_strdup (modest_window_get_active_account(win));
1080                 if (!acc_name)
1081                         acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1082                 if (!acc_name) {
1083                         g_printerr ("modest: cannot get default account\n");
1084                         return;
1085                 }
1086         } else {
1087                 acc_name = g_strdup (account_name);
1088         }
1089
1090         /* Set send/receive operation in progress */    
1091         modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1092
1093         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1094         g_signal_connect (G_OBJECT(mail_op), "progress-changed", 
1095                           G_CALLBACK (_on_send_receive_progress_changed), 
1096                           win);
1097
1098         /* Send & receive. */
1099         /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1100         /* Receive and then send. The operation is tagged initially as
1101            a receive operation because the account update performs a
1102            receive and then a send. The operation changes its type
1103            internally, so the progress objects will receive the proper
1104            progress information */
1105         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1106         modest_mail_operation_update_account (mail_op, acc_name);
1107         g_object_unref (G_OBJECT (mail_op));
1108         
1109         /* Free */
1110         g_free (acc_name);
1111 }
1112
1113 /*
1114  * Refreshes all accounts. This function will be used by automatic
1115  * updates
1116  */
1117 void
1118 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1119 {
1120         GSList *account_names, *iter;
1121
1122         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1123                                                           TRUE);
1124
1125         iter = account_names;
1126         while (iter) {                  
1127                 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1128                 iter = g_slist_next (iter);
1129         }
1130         
1131         g_slist_foreach (account_names, (GFunc) g_free, NULL);
1132         g_slist_free (account_names);
1133 }
1134
1135 /*
1136  * Handler of the click on Send&Receive button in the main toolbar
1137  */
1138 void
1139 modest_ui_actions_on_send_receive (GtkAction *action,  ModestWindow *win)
1140 {
1141         /* Check if accounts exist */
1142         gboolean accounts_exist = 
1143                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1144         
1145         /* If not, allow the user to create an account before trying to send/receive. */
1146         if (!accounts_exist)
1147                 modest_ui_actions_on_accounts (NULL, win);
1148         
1149         /* Refresh the active account */
1150         modest_ui_actions_do_send_receive (NULL, win);
1151 }
1152
1153
1154 void
1155 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1156 {
1157         ModestConf *conf;
1158         GtkWidget *header_view;
1159         
1160         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1161
1162         header_view = modest_main_window_get_child_widget (main_window,
1163                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1164         if (!header_view)
1165                 return;
1166
1167         conf = modest_runtime_get_conf ();
1168         
1169         /* what is saved/restored is depending on the style; thus; we save with
1170          * old style, then update the style, and restore for this new style
1171          */
1172         modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1173         
1174         if (modest_header_view_get_style
1175             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1176                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1177                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
1178         else
1179                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1180                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
1181
1182         modest_widget_memory_restore (conf, G_OBJECT(header_view),
1183                                       MODEST_CONF_HEADER_VIEW_KEY);
1184 }
1185
1186
1187 void 
1188 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
1189                                       TnyHeader *header,
1190                                       ModestMainWindow *main_window)
1191 {
1192         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1193         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1194         
1195         /* If no header has been selected then exit */
1196         if (!header)
1197                 return;
1198         
1199         /* Update Main window title */
1200         if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1201                 const gchar *subject = tny_header_get_subject (header);
1202                 if (subject && strlen(subject) > 0)
1203                         gtk_window_set_title (GTK_WINDOW (main_window), subject);
1204                 else
1205                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1206         }
1207
1208         /* Update toolbar dimming state */
1209         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1210 }
1211
1212 void
1213 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1214                                        TnyHeader *header,
1215                                        ModestMainWindow *main_window)
1216 {
1217         TnyList *headers;
1218
1219         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1220         
1221         if (!header)
1222                 return;
1223
1224         headers = tny_simple_list_new ();
1225         tny_list_prepend (headers, G_OBJECT (header));
1226
1227         _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1228
1229         g_object_unref (headers);
1230 }
1231
1232 static void
1233 set_active_account_from_tny_account (TnyAccount *account,
1234                                      ModestWindow *window)
1235 {
1236         const gchar *server_acc_name = tny_account_get_id (account);
1237         
1238         /* We need the TnyAccount provided by the
1239            account store because that is the one that
1240            knows the name of the Modest account */
1241         TnyAccount *modest_server_account = modest_server_account = 
1242                 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1243                                                              MODEST_TNY_ACCOUNT_STORE_QUERY_ID, 
1244                                                              server_acc_name);
1245         
1246         const gchar *modest_acc_name = 
1247                 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1248         modest_window_set_active_account (window, modest_acc_name);
1249         g_object_unref (modest_server_account);
1250 }
1251
1252
1253 static void
1254 folder_refreshed_cb (const GObject *obj, 
1255                      TnyFolder *folder, 
1256                      gpointer user_data)
1257 {
1258         printf ("DEBUG: %s\n", __FUNCTION__);
1259         ModestMainWindow *win = NULL;
1260         GtkWidget *header_view;
1261
1262         g_return_if_fail (TNY_IS_FOLDER (folder));
1263
1264         win = MODEST_MAIN_WINDOW (user_data);
1265         header_view = 
1266                 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1267
1268         /* Check if folder is empty and set headers view contents style */
1269         if (tny_folder_get_all_count (folder) == 0) {
1270         printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1271                 modest_main_window_set_contents_style (win,
1272                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1273         } else {
1274                 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1275                 /* Restore configuration. There is no need to set the
1276                    contents style to headers because it was already
1277                    being done in folder_selection_changed */
1278                 modest_widget_memory_restore (modest_runtime_get_conf (), 
1279                                               G_OBJECT(header_view),
1280                                               MODEST_CONF_HEADER_VIEW_KEY);
1281         }
1282 }
1283
1284 void 
1285 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1286                                                TnyFolderStore *folder_store, 
1287                                                gboolean selected,
1288                                                ModestMainWindow *main_window)
1289 {
1290         ModestConf *conf;
1291         GtkWidget *header_view;
1292
1293         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1294
1295         header_view = modest_main_window_get_child_widget(main_window,
1296                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
1297         if (!header_view)
1298                 return;
1299         
1300         conf = modest_runtime_get_conf ();
1301
1302         if (TNY_IS_ACCOUNT (folder_store)) {
1303                 /* Update active account */
1304                 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1305                 /* Show account details */
1306                 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1307         } else {
1308                 if (TNY_IS_FOLDER (folder_store) && selected) {
1309                         
1310                         if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1311                                 /* Update the active account */
1312                                 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1313                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1314                                 g_object_unref (account);
1315                         }
1316
1317                         /* Set the header view, we could change it to
1318                            the empty view after the refresh */
1319                         modest_main_window_set_contents_style (main_window, 
1320                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1321                         
1322                         modest_widget_memory_save (modest_runtime_get_conf(),
1323                                                    G_OBJECT(header_view),
1324                                                    MODEST_CONF_HEADER_VIEW_KEY);
1325
1326                         /* Set folder on header view. This function
1327                            will call tny_folder_refresh_async so we
1328                            pass a callback that will be called when
1329                            finished. We use that callback to set the
1330                            empty view if there are no messages */
1331                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1332                                                        TNY_FOLDER (folder_store),
1333                                                        folder_refreshed_cb,
1334                                                        main_window);
1335                 } else {
1336                         /* Update the active account */
1337                         modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1338                         /* Do not show folder */
1339                         modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1340                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1341                 }                       
1342         }
1343
1344         /* Update toolbar dimming state */
1345         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1346 }
1347
1348 void 
1349 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1350                                      ModestWindow *win)
1351 {
1352         GtkWidget *dialog;
1353         gchar *txt, *item;
1354         gboolean online;
1355
1356         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1357         
1358         if (g_main_depth > 0)   
1359                 gdk_threads_enter ();
1360         online = tny_device_is_online (modest_runtime_get_device());
1361
1362         if (online) {
1363                 /* already online -- the item is simply not there... */
1364                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1365                                                  GTK_DIALOG_MODAL,
1366                                                  GTK_MESSAGE_WARNING,
1367                                                  GTK_BUTTONS_OK,
1368                                                  _("The %s you selected cannot be found"),
1369                                                  item);
1370                 gtk_dialog_run (GTK_DIALOG(dialog));
1371         } else {
1372                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1373                                                       GTK_WINDOW (win),
1374                                                       GTK_DIALOG_MODAL,
1375                                                       GTK_STOCK_CANCEL,
1376                                                       GTK_RESPONSE_REJECT,
1377                                                       GTK_STOCK_OK,
1378                                                       GTK_RESPONSE_ACCEPT,
1379                                                       NULL);
1380                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1381                                          "Do you want to get online?"), item);
1382                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1383                                     gtk_label_new (txt), FALSE, FALSE, 0);
1384                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1385                 g_free (txt);
1386
1387                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1388                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1389 //                      modest_platform_connect_and_wait ();
1390                 }
1391         }
1392         gtk_widget_destroy (dialog);
1393         if (g_main_depth > 0)   
1394                 gdk_threads_leave ();
1395 }
1396
1397 void
1398 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1399                                      ModestWindow *win)
1400 {
1401         /* g_message ("%s %s", __FUNCTION__, link); */
1402 }       
1403
1404
1405 void
1406 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1407                                         ModestWindow *win)
1408 {
1409         modest_platform_activate_uri (link);
1410 }
1411
1412 void
1413 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1414                                           ModestWindow *win)
1415 {
1416         modest_platform_show_uri_popup (link);
1417 }
1418
1419 void
1420 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1421                                              ModestWindow *win)
1422 {
1423         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1424 }
1425
1426 void
1427 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1428                                           const gchar *address,
1429                                           ModestWindow *win)
1430 {
1431         /* g_message ("%s %s", __FUNCTION__, address); */
1432 }
1433
1434 void
1435 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1436 {
1437         TnyTransportAccount *transport_account;
1438         ModestMailOperation *mail_operation;
1439         MsgData *data;
1440         gchar *account_name, *from;
1441         ModestAccountMgr *account_mgr;
1442
1443         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1444         
1445         data = modest_msg_edit_window_get_msg_data (edit_window);
1446
1447         account_mgr = modest_runtime_get_account_mgr();
1448         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1449         if (!account_name) 
1450                 account_name = modest_account_mgr_get_default_account (account_mgr);
1451         if (!account_name) {
1452                 g_printerr ("modest: no account found\n");
1453                 modest_msg_edit_window_free_msg_data (edit_window, data);
1454                 return;
1455         }
1456
1457         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1458                 account_name = g_strdup (data->account_name);
1459         }
1460
1461         transport_account =
1462                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1463                                       (modest_runtime_get_account_store(),
1464                                        account_name,
1465                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1466         if (!transport_account) {
1467                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1468                 g_free (account_name);
1469                 modest_msg_edit_window_free_msg_data (edit_window, data);
1470                 return;
1471         }
1472         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1473
1474         /* Create the mail operation */         
1475         mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1476         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1477
1478         modest_mail_operation_save_to_drafts (mail_operation,
1479                                               transport_account,
1480                                               data->draft_msg,
1481                                               from,
1482                                               data->to, 
1483                                               data->cc, 
1484                                               data->bcc,
1485                                               data->subject, 
1486                                               data->plain_body, 
1487                                               data->html_body,
1488                                               data->attachments,
1489                                               data->priority_flags);
1490         /* Frees */
1491         g_free (from);
1492         g_free (account_name);
1493         g_object_unref (G_OBJECT (transport_account));
1494         g_object_unref (G_OBJECT (mail_operation));
1495
1496         modest_msg_edit_window_free_msg_data (edit_window, data);
1497
1498         /* Save settings and close the window */
1499         gtk_widget_destroy (GTK_WIDGET (edit_window));
1500 }
1501
1502 /* For instance, when clicking the Send toolbar button when editing a message: */
1503 void
1504 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1505 {
1506         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1507
1508         if (!modest_msg_edit_window_check_names (edit_window))
1509                 return;
1510         
1511         /* FIXME: Code added just for testing. The final version will
1512            use the send queue provided by tinymail and some
1513            classifier */
1514         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1515         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1516         if (!account_name) 
1517                 account_name = modest_account_mgr_get_default_account (account_mgr);
1518                 
1519         if (!account_name) {
1520                 g_printerr ("modest: no account found\n");
1521                 return;
1522         }
1523         
1524         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1525
1526         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1527                 account_name = g_strdup (data->account_name);
1528         }
1529         
1530         /* Get the currently-active transport account for this modest account: */
1531         TnyTransportAccount *transport_account =
1532                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1533                                       (modest_runtime_get_account_store(),
1534                                        account_name));
1535         if (!transport_account) {
1536                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1537                 g_free (account_name);
1538                 modest_msg_edit_window_free_msg_data (edit_window, data);
1539                 return;
1540         }
1541         
1542         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1543
1544         /* mail content checks and dialogs */
1545         if (data->subject == NULL || data->subject[0] == '\0') {
1546                 GtkResponseType response;
1547                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1548                                                                     _("mcen_nc_subject_is_empty_send"));
1549                 if (response == GTK_RESPONSE_CANCEL) {
1550                         g_free (account_name);
1551                         return;
1552                 }
1553         }
1554
1555         if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1556                 GtkResponseType response;
1557                 gchar *note_message;
1558                 gchar *note_subject = data->subject;
1559                 if (note_subject == NULL || note_subject[0] == '\0')
1560                         note_subject = _("mail_va_no_subject");
1561                 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1562                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1563                                                                     note_message);
1564                 g_free (note_message);
1565                 if (response == GTK_RESPONSE_CANCEL) {
1566                         g_free (account_name);
1567                         return;
1568                 }
1569         }
1570
1571         /* Create the mail operation */
1572         ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1573         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1574
1575         modest_mail_operation_send_new_mail (mail_operation,
1576                                              transport_account,
1577                                              data->draft_msg,
1578                                              from,
1579                                              data->to, 
1580                                              data->cc, 
1581                                              data->bcc,
1582                                              data->subject, 
1583                                              data->plain_body, 
1584                                              data->html_body,
1585                                              data->attachments,
1586                                              data->priority_flags);
1587                                              
1588         /* Free data: */
1589         g_free (from);
1590         g_free (account_name);
1591         g_object_unref (G_OBJECT (transport_account));
1592         g_object_unref (G_OBJECT (mail_operation));
1593
1594         modest_msg_edit_window_free_msg_data (edit_window, data);
1595
1596         /* Save settings and close the window: */
1597         gtk_widget_destroy (GTK_WIDGET (edit_window));
1598 }
1599
1600 void 
1601 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1602                                   ModestMsgEditWindow *window)
1603 {
1604         ModestMsgEditFormatState *format_state = NULL;
1605
1606         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1607         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1608
1609         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1610                 return;
1611
1612         format_state = modest_msg_edit_window_get_format_state (window);
1613         g_return_if_fail (format_state != NULL);
1614
1615         format_state->bold = gtk_toggle_action_get_active (action);
1616         modest_msg_edit_window_set_format_state (window, format_state);
1617         g_free (format_state);
1618         
1619 }
1620
1621 void 
1622 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1623                                      ModestMsgEditWindow *window)
1624 {
1625         ModestMsgEditFormatState *format_state = NULL;
1626
1627         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1628         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1629
1630         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1631                 return;
1632
1633         format_state = modest_msg_edit_window_get_format_state (window);
1634         g_return_if_fail (format_state != NULL);
1635
1636         format_state->italics = gtk_toggle_action_get_active (action);
1637         modest_msg_edit_window_set_format_state (window, format_state);
1638         g_free (format_state);
1639         
1640 }
1641
1642 void 
1643 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1644                                      ModestMsgEditWindow *window)
1645 {
1646         ModestMsgEditFormatState *format_state = NULL;
1647
1648         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1649         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1650
1651         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1652                 return;
1653
1654         format_state = modest_msg_edit_window_get_format_state (window);
1655         g_return_if_fail (format_state != NULL);
1656
1657         format_state->bullet = gtk_toggle_action_get_active (action);
1658         modest_msg_edit_window_set_format_state (window, format_state);
1659         g_free (format_state);
1660         
1661 }
1662
1663 void 
1664 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1665                                      GtkRadioAction *selected,
1666                                      ModestMsgEditWindow *window)
1667 {
1668         ModestMsgEditFormatState *format_state = NULL;
1669         GtkJustification value;
1670
1671         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1672
1673         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1674                 return;
1675
1676         value = gtk_radio_action_get_current_value (selected);
1677
1678         format_state = modest_msg_edit_window_get_format_state (window);
1679         g_return_if_fail (format_state != NULL);
1680
1681         format_state->justification = value;
1682         modest_msg_edit_window_set_format_state (window, format_state);
1683         g_free (format_state);
1684 }
1685
1686 void 
1687 modest_ui_actions_on_select_editor_color (GtkAction *action,
1688                                           ModestMsgEditWindow *window)
1689 {
1690         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1691         g_return_if_fail (GTK_IS_ACTION (action));
1692
1693         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1694                 return;
1695
1696         modest_msg_edit_window_select_color (window);
1697 }
1698
1699 void 
1700 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1701                                                      ModestMsgEditWindow *window)
1702 {
1703         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1704         g_return_if_fail (GTK_IS_ACTION (action));
1705
1706         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1707                 return;
1708
1709         modest_msg_edit_window_select_background_color (window);
1710 }
1711
1712 void 
1713 modest_ui_actions_on_insert_image (GtkAction *action,
1714                                    ModestMsgEditWindow *window)
1715 {
1716         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1717         g_return_if_fail (GTK_IS_ACTION (action));
1718
1719         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1720                 return;
1721
1722         modest_msg_edit_window_insert_image (window);
1723 }
1724
1725 void 
1726 modest_ui_actions_on_attach_file (GtkAction *action,
1727                                   ModestMsgEditWindow *window)
1728 {
1729         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1730         g_return_if_fail (GTK_IS_ACTION (action));
1731
1732         modest_msg_edit_window_attach_file (window);
1733 }
1734
1735 void 
1736 modest_ui_actions_on_remove_attachments (GtkAction *action,
1737                                          ModestMsgEditWindow *window)
1738 {
1739         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1740         g_return_if_fail (GTK_IS_ACTION (action));
1741
1742         modest_msg_edit_window_remove_attachments (window, NULL);
1743 }
1744
1745 /*
1746  * Shows a dialog with an entry that asks for some text. The returned
1747  * value must be freed by the caller. The dialog window title will be
1748  * set to @title.
1749  */
1750 static gchar *
1751 ask_for_folder_name (GtkWindow *parent_window,
1752                      const gchar *title)
1753 {
1754         GtkWidget *dialog, *entry;
1755         gchar *folder_name = NULL;
1756
1757         /* Ask for folder name */
1758         dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1759                                               parent_window,
1760                                               GTK_DIALOG_MODAL,
1761                                               GTK_STOCK_CANCEL,
1762                                               GTK_RESPONSE_REJECT,
1763                                               GTK_STOCK_OK,
1764                                               GTK_RESPONSE_ACCEPT,
1765                                               NULL);
1766         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1767                             gtk_label_new(title),
1768                             FALSE, FALSE, 0);
1769                 
1770         entry = gtk_entry_new_with_max_length (40);
1771         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1772                             entry,
1773                             TRUE, FALSE, 0);    
1774         
1775         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1776         
1777         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)         
1778                 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1779
1780         gtk_widget_destroy (dialog);
1781
1782         return folder_name;
1783 }
1784
1785 void 
1786 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1787 {
1788         TnyFolderStore *parent_folder;
1789         GtkWidget *folder_view;
1790         
1791         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1792
1793         folder_view = modest_main_window_get_child_widget (main_window,
1794                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1795         if (!folder_view)
1796                 return;
1797
1798         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1799         
1800         if (parent_folder) {
1801                 gboolean finished = FALSE;
1802                 gint result;
1803                 gchar *folder_name = NULL, *suggested_name = NULL;
1804
1805                 /* Run the new folder dialog */
1806                 while (!finished) {
1807                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1808                                                                         parent_folder,
1809                                                                         suggested_name,
1810                                                                         &folder_name);
1811
1812                         if (result == GTK_RESPONSE_REJECT) {
1813                                 finished = TRUE;
1814                         } else {
1815                                 ModestMailOperation *mail_op;
1816                                 TnyFolder *new_folder = NULL;
1817
1818                                 mail_op  = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, 
1819                                                                       G_OBJECT(main_window));
1820                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1821                                                                  mail_op);
1822                                 new_folder = modest_mail_operation_create_folder (mail_op,
1823                                                                                   parent_folder,
1824                                                                                   (const gchar *) folder_name);
1825                                 if (new_folder) {
1826                                         g_object_unref (new_folder);
1827                                         finished = TRUE;
1828                                 }
1829                                 g_object_unref (mail_op);
1830                         }
1831                         g_free (folder_name);
1832                         folder_name = NULL;
1833                 }
1834
1835                 g_object_unref (parent_folder);
1836         }
1837 }
1838
1839 void 
1840 modest_ui_actions_on_rename_folder (GtkAction *action,
1841                                      ModestMainWindow *main_window)
1842 {
1843         TnyFolderStore *folder;
1844         GtkWidget *folder_view;
1845         GtkWidget *header_view; 
1846
1847         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1848
1849         folder_view = modest_main_window_get_child_widget (main_window,
1850                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1851         if (!folder_view)
1852                 return;
1853
1854         header_view = modest_main_window_get_child_widget (main_window,
1855                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1856         
1857         if (!header_view)
1858                 return;
1859
1860         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1861         
1862         if (folder && TNY_IS_FOLDER (folder)) {
1863                 gchar *folder_name;
1864                 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1865                                                    _("Please enter a new name for the folder"));
1866
1867                 if (folder_name != NULL && strlen (folder_name) > 0) {
1868                         ModestMailOperation *mail_op;
1869
1870                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1871                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1872                                                          mail_op);
1873
1874                         modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1875
1876                         modest_mail_operation_rename_folder (mail_op,
1877                                                              TNY_FOLDER (folder),
1878                                                              (const gchar *) folder_name);
1879
1880                         g_object_unref (mail_op);
1881                         g_free (folder_name);
1882                 }
1883                 g_object_unref (folder);
1884         }
1885 }
1886
1887 static void
1888 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1889                                                gpointer user_data)
1890 {
1891         GObject *win = modest_mail_operation_get_source (mail_op);
1892
1893         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1894                                                 _("mail_in_ui_folder_delete_error"));
1895 }
1896
1897 static void
1898 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
1899 {
1900         TnyFolderStore *folder;
1901         GtkWidget *folder_view;
1902         gint response;
1903         gchar *message;
1904         
1905         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1906
1907         folder_view = modest_main_window_get_child_widget (main_window,
1908                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1909         if (!folder_view)
1910                 return;
1911
1912         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1913
1914         /* Show an error if it's an account */
1915         if (!TNY_IS_FOLDER (folder)) {
1916                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1917                                                         _("mail_in_ui_folder_delete_error"));
1918                 return ;
1919         }
1920
1921         /* Ask the user */      
1922         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
1923                                     tny_folder_get_name (TNY_FOLDER (folder)));
1924         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window), 
1925                                                             (const gchar *) message);
1926         g_free (message);
1927
1928         if (response == GTK_RESPONSE_OK) {
1929                 ModestMailOperation *mail_op = 
1930                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, 
1931                                                                        G_OBJECT(main_window),
1932                                                                        modest_ui_actions_delete_folder_error_handler,
1933                                                                        NULL);
1934
1935                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1936                                                  mail_op);
1937                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1938                 g_object_unref (G_OBJECT (mail_op));
1939         }
1940
1941         g_object_unref (G_OBJECT (folder));
1942 }
1943
1944 void 
1945 modest_ui_actions_on_delete_folder (GtkAction *action,
1946                                      ModestMainWindow *main_window)
1947 {
1948         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1949
1950         delete_folder (main_window, FALSE);
1951 }
1952
1953 void 
1954 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1955 {
1956         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1957         
1958         delete_folder (main_window, TRUE);
1959 }
1960
1961 void
1962 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
1963                                          const gchar* server_account_name,
1964                                          gchar **username,
1965                                          gchar **password, 
1966                                          gboolean *cancel, 
1967                                          gboolean *remember,
1968                                          ModestMainWindow *main_window)
1969 {
1970         g_return_if_fail(server_account_name);
1971         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1972         
1973         /* Initalize output parameters: */
1974         if (cancel)
1975                 *cancel = FALSE;
1976                 
1977         if (remember)
1978                 *remember = TRUE;
1979                 
1980 #ifdef MODEST_PLATFORM_MAEMO
1981         /* Maemo uses a different (awkward) button order,
1982          * It should probably just use gtk_alternative_dialog_button_order ().
1983          */
1984         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1985                                               NULL,
1986                                               GTK_DIALOG_MODAL,
1987                                               GTK_STOCK_OK,
1988                                               GTK_RESPONSE_ACCEPT,
1989                                               GTK_STOCK_CANCEL,
1990                                               GTK_RESPONSE_REJECT,
1991                                               NULL);
1992 #else
1993         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1994                                               NULL,
1995                                               GTK_DIALOG_MODAL,
1996                                               GTK_STOCK_CANCEL,
1997                                               GTK_RESPONSE_REJECT,
1998                                               GTK_STOCK_OK,
1999                                               GTK_RESPONSE_ACCEPT,
2000                                               NULL);
2001 #endif /* MODEST_PLATFORM_MAEMO */
2002
2003         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2004         
2005         gchar *server_name = modest_server_account_get_hostname (
2006                 modest_runtime_get_account_mgr(), server_account_name);
2007         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2008                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2009                 *cancel = TRUE;
2010                 return;
2011         }
2012         
2013         /* This causes a warning because the logical ID has no %s in it, 
2014          * though the translation does, but there is not much we can do about that: */
2015         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2016         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2017                             FALSE, FALSE, 0);
2018         g_free (txt);
2019         g_free (server_name);
2020         server_name = NULL;
2021
2022         /* username: */
2023         gchar *initial_username = modest_server_account_get_username (
2024                 modest_runtime_get_account_mgr(), server_account_name);
2025         
2026         GtkWidget *entry_username = gtk_entry_new ();
2027         if (initial_username)
2028                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2029         /* Dim this if a connection has ever succeeded with this username,
2030          * as per the UI spec: */
2031         const gboolean username_known = 
2032                 modest_server_account_get_username_has_succeeded(
2033                         modest_runtime_get_account_mgr(), server_account_name);
2034         gtk_widget_set_sensitive (entry_username, !username_known);
2035         
2036 #ifdef MODEST_PLATFORM_MAEMO
2037         /* Auto-capitalization is the default, so let's turn it off: */
2038         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2039         
2040         /* Create a size group to be used by all captions.
2041          * Note that HildonCaption does not create a default size group if we do not specify one.
2042          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2043         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2044         
2045         GtkWidget *caption = hildon_caption_new (sizegroup, 
2046                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2047         gtk_widget_show (entry_username);
2048         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2049                 FALSE, FALSE, MODEST_MARGIN_HALF);
2050         gtk_widget_show (caption);
2051 #else 
2052         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2053                             TRUE, FALSE, 0);
2054 #endif /* MODEST_PLATFORM_MAEMO */      
2055                             
2056         /* password: */
2057         GtkWidget *entry_password = gtk_entry_new ();
2058         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2059         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2060         
2061 #ifdef MODEST_PLATFORM_MAEMO
2062         /* Auto-capitalization is the default, so let's turn it off: */
2063         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2064                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2065         
2066         caption = hildon_caption_new (sizegroup, 
2067                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2068         gtk_widget_show (entry_password);
2069         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2070                 FALSE, FALSE, MODEST_MARGIN_HALF);
2071         gtk_widget_show (caption);
2072         g_object_unref (sizegroup);
2073 #else 
2074         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2075                             TRUE, FALSE, 0);
2076 #endif /* MODEST_PLATFORM_MAEMO */      
2077                                 
2078 /* This is not in the Maemo UI spec:
2079         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2080         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2081                             TRUE, FALSE, 0);
2082 */
2083
2084         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2085         
2086         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2087                 if (username) {
2088                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2089                         
2090                         modest_server_account_set_username (
2091                                  modest_runtime_get_account_mgr(), server_account_name, 
2092                                  *username);
2093                                  
2094                         const gboolean username_was_changed = 
2095                                 (strcmp (*username, initial_username) != 0);
2096                         if (username_was_changed) {
2097                                 /* To actually use a changed username, 
2098                                  * we must reset the connection, according to pvanhoof.
2099                                  * This _might_ be a sensible way to do that: */
2100                                  TnyDevice *device = modest_runtime_get_device();
2101                                  tny_device_force_offline (device);
2102                                  tny_device_force_online (device);
2103                         }
2104                 }
2105                         
2106                 if (password) {
2107                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2108                         
2109                         /* We do not save the password in the configuration, 
2110                          * because this function is only called for passwords that should 
2111                          * not be remembered:
2112                         modest_server_account_set_password (
2113                                  modest_runtime_get_account_mgr(), server_account_name, 
2114                                  *password);
2115                         */
2116                 }
2117                 
2118                 if (cancel)
2119                         *cancel   = FALSE;
2120                         
2121         } else {
2122                 if (username)
2123                         *username = NULL;
2124                         
2125                 if (password)
2126                         *password = NULL;
2127                         
2128                 if (cancel)
2129                         *cancel   = TRUE;
2130         }
2131
2132 /* This is not in the Maemo UI spec:
2133         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2134                 *remember = TRUE;
2135         else
2136                 *remember = FALSE;
2137 */
2138
2139         gtk_widget_destroy (dialog);
2140         
2141         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2142 }
2143
2144 void
2145 modest_ui_actions_on_cut (GtkAction *action,
2146                           ModestWindow *window)
2147 {
2148         GtkWidget *focused_widget;
2149
2150         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2151         if (GTK_IS_EDITABLE (focused_widget)) {
2152                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2153         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2154                 GtkTextBuffer *buffer;
2155                 GtkClipboard *clipboard;
2156
2157                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2158                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2159                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2160         }
2161 }
2162
2163 void
2164 modest_ui_actions_on_copy (GtkAction *action,
2165                            ModestWindow *window)
2166 {
2167         GtkClipboard *clipboard;
2168         GtkWidget *focused_widget;
2169
2170         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2171         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2172         if (GTK_IS_LABEL (focused_widget)) {
2173                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2174         } else if (GTK_IS_EDITABLE (focused_widget)) {
2175                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2176         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2177                 GtkTextBuffer *buffer;
2178
2179                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2180                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2181         }
2182 }
2183
2184 void
2185 modest_ui_actions_on_undo (GtkAction *action,
2186                            ModestWindow *window)
2187 {
2188         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2189                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2190         } else {
2191                 g_return_if_reached ();
2192         }
2193 }
2194
2195 void
2196 modest_ui_actions_on_paste (GtkAction *action,
2197                             ModestWindow *window)
2198 {
2199         GtkWidget *focused_widget;
2200
2201         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2202         if (GTK_IS_EDITABLE (focused_widget)) {
2203                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2204         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2205                 GtkTextBuffer *buffer;
2206                 GtkClipboard *clipboard;
2207
2208                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2209                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2210                 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2211         }
2212 }
2213
2214 void
2215 modest_ui_actions_on_select_all (GtkAction *action,
2216                                  ModestWindow *window)
2217 {
2218         GtkWidget *focused_widget;
2219
2220         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2221         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2222                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2223         } else if (GTK_IS_LABEL (focused_widget)) {
2224                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2225         } else if (GTK_IS_EDITABLE (focused_widget)) {
2226                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2227         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2228                 GtkTextBuffer *buffer;
2229                 GtkTextIter start, end;
2230
2231                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2232                 gtk_text_buffer_get_start_iter (buffer, &start);
2233                 gtk_text_buffer_get_end_iter (buffer, &end);
2234                 gtk_text_buffer_select_range (buffer, &start, &end);
2235         }
2236         else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2237                  (MODEST_IS_HEADER_VIEW (focused_widget))) {
2238                 
2239                 GtkTreeSelection *selection = NULL;
2240
2241                 /* Get header view */           
2242                 GtkWidget *header_view = focused_widget;
2243                 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2244                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2245                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2246
2247                 /* Select all messages */
2248                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2249                 gtk_tree_selection_select_all (selection);
2250         } else if (GTK_IS_HTML (focused_widget)) {
2251                 gtk_html_select_all (GTK_HTML (focused_widget));
2252         }
2253 }
2254
2255 void
2256 modest_ui_actions_on_mark_as_read (GtkAction *action,
2257                                    ModestWindow *window)
2258 {       
2259         g_return_if_fail (MODEST_IS_WINDOW(window));
2260                 
2261         /* Mark each header as read */
2262         do_headers_action (window, headers_action_mark_as_read, NULL);
2263 }
2264
2265 void
2266 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2267                                      ModestWindow *window)
2268 {       
2269         g_return_if_fail (MODEST_IS_WINDOW(window));
2270                 
2271         /* Mark each header as read */
2272         do_headers_action (window, headers_action_mark_as_unread, NULL);
2273 }
2274
2275 void
2276 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2277                                   GtkRadioAction *selected,
2278                                   ModestWindow *window)
2279 {
2280         gint value;
2281
2282         value = gtk_radio_action_get_current_value (selected);
2283         if (MODEST_IS_WINDOW (window)) {
2284                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2285         }
2286 }
2287
2288 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2289                                                         GtkRadioAction *selected,
2290                                                         ModestWindow *window)
2291 {
2292         TnyHeaderFlags flags;
2293         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2294
2295         flags = gtk_radio_action_get_current_value (selected);
2296         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2297 }
2298
2299 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2300                                                            GtkRadioAction *selected,
2301                                                            ModestWindow *window)
2302 {
2303         gint file_format;
2304
2305         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2306
2307         file_format = gtk_radio_action_get_current_value (selected);
2308         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2309 }
2310
2311
2312 void     
2313 modest_ui_actions_on_zoom_plus (GtkAction *action,
2314                                 ModestWindow *window)
2315 {
2316         g_return_if_fail (MODEST_IS_WINDOW (window));
2317
2318         modest_window_zoom_plus (MODEST_WINDOW (window));
2319 }
2320
2321 void     
2322 modest_ui_actions_on_zoom_minus (GtkAction *action,
2323                                  ModestWindow *window)
2324 {
2325         g_return_if_fail (MODEST_IS_WINDOW (window));
2326
2327         modest_window_zoom_minus (MODEST_WINDOW (window));
2328 }
2329
2330 void     
2331 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
2332                                            ModestWindow *window)
2333 {
2334         ModestWindowMgr *mgr;
2335         gboolean fullscreen, active;
2336         g_return_if_fail (MODEST_IS_WINDOW (window));
2337
2338         mgr = modest_runtime_get_window_mgr ();
2339
2340         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2341         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2342
2343         if (active != fullscreen) {
2344                 modest_window_mgr_set_fullscreen_mode (mgr, active);
2345                 gtk_window_present (GTK_WINDOW (window));
2346         }
2347 }
2348
2349 void
2350 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2351                                         ModestWindow *window)
2352 {
2353         ModestWindowMgr *mgr;
2354         gboolean fullscreen;
2355
2356         g_return_if_fail (MODEST_IS_WINDOW (window));
2357
2358         mgr = modest_runtime_get_window_mgr ();
2359         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2360         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2361
2362         gtk_window_present (GTK_WINDOW (window));
2363 }
2364
2365 /* 
2366  * Used by modest_ui_actions_on_details to call do_headers_action 
2367  */
2368 static void
2369 headers_action_show_details (TnyHeader *header, 
2370                              ModestWindow *window,
2371                              gpointer user_data)
2372
2373 {
2374         GtkWidget *dialog;
2375         
2376         /* Create dialog */
2377         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2378
2379         /* Run dialog */
2380         gtk_widget_show_all (dialog);
2381         gtk_dialog_run (GTK_DIALOG (dialog));
2382
2383         gtk_widget_destroy (dialog);
2384 }
2385
2386 /*
2387  * Show the folder details in a ModestDetailsDialog widget
2388  */
2389 static void
2390 show_folder_details (TnyFolder *folder, 
2391                      GtkWindow *window)
2392 {
2393         GtkWidget *dialog;
2394         
2395         /* Create dialog */
2396         dialog = modest_details_dialog_new_with_folder (window, folder);
2397
2398         /* Run dialog */
2399         gtk_widget_show_all (dialog);
2400         gtk_dialog_run (GTK_DIALOG (dialog));
2401
2402         gtk_widget_destroy (dialog);
2403 }
2404
2405 /*
2406  * Show the header details in a ModestDetailsDialog widget
2407  */
2408 void     
2409 modest_ui_actions_on_details (GtkAction *action, 
2410                               ModestWindow *win)
2411 {
2412         TnyList * headers_list;
2413         TnyIterator *iter;
2414         TnyHeader *header;              
2415
2416         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2417                 TnyMsg *msg;
2418
2419                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2420                 if (!msg)
2421                         return;
2422                 g_object_unref (msg);           
2423
2424                 headers_list = get_selected_headers (win);
2425                 if (!headers_list)
2426                         return;
2427
2428                 iter = tny_list_create_iterator (headers_list);
2429
2430                 header = TNY_HEADER (tny_iterator_get_current (iter));
2431                 headers_action_show_details (header, win, NULL);
2432                 g_object_unref (header);
2433
2434                 g_object_unref (iter);
2435                 g_object_unref (headers_list);
2436
2437         } else if (MODEST_IS_MAIN_WINDOW (win)) {
2438                 GtkWidget *folder_view, *header_view;
2439
2440                 /* Check which widget has the focus */
2441                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2442                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
2443                 if (gtk_widget_is_focus (folder_view)) {
2444                         TnyFolder *folder;
2445
2446                         folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2447
2448                         /* Show only when it's a folder */
2449                         if (!folder || !TNY_IS_FOLDER (folder))
2450                                 return;
2451
2452                         show_folder_details (folder, GTK_WINDOW (win));
2453
2454                 } else {
2455                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2456                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2457                         /* Show details of each header */
2458                         do_headers_action (win, headers_action_show_details, header_view);
2459                 }
2460         }
2461 }
2462
2463 void     
2464 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2465                                      ModestMsgEditWindow *window)
2466 {
2467         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2468
2469         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2470 }
2471
2472 void     
2473 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2474                                       ModestMsgEditWindow *window)
2475 {
2476         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2477
2478         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2479 }
2480
2481 void
2482 modest_ui_actions_toggle_folders_view (GtkAction *action, 
2483                                        ModestMainWindow *main_window)
2484 {
2485         ModestConf *conf;
2486         
2487         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2488
2489         conf = modest_runtime_get_conf ();
2490         
2491         if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2492                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2493         else
2494                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2495 }
2496
2497 void 
2498 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
2499                                      ModestWindow *window)
2500 {
2501         gboolean active, fullscreen = FALSE;
2502         ModestWindowMgr *mgr;
2503
2504         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2505
2506         /* Check if we want to toggle the toolbar vuew in fullscreen
2507            or normal mode */
2508         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
2509                      "ViewShowToolbarFullScreen")) {
2510                 fullscreen = TRUE;
2511         }
2512
2513         /* Toggle toolbar */
2514         mgr = modest_runtime_get_window_mgr ();
2515         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2516 }
2517
2518 void     
2519 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2520                                            ModestMsgEditWindow *window)
2521 {
2522         modest_msg_edit_window_select_font (window);
2523 }
2524
2525 void
2526 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2527                                                   const gchar *display_name,
2528                                                   GtkWindow *window)
2529 {
2530         /* Do not change the application name if the widget has not
2531            the focus. This callback could be called even if the folder
2532            view has not the focus, because the handled signal could be
2533            emitted when the folder view is redrawn */
2534         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2535                 if (display_name)
2536                         gtk_window_set_title (window, display_name);
2537                 else
2538                         gtk_window_set_title (window, " ");
2539         }
2540 }
2541
2542 void
2543 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2544 {
2545         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2546         modest_msg_edit_window_select_contacts (window);
2547 }
2548
2549 void
2550 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2551 {
2552         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2553         modest_msg_edit_window_check_names (window);
2554 }
2555
2556
2557 static GtkWidget*
2558 create_move_to_dialog (ModestWindow *win,
2559                        GtkWidget *folder_view,
2560                        GtkWidget **tree_view)
2561 {
2562         GtkWidget *dialog, *scroll;
2563
2564         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2565                                               GTK_WINDOW (win),
2566                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2567                                               GTK_STOCK_OK,
2568                                               GTK_RESPONSE_ACCEPT,
2569                                               GTK_STOCK_CANCEL,
2570                                               GTK_RESPONSE_REJECT,
2571                                               NULL);
2572
2573         /* Create scrolled window */
2574         scroll = gtk_scrolled_window_new (NULL, NULL);
2575         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
2576                                          GTK_POLICY_AUTOMATIC,
2577                                          GTK_POLICY_AUTOMATIC);
2578
2579         /* Create folder view */
2580         *tree_view = modest_platform_create_folder_view (NULL);
2581
2582         /* It could happen that we're trying to move a message from a
2583            window (msg window for example) after the main window was
2584            closed, so we can not just get the model of the folder
2585            view */
2586         if (MODEST_IS_FOLDER_VIEW (folder_view))
2587                 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2588                                          gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2589         else
2590                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
2591                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2592
2593         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2594
2595         /* Add scroll to dialog */
2596         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
2597                             scroll, FALSE, FALSE, 0);
2598
2599         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2600
2601         /* Select INBOX or local account */
2602         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2603
2604         return dialog;
2605 }
2606
2607 /*
2608  * Returns TRUE if at least one of the headers of the list belongs to
2609  * a message that has been fully retrieved.
2610  */
2611 static gboolean
2612 has_retrieved_msgs (TnyList *list)
2613 {
2614         TnyIterator *iter;
2615         gboolean found = FALSE;
2616
2617         iter = tny_list_create_iterator (list);
2618         while (tny_iterator_is_done (iter) && !found) {
2619                 TnyHeader *header;
2620                 TnyHeaderFlags flags;
2621
2622                 header = TNY_HEADER (tny_iterator_get_current (iter));
2623                 flags = tny_header_get_flags (header);
2624                 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2625                         found = TRUE;
2626
2627                 if (!found)
2628                         tny_iterator_next (iter);
2629         }
2630         g_object_unref (iter);
2631
2632         return found;
2633 }
2634
2635 /*
2636  * Shows a confirmation dialog to the user when we're moving messages
2637  * from a remote server to the local storage. Returns the dialog
2638  * response. If it's other kind of movement the it always returns
2639  * GTK_RESPONSE_OK
2640  */
2641 static gint
2642 msgs_move_to_confirmation (GtkWindow *win,
2643                            TnyFolder *dest_folder,
2644                            TnyList *headers)
2645 {
2646         gint response = GTK_RESPONSE_OK;
2647
2648         /* If the destination is a local folder */
2649         if (modest_tny_folder_is_local_folder (dest_folder)) {
2650                 TnyFolder *src_folder;
2651                 TnyIterator *iter;
2652                 TnyHeader *header;
2653
2654                 /* Get source folder */
2655                 iter = tny_list_create_iterator (headers);
2656                 header = TNY_HEADER (tny_iterator_get_current (iter));
2657                 src_folder = tny_header_get_folder (header);
2658                 g_object_unref (header);
2659                 g_object_unref (iter);
2660
2661                 /* If the source is a remote folder */
2662                 if (!modest_tny_folder_is_local_folder (src_folder)) {
2663                         const gchar *message;
2664                         
2665                         if (tny_list_get_length (headers) == 1)
2666                                 if (has_retrieved_msgs (headers))
2667                                         message = _("mcen_nc_move_retrieve");
2668                                 else
2669                                         message = _("mcen_nc_move_header");
2670                         else
2671                                 if (has_retrieved_msgs (headers))
2672                                         message = _("mcen_nc_move_retrieves");
2673                                 else
2674                                         message = _("mcen_nc_move_headers");
2675                         
2676                         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2677                                                                             (const gchar *) message);
2678                 }
2679                 g_object_unref (src_folder);
2680         }
2681         return response;
2682 }
2683
2684
2685 static void
2686 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2687 {
2688         ModestMsgViewWindow *self = NULL;
2689         gboolean found = FALSE;
2690
2691         g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2692         self = MODEST_MSG_VIEW_WINDOW (object);
2693
2694         found = modest_msg_view_window_select_first_message (self);
2695         g_return_if_fail (found);
2696 }
2697
2698 void
2699 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
2700                                              gpointer user_data)
2701 {
2702         GObject *win = modest_mail_operation_get_source (mail_op);
2703
2704         /* TODO: show error message */
2705         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2706                                                 _("mail_in_ui_folder_move_target_error"));
2707 }
2708
2709 /*
2710  * UI handler for the "Move to" action when invoked from the
2711  * ModestMainWindow
2712  */
2713 static void 
2714 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
2715                                           ModestMainWindow *win)
2716 {
2717         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2718         GtkWidget *header_view = NULL;
2719         gint result;
2720         TnyFolderStore *folder_store = NULL;
2721         ModestMailOperation *mail_op = NULL;
2722
2723         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2724
2725         /* Get the folder view */
2726         folder_view = modest_main_window_get_child_widget (win,
2727                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2728
2729         /* Get header view */
2730         header_view = modest_main_window_get_child_widget (win,
2731                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2732
2733         /* Create and run the dialog */
2734         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2735         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2736         result = gtk_dialog_run (GTK_DIALOG(dialog));
2737         g_object_ref (tree_view);
2738
2739         /* We do this to save an indentation level ;-) */
2740         if (result != GTK_RESPONSE_ACCEPT)
2741                 goto end;
2742
2743         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2744
2745         if (TNY_IS_ACCOUNT (folder_store))
2746                 goto end;
2747
2748         /* Get folder or messages to transfer */
2749         if (gtk_widget_is_focus (folder_view)) {
2750                 TnyFolderStore *src_folder;
2751                 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2752
2753                 /* Clean folder on header view before moving it */
2754                 modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); 
2755
2756                 if (TNY_IS_FOLDER (src_folder)) {
2757                         mail_op = 
2758                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
2759                                                                                G_OBJECT(win),
2760                                                                                modest_ui_actions_move_folder_error_handler,
2761                                                                                NULL);
2762                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2763
2764                         modest_mail_operation_xfer_folder (mail_op, 
2765                                                            TNY_FOLDER (src_folder),
2766                                                            folder_store,
2767                                                            TRUE);
2768                         /* Unref mail operation */
2769                         g_object_unref (G_OBJECT (mail_op));
2770                 }
2771
2772                 /* Frees */
2773                 g_object_unref (G_OBJECT (src_folder));
2774         } else {
2775                 if (gtk_widget_is_focus (header_view)) {
2776                         TnyList *headers;
2777                         gint response;
2778
2779                         headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2780
2781                         /* Ask for user confirmation */
2782                         response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2783                                                               TNY_FOLDER (folder_store), 
2784                                                               headers);
2785
2786                         /* Transfer messages */
2787                         if (response == GTK_RESPONSE_OK) {
2788                                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2789                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2790                                                                  mail_op);
2791
2792                                 modest_mail_operation_xfer_msgs (mail_op, 
2793                                                                  headers,
2794                                                                  TNY_FOLDER (folder_store),
2795                                                                  TRUE,
2796                                                                  NULL,
2797                                                                  NULL);
2798
2799                                 g_object_unref (G_OBJECT (mail_op));
2800                         }
2801                         g_object_unref (headers);
2802                 }
2803         }
2804         g_object_unref (folder_store);
2805  end:
2806         gtk_widget_destroy (dialog);
2807 }
2808
2809
2810 /*
2811  * UI handler for the "Move to" action when invoked from the
2812  * ModestMsgViewWindow
2813  */
2814 static void 
2815 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
2816                                               ModestMsgViewWindow *win)
2817 {
2818         GtkWidget *dialog, *folder_view, *tree_view = NULL;
2819         gint result;
2820         ModestMainWindow *main_window;
2821         TnyHeader *header;
2822         TnyList *headers;
2823
2824         /* Get the folder view */
2825         main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2826         if (main_window)
2827                 folder_view = modest_main_window_get_child_widget (main_window,
2828                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
2829         else
2830                 folder_view = NULL;
2831
2832         /* Create and run the dialog */
2833         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);  
2834         result = gtk_dialog_run (GTK_DIALOG(dialog));
2835         g_object_ref (tree_view);
2836
2837         if (result == GTK_RESPONSE_ACCEPT) {
2838                 TnyFolderStore *folder_store;
2839                 gint response;
2840
2841                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2842
2843                 /* Create header list */
2844                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
2845                 headers = tny_simple_list_new ();
2846                 tny_list_prepend (headers, G_OBJECT (header));
2847                 g_object_unref (header);
2848
2849                 /* Ask user for confirmation. MSG-NOT404 */
2850                 response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2851                                                       TNY_FOLDER (folder_store), 
2852                                                       headers);
2853
2854                 /* Transfer current msg */
2855                 if (response == GTK_RESPONSE_OK) {
2856                         ModestMailOperation *mail_op;
2857
2858                         /* Create mail op */
2859                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2860                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2861                                                          mail_op);
2862                         
2863                         /* Transfer messages */
2864                         modest_mail_operation_xfer_msgs (mail_op, 
2865                                                          headers,
2866                                                          TNY_FOLDER (folder_store),
2867                                                          TRUE,
2868                                                          tranasfer_msgs_from_viewer_cb,
2869                                                          NULL);
2870                         g_object_unref (G_OBJECT (mail_op));
2871                 }
2872                 g_object_unref (headers);
2873                 g_object_unref (folder_store);
2874         }
2875         gtk_widget_destroy (dialog);
2876 }
2877
2878 void 
2879 modest_ui_actions_on_move_to (GtkAction *action, 
2880                               ModestWindow *win)
2881 {
2882         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2883                           MODEST_IS_MSG_VIEW_WINDOW (win));
2884
2885         if (MODEST_IS_MAIN_WINDOW (win)) 
2886                 modest_ui_actions_on_main_window_move_to (action, 
2887                                                           MODEST_MAIN_WINDOW (win));
2888         else
2889                 modest_ui_actions_on_msg_view_window_move_to (action, 
2890                                                               MODEST_MSG_VIEW_WINDOW (win));
2891 }
2892
2893 /*
2894  * Calls #HeadersFunc for each header already selected in the main
2895  * window or the message currently being shown in the msg view window
2896  */
2897 static void
2898 do_headers_action (ModestWindow *win, 
2899                    HeadersFunc func,
2900                    gpointer user_data)
2901 {
2902         TnyList *headers_list;
2903         TnyIterator *iter;
2904         TnyHeader *header;
2905         TnyFolder *folder;
2906
2907         /* Get headers */
2908         headers_list = get_selected_headers (win);
2909         if (!headers_list)
2910                 return;
2911
2912         /* Get the folder */
2913         iter = tny_list_create_iterator (headers_list);
2914         header = TNY_HEADER (tny_iterator_get_current (iter));
2915         folder = tny_header_get_folder (header);
2916         g_object_unref (header);
2917
2918         /* Call the function for each header */
2919         while (!tny_iterator_is_done (iter)) {
2920                 header = TNY_HEADER (tny_iterator_get_current (iter));
2921                 func (header, win, user_data);
2922                 g_object_unref (header);
2923                 tny_iterator_next (iter);
2924         }
2925
2926         /* Trick: do a poke status in order to speed up the signaling
2927            of observers */
2928         tny_folder_poke_status (folder);
2929
2930         /* Frees */
2931         g_object_unref (folder);
2932         g_object_unref (iter);
2933         g_object_unref (headers_list);
2934 }
2935
2936 void 
2937 modest_ui_actions_view_attachment (GtkAction *action,
2938                                    ModestWindow *window)
2939 {
2940         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2941                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2942         } else {
2943                 /* not supported window for this action */
2944                 g_return_if_reached ();
2945         }
2946 }
2947
2948 void
2949 modest_ui_actions_save_attachments (GtkAction *action,
2950                                     ModestWindow *window)
2951 {
2952         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2953                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2954         } else {
2955                 /* not supported window for this action */
2956                 g_return_if_reached ();
2957         }
2958 }
2959
2960 void
2961 modest_ui_actions_remove_attachments (GtkAction *action,
2962                                       ModestWindow *window)
2963 {
2964         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2965                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2966         } else {
2967                 /* not supported window for this action */
2968                 g_return_if_reached ();
2969         }
2970 }
2971
2972 void 
2973 modest_ui_actions_on_settings (GtkAction *action, 
2974                                ModestWindow *win)
2975 {
2976         GtkWidget *dialog;
2977
2978         dialog = modest_platform_get_global_settings_dialog ();
2979         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2980         gtk_widget_show (dialog);
2981
2982         gtk_dialog_run (GTK_DIALOG (dialog));
2983
2984         gtk_widget_destroy (dialog);
2985 }
2986
2987 void 
2988 modest_ui_actions_on_help (GtkAction *action, 
2989                            ModestWindow *win)
2990 {
2991         const gchar *help_id = NULL;
2992
2993         if (MODEST_IS_MAIN_WINDOW (win)) {
2994                 const gchar *action_name;
2995                 action_name = gtk_action_get_name (action);
2996
2997                 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2998                     !strcmp (action_name, "HeaderViewCSMHelp")) {
2999                         GtkWidget *folder_view;
3000                         TnyFolderStore *folder_store;
3001                         /* Get selected folder */
3002                         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3003                                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
3004                         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3005
3006                         /* Switch help_id */
3007                         if (TNY_IS_FOLDER (folder_store)) {
3008                                 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3009                                 case TNY_FOLDER_TYPE_NORMAL:
3010                                         help_id = "applications_email_userfolder";
3011                                         break;
3012                                 case TNY_FOLDER_TYPE_INBOX:
3013                                         help_id = "applications_email_inbox";
3014                                         break;
3015                                 case TNY_FOLDER_TYPE_OUTBOX:
3016                                         help_id = "applications_email_outbox";
3017                                         break;
3018                                 case TNY_FOLDER_TYPE_SENT:
3019                                         help_id = "applications_email_sent";
3020                                         break;
3021                                 case TNY_FOLDER_TYPE_DRAFTS:
3022                                         help_id = "applications_email_drafts";
3023                                         break;
3024                                 case TNY_FOLDER_TYPE_ARCHIVE:
3025                                         help_id = "applications_email_archive";
3026                                         break;
3027                                 default:
3028                                         help_id = NULL;
3029                                 }
3030                         }
3031                 } else {
3032                         help_id = "applications_email_mainview";        
3033                 }
3034         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3035                 help_id = "applications_email_viewer";
3036         } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3037                 help_id = "applications_email_editor";
3038
3039         modest_platform_show_help (GTK_WINDOW (win), help_id);
3040 }
3041
3042 void 
3043 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3044                                             ModestWindow *window)
3045 {
3046         ModestMailOperation *mail_op;
3047         TnyList *headers;
3048
3049         /* Get headers */
3050         headers = get_selected_headers (window);
3051         if (!headers)
3052                 return;
3053
3054         /* Create mail operation */
3055         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3056                                                                  G_OBJECT (window),
3057                                                                  modest_ui_actions_get_msgs_full_error_handler, 
3058                                                                  NULL);
3059         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3060         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3061
3062         /* Frees */
3063         g_object_unref (headers);
3064         g_object_unref (mail_op);
3065 }
3066
3067 void
3068 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3069                                           ModestWindow *window)
3070 {
3071         g_return_if_fail (MODEST_IS_WINDOW (window));
3072
3073         /* Update dimmed */     
3074         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3075 }
3076
3077 void
3078 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3079                                           ModestWindow *window)
3080 {
3081         g_return_if_fail (MODEST_IS_WINDOW (window));
3082
3083         /* Update dimmed */     
3084         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3085 }
3086
3087 void
3088 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3089                                           ModestWindow *window)
3090 {
3091         g_return_if_fail (MODEST_IS_WINDOW (window));
3092
3093         /* Update dimmed */     
3094         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3095 }
3096
3097 void
3098 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3099                                           ModestWindow *window)
3100 {
3101         g_return_if_fail (MODEST_IS_WINDOW (window));
3102
3103         /* Update dimmed */     
3104         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3105 }
3106
3107 void
3108 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3109                                           ModestWindow *window)
3110 {
3111         g_return_if_fail (MODEST_IS_WINDOW (window));
3112
3113         /* Update dimmed */     
3114         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3115 }
3116
3117 void
3118 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3119                                                  ModestWindow *window)
3120 {
3121         g_return_if_fail (MODEST_IS_WINDOW (window));
3122
3123         /* Update dimmed */     
3124         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3125 }
3126
3127 void
3128 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3129                                                      ModestWindow *window)
3130 {
3131         g_return_if_fail (MODEST_IS_WINDOW (window));
3132
3133         /* Update dimmed */     
3134         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3135 }
3136
3137 void
3138 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3139                                                      ModestWindow *window)
3140 {
3141         g_return_if_fail (MODEST_IS_WINDOW (window));
3142
3143         /* Update dimmed */     
3144         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3145 }
3146
3147 void
3148 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3149 {
3150         g_return_if_fail (MODEST_IS_WINDOW (window));
3151
3152         /* Update dimmed */     
3153         modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");  
3154 }
3155
3156 void
3157 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3158 {
3159         g_return_if_fail (MODEST_IS_WINDOW (window));
3160
3161         modest_platform_show_search_messages (GTK_WINDOW (window));
3162 }
3163
3164 void     
3165 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3166 {
3167         g_return_if_fail (MODEST_IS_WINDOW (win));
3168         modest_platform_show_addressbook (GTK_WINDOW (win));
3169 }
3170
3171
3172 void
3173 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3174                                           ModestWindow *window)
3175 {
3176         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3177
3178         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3179 }
3180
3181 static void 
3182 _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
3183                                    ModestMailOperationState *state,
3184                                    gpointer user_data)
3185 {
3186         g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3187
3188         /* Set send/receive operation finished */       
3189         if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3190                 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
3191         
3192 }