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