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