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