Work for making select all work as expected in
[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         ModestMainWindow *win = NULL;
1259         GtkWidget *header_view;
1260
1261         g_return_if_fail (TNY_IS_FOLDER (folder));
1262
1263         win = MODEST_MAIN_WINDOW (user_data);
1264         header_view = 
1265                 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1266
1267         /* Check if folder is empty and set headers view contents style */
1268         if (tny_folder_get_all_count (folder) == 0) {
1269                 modest_main_window_set_contents_style (win,
1270                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1271         } else {
1272                 /* Restore configuration. There is no need to set the
1273                    contents style to headers because it was already
1274                    being done in folder_selection_changed */
1275                 modest_widget_memory_restore (modest_runtime_get_conf (), 
1276                                               G_OBJECT(header_view),
1277                                               MODEST_CONF_HEADER_VIEW_KEY);
1278         }
1279 }
1280
1281 void 
1282 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1283                                                TnyFolderStore *folder_store, 
1284                                                gboolean selected,
1285                                                ModestMainWindow *main_window)
1286 {
1287         ModestConf *conf;
1288         GtkWidget *header_view;
1289
1290         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1291
1292         header_view = modest_main_window_get_child_widget(main_window,
1293                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
1294         if (!header_view)
1295                 return;
1296         
1297         conf = modest_runtime_get_conf ();
1298
1299         if (TNY_IS_ACCOUNT (folder_store)) {
1300                 /* Update active account */
1301                 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1302                 /* Show account details */
1303                 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1304         } else {
1305                 if (TNY_IS_FOLDER (folder_store) && selected) {
1306                         
1307                         if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1308                                 /* Update the active account */
1309                                 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1310                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1311                                 g_object_unref (account);
1312                         }
1313
1314                         /* Set the header view, we could change it to
1315                            the empty view after the refresh */
1316                         modest_main_window_set_contents_style (main_window, 
1317                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1318                         
1319                         modest_widget_memory_save (modest_runtime_get_conf(),
1320                                                    G_OBJECT(header_view),
1321                                                    MODEST_CONF_HEADER_VIEW_KEY);
1322
1323                         /* Set folder on header view. This function
1324                            will call tny_folder_refresh_async so we
1325                            pass a callback that will be called when
1326                            finished. We use that callback to set the
1327                            empty view if there are no messages */
1328                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1329                                                        TNY_FOLDER (folder_store),
1330                                                        folder_refreshed_cb,
1331                                                        main_window);
1332                 } else {
1333                         /* Update the active account */
1334                         modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1335                         /* Do not show folder */
1336                         modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1337                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1338                 }                       
1339         }
1340
1341         /* Update toolbar dimming state */
1342         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1343 }
1344
1345 void 
1346 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1347                                      ModestWindow *win)
1348 {
1349         GtkWidget *dialog;
1350         gchar *txt, *item;
1351         gboolean online;
1352
1353         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1354         
1355         if (g_main_depth > 0)   
1356                 gdk_threads_enter ();
1357         online = tny_device_is_online (modest_runtime_get_device());
1358
1359         if (online) {
1360                 /* already online -- the item is simply not there... */
1361                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1362                                                  GTK_DIALOG_MODAL,
1363                                                  GTK_MESSAGE_WARNING,
1364                                                  GTK_BUTTONS_OK,
1365                                                  _("The %s you selected cannot be found"),
1366                                                  item);
1367                 gtk_dialog_run (GTK_DIALOG(dialog));
1368         } else {
1369                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1370                                                       GTK_WINDOW (win),
1371                                                       GTK_DIALOG_MODAL,
1372                                                       GTK_STOCK_CANCEL,
1373                                                       GTK_RESPONSE_REJECT,
1374                                                       GTK_STOCK_OK,
1375                                                       GTK_RESPONSE_ACCEPT,
1376                                                       NULL);
1377                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1378                                          "Do you want to get online?"), item);
1379                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1380                                     gtk_label_new (txt), FALSE, FALSE, 0);
1381                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1382                 g_free (txt);
1383
1384                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1385                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1386 //                      modest_platform_connect_and_wait ();
1387                 }
1388         }
1389         gtk_widget_destroy (dialog);
1390         if (g_main_depth > 0)   
1391                 gdk_threads_leave ();
1392 }
1393
1394 void
1395 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1396                                      ModestWindow *win)
1397 {
1398         /* g_message ("%s %s", __FUNCTION__, link); */
1399 }       
1400
1401
1402 void
1403 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1404                                         ModestWindow *win)
1405 {
1406         modest_platform_activate_uri (link);
1407 }
1408
1409 void
1410 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1411                                           ModestWindow *win)
1412 {
1413         modest_platform_show_uri_popup (link);
1414 }
1415
1416 void
1417 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1418                                              ModestWindow *win)
1419 {
1420         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1421 }
1422
1423 void
1424 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1425                                           const gchar *address,
1426                                           ModestWindow *win)
1427 {
1428         /* g_message ("%s %s", __FUNCTION__, address); */
1429 }
1430
1431 void
1432 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1433 {
1434         TnyTransportAccount *transport_account;
1435         ModestMailOperation *mail_operation;
1436         MsgData *data;
1437         gchar *account_name, *from;
1438         ModestAccountMgr *account_mgr;
1439
1440         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1441         
1442         data = modest_msg_edit_window_get_msg_data (edit_window);
1443
1444         account_mgr = modest_runtime_get_account_mgr();
1445         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1446         if (!account_name) 
1447                 account_name = modest_account_mgr_get_default_account (account_mgr);
1448         if (!account_name) {
1449                 g_printerr ("modest: no account found\n");
1450                 modest_msg_edit_window_free_msg_data (edit_window, data);
1451                 return;
1452         }
1453
1454         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1455                 account_name = g_strdup (data->account_name);
1456         }
1457
1458         transport_account =
1459                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1460                                       (modest_runtime_get_account_store(),
1461                                        account_name,
1462                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1463         if (!transport_account) {
1464                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1465                 g_free (account_name);
1466                 modest_msg_edit_window_free_msg_data (edit_window, data);
1467                 return;
1468         }
1469         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1470
1471         /* Create the mail operation */         
1472         mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1473         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1474
1475         modest_mail_operation_save_to_drafts (mail_operation,
1476                                               transport_account,
1477                                               data->draft_msg,
1478                                               from,
1479                                               data->to, 
1480                                               data->cc, 
1481                                               data->bcc,
1482                                               data->subject, 
1483                                               data->plain_body, 
1484                                               data->html_body,
1485                                               data->attachments,
1486                                               data->priority_flags);
1487         /* Frees */
1488         g_free (from);
1489         g_free (account_name);
1490         g_object_unref (G_OBJECT (transport_account));
1491         g_object_unref (G_OBJECT (mail_operation));
1492
1493         modest_msg_edit_window_free_msg_data (edit_window, data);
1494
1495         /* Save settings and close the window */
1496         gtk_widget_destroy (GTK_WIDGET (edit_window));
1497 }
1498
1499 /* For instance, when clicking the Send toolbar button when editing a message: */
1500 void
1501 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1502 {
1503         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1504
1505         if (!modest_msg_edit_window_check_names (edit_window))
1506                 return;
1507         
1508         /* FIXME: Code added just for testing. The final version will
1509            use the send queue provided by tinymail and some
1510            classifier */
1511         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1512         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1513         if (!account_name) 
1514                 account_name = modest_account_mgr_get_default_account (account_mgr);
1515                 
1516         if (!account_name) {
1517                 g_printerr ("modest: no account found\n");
1518                 return;
1519         }
1520         
1521         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1522
1523         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1524                 account_name = g_strdup (data->account_name);
1525         }
1526         
1527         /* Get the currently-active transport account for this modest account: */
1528         TnyTransportAccount *transport_account =
1529                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1530                                       (modest_runtime_get_account_store(),
1531                                        account_name));
1532         if (!transport_account) {
1533                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1534                 g_free (account_name);
1535                 modest_msg_edit_window_free_msg_data (edit_window, data);
1536                 return;
1537         }
1538         
1539         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1540
1541         /* mail content checks and dialogs */
1542         if (data->subject == NULL || data->subject[0] == '\0') {
1543                 GtkResponseType response;
1544                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1545                                                                     _("mcen_nc_subject_is_empty_send"));
1546                 if (response == GTK_RESPONSE_CANCEL) {
1547                         g_free (account_name);
1548                         return;
1549                 }
1550         }
1551
1552         if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1553                 GtkResponseType response;
1554                 gchar *note_message;
1555                 gchar *note_subject = data->subject;
1556                 if (note_subject == NULL || note_subject[0] == '\0')
1557                         note_subject = _("mail_va_no_subject");
1558                 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1559                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1560                                                                     note_message);
1561                 g_free (note_message);
1562                 if (response == GTK_RESPONSE_CANCEL) {
1563                         g_free (account_name);
1564                         return;
1565                 }
1566         }
1567
1568         /* Create the mail operation */
1569         ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1570         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1571
1572         modest_mail_operation_send_new_mail (mail_operation,
1573                                              transport_account,
1574                                              data->draft_msg,
1575                                              from,
1576                                              data->to, 
1577                                              data->cc, 
1578                                              data->bcc,
1579                                              data->subject, 
1580                                              data->plain_body, 
1581                                              data->html_body,
1582                                              data->attachments,
1583                                              data->priority_flags);
1584                                              
1585         /* Free data: */
1586         g_free (from);
1587         g_free (account_name);
1588         g_object_unref (G_OBJECT (transport_account));
1589         g_object_unref (G_OBJECT (mail_operation));
1590
1591         modest_msg_edit_window_free_msg_data (edit_window, data);
1592
1593         /* Save settings and close the window: */
1594         gtk_widget_destroy (GTK_WIDGET (edit_window));
1595 }
1596
1597 void 
1598 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1599                                   ModestMsgEditWindow *window)
1600 {
1601         ModestMsgEditFormatState *format_state = NULL;
1602
1603         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1604         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1605
1606         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1607                 return;
1608
1609         format_state = modest_msg_edit_window_get_format_state (window);
1610         g_return_if_fail (format_state != NULL);
1611
1612         format_state->bold = gtk_toggle_action_get_active (action);
1613         modest_msg_edit_window_set_format_state (window, format_state);
1614         g_free (format_state);
1615         
1616 }
1617
1618 void 
1619 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1620                                      ModestMsgEditWindow *window)
1621 {
1622         ModestMsgEditFormatState *format_state = NULL;
1623
1624         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1625         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1626
1627         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1628                 return;
1629
1630         format_state = modest_msg_edit_window_get_format_state (window);
1631         g_return_if_fail (format_state != NULL);
1632
1633         format_state->italics = gtk_toggle_action_get_active (action);
1634         modest_msg_edit_window_set_format_state (window, format_state);
1635         g_free (format_state);
1636         
1637 }
1638
1639 void 
1640 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1641                                      ModestMsgEditWindow *window)
1642 {
1643         ModestMsgEditFormatState *format_state = NULL;
1644
1645         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1646         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1647
1648         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1649                 return;
1650
1651         format_state = modest_msg_edit_window_get_format_state (window);
1652         g_return_if_fail (format_state != NULL);
1653
1654         format_state->bullet = gtk_toggle_action_get_active (action);
1655         modest_msg_edit_window_set_format_state (window, format_state);
1656         g_free (format_state);
1657         
1658 }
1659
1660 void 
1661 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1662                                      GtkRadioAction *selected,
1663                                      ModestMsgEditWindow *window)
1664 {
1665         ModestMsgEditFormatState *format_state = NULL;
1666         GtkJustification value;
1667
1668         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1669
1670         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1671                 return;
1672
1673         value = gtk_radio_action_get_current_value (selected);
1674
1675         format_state = modest_msg_edit_window_get_format_state (window);
1676         g_return_if_fail (format_state != NULL);
1677
1678         format_state->justification = value;
1679         modest_msg_edit_window_set_format_state (window, format_state);
1680         g_free (format_state);
1681 }
1682
1683 void 
1684 modest_ui_actions_on_select_editor_color (GtkAction *action,
1685                                           ModestMsgEditWindow *window)
1686 {
1687         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1688         g_return_if_fail (GTK_IS_ACTION (action));
1689
1690         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1691                 return;
1692
1693         modest_msg_edit_window_select_color (window);
1694 }
1695
1696 void 
1697 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1698                                                      ModestMsgEditWindow *window)
1699 {
1700         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1701         g_return_if_fail (GTK_IS_ACTION (action));
1702
1703         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1704                 return;
1705
1706         modest_msg_edit_window_select_background_color (window);
1707 }
1708
1709 void 
1710 modest_ui_actions_on_insert_image (GtkAction *action,
1711                                    ModestMsgEditWindow *window)
1712 {
1713         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1714         g_return_if_fail (GTK_IS_ACTION (action));
1715
1716         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1717                 return;
1718
1719         modest_msg_edit_window_insert_image (window);
1720 }
1721
1722 void 
1723 modest_ui_actions_on_attach_file (GtkAction *action,
1724                                   ModestMsgEditWindow *window)
1725 {
1726         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1727         g_return_if_fail (GTK_IS_ACTION (action));
1728
1729         modest_msg_edit_window_attach_file (window);
1730 }
1731
1732 void 
1733 modest_ui_actions_on_remove_attachments (GtkAction *action,
1734                                          ModestMsgEditWindow *window)
1735 {
1736         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1737         g_return_if_fail (GTK_IS_ACTION (action));
1738
1739         modest_msg_edit_window_remove_attachments (window, NULL);
1740 }
1741
1742 /*
1743  * Shows a dialog with an entry that asks for some text. The returned
1744  * value must be freed by the caller. The dialog window title will be
1745  * set to @title.
1746  */
1747 static gchar *
1748 ask_for_folder_name (GtkWindow *parent_window,
1749                      const gchar *title)
1750 {
1751         GtkWidget *dialog, *entry;
1752         gchar *folder_name = NULL;
1753
1754         /* Ask for folder name */
1755         dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1756                                               parent_window,
1757                                               GTK_DIALOG_MODAL,
1758                                               GTK_STOCK_CANCEL,
1759                                               GTK_RESPONSE_REJECT,
1760                                               GTK_STOCK_OK,
1761                                               GTK_RESPONSE_ACCEPT,
1762                                               NULL);
1763         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1764                             gtk_label_new(title),
1765                             FALSE, FALSE, 0);
1766                 
1767         entry = gtk_entry_new_with_max_length (40);
1768         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1769                             entry,
1770                             TRUE, FALSE, 0);    
1771         
1772         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1773         
1774         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)         
1775                 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1776
1777         gtk_widget_destroy (dialog);
1778
1779         return folder_name;
1780 }
1781
1782 void 
1783 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1784 {
1785         TnyFolderStore *parent_folder;
1786         GtkWidget *folder_view;
1787         
1788         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1789
1790         folder_view = modest_main_window_get_child_widget (main_window,
1791                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1792         if (!folder_view)
1793                 return;
1794
1795         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1796         
1797         if (parent_folder) {
1798                 gboolean finished = FALSE;
1799                 gint result;
1800                 gchar *folder_name = NULL, *suggested_name = NULL;
1801
1802                 /* Run the new folder dialog */
1803                 while (!finished) {
1804                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1805                                                                         parent_folder,
1806                                                                         suggested_name,
1807                                                                         &folder_name);
1808
1809                         if (result == GTK_RESPONSE_REJECT) {
1810                                 finished = TRUE;
1811                         } else {
1812                                 ModestMailOperation *mail_op;
1813                                 TnyFolder *new_folder = NULL;
1814
1815                                 mail_op  = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, 
1816                                                                       G_OBJECT(main_window));
1817                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1818                                                                  mail_op);
1819                                 new_folder = modest_mail_operation_create_folder (mail_op,
1820                                                                                   parent_folder,
1821                                                                                   (const gchar *) folder_name);
1822                                 if (new_folder) {
1823                                         g_object_unref (new_folder);
1824                                         finished = TRUE;
1825                                 }
1826                                 g_object_unref (mail_op);
1827                         }
1828                         g_free (folder_name);
1829                         folder_name = NULL;
1830                 }
1831
1832                 g_object_unref (parent_folder);
1833         }
1834 }
1835
1836 void 
1837 modest_ui_actions_on_rename_folder (GtkAction *action,
1838                                      ModestMainWindow *main_window)
1839 {
1840         TnyFolderStore *folder;
1841         GtkWidget *folder_view;
1842         GtkWidget *header_view; 
1843
1844         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1845
1846         folder_view = modest_main_window_get_child_widget (main_window,
1847                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1848         if (!folder_view)
1849                 return;
1850
1851         header_view = modest_main_window_get_child_widget (main_window,
1852                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1853         
1854         if (!header_view)
1855                 return;
1856
1857         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1858         
1859         if (folder && TNY_IS_FOLDER (folder)) {
1860                 gchar *folder_name;
1861                 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1862                                                    _("Please enter a new name for the folder"));
1863
1864                 if (folder_name != NULL && strlen (folder_name) > 0) {
1865                         ModestMailOperation *mail_op;
1866
1867                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1868                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1869                                                          mail_op);
1870
1871                         modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1872
1873                         modest_mail_operation_rename_folder (mail_op,
1874                                                              TNY_FOLDER (folder),
1875                                                              (const gchar *) folder_name);
1876
1877                         g_object_unref (mail_op);
1878                         g_free (folder_name);
1879                 }
1880                 g_object_unref (folder);
1881         }
1882 }
1883
1884 static void
1885 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1886                                                gpointer user_data)
1887 {
1888         GObject *win = modest_mail_operation_get_source (mail_op);
1889
1890         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1891                                                 _("mail_in_ui_folder_delete_error"));
1892 }
1893
1894 static void
1895 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
1896 {
1897         TnyFolderStore *folder;
1898         GtkWidget *folder_view;
1899         gint response;
1900         gchar *message;
1901         
1902         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1903
1904         folder_view = modest_main_window_get_child_widget (main_window,
1905                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1906         if (!folder_view)
1907                 return;
1908
1909         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1910
1911         /* Show an error if it's an account */
1912         if (!TNY_IS_FOLDER (folder)) {
1913                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1914                                                         _("mail_in_ui_folder_delete_error"));
1915                 return ;
1916         }
1917
1918         /* Ask the user */      
1919         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
1920                                     tny_folder_get_name (TNY_FOLDER (folder)));
1921         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window), 
1922                                                             (const gchar *) message);
1923         g_free (message);
1924
1925         if (response == GTK_RESPONSE_OK) {
1926                 ModestMailOperation *mail_op = 
1927                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, 
1928                                                                        G_OBJECT(main_window),
1929                                                                        modest_ui_actions_delete_folder_error_handler,
1930                                                                        NULL);
1931
1932                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1933                                                  mail_op);
1934                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1935                 g_object_unref (G_OBJECT (mail_op));
1936         }
1937
1938         g_object_unref (G_OBJECT (folder));
1939 }
1940
1941 void 
1942 modest_ui_actions_on_delete_folder (GtkAction *action,
1943                                      ModestMainWindow *main_window)
1944 {
1945         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1946
1947         delete_folder (main_window, FALSE);
1948 }
1949
1950 void 
1951 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1952 {
1953         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1954         
1955         delete_folder (main_window, TRUE);
1956 }
1957
1958 void
1959 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
1960                                          const gchar* server_account_name,
1961                                          gchar **username,
1962                                          gchar **password, 
1963                                          gboolean *cancel, 
1964                                          gboolean *remember,
1965                                          ModestMainWindow *main_window)
1966 {
1967         g_return_if_fail(server_account_name);
1968         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1969         
1970         /* Initalize output parameters: */
1971         if (cancel)
1972                 *cancel = FALSE;
1973                 
1974         if (remember)
1975                 *remember = TRUE;
1976                 
1977 #ifdef MODEST_PLATFORM_MAEMO
1978         /* Maemo uses a different (awkward) button order,
1979          * It should probably just use gtk_alternative_dialog_button_order ().
1980          */
1981         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1982                                               NULL,
1983                                               GTK_DIALOG_MODAL,
1984                                               GTK_STOCK_OK,
1985                                               GTK_RESPONSE_ACCEPT,
1986                                               GTK_STOCK_CANCEL,
1987                                               GTK_RESPONSE_REJECT,
1988                                               NULL);
1989 #else
1990         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1991                                               NULL,
1992                                               GTK_DIALOG_MODAL,
1993                                               GTK_STOCK_CANCEL,
1994                                               GTK_RESPONSE_REJECT,
1995                                               GTK_STOCK_OK,
1996                                               GTK_RESPONSE_ACCEPT,
1997                                               NULL);
1998 #endif /* MODEST_PLATFORM_MAEMO */
1999
2000         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2001         
2002         gchar *server_name = modest_server_account_get_hostname (
2003                 modest_runtime_get_account_mgr(), server_account_name);
2004         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2005                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2006                 *cancel = TRUE;
2007                 return;
2008         }
2009         
2010         /* This causes a warning because the logical ID has no %s in it, 
2011          * though the translation does, but there is not much we can do about that: */
2012         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2013         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2014                             FALSE, FALSE, 0);
2015         g_free (txt);
2016         g_free (server_name);
2017         server_name = NULL;
2018
2019         /* username: */
2020         gchar *initial_username = modest_server_account_get_username (
2021                 modest_runtime_get_account_mgr(), server_account_name);
2022         
2023         GtkWidget *entry_username = gtk_entry_new ();
2024         if (initial_username)
2025                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2026         /* Dim this if a connection has ever succeeded with this username,
2027          * as per the UI spec: */
2028         const gboolean username_known = 
2029                 modest_server_account_get_username_has_succeeded(
2030                         modest_runtime_get_account_mgr(), server_account_name);
2031         gtk_widget_set_sensitive (entry_username, !username_known);
2032         
2033 #ifdef MODEST_PLATFORM_MAEMO
2034         /* Auto-capitalization is the default, so let's turn it off: */
2035         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2036         
2037         /* Create a size group to be used by all captions.
2038          * Note that HildonCaption does not create a default size group if we do not specify one.
2039          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2040         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2041         
2042         GtkWidget *caption = hildon_caption_new (sizegroup, 
2043                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2044         gtk_widget_show (entry_username);
2045         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2046                 FALSE, FALSE, MODEST_MARGIN_HALF);
2047         gtk_widget_show (caption);
2048 #else 
2049         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2050                             TRUE, FALSE, 0);
2051 #endif /* MODEST_PLATFORM_MAEMO */      
2052                             
2053         /* password: */
2054         GtkWidget *entry_password = gtk_entry_new ();
2055         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2056         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2057         
2058 #ifdef MODEST_PLATFORM_MAEMO
2059         /* Auto-capitalization is the default, so let's turn it off: */
2060         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2061                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2062         
2063         caption = hildon_caption_new (sizegroup, 
2064                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2065         gtk_widget_show (entry_password);
2066         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2067                 FALSE, FALSE, MODEST_MARGIN_HALF);
2068         gtk_widget_show (caption);
2069         g_object_unref (sizegroup);
2070 #else 
2071         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2072                             TRUE, FALSE, 0);
2073 #endif /* MODEST_PLATFORM_MAEMO */      
2074                                 
2075 /* This is not in the Maemo UI spec:
2076         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2077         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2078                             TRUE, FALSE, 0);
2079 */
2080
2081         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2082         
2083         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2084                 if (username) {
2085                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2086                         
2087                         modest_server_account_set_username (
2088                                  modest_runtime_get_account_mgr(), server_account_name, 
2089                                  *username);
2090                                  
2091                         const gboolean username_was_changed = 
2092                                 (strcmp (*username, initial_username) != 0);
2093                         if (username_was_changed) {
2094                                 /* To actually use a changed username, 
2095                                  * we must reset the connection, according to pvanhoof.
2096                                  * This _might_ be a sensible way to do that: */
2097                                  TnyDevice *device = modest_runtime_get_device();
2098                                  tny_device_force_offline (device);
2099                                  tny_device_force_online (device);
2100                         }
2101                 }
2102                         
2103                 if (password) {
2104                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2105                         
2106                         /* We do not save the password in the configuration, 
2107                          * because this function is only called for passwords that should 
2108                          * not be remembered:
2109                         modest_server_account_set_password (
2110                                  modest_runtime_get_account_mgr(), server_account_name, 
2111                                  *password);
2112                         */
2113                 }
2114                 
2115                 if (cancel)
2116                         *cancel   = FALSE;
2117                         
2118         } else {
2119                 if (username)
2120                         *username = NULL;
2121                         
2122                 if (password)
2123                         *password = NULL;
2124                         
2125                 if (cancel)
2126                         *cancel   = TRUE;
2127         }
2128
2129 /* This is not in the Maemo UI spec:
2130         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2131                 *remember = TRUE;
2132         else
2133                 *remember = FALSE;
2134 */
2135
2136         gtk_widget_destroy (dialog);
2137         
2138         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2139 }
2140
2141 void
2142 modest_ui_actions_on_cut (GtkAction *action,
2143                           ModestWindow *window)
2144 {
2145         GtkWidget *focused_widget;
2146
2147         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2148         if (GTK_IS_EDITABLE (focused_widget)) {
2149                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2150         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2151                 GtkTextBuffer *buffer;
2152                 GtkClipboard *clipboard;
2153
2154                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2155                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2156                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2157         }
2158 }
2159
2160 void
2161 modest_ui_actions_on_copy (GtkAction *action,
2162                            ModestWindow *window)
2163 {
2164         GtkClipboard *clipboard;
2165         GtkWidget *focused_widget;
2166
2167         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2168         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2169         if (GTK_IS_LABEL (focused_widget)) {
2170                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2171         } else if (GTK_IS_EDITABLE (focused_widget)) {
2172                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2173         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2174                 GtkTextBuffer *buffer;
2175
2176                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2177                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2178         }
2179 }
2180
2181 void
2182 modest_ui_actions_on_undo (GtkAction *action,
2183                            ModestWindow *window)
2184 {
2185         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2186                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2187         } else {
2188                 g_return_if_reached ();
2189         }
2190 }
2191
2192 void
2193 modest_ui_actions_on_paste (GtkAction *action,
2194                             ModestWindow *window)
2195 {
2196         GtkWidget *focused_widget;
2197
2198         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2199         if (GTK_IS_EDITABLE (focused_widget)) {
2200                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2201         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2202                 GtkTextBuffer *buffer;
2203                 GtkClipboard *clipboard;
2204
2205                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2206                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2207                 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2208         }
2209 }
2210
2211 void
2212 modest_ui_actions_on_select_all (GtkAction *action,
2213                                  ModestWindow *window)
2214 {
2215         GtkWidget *focused_widget;
2216
2217         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2218         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2219                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2220         } else if (GTK_IS_LABEL (focused_widget)) {
2221                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2222         } else if (GTK_IS_EDITABLE (focused_widget)) {
2223                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2224         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2225                 GtkTextBuffer *buffer;
2226                 GtkTextIter start, end;
2227
2228                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2229                 gtk_text_buffer_get_start_iter (buffer, &start);
2230                 gtk_text_buffer_get_end_iter (buffer, &end);
2231                 gtk_text_buffer_select_range (buffer, &start, &end);
2232         }
2233         else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2234                  (MODEST_IS_HEADER_VIEW (focused_widget))) {
2235                 
2236                 GtkTreeSelection *selection = NULL;
2237
2238                 /* Get header view */           
2239                 GtkWidget *header_view = focused_widget;
2240                 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2241                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2242                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2243
2244                 /* Select all messages */
2245                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2246                 gtk_tree_selection_select_all (selection);
2247         } else if (GTK_IS_HTML (focused_widget)) {
2248                 gtk_html_select_all (GTK_HTML (focused_widget));
2249         }
2250 }
2251
2252 void
2253 modest_ui_actions_on_mark_as_read (GtkAction *action,
2254                                    ModestWindow *window)
2255 {       
2256         g_return_if_fail (MODEST_IS_WINDOW(window));
2257                 
2258         /* Mark each header as read */
2259         do_headers_action (window, headers_action_mark_as_read, NULL);
2260 }
2261
2262 void
2263 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2264                                      ModestWindow *window)
2265 {       
2266         g_return_if_fail (MODEST_IS_WINDOW(window));
2267                 
2268         /* Mark each header as read */
2269         do_headers_action (window, headers_action_mark_as_unread, NULL);
2270 }
2271
2272 void
2273 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2274                                   GtkRadioAction *selected,
2275                                   ModestWindow *window)
2276 {
2277         gint value;
2278
2279         value = gtk_radio_action_get_current_value (selected);
2280         if (MODEST_IS_WINDOW (window)) {
2281                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2282         }
2283 }
2284
2285 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2286                                                         GtkRadioAction *selected,
2287                                                         ModestWindow *window)
2288 {
2289         TnyHeaderFlags flags;
2290         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2291
2292         flags = gtk_radio_action_get_current_value (selected);
2293         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2294 }
2295
2296 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2297                                                            GtkRadioAction *selected,
2298                                                            ModestWindow *window)
2299 {
2300         gint file_format;
2301
2302         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2303
2304         file_format = gtk_radio_action_get_current_value (selected);
2305         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2306 }
2307
2308
2309 void     
2310 modest_ui_actions_on_zoom_plus (GtkAction *action,
2311                                 ModestWindow *window)
2312 {
2313         g_return_if_fail (MODEST_IS_WINDOW (window));
2314
2315         modest_window_zoom_plus (MODEST_WINDOW (window));
2316 }
2317
2318 void     
2319 modest_ui_actions_on_zoom_minus (GtkAction *action,
2320                                  ModestWindow *window)
2321 {
2322         g_return_if_fail (MODEST_IS_WINDOW (window));
2323
2324         modest_window_zoom_minus (MODEST_WINDOW (window));
2325 }
2326
2327 void     
2328 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
2329                                            ModestWindow *window)
2330 {
2331         ModestWindowMgr *mgr;
2332         gboolean fullscreen, active;
2333         g_return_if_fail (MODEST_IS_WINDOW (window));
2334
2335         mgr = modest_runtime_get_window_mgr ();
2336
2337         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2338         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2339
2340         if (active != fullscreen) {
2341                 modest_window_mgr_set_fullscreen_mode (mgr, active);
2342                 gtk_window_present (GTK_WINDOW (window));
2343         }
2344 }
2345
2346 void
2347 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2348                                         ModestWindow *window)
2349 {
2350         ModestWindowMgr *mgr;
2351         gboolean fullscreen;
2352
2353         g_return_if_fail (MODEST_IS_WINDOW (window));
2354
2355         mgr = modest_runtime_get_window_mgr ();
2356         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2357         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2358
2359         gtk_window_present (GTK_WINDOW (window));
2360 }
2361
2362 /* 
2363  * Used by modest_ui_actions_on_details to call do_headers_action 
2364  */
2365 static void
2366 headers_action_show_details (TnyHeader *header, 
2367                              ModestWindow *window,
2368                              gpointer user_data)
2369
2370 {
2371         GtkWidget *dialog;
2372         
2373         /* Create dialog */
2374         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2375
2376         /* Run dialog */
2377         gtk_widget_show_all (dialog);
2378         gtk_dialog_run (GTK_DIALOG (dialog));
2379
2380         gtk_widget_destroy (dialog);
2381 }
2382
2383 /*
2384  * Show the folder details in a ModestDetailsDialog widget
2385  */
2386 static void
2387 show_folder_details (TnyFolder *folder, 
2388                      GtkWindow *window)
2389 {
2390         GtkWidget *dialog;
2391         
2392         /* Create dialog */
2393         dialog = modest_details_dialog_new_with_folder (window, folder);
2394
2395         /* Run dialog */
2396         gtk_widget_show_all (dialog);
2397         gtk_dialog_run (GTK_DIALOG (dialog));
2398
2399         gtk_widget_destroy (dialog);
2400 }
2401
2402 /*
2403  * Show the header details in a ModestDetailsDialog widget
2404  */
2405 void     
2406 modest_ui_actions_on_details (GtkAction *action, 
2407                               ModestWindow *win)
2408 {
2409         TnyList * headers_list;
2410         TnyIterator *iter;
2411         TnyHeader *header;              
2412
2413         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2414                 TnyMsg *msg;
2415
2416                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2417                 if (!msg)
2418                         return;
2419                 g_object_unref (msg);           
2420
2421                 headers_list = get_selected_headers (win);
2422                 if (!headers_list)
2423                         return;
2424
2425                 iter = tny_list_create_iterator (headers_list);
2426
2427                 header = TNY_HEADER (tny_iterator_get_current (iter));
2428                 headers_action_show_details (header, win, NULL);
2429                 g_object_unref (header);
2430
2431                 g_object_unref (iter);
2432                 g_object_unref (headers_list);
2433
2434         } else if (MODEST_IS_MAIN_WINDOW (win)) {
2435                 GtkWidget *folder_view, *header_view;
2436
2437                 /* Check which widget has the focus */
2438                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2439                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
2440                 if (gtk_widget_is_focus (folder_view)) {
2441                         TnyFolder *folder;
2442
2443                         folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2444
2445                         /* Show only when it's a folder */
2446                         if (!folder || !TNY_IS_FOLDER (folder))
2447                                 return;
2448
2449                         show_folder_details (folder, GTK_WINDOW (win));
2450
2451                 } else {
2452                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2453                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2454                         /* Show details of each header */
2455                         do_headers_action (win, headers_action_show_details, header_view);
2456                 }
2457         }
2458 }
2459
2460 void     
2461 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2462                                      ModestMsgEditWindow *window)
2463 {
2464         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2465
2466         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2467 }
2468
2469 void     
2470 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2471                                       ModestMsgEditWindow *window)
2472 {
2473         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2474
2475         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2476 }
2477
2478 void
2479 modest_ui_actions_toggle_folders_view (GtkAction *action, 
2480                                        ModestMainWindow *main_window)
2481 {
2482         ModestConf *conf;
2483         
2484         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2485
2486         conf = modest_runtime_get_conf ();
2487         
2488         if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2489                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2490         else
2491                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2492 }
2493
2494 void 
2495 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
2496                                      ModestWindow *window)
2497 {
2498         gboolean active, fullscreen = FALSE;
2499         ModestWindowMgr *mgr;
2500
2501         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2502
2503         /* Check if we want to toggle the toolbar vuew in fullscreen
2504            or normal mode */
2505         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
2506                      "ViewShowToolbarFullScreen")) {
2507                 fullscreen = TRUE;
2508         }
2509
2510         /* Toggle toolbar */
2511         mgr = modest_runtime_get_window_mgr ();
2512         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2513 }
2514
2515 void     
2516 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2517                                            ModestMsgEditWindow *window)
2518 {
2519         modest_msg_edit_window_select_font (window);
2520 }
2521
2522 void
2523 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2524                                                   const gchar *display_name,
2525                                                   GtkWindow *window)
2526 {
2527         /* Do not change the application name if the widget has not
2528            the focus. This callback could be called even if the folder
2529            view has not the focus, because the handled signal could be
2530            emitted when the folder view is redrawn */
2531         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2532                 if (display_name)
2533                         gtk_window_set_title (window, display_name);
2534                 else
2535                         gtk_window_set_title (window, " ");
2536         }
2537 }
2538
2539 void
2540 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2541 {
2542         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2543         modest_msg_edit_window_select_contacts (window);
2544 }
2545
2546 void
2547 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2548 {
2549         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2550         modest_msg_edit_window_check_names (window);
2551 }
2552
2553
2554 static GtkWidget*
2555 create_move_to_dialog (ModestWindow *win,
2556                        GtkWidget *folder_view,
2557                        GtkWidget **tree_view)
2558 {
2559         GtkWidget *dialog, *scroll;
2560
2561         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2562                                               GTK_WINDOW (win),
2563                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2564                                               GTK_STOCK_OK,
2565                                               GTK_RESPONSE_ACCEPT,
2566                                               GTK_STOCK_CANCEL,
2567                                               GTK_RESPONSE_REJECT,
2568                                               NULL);
2569
2570         /* Create scrolled window */
2571         scroll = gtk_scrolled_window_new (NULL, NULL);
2572         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
2573                                          GTK_POLICY_AUTOMATIC,
2574                                          GTK_POLICY_AUTOMATIC);
2575
2576         /* Create folder view */
2577         *tree_view = modest_folder_view_new (NULL);
2578
2579         /* It could happen that we're trying to move a message from a
2580            window (msg window for example) after the main window was
2581            closed, so we can not just get the model of the folder
2582            view */
2583         if (MODEST_IS_FOLDER_VIEW (folder_view))
2584                 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2585                                          gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2586         else
2587                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
2588                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2589
2590         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2591
2592         /* Add scroll to dialog */
2593         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
2594                             scroll, FALSE, FALSE, 0);
2595
2596         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2597
2598         return dialog;
2599 }
2600
2601 /*
2602  * Returns TRUE if at least one of the headers of the list belongs to
2603  * a message that has been fully retrieved.
2604  */
2605 static gboolean
2606 has_retrieved_msgs (TnyList *list)
2607 {
2608         TnyIterator *iter;
2609         gboolean found = FALSE;
2610
2611         iter = tny_list_create_iterator (list);
2612         while (tny_iterator_is_done (iter) && !found) {
2613                 TnyHeader *header;
2614                 TnyHeaderFlags flags;
2615
2616                 header = TNY_HEADER (tny_iterator_get_current (iter));
2617                 flags = tny_header_get_flags (header);
2618                 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2619                         found = TRUE;
2620
2621                 if (!found)
2622                         tny_iterator_next (iter);
2623         }
2624         g_object_unref (iter);
2625
2626         return found;
2627 }
2628
2629 /*
2630  * Shows a confirmation dialog to the user when we're moving messages
2631  * from a remote server to the local storage. Returns the dialog
2632  * response. If it's other kind of movement the it always returns
2633  * GTK_RESPONSE_OK
2634  */
2635 static gint
2636 msgs_move_to_confirmation (GtkWindow *win,
2637                            TnyFolder *dest_folder,
2638                            TnyList *headers)
2639 {
2640         gint response = GTK_RESPONSE_OK;
2641
2642         /* If the destination is a local folder */
2643         if (modest_tny_folder_is_local_folder (dest_folder)) {
2644                 TnyFolder *src_folder;
2645                 TnyIterator *iter;
2646                 TnyHeader *header;
2647
2648                 /* Get source folder */
2649                 iter = tny_list_create_iterator (headers);
2650                 header = TNY_HEADER (tny_iterator_get_current (iter));
2651                 src_folder = tny_header_get_folder (header);
2652                 g_object_unref (header);
2653                 g_object_unref (iter);
2654
2655                 /* If the source is a remote folder */
2656                 if (!modest_tny_folder_is_local_folder (src_folder)) {
2657                         const gchar *message;
2658                         
2659                         if (tny_list_get_length (headers) == 1)
2660                                 if (has_retrieved_msgs (headers))
2661                                         message = _("mcen_nc_move_retrieve");
2662                                 else
2663                                         message = _("mcen_nc_move_header");
2664                         else
2665                                 if (has_retrieved_msgs (headers))
2666                                         message = _("mcen_nc_move_retrieves");
2667                                 else
2668                                         message = _("mcen_nc_move_headers");
2669                         
2670                         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2671                                                                             (const gchar *) message);
2672                 }
2673                 g_object_unref (src_folder);
2674         }
2675         return response;
2676 }
2677
2678
2679 static void
2680 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2681 {
2682         ModestMsgViewWindow *self = NULL;
2683         gboolean found = FALSE;
2684
2685         g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2686         self = MODEST_MSG_VIEW_WINDOW (object);
2687
2688         found = modest_msg_view_window_select_first_message (self);
2689         g_return_if_fail (found);
2690 }
2691
2692 void
2693 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
2694                                              gpointer user_data)
2695 {
2696         GObject *win = modest_mail_operation_get_source (mail_op);
2697
2698         /* TODO: show error message */
2699         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2700                                                 _("mail_in_ui_folder_move_target_error"));
2701 }
2702
2703 /*
2704  * UI handler for the "Move to" action when invoked from the
2705  * ModestMainWindow
2706  */
2707 static void 
2708 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
2709                                           ModestMainWindow *win)
2710 {
2711         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2712         GtkWidget *header_view = NULL;
2713         gint result;
2714         TnyFolderStore *folder_store = NULL;
2715         ModestMailOperation *mail_op = NULL;
2716
2717         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2718
2719         /* Get the folder view */
2720         folder_view = modest_main_window_get_child_widget (win,
2721                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2722
2723         /* Get header view */
2724         header_view = modest_main_window_get_child_widget (win,
2725                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2726
2727         /* Create and run the dialog */
2728         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2729         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2730         result = gtk_dialog_run (GTK_DIALOG(dialog));
2731         g_object_ref (tree_view);
2732
2733         /* We do this to save an indentation level ;-) */
2734         if (result != GTK_RESPONSE_ACCEPT)
2735                 goto end;
2736
2737         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2738
2739         if (TNY_IS_ACCOUNT (folder_store))
2740                 goto end;
2741
2742         /* Get folder or messages to transfer */
2743         if (gtk_widget_is_focus (folder_view)) {
2744                 TnyFolderStore *src_folder;
2745                 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2746
2747                 /* Clean folder on header view before moving it */
2748                 modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); 
2749
2750                 if (TNY_IS_FOLDER (src_folder)) {
2751                         mail_op = 
2752                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
2753                                                                                G_OBJECT(win),
2754                                                                                modest_ui_actions_move_folder_error_handler,
2755                                                                                NULL);
2756                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2757
2758                         modest_mail_operation_xfer_folder (mail_op, 
2759                                                            TNY_FOLDER (src_folder),
2760                                                            folder_store,
2761                                                            TRUE);
2762                         /* Unref mail operation */
2763                         g_object_unref (G_OBJECT (mail_op));
2764                 }
2765
2766                 /* Frees */
2767                 g_object_unref (G_OBJECT (src_folder));
2768         } else {
2769                 if (gtk_widget_is_focus (header_view)) {
2770                         TnyList *headers;
2771                         gint response;
2772
2773                         headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2774
2775                         /* Ask for user confirmation */
2776                         response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2777                                                               TNY_FOLDER (folder_store), 
2778                                                               headers);
2779
2780                         /* Transfer messages */
2781                         if (response == GTK_RESPONSE_OK) {
2782                                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2783                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2784                                                                  mail_op);
2785
2786                                 modest_mail_operation_xfer_msgs (mail_op, 
2787                                                                  headers,
2788                                                                  TNY_FOLDER (folder_store),
2789                                                                  TRUE,
2790                                                                  NULL,
2791                                                                  NULL);
2792
2793                                 g_object_unref (G_OBJECT (mail_op));
2794                         }
2795                         g_object_unref (headers);
2796                 }
2797         }
2798         g_object_unref (folder_store);
2799  end:
2800         gtk_widget_destroy (dialog);
2801 }
2802
2803
2804 /*
2805  * UI handler for the "Move to" action when invoked from the
2806  * ModestMsgViewWindow
2807  */
2808 static void 
2809 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
2810                                               ModestMsgViewWindow *win)
2811 {
2812         GtkWidget *dialog, *folder_view, *tree_view = NULL;
2813         gint result;
2814         ModestMainWindow *main_window;
2815         TnyHeader *header;
2816         TnyList *headers;
2817
2818         /* Get the folder view */
2819         main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2820         if (main_window)
2821                 folder_view = modest_main_window_get_child_widget (main_window,
2822                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
2823         else
2824                 folder_view = NULL;
2825
2826         /* Create and run the dialog */
2827         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);  
2828         result = gtk_dialog_run (GTK_DIALOG(dialog));
2829         g_object_ref (tree_view);
2830
2831         if (result == GTK_RESPONSE_ACCEPT) {
2832                 TnyFolderStore *folder_store;
2833                 gint response;
2834
2835                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2836
2837                 /* Create header list */
2838                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
2839                 headers = tny_simple_list_new ();
2840                 tny_list_prepend (headers, G_OBJECT (header));
2841                 g_object_unref (header);
2842
2843                 /* Ask user for confirmation. MSG-NOT404 */
2844                 response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2845                                                       TNY_FOLDER (folder_store), 
2846                                                       headers);
2847
2848                 /* Transfer current msg */
2849                 if (response == GTK_RESPONSE_OK) {
2850                         ModestMailOperation *mail_op;
2851
2852                         /* Create mail op */
2853                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2854                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2855                                                          mail_op);
2856                         
2857                         /* Transfer messages */
2858                         modest_mail_operation_xfer_msgs (mail_op, 
2859                                                          headers,
2860                                                          TNY_FOLDER (folder_store),
2861                                                          TRUE,
2862                                                          tranasfer_msgs_from_viewer_cb,
2863                                                          NULL);
2864                         g_object_unref (G_OBJECT (mail_op));
2865                 }
2866                 g_object_unref (headers);
2867                 g_object_unref (folder_store);
2868         }
2869         gtk_widget_destroy (dialog);
2870 }
2871
2872 void 
2873 modest_ui_actions_on_move_to (GtkAction *action, 
2874                               ModestWindow *win)
2875 {
2876         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2877                           MODEST_IS_MSG_VIEW_WINDOW (win));
2878
2879         if (MODEST_IS_MAIN_WINDOW (win)) 
2880                 modest_ui_actions_on_main_window_move_to (action, 
2881                                                           MODEST_MAIN_WINDOW (win));
2882         else
2883                 modest_ui_actions_on_msg_view_window_move_to (action, 
2884                                                               MODEST_MSG_VIEW_WINDOW (win));
2885 }
2886
2887 /*
2888  * Calls #HeadersFunc for each header already selected in the main
2889  * window or the message currently being shown in the msg view window
2890  */
2891 static void
2892 do_headers_action (ModestWindow *win, 
2893                    HeadersFunc func,
2894                    gpointer user_data)
2895 {
2896         TnyList *headers_list;
2897         TnyIterator *iter;
2898
2899         /* Get headers */
2900         headers_list = get_selected_headers (win);
2901         if (!headers_list)
2902                 return;
2903
2904         /* Call the function for each header */
2905         iter = tny_list_create_iterator (headers_list);
2906         while (!tny_iterator_is_done (iter)) {
2907                 TnyHeader *header;
2908
2909                 header = TNY_HEADER (tny_iterator_get_current (iter));
2910                 func (header, win, user_data);
2911                 g_object_unref (header);
2912                 tny_iterator_next (iter);
2913         }
2914         g_object_unref (iter);
2915         g_object_unref (headers_list);
2916 }
2917
2918 void 
2919 modest_ui_actions_view_attachment (GtkAction *action,
2920                                    ModestWindow *window)
2921 {
2922         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2923                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2924         } else {
2925                 /* not supported window for this action */
2926                 g_return_if_reached ();
2927         }
2928 }
2929
2930 void
2931 modest_ui_actions_save_attachments (GtkAction *action,
2932                                     ModestWindow *window)
2933 {
2934         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2935                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2936         } else {
2937                 /* not supported window for this action */
2938                 g_return_if_reached ();
2939         }
2940 }
2941
2942 void
2943 modest_ui_actions_remove_attachments (GtkAction *action,
2944                                       ModestWindow *window)
2945 {
2946         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2947                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2948         } else {
2949                 /* not supported window for this action */
2950                 g_return_if_reached ();
2951         }
2952 }
2953
2954 void 
2955 modest_ui_actions_on_settings (GtkAction *action, 
2956                                ModestWindow *win)
2957 {
2958         GtkWidget *dialog;
2959
2960         dialog = modest_platform_get_global_settings_dialog ();
2961         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2962         gtk_widget_show (dialog);
2963
2964         gtk_dialog_run (GTK_DIALOG (dialog));
2965
2966         gtk_widget_destroy (dialog);
2967 }
2968
2969 void 
2970 modest_ui_actions_on_help (GtkAction *action, 
2971                            ModestWindow *win)
2972 {
2973         const gchar *help_id = NULL;
2974
2975         if (MODEST_IS_MAIN_WINDOW (win)) {
2976                 const gchar *action_name;
2977                 action_name = gtk_action_get_name (action);
2978
2979                 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2980                     !strcmp (action_name, "HeaderViewCSMHelp")) {
2981                         GtkWidget *folder_view;
2982                         TnyFolderStore *folder_store;
2983                         /* Get selected folder */
2984                         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2985                                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2986                         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2987
2988                         /* Switch help_id */
2989                         if (TNY_IS_FOLDER (folder_store)) {
2990                                 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2991                                 case TNY_FOLDER_TYPE_NORMAL:
2992                                         help_id = "applications_email_userfolder";
2993                                         break;
2994                                 case TNY_FOLDER_TYPE_INBOX:
2995                                         help_id = "applications_email_inbox";
2996                                         break;
2997                                 case TNY_FOLDER_TYPE_OUTBOX:
2998                                         help_id = "applications_email_outbox";
2999                                         break;
3000                                 case TNY_FOLDER_TYPE_SENT:
3001                                         help_id = "applications_email_sent";
3002                                         break;
3003                                 case TNY_FOLDER_TYPE_DRAFTS:
3004                                         help_id = "applications_email_drafts";
3005                                         break;
3006                                 case TNY_FOLDER_TYPE_ARCHIVE:
3007                                         help_id = "applications_email_archive";
3008                                         break;
3009                                 default:
3010                                         help_id = NULL;
3011                                 }
3012                         }
3013                 } else {
3014                         help_id = "applications_email_mainview";        
3015                 }
3016         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3017                 help_id = "applications_email_viewer";
3018         } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3019                 help_id = "applications_email_editor";
3020
3021         modest_platform_show_help (GTK_WINDOW (win), help_id);
3022 }
3023
3024 void 
3025 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3026                                             ModestWindow *window)
3027 {
3028         ModestMailOperation *mail_op;
3029         TnyList *headers;
3030
3031         /* Get headers */
3032         headers = get_selected_headers (window);
3033         if (!headers)
3034                 return;
3035
3036         /* Create mail operation */
3037         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3038                                                                  G_OBJECT (window),
3039                                                                  modest_ui_actions_get_msgs_full_error_handler, 
3040                                                                  NULL);
3041         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3042         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3043
3044         /* Frees */
3045         g_object_unref (headers);
3046         g_object_unref (mail_op);
3047 }
3048
3049 void
3050 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3051                                           ModestWindow *window)
3052 {
3053         g_return_if_fail (MODEST_IS_WINDOW (window));
3054
3055         /* Update dimmed */     
3056         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3057 }
3058
3059 void
3060 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3061                                           ModestWindow *window)
3062 {
3063         g_return_if_fail (MODEST_IS_WINDOW (window));
3064
3065         /* Update dimmed */     
3066         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3067 }
3068
3069 void
3070 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3071                                           ModestWindow *window)
3072 {
3073         g_return_if_fail (MODEST_IS_WINDOW (window));
3074
3075         /* Update dimmed */     
3076         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3077 }
3078
3079 void
3080 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3081                                           ModestWindow *window)
3082 {
3083         g_return_if_fail (MODEST_IS_WINDOW (window));
3084
3085         /* Update dimmed */     
3086         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3087 }
3088
3089 void
3090 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3091                                           ModestWindow *window)
3092 {
3093         g_return_if_fail (MODEST_IS_WINDOW (window));
3094
3095         /* Update dimmed */     
3096         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3097 }
3098
3099 void
3100 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3101                                                  ModestWindow *window)
3102 {
3103         g_return_if_fail (MODEST_IS_WINDOW (window));
3104
3105         /* Update dimmed */     
3106         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3107 }
3108
3109 void
3110 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3111                                                      ModestWindow *window)
3112 {
3113         g_return_if_fail (MODEST_IS_WINDOW (window));
3114
3115         /* Update dimmed */     
3116         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3117 }
3118
3119 void
3120 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3121                                                      ModestWindow *window)
3122 {
3123         g_return_if_fail (MODEST_IS_WINDOW (window));
3124
3125         /* Update dimmed */     
3126         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3127 }
3128
3129 void
3130 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3131 {
3132         g_return_if_fail (MODEST_IS_WINDOW (window));
3133
3134         /* Update dimmed */     
3135         modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");  
3136 }
3137
3138 void
3139 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3140 {
3141         g_return_if_fail (MODEST_IS_WINDOW (window));
3142
3143         modest_platform_show_search_messages (GTK_WINDOW (window));
3144 }
3145
3146 void     
3147 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3148 {
3149         g_return_if_fail (MODEST_IS_WINDOW (win));
3150         modest_platform_show_addressbook (GTK_WINDOW (win));
3151 }
3152
3153
3154 void
3155 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3156                                           ModestWindow *window)
3157 {
3158         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3159
3160         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3161 }
3162
3163 static void 
3164 _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
3165                                    ModestMailOperationState *state,
3166                                    gpointer user_data)
3167 {
3168         g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3169
3170         /* Set send/receive operation finished */       
3171         if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3172                 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
3173         
3174 }