a7675347b1ababd2e11efb93ff7c70ec13c6b0fc
[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
673         /* Look if we already have a message view for each header. If
674            true, then remove the header from the list of headers to
675            open */
676         mgr = modest_runtime_get_window_mgr ();
677         iter = tny_list_create_iterator (headers);
678         while (!tny_iterator_is_done (iter)) {
679                 ModestWindow *window;
680                 TnyHeader *header;
681                 
682                 header = TNY_HEADER (tny_iterator_get_current (iter));
683                 window = modest_window_mgr_find_window_by_header (mgr, header);
684                 if (window) {
685                         /* Do not open again the message and present
686                            the window to the user */
687                         tny_list_remove (headers, G_OBJECT (header));
688                         gtk_window_present (GTK_WINDOW (window));
689                 }
690
691                 g_object_unref (header);
692                 tny_iterator_next (iter);
693         }
694
695         
696         /* Open each message */
697         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
698                                                                  G_OBJECT (win), 
699                                                                  modest_ui_actions_get_msgs_full_error_handler, 
700                                                                  NULL);
701         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
702         modest_mail_operation_get_msgs_full (mail_op, 
703                                              headers, 
704                                              open_msg_cb, 
705                                              NULL, 
706                                              NULL);
707         /* Clean */
708         g_object_unref (iter);
709         g_object_unref(mail_op);
710 }
711
712 void
713 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
714 {
715         TnyList *headers;
716
717         /* Get headers */
718         headers = get_selected_headers (win);
719         if (!headers)
720                 return;
721
722         /* Open them */
723         _modest_ui_actions_open (headers, win);
724
725         g_object_unref(headers);
726 }
727
728
729 static void
730 free_reply_forward_helper (gpointer data)
731 {
732         ReplyForwardHelper *helper;
733
734         helper = (ReplyForwardHelper *) data;
735         g_free (helper->account_name);
736         g_slice_free (ReplyForwardHelper, helper);
737 }
738
739 static void
740 reply_forward_cb (ModestMailOperation *mail_op, 
741                   TnyHeader *header, 
742                   TnyMsg *msg,
743                   gpointer user_data)
744 {
745         TnyMsg *new_msg;
746         ReplyForwardHelper *rf_helper;
747         ModestWindow *msg_win;
748         ModestEditType edit_type;
749         gchar *from;
750         TnyAccount *account = NULL;
751         ModestWindowMgr *mgr;
752         gchar *signature = NULL;
753                         
754         g_return_if_fail (user_data != NULL);
755         rf_helper = (ReplyForwardHelper *) user_data;
756
757         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
758                                                    rf_helper->account_name);
759         if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
760                                          rf_helper->account_name,
761                                          MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
762                 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
763                                                            rf_helper->account_name,
764                                                            MODEST_ACCOUNT_SIGNATURE, FALSE);
765         }
766
767         /* Create reply mail */
768         switch (rf_helper->action) {
769         case ACTION_REPLY:
770                 new_msg = 
771                         modest_tny_msg_create_reply_msg (msg,  from, signature,
772                                                          rf_helper->reply_forward_type,
773                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
774                 break;
775         case ACTION_REPLY_TO_ALL:
776                 new_msg = 
777                         modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
778                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
779                 edit_type = MODEST_EDIT_TYPE_REPLY;
780                 break;
781         case ACTION_FORWARD:
782                 new_msg = 
783                         modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
784                 edit_type = MODEST_EDIT_TYPE_FORWARD;
785                 break;
786         default:
787                 g_return_if_reached ();
788                 return;
789         }
790
791         g_free (signature);
792
793         if (!new_msg) {
794                 g_printerr ("modest: failed to create message\n");
795                 goto cleanup;
796         }
797
798         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
799                                                                        rf_helper->account_name,
800                                                                        TNY_ACCOUNT_TYPE_STORE);
801         if (!account) {
802                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
803                 goto cleanup;
804         }
805
806         /* Create and register the windows */
807         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
808         mgr = modest_runtime_get_window_mgr ();
809         modest_window_mgr_register_window (mgr, msg_win);
810
811         if (rf_helper->parent_window != NULL) {
812                 gdouble parent_zoom;
813
814                 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
815                 modest_window_set_zoom (msg_win, parent_zoom);
816         }
817
818         /* Show edit window */
819         gtk_widget_show_all (GTK_WIDGET (msg_win));
820
821 cleanup:
822         if (new_msg)
823                 g_object_unref (G_OBJECT (new_msg));
824         if (account)
825                 g_object_unref (G_OBJECT (account));
826         g_object_unref (msg);
827         g_object_unref (header);
828 }
829
830 /*
831  * Checks a list of headers. If any of them are not currently
832  * downloaded (CACHED) then it asks the user for permission to
833  * download them.
834  *
835  * Returns FALSE if the user does not want to download the
836  * messages. Returns TRUE if the user allowed the download or if all
837  * of them are currently downloaded
838  */
839 static gboolean
840 download_uncached_messages (TnyList *header_list, GtkWindow *win)
841 {
842         TnyIterator *iter;
843         gboolean found, retval;
844
845         iter = tny_list_create_iterator (header_list);
846         found = FALSE;
847         while (!tny_iterator_is_done (iter) && !found) {
848                 TnyHeader *header;
849                 TnyHeaderFlags flags;
850
851                 header = TNY_HEADER (tny_iterator_get_current (iter));
852                 flags = tny_header_get_flags (header);
853                 /* TODO: is this the right flag?, it seems that some
854                    headers that have been previously downloaded do not
855                    come with it */
856                 found = !(flags & TNY_HEADER_FLAG_CACHED);
857                 g_object_unref (header);
858                 tny_iterator_next (iter);
859         }
860         g_object_unref (iter);
861
862         /* Ask for user permission to download the messages */
863         retval = TRUE;
864         if (found) {
865                 GtkResponseType response;
866                 response = 
867                         modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
868                                                                  _("mcen_nc_get_multi_msg_txt"));
869                 if (response == GTK_RESPONSE_CANCEL)
870                         retval = FALSE;
871         }
872         return retval;
873 }
874
875
876 /*
877  * Common code for the reply and forward actions
878  */
879 static void
880 reply_forward (ReplyForwardAction action, ModestWindow *win)
881 {
882         ModestMailOperation *mail_op = NULL;
883         TnyList *header_list = NULL;
884         ReplyForwardHelper *rf_helper = NULL;
885         guint reply_forward_type;
886         gboolean continue_download;
887         
888         g_return_if_fail (MODEST_IS_WINDOW(win));
889
890         header_list = get_selected_headers (win);
891         if (!header_list)
892                 return;
893
894         /* Check that the messages have been previously downloaded */
895         continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
896         if (!continue_download) {
897                 g_object_unref (header_list);
898                 return;
899         }
900         
901         reply_forward_type = 
902                 modest_conf_get_int (modest_runtime_get_conf (),
903                                      (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
904                                      NULL);
905         /* We assume that we can only select messages of the
906            same folder and that we reply all of them from the
907            same account. In fact the interface currently only
908            allows single selection */
909         
910         /* Fill helpers */
911         rf_helper = g_slice_new0 (ReplyForwardHelper);
912         rf_helper->reply_forward_type = reply_forward_type;
913         rf_helper->action = action;
914         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
915         if ((win != NULL) && (MODEST_IS_WINDOW (win)))
916                 rf_helper->parent_window = GTK_WIDGET (win);
917         if (!rf_helper->account_name)
918                 rf_helper->account_name =
919                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
920
921         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
922                 TnyMsg *msg;
923                 TnyHeader *header;
924                 /* Get header and message. Do not free them here, the
925                    reply_forward_cb must do it */
926                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
927                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
928                 if (!msg || !header) {
929                         if (msg)
930                                 g_object_unref (msg);
931                         if (header)
932                                 g_object_unref (header);
933                         g_printerr ("modest: no message found\n");
934                         return;
935                 } else
936                         reply_forward_cb (NULL, header, msg, rf_helper);
937         } else {
938                 /* Retrieve messages */
939                 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
940                                                                          G_OBJECT(win),
941                                                                          modest_ui_actions_get_msgs_full_error_handler, 
942                                                                          NULL);
943                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
944                 modest_mail_operation_get_msgs_full (mail_op, 
945                                                      header_list, 
946                                                      reply_forward_cb, 
947                                                      rf_helper, 
948                                                      free_reply_forward_helper);
949
950                 /* Clean */
951                 g_object_unref(mail_op);
952         }
953
954         /* Free */
955         g_object_unref (header_list);
956 }
957
958 void
959 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
960 {
961         g_return_if_fail (MODEST_IS_WINDOW(win));
962
963         reply_forward (ACTION_REPLY, win);
964 }
965
966 void
967 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
968 {
969         g_return_if_fail (MODEST_IS_WINDOW(win));
970
971         reply_forward (ACTION_FORWARD, win);
972 }
973
974 void
975 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
976 {
977         g_return_if_fail (MODEST_IS_WINDOW(win));
978
979         reply_forward (ACTION_REPLY_TO_ALL, win);
980 }
981
982 void 
983 modest_ui_actions_on_next (GtkAction *action, 
984                            ModestWindow *window)
985 {
986         if (MODEST_IS_MAIN_WINDOW (window)) {
987                 GtkWidget *header_view;
988
989                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
990                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
991                 if (!header_view)
992                         return;
993         
994                 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); 
995         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
996                 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
997         } else {
998                 g_return_if_reached ();
999         }
1000 }
1001
1002 void 
1003 modest_ui_actions_on_prev (GtkAction *action, 
1004                            ModestWindow *window)
1005 {
1006         g_return_if_fail (MODEST_IS_WINDOW(window));
1007
1008         if (MODEST_IS_MAIN_WINDOW (window)) {
1009                 GtkWidget *header_view;
1010                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1011                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1012                 if (!header_view)
1013                         return;
1014                 
1015                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
1016         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1017                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1018         } else {
1019                 g_return_if_reached ();
1020         }
1021 }
1022
1023 void 
1024 modest_ui_actions_on_sort (GtkAction *action, 
1025                            ModestWindow *window)
1026 {
1027         g_return_if_fail (MODEST_IS_WINDOW(window));
1028
1029         if (MODEST_IS_MAIN_WINDOW (window)) {
1030                 GtkWidget *header_view;
1031                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1032                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1033                 if (!header_view)
1034                         return;
1035
1036                 /* Show sorting dialog */
1037                 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);     
1038         }
1039 }
1040
1041 /*
1042  * This function performs the send & receive required actions. The
1043  * window is used to create the mail operation. Typically it should
1044  * always be the main window, but we pass it as argument in order to
1045  * be more flexible.
1046  */
1047 void
1048 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1049 {
1050         gchar *acc_name = NULL;
1051         ModestMailOperation *mail_op;
1052
1053         /* If no account name was provided then get the current account, and if
1054            there is no current account then pick the default one: */
1055         if (!account_name) {
1056                 acc_name = g_strdup (modest_window_get_active_account(win));
1057                 if (!acc_name)
1058                         acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1059                 if (!acc_name) {
1060                         g_printerr ("modest: cannot get default account\n");
1061                         return;
1062                 }
1063         } else {
1064                 acc_name = g_strdup (account_name);
1065         }
1066
1067         /* Set send/receive operation in progress */    
1068         modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1069
1070         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1071         g_signal_connect (G_OBJECT(mail_op), "progress-changed", 
1072                           G_CALLBACK (_on_send_receive_progress_changed), 
1073                           win);
1074
1075         /* Send & receive. */
1076         /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1077         /* Receive and then send. The operation is tagged initially as
1078            a receive operation because the account update performs a
1079            receive and then a send. The operation changes its type
1080            internally, so the progress objects will receive the proper
1081            progress information */
1082         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1083         modest_mail_operation_update_account (mail_op, acc_name);
1084         g_object_unref (G_OBJECT (mail_op));
1085         
1086         /* Free */
1087         g_free (acc_name);
1088 }
1089
1090 /*
1091  * Refreshes all accounts. This function will be used by automatic
1092  * updates
1093  */
1094 void
1095 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1096 {
1097         GSList *account_names, *iter;
1098
1099         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1100                                                           TRUE);
1101
1102         iter = account_names;
1103         while (iter) {                  
1104                 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1105                 iter = g_slist_next (iter);
1106         }
1107         
1108         g_slist_foreach (account_names, (GFunc) g_free, NULL);
1109         g_slist_free (account_names);
1110 }
1111
1112 /*
1113  * Handler of the click on Send&Receive button in the main toolbar
1114  */
1115 void
1116 modest_ui_actions_on_send_receive (GtkAction *action,  ModestWindow *win)
1117 {
1118         /* Check if accounts exist */
1119         gboolean accounts_exist = 
1120                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1121         
1122         /* If not, allow the user to create an account before trying to send/receive. */
1123         if (!accounts_exist)
1124                 modest_ui_actions_on_accounts (NULL, win);
1125         
1126         /* Refresh the active account */
1127         modest_ui_actions_do_send_receive (NULL, win);
1128 }
1129
1130
1131 void
1132 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1133 {
1134         ModestConf *conf;
1135         GtkWidget *header_view;
1136         
1137         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1138
1139         header_view = modest_main_window_get_child_widget (main_window,
1140                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1141         if (!header_view)
1142                 return;
1143
1144         conf = modest_runtime_get_conf ();
1145         
1146         /* what is saved/restored is depending on the style; thus; we save with
1147          * old style, then update the style, and restore for this new style
1148          */
1149         modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1150         
1151         if (modest_header_view_get_style
1152             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1153                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1154                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
1155         else
1156                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1157                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
1158
1159         modest_widget_memory_restore (conf, G_OBJECT(header_view),
1160                                       MODEST_CONF_HEADER_VIEW_KEY);
1161 }
1162
1163
1164 void 
1165 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
1166                                       TnyHeader *header,
1167                                       ModestMainWindow *main_window)
1168 {
1169         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1170         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1171         
1172         /* If no header has been selected then exit */
1173         if (!header)
1174                 return;
1175         
1176         /* Update Main window title */
1177         if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1178                 const gchar *subject = tny_header_get_subject (header);
1179                 if (subject && strlen(subject) > 0)
1180                         gtk_window_set_title (GTK_WINDOW (main_window), subject);
1181                 else
1182                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1183         }
1184
1185         /* Update toolbar dimming state */
1186         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1187 }
1188
1189 void
1190 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1191                                        TnyHeader *header,
1192                                        ModestMainWindow *main_window)
1193 {
1194         TnyList *headers;
1195
1196         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1197         
1198         if (!header)
1199                 return;
1200
1201         headers = tny_simple_list_new ();
1202         tny_list_prepend (headers, G_OBJECT (header));
1203
1204         _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1205
1206         g_object_unref (headers);
1207 }
1208
1209 static void
1210 set_active_account_from_tny_account (TnyAccount *account,
1211                                      ModestWindow *window)
1212 {
1213         const gchar *server_acc_name = tny_account_get_id (account);
1214         
1215         /* We need the TnyAccount provided by the
1216            account store because that is the one that
1217            knows the name of the Modest account */
1218         TnyAccount *modest_server_account = modest_server_account = 
1219                 modest_tny_account_store_get_tny_account_by_id  (modest_runtime_get_account_store (), 
1220                                                                  server_acc_name);
1221         
1222         const gchar *modest_acc_name = 
1223                 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1224         modest_window_set_active_account (window, modest_acc_name);
1225         g_object_unref (modest_server_account);
1226 }
1227
1228 void 
1229 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1230                                                TnyFolderStore *folder_store, 
1231                                                gboolean selected,
1232                                                ModestMainWindow *main_window)
1233 {
1234         ModestConf *conf;
1235         GtkWidget *header_view;
1236         gboolean folder_empty = FALSE;
1237
1238         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1239
1240         header_view = modest_main_window_get_child_widget(main_window,
1241                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
1242         if (!header_view)
1243                 return;
1244         
1245         conf = modest_runtime_get_conf ();
1246
1247         if (TNY_IS_ACCOUNT (folder_store)) {
1248                 /* Update active account */
1249                 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1250                 /* Show account details */
1251                 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1252         } else {
1253                 if (TNY_IS_FOLDER (folder_store) && selected) {
1254                         
1255                         if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1256                                 /* Update the active account */
1257                                 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1258                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1259                                 g_object_unref (account);
1260                         }
1261                         
1262
1263                         /* Set folder on header view */
1264                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1265                                                        TNY_FOLDER (folder_store));                              
1266                         
1267                         /* Set main view style */
1268                         folder_empty = tny_folder_get_all_count (TNY_FOLDER (folder_store)) == 0;
1269                         if (folder_empty)  {
1270                                 modest_main_window_set_contents_style (main_window, 
1271                                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1272                         }
1273                         else {
1274                                 modest_main_window_set_contents_style (main_window, 
1275                                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1276                                 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1277                                                               MODEST_CONF_HEADER_VIEW_KEY);
1278                         }
1279                 } else {
1280                         /* Update the active account */
1281                         modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1282                         /* Do not show folder */
1283                         modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1284                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1285                 }
1286         }
1287
1288         /* Update toolbar dimming state */
1289         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1290 }
1291
1292 void 
1293 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1294                                      ModestWindow *win)
1295 {
1296         GtkWidget *dialog;
1297         gchar *txt, *item;
1298         gboolean online;
1299
1300         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1301         
1302         if (g_main_depth > 0)   
1303                 gdk_threads_enter ();
1304         online = tny_device_is_online (modest_runtime_get_device());
1305
1306         if (online) {
1307                 /* already online -- the item is simply not there... */
1308                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1309                                                  GTK_DIALOG_MODAL,
1310                                                  GTK_MESSAGE_WARNING,
1311                                                  GTK_BUTTONS_OK,
1312                                                  _("The %s you selected cannot be found"),
1313                                                  item);
1314                 gtk_dialog_run (GTK_DIALOG(dialog));
1315         } else {
1316                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1317                                                       GTK_WINDOW (win),
1318                                                       GTK_DIALOG_MODAL,
1319                                                       GTK_STOCK_CANCEL,
1320                                                       GTK_RESPONSE_REJECT,
1321                                                       GTK_STOCK_OK,
1322                                                       GTK_RESPONSE_ACCEPT,
1323                                                       NULL);
1324                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1325                                          "Do you want to get online?"), item);
1326                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1327                                     gtk_label_new (txt), FALSE, FALSE, 0);
1328                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1329                 g_free (txt);
1330
1331                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1332                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1333 //                      modest_platform_connect_and_wait ();;
1334                 }
1335         }
1336         gtk_widget_destroy (dialog);
1337         if (g_main_depth > 0)   
1338                 gdk_threads_leave ();
1339 }
1340
1341 void
1342 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1343                                      ModestWindow *win)
1344 {
1345         /* g_message ("%s %s", __FUNCTION__, link); */
1346 }       
1347
1348
1349 void
1350 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1351                                         ModestWindow *win)
1352 {
1353         modest_platform_activate_uri (link);
1354 }
1355
1356 void
1357 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1358                                           ModestWindow *win)
1359 {
1360         modest_platform_show_uri_popup (link);
1361 }
1362
1363 void
1364 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1365                                              ModestWindow *win)
1366 {
1367         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1368 }
1369
1370 void
1371 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1372                                           const gchar *address,
1373                                           ModestWindow *win)
1374 {
1375         /* g_message ("%s %s", __FUNCTION__, address); */
1376 }
1377
1378 void
1379 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1380 {
1381         TnyTransportAccount *transport_account;
1382         ModestMailOperation *mail_operation;
1383         MsgData *data;
1384         gchar *account_name, *from;
1385         ModestAccountMgr *account_mgr;
1386
1387         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1388         
1389         data = modest_msg_edit_window_get_msg_data (edit_window);
1390
1391         account_mgr = modest_runtime_get_account_mgr();
1392         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1393         if (!account_name) 
1394                 account_name = modest_account_mgr_get_default_account (account_mgr);
1395         if (!account_name) {
1396                 g_printerr ("modest: no account found\n");
1397                 modest_msg_edit_window_free_msg_data (edit_window, data);
1398                 return;
1399         }
1400
1401         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1402                 account_name = g_strdup (data->account_name);
1403         }
1404
1405         transport_account =
1406                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1407                                       (modest_runtime_get_account_store(),
1408                                        account_name,
1409                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1410         if (!transport_account) {
1411                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1412                 g_free (account_name);
1413                 modest_msg_edit_window_free_msg_data (edit_window, data);
1414                 return;
1415         }
1416         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1417
1418         /* Create the mail operation */         
1419         mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1420         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1421
1422         modest_mail_operation_save_to_drafts (mail_operation,
1423                                               transport_account,
1424                                               data->draft_msg,
1425                                               from,
1426                                               data->to, 
1427                                               data->cc, 
1428                                               data->bcc,
1429                                               data->subject, 
1430                                               data->plain_body, 
1431                                               data->html_body,
1432                                               data->attachments,
1433                                               data->priority_flags);
1434         /* Frees */
1435         g_free (from);
1436         g_free (account_name);
1437         g_object_unref (G_OBJECT (transport_account));
1438         g_object_unref (G_OBJECT (mail_operation));
1439
1440         modest_msg_edit_window_free_msg_data (edit_window, data);
1441
1442         /* Save settings and close the window */
1443         gtk_widget_destroy (GTK_WIDGET (edit_window));
1444 }
1445
1446 /* For instance, when clicking the Send toolbar button when editing a message: */
1447 void
1448 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1449 {
1450         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1451
1452         if (!modest_msg_edit_window_check_names (edit_window))
1453                 return;
1454         
1455         /* FIXME: Code added just for testing. The final version will
1456            use the send queue provided by tinymail and some
1457            classifier */
1458         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1459         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1460         if (!account_name) 
1461                 account_name = modest_account_mgr_get_default_account (account_mgr);
1462                 
1463         if (!account_name) {
1464                 g_printerr ("modest: no account found\n");
1465                 return;
1466         }
1467         
1468         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1469
1470         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1471                 account_name = g_strdup (data->account_name);
1472         }
1473         
1474         /* Get the currently-active transport account for this modest account: */
1475         TnyTransportAccount *transport_account =
1476                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1477                                       (modest_runtime_get_account_store(),
1478                                        account_name));
1479         if (!transport_account) {
1480                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1481                 g_free (account_name);
1482                 modest_msg_edit_window_free_msg_data (edit_window, data);
1483                 return;
1484         }
1485         
1486         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1487
1488         /* mail content checks and dialogs */
1489         if (data->subject == NULL || data->subject[0] == '\0') {
1490                 GtkResponseType response;
1491                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1492                                                                     _("mcen_nc_subject_is_empty_send"));
1493                 if (response == GTK_RESPONSE_CANCEL) {
1494                         g_free (account_name);
1495                         return;
1496                 }
1497         }
1498
1499         if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1500                 GtkResponseType response;
1501                 gchar *note_message;
1502                 gchar *note_subject = data->subject;
1503                 if (note_subject == NULL || note_subject[0] == '\0')
1504                         note_subject = _("mail_va_no_subject");
1505                 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1506                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1507                                                                     note_message);
1508                 g_free (note_message);
1509                 if (response == GTK_RESPONSE_CANCEL) {
1510                         g_free (account_name);
1511                         return;
1512                 }
1513         }
1514
1515         /* Create the mail operation */
1516         ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1517         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1518
1519         modest_mail_operation_send_new_mail (mail_operation,
1520                                              transport_account,
1521                                              data->draft_msg,
1522                                              from,
1523                                              data->to, 
1524                                              data->cc, 
1525                                              data->bcc,
1526                                              data->subject, 
1527                                              data->plain_body, 
1528                                              data->html_body,
1529                                              data->attachments,
1530                                              data->priority_flags);
1531                                              
1532         /* Free data: */
1533         g_free (from);
1534         g_free (account_name);
1535         g_object_unref (G_OBJECT (transport_account));
1536         g_object_unref (G_OBJECT (mail_operation));
1537
1538         modest_msg_edit_window_free_msg_data (edit_window, data);
1539
1540         /* Save settings and close the window: */
1541         gtk_widget_destroy (GTK_WIDGET (edit_window));
1542 }
1543
1544 void 
1545 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1546                                   ModestMsgEditWindow *window)
1547 {
1548         ModestMsgEditFormatState *format_state = NULL;
1549
1550         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1551         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1552
1553         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1554                 return;
1555
1556         format_state = modest_msg_edit_window_get_format_state (window);
1557         g_return_if_fail (format_state != NULL);
1558
1559         format_state->bold = gtk_toggle_action_get_active (action);
1560         modest_msg_edit_window_set_format_state (window, format_state);
1561         g_free (format_state);
1562         
1563 }
1564
1565 void 
1566 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1567                                      ModestMsgEditWindow *window)
1568 {
1569         ModestMsgEditFormatState *format_state = NULL;
1570
1571         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1572         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1573
1574         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1575                 return;
1576
1577         format_state = modest_msg_edit_window_get_format_state (window);
1578         g_return_if_fail (format_state != NULL);
1579
1580         format_state->italics = gtk_toggle_action_get_active (action);
1581         modest_msg_edit_window_set_format_state (window, format_state);
1582         g_free (format_state);
1583         
1584 }
1585
1586 void 
1587 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1588                                      ModestMsgEditWindow *window)
1589 {
1590         ModestMsgEditFormatState *format_state = NULL;
1591
1592         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1593         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1594
1595         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1596                 return;
1597
1598         format_state = modest_msg_edit_window_get_format_state (window);
1599         g_return_if_fail (format_state != NULL);
1600
1601         format_state->bullet = gtk_toggle_action_get_active (action);
1602         modest_msg_edit_window_set_format_state (window, format_state);
1603         g_free (format_state);
1604         
1605 }
1606
1607 void 
1608 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1609                                      GtkRadioAction *selected,
1610                                      ModestMsgEditWindow *window)
1611 {
1612         ModestMsgEditFormatState *format_state = NULL;
1613         GtkJustification value;
1614
1615         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1616
1617         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1618                 return;
1619
1620         value = gtk_radio_action_get_current_value (selected);
1621
1622         format_state = modest_msg_edit_window_get_format_state (window);
1623         g_return_if_fail (format_state != NULL);
1624
1625         format_state->justification = value;
1626         modest_msg_edit_window_set_format_state (window, format_state);
1627         g_free (format_state);
1628 }
1629
1630 void 
1631 modest_ui_actions_on_select_editor_color (GtkAction *action,
1632                                           ModestMsgEditWindow *window)
1633 {
1634         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1635         g_return_if_fail (GTK_IS_ACTION (action));
1636
1637         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1638                 return;
1639
1640         modest_msg_edit_window_select_color (window);
1641 }
1642
1643 void 
1644 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1645                                                      ModestMsgEditWindow *window)
1646 {
1647         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1648         g_return_if_fail (GTK_IS_ACTION (action));
1649
1650         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1651                 return;
1652
1653         modest_msg_edit_window_select_background_color (window);
1654 }
1655
1656 void 
1657 modest_ui_actions_on_insert_image (GtkAction *action,
1658                                    ModestMsgEditWindow *window)
1659 {
1660         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1661         g_return_if_fail (GTK_IS_ACTION (action));
1662
1663         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1664                 return;
1665
1666         modest_msg_edit_window_insert_image (window);
1667 }
1668
1669 void 
1670 modest_ui_actions_on_attach_file (GtkAction *action,
1671                                   ModestMsgEditWindow *window)
1672 {
1673         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1674         g_return_if_fail (GTK_IS_ACTION (action));
1675
1676         modest_msg_edit_window_attach_file (window);
1677 }
1678
1679 void 
1680 modest_ui_actions_on_remove_attachments (GtkAction *action,
1681                                          ModestMsgEditWindow *window)
1682 {
1683         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1684         g_return_if_fail (GTK_IS_ACTION (action));
1685
1686         modest_msg_edit_window_remove_attachments (window, NULL);
1687 }
1688
1689 /*
1690  * Shows a dialog with an entry that asks for some text. The returned
1691  * value must be freed by the caller. The dialog window title will be
1692  * set to @title.
1693  */
1694 static gchar *
1695 ask_for_folder_name (GtkWindow *parent_window,
1696                      const gchar *title)
1697 {
1698         GtkWidget *dialog, *entry;
1699         gchar *folder_name = NULL;
1700
1701         /* Ask for folder name */
1702         dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1703                                               parent_window,
1704                                               GTK_DIALOG_MODAL,
1705                                               GTK_STOCK_CANCEL,
1706                                               GTK_RESPONSE_REJECT,
1707                                               GTK_STOCK_OK,
1708                                               GTK_RESPONSE_ACCEPT,
1709                                               NULL);
1710         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1711                             gtk_label_new(title),
1712                             FALSE, FALSE, 0);
1713                 
1714         entry = gtk_entry_new_with_max_length (40);
1715         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1716                             entry,
1717                             TRUE, FALSE, 0);    
1718         
1719         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1720         
1721         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)         
1722                 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1723
1724         gtk_widget_destroy (dialog);
1725
1726         return folder_name;
1727 }
1728
1729 void 
1730 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1731 {
1732         TnyFolderStore *parent_folder;
1733         GtkWidget *folder_view;
1734         
1735         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1736
1737         folder_view = modest_main_window_get_child_widget (main_window,
1738                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1739         if (!folder_view)
1740                 return;
1741
1742         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1743         
1744         if (parent_folder) {
1745                 gboolean finished = FALSE;
1746                 gint result;
1747                 gchar *folder_name = NULL, *suggested_name = NULL;
1748
1749                 /* Run the new folder dialog */
1750                 while (!finished) {
1751                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1752                                                                         parent_folder,
1753                                                                         suggested_name,
1754                                                                         &folder_name);
1755
1756                         if (result == GTK_RESPONSE_REJECT) {
1757                                 finished = TRUE;
1758                         } else {
1759                                 ModestMailOperation *mail_op;
1760                                 TnyFolder *new_folder = NULL;
1761
1762                                 mail_op  = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, 
1763                                                                       G_OBJECT(main_window));
1764                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1765                                                                  mail_op);
1766                                 new_folder = modest_mail_operation_create_folder (mail_op,
1767                                                                                   parent_folder,
1768                                                                                   (const gchar *) folder_name);
1769                                 if (new_folder) {
1770                                         g_object_unref (new_folder);
1771                                         finished = TRUE;
1772                                 }
1773                                 g_object_unref (mail_op);
1774                         }
1775                         g_free (folder_name);
1776                         folder_name = NULL;
1777                 }
1778
1779                 g_object_unref (parent_folder);
1780         }
1781 }
1782
1783 void 
1784 modest_ui_actions_on_rename_folder (GtkAction *action,
1785                                      ModestMainWindow *main_window)
1786 {
1787         TnyFolderStore *folder;
1788         GtkWidget *folder_view;
1789         GtkWidget *header_view; 
1790
1791         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1792
1793         folder_view = modest_main_window_get_child_widget (main_window,
1794                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1795         if (!folder_view)
1796                 return;
1797
1798         header_view = modest_main_window_get_child_widget (main_window,
1799                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1800         
1801         if (!header_view)
1802                 return;
1803
1804         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1805         
1806         if (folder && TNY_IS_FOLDER (folder)) {
1807                 gchar *folder_name;
1808                 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1809                                                    _("Please enter a new name for the folder"));
1810
1811                 if (folder_name != NULL && strlen (folder_name) > 0) {
1812                         ModestMailOperation *mail_op;
1813
1814                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1815                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1816                                                          mail_op);
1817
1818                         modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1819
1820                         modest_mail_operation_rename_folder (mail_op,
1821                                                              TNY_FOLDER (folder),
1822                                                              (const gchar *) folder_name);
1823
1824                         g_object_unref (mail_op);
1825                         g_free (folder_name);
1826                 }
1827                 g_object_unref (folder);
1828         }
1829 }
1830
1831 static void
1832 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1833                                                gpointer user_data)
1834 {
1835         GObject *win = modest_mail_operation_get_source (mail_op);
1836
1837         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1838                                                 _("mail_in_ui_folder_delete_error"));
1839 }
1840
1841 static void
1842 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
1843 {
1844         TnyFolderStore *folder;
1845         GtkWidget *folder_view;
1846         gint response;
1847         gchar *message;
1848         
1849         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1850
1851         folder_view = modest_main_window_get_child_widget (main_window,
1852                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1853         if (!folder_view)
1854                 return;
1855
1856         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1857
1858         /* Show an error if it's an account */
1859         if (!TNY_IS_FOLDER (folder)) {
1860                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1861                                                         _("mail_in_ui_folder_delete_error"));
1862                 return ;
1863         }
1864
1865         /* Ask the user */      
1866         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
1867                                     tny_folder_get_name (TNY_FOLDER (folder)));
1868         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window), 
1869                                                             (const gchar *) message);
1870         g_free (message);
1871
1872         if (response == GTK_RESPONSE_OK) {
1873                 ModestMailOperation *mail_op = 
1874                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, 
1875                                                                        G_OBJECT(main_window),
1876                                                                        modest_ui_actions_delete_folder_error_handler,
1877                                                                        NULL);
1878
1879                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1880                                                  mail_op);
1881                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1882                 g_object_unref (G_OBJECT (mail_op));
1883         }
1884
1885         g_object_unref (G_OBJECT (folder));
1886 }
1887
1888 void 
1889 modest_ui_actions_on_delete_folder (GtkAction *action,
1890                                      ModestMainWindow *main_window)
1891 {
1892         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1893
1894         delete_folder (main_window, FALSE);
1895 }
1896
1897 void 
1898 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1899 {
1900         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1901         
1902         delete_folder (main_window, TRUE);
1903 }
1904
1905 void
1906 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
1907                                          const gchar* server_account_name,
1908                                          gchar **username,
1909                                          gchar **password, 
1910                                          gboolean *cancel, 
1911                                          gboolean *remember,
1912                                          ModestMainWindow *main_window)
1913 {
1914         g_return_if_fail(server_account_name);
1915         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1916         
1917         /* Initalize output parameters: */
1918         if (cancel)
1919                 *cancel = FALSE;
1920                 
1921         if (remember)
1922                 *remember = TRUE;
1923                 
1924 #ifdef MODEST_PLATFORM_MAEMO
1925         /* Maemo uses a different (awkward) button order,
1926          * It should probably just use gtk_alternative_dialog_button_order ().
1927          */
1928         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1929                                               NULL,
1930                                               GTK_DIALOG_MODAL,
1931                                               GTK_STOCK_OK,
1932                                               GTK_RESPONSE_ACCEPT,
1933                                               GTK_STOCK_CANCEL,
1934                                               GTK_RESPONSE_REJECT,
1935                                               NULL);
1936 #else
1937         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1938                                               NULL,
1939                                               GTK_DIALOG_MODAL,
1940                                               GTK_STOCK_CANCEL,
1941                                               GTK_RESPONSE_REJECT,
1942                                               GTK_STOCK_OK,
1943                                               GTK_RESPONSE_ACCEPT,
1944                                               NULL);
1945 #endif /* MODEST_PLATFORM_MAEMO */
1946
1947         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1948         
1949         gchar *server_name = modest_server_account_get_hostname (
1950                 modest_runtime_get_account_mgr(), server_account_name);
1951         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
1952                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
1953                 *cancel = TRUE;
1954                 return;
1955         }
1956         
1957         /* This causes a warning because the logical ID has no %s in it, 
1958          * though the translation does, but there is not much we can do about that: */
1959         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1960         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1961                             FALSE, FALSE, 0);
1962         g_free (txt);
1963         g_free (server_name);
1964         server_name = NULL;
1965
1966         /* username: */
1967         gchar *initial_username = modest_server_account_get_username (
1968                 modest_runtime_get_account_mgr(), server_account_name);
1969         
1970         GtkWidget *entry_username = gtk_entry_new ();
1971         if (initial_username)
1972                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1973         /* Dim this if a connection has ever succeeded with this username,
1974          * as per the UI spec: */
1975         const gboolean username_known = 
1976                 modest_server_account_get_username_has_succeeded(
1977                         modest_runtime_get_account_mgr(), server_account_name);
1978         gtk_widget_set_sensitive (entry_username, !username_known);
1979         
1980 #ifdef MODEST_PLATFORM_MAEMO
1981         /* Auto-capitalization is the default, so let's turn it off: */
1982         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1983         
1984         /* Create a size group to be used by all captions.
1985          * Note that HildonCaption does not create a default size group if we do not specify one.
1986          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1987         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1988         
1989         GtkWidget *caption = hildon_caption_new (sizegroup, 
1990                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1991         gtk_widget_show (entry_username);
1992         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
1993                 FALSE, FALSE, MODEST_MARGIN_HALF);
1994         gtk_widget_show (caption);
1995 #else 
1996         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1997                             TRUE, FALSE, 0);
1998 #endif /* MODEST_PLATFORM_MAEMO */      
1999                             
2000         /* password: */
2001         GtkWidget *entry_password = gtk_entry_new ();
2002         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2003         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2004         
2005 #ifdef MODEST_PLATFORM_MAEMO
2006         /* Auto-capitalization is the default, so let's turn it off: */
2007         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2008                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2009         
2010         caption = hildon_caption_new (sizegroup, 
2011                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2012         gtk_widget_show (entry_password);
2013         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2014                 FALSE, FALSE, MODEST_MARGIN_HALF);
2015         gtk_widget_show (caption);
2016         g_object_unref (sizegroup);
2017 #else 
2018         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2019                             TRUE, FALSE, 0);
2020 #endif /* MODEST_PLATFORM_MAEMO */      
2021                                 
2022 /* This is not in the Maemo UI spec:
2023         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2024         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2025                             TRUE, FALSE, 0);
2026 */
2027
2028         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2029         
2030         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2031                 if (username) {
2032                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2033                         
2034                         modest_server_account_set_username (
2035                                  modest_runtime_get_account_mgr(), server_account_name, 
2036                                  *username);
2037                                  
2038                         const gboolean username_was_changed = 
2039                                 (strcmp (*username, initial_username) != 0);
2040                         if (username_was_changed) {
2041                                 /* To actually use a changed username, 
2042                                  * we must reset the connection, according to pvanhoof.
2043                                  * This _might_ be a sensible way to do that: */
2044                                  TnyDevice *device = modest_runtime_get_device();
2045                                  tny_device_force_offline (device);
2046                                  tny_device_force_online (device);
2047                         }
2048                 }
2049                         
2050                 if (password) {
2051                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2052                         
2053                         /* We do not save the password in the configuration, 
2054                          * because this function is only called for passwords that should 
2055                          * not be remembered:
2056                         modest_server_account_set_password (
2057                                  modest_runtime_get_account_mgr(), server_account_name, 
2058                                  *password);
2059                         */
2060                 }
2061                 
2062                 if (cancel)
2063                         *cancel   = FALSE;
2064                         
2065         } else {
2066                 if (username)
2067                         *username = NULL;
2068                         
2069                 if (password)
2070                         *password = NULL;
2071                         
2072                 if (cancel)
2073                         *cancel   = TRUE;
2074         }
2075
2076 /* This is not in the Maemo UI spec:
2077         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2078                 *remember = TRUE;
2079         else
2080                 *remember = FALSE;
2081 */
2082
2083         gtk_widget_destroy (dialog);
2084         
2085         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2086 }
2087
2088 void
2089 modest_ui_actions_on_cut (GtkAction *action,
2090                           ModestWindow *window)
2091 {
2092         GtkWidget *focused_widget;
2093
2094         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2095         if (GTK_IS_EDITABLE (focused_widget)) {
2096                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2097         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2098                 GtkTextBuffer *buffer;
2099                 GtkClipboard *clipboard;
2100
2101                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2102                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2103                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2104         }
2105 }
2106
2107 void
2108 modest_ui_actions_on_copy (GtkAction *action,
2109                            ModestWindow *window)
2110 {
2111         GtkClipboard *clipboard;
2112         GtkWidget *focused_widget;
2113
2114         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2115         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2116         if (GTK_IS_LABEL (focused_widget)) {
2117                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2118         } else if (GTK_IS_EDITABLE (focused_widget)) {
2119                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2120         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2121                 GtkTextBuffer *buffer;
2122
2123                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2124                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2125         }
2126 }
2127
2128 void
2129 modest_ui_actions_on_undo (GtkAction *action,
2130                            ModestWindow *window)
2131 {
2132         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2133                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2134         } else {
2135                 g_return_if_reached ();
2136         }
2137 }
2138
2139 void
2140 modest_ui_actions_on_paste (GtkAction *action,
2141                             ModestWindow *window)
2142 {
2143         GtkWidget *focused_widget;
2144
2145         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2146         if (GTK_IS_EDITABLE (focused_widget)) {
2147                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2148         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2149                 GtkTextBuffer *buffer;
2150                 GtkClipboard *clipboard;
2151
2152                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2153                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2154                 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2155         }
2156 }
2157
2158 void
2159 modest_ui_actions_on_select_all (GtkAction *action,
2160                                  ModestWindow *window)
2161 {
2162         GtkWidget *focused_widget;
2163
2164         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2165         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2166                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2167         } else if (GTK_IS_LABEL (focused_widget)) {
2168                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2169         } else if (GTK_IS_EDITABLE (focused_widget)) {
2170                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2171         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2172                 GtkTextBuffer *buffer;
2173                 GtkTextIter start, end;
2174
2175                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2176                 gtk_text_buffer_get_start_iter (buffer, &start);
2177                 gtk_text_buffer_get_end_iter (buffer, &end);
2178                 gtk_text_buffer_select_range (buffer, &start, &end);
2179         }
2180         else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2181                  (MODEST_IS_HEADER_VIEW (focused_widget))) {
2182                 
2183                 GtkTreeSelection *selection = NULL;
2184
2185                 /* Get header view */           
2186                 GtkWidget *header_view = focused_widget;
2187                 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2188                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2189                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2190
2191                 /* Select all messages */
2192                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2193                 gtk_tree_selection_select_all (selection);
2194         }
2195 }
2196
2197 void
2198 modest_ui_actions_on_mark_as_read (GtkAction *action,
2199                                    ModestWindow *window)
2200 {       
2201         g_return_if_fail (MODEST_IS_WINDOW(window));
2202                 
2203         /* Mark each header as read */
2204         do_headers_action (window, headers_action_mark_as_read, NULL);
2205 }
2206
2207 void
2208 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2209                                      ModestWindow *window)
2210 {       
2211         g_return_if_fail (MODEST_IS_WINDOW(window));
2212                 
2213         /* Mark each header as read */
2214         do_headers_action (window, headers_action_mark_as_unread, NULL);
2215 }
2216
2217 void
2218 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2219                                   GtkRadioAction *selected,
2220                                   ModestWindow *window)
2221 {
2222         gint value;
2223
2224         value = gtk_radio_action_get_current_value (selected);
2225         if (MODEST_IS_WINDOW (window)) {
2226                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2227         }
2228 }
2229
2230 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2231                                                         GtkRadioAction *selected,
2232                                                         ModestWindow *window)
2233 {
2234         TnyHeaderFlags flags;
2235         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2236
2237         flags = gtk_radio_action_get_current_value (selected);
2238         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2239 }
2240
2241 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2242                                                            GtkRadioAction *selected,
2243                                                            ModestWindow *window)
2244 {
2245         gint file_format;
2246
2247         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2248
2249         file_format = gtk_radio_action_get_current_value (selected);
2250         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2251 }
2252
2253
2254 void     
2255 modest_ui_actions_on_zoom_plus (GtkAction *action,
2256                                 ModestWindow *window)
2257 {
2258         g_return_if_fail (MODEST_IS_WINDOW (window));
2259
2260         modest_window_zoom_plus (MODEST_WINDOW (window));
2261 }
2262
2263 void     
2264 modest_ui_actions_on_zoom_minus (GtkAction *action,
2265                                  ModestWindow *window)
2266 {
2267         g_return_if_fail (MODEST_IS_WINDOW (window));
2268
2269         modest_window_zoom_minus (MODEST_WINDOW (window));
2270 }
2271
2272 void     
2273 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
2274                                            ModestWindow *window)
2275 {
2276         ModestWindowMgr *mgr;
2277         gboolean fullscreen, active;
2278         g_return_if_fail (MODEST_IS_WINDOW (window));
2279
2280         mgr = modest_runtime_get_window_mgr ();
2281
2282         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2283         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2284
2285         if (active != fullscreen) {
2286                 modest_window_mgr_set_fullscreen_mode (mgr, active);
2287                 gtk_window_present (GTK_WINDOW (window));
2288         }
2289 }
2290
2291 void
2292 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2293                                         ModestWindow *window)
2294 {
2295         ModestWindowMgr *mgr;
2296         gboolean fullscreen;
2297
2298         g_return_if_fail (MODEST_IS_WINDOW (window));
2299
2300         mgr = modest_runtime_get_window_mgr ();
2301         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2302         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2303
2304         gtk_window_present (GTK_WINDOW (window));
2305 }
2306
2307 /* 
2308  * Used by modest_ui_actions_on_details to call do_headers_action 
2309  */
2310 static void
2311 headers_action_show_details (TnyHeader *header, 
2312                              ModestWindow *window,
2313                              gpointer user_data)
2314
2315 {
2316         GtkWidget *dialog;
2317         
2318         /* Create dialog */
2319         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2320
2321         /* Run dialog */
2322         gtk_widget_show_all (dialog);
2323         gtk_dialog_run (GTK_DIALOG (dialog));
2324
2325         gtk_widget_destroy (dialog);
2326 }
2327
2328 /*
2329  * Show the folder details in a ModestDetailsDialog widget
2330  */
2331 static void
2332 show_folder_details (TnyFolder *folder, 
2333                      GtkWindow *window)
2334 {
2335         GtkWidget *dialog;
2336         
2337         /* Create dialog */
2338         dialog = modest_details_dialog_new_with_folder (window, folder);
2339
2340         /* Run dialog */
2341         gtk_widget_show_all (dialog);
2342         gtk_dialog_run (GTK_DIALOG (dialog));
2343
2344         gtk_widget_destroy (dialog);
2345 }
2346
2347 /*
2348  * Show the header details in a ModestDetailsDialog widget
2349  */
2350 void     
2351 modest_ui_actions_on_details (GtkAction *action, 
2352                               ModestWindow *win)
2353 {
2354         TnyList * headers_list;
2355         TnyIterator *iter;
2356         TnyHeader *header;              
2357
2358         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2359                 TnyMsg *msg;
2360
2361                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2362                 if (!msg)
2363                         return;
2364                 g_object_unref (msg);           
2365
2366                 headers_list = get_selected_headers (win);
2367                 if (!headers_list)
2368                         return;
2369
2370                 iter = tny_list_create_iterator (headers_list);
2371
2372                 header = TNY_HEADER (tny_iterator_get_current (iter));
2373                 headers_action_show_details (header, win, NULL);
2374                 g_object_unref (header);
2375
2376                 g_object_unref (iter);
2377                 g_object_unref (headers_list);
2378
2379         } else if (MODEST_IS_MAIN_WINDOW (win)) {
2380                 GtkWidget *folder_view, *header_view;
2381
2382                 /* Check which widget has the focus */
2383                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2384                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
2385                 if (gtk_widget_is_focus (folder_view)) {
2386                         TnyFolder *folder;
2387
2388                         folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2389
2390                         /* Show only when it's a folder */
2391                         if (!folder || !TNY_IS_FOLDER (folder))
2392                                 return;
2393
2394                         show_folder_details (folder, GTK_WINDOW (win));
2395
2396                 } else {
2397                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2398                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2399                         /* Show details of each header */
2400                         do_headers_action (win, headers_action_show_details, header_view);
2401                 }
2402         }
2403 }
2404
2405 void     
2406 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2407                                      ModestMsgEditWindow *window)
2408 {
2409         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2410
2411         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2412 }
2413
2414 void     
2415 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2416                                       ModestMsgEditWindow *window)
2417 {
2418         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2419
2420         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2421 }
2422
2423 void
2424 modest_ui_actions_toggle_folders_view (GtkAction *action, 
2425                                        ModestMainWindow *main_window)
2426 {
2427         ModestConf *conf;
2428         
2429         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2430
2431         conf = modest_runtime_get_conf ();
2432         
2433         if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2434                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2435         else
2436                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2437 }
2438
2439 void 
2440 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
2441                                      ModestWindow *window)
2442 {
2443         gboolean active, fullscreen = FALSE;
2444         ModestWindowMgr *mgr;
2445
2446         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2447
2448         /* Check if we want to toggle the toolbar vuew in fullscreen
2449            or normal mode */
2450         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
2451                      "ViewShowToolbarFullScreen")) {
2452                 fullscreen = TRUE;
2453         }
2454
2455         /* Toggle toolbar */
2456         mgr = modest_runtime_get_window_mgr ();
2457         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2458 }
2459
2460 void     
2461 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2462                                            ModestMsgEditWindow *window)
2463 {
2464         modest_msg_edit_window_select_font (window);
2465 }
2466
2467 void
2468 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2469                                                   const gchar *display_name,
2470                                                   GtkWindow *window)
2471 {
2472         /* Do not change the application name if the widget has not
2473            the focus. This callback could be called even if the folder
2474            view has not the focus, because the handled signal could be
2475            emitted when the folder view is redrawn */
2476         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2477                 if (display_name)
2478                         gtk_window_set_title (window, display_name);
2479                 else
2480                         gtk_window_set_title (window, " ");
2481         }
2482 }
2483
2484 void
2485 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2486 {
2487         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2488         modest_msg_edit_window_select_contacts (window);
2489 }
2490
2491 void
2492 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2493 {
2494         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2495         modest_msg_edit_window_check_names (window);
2496 }
2497
2498
2499 static GtkWidget*
2500 create_move_to_dialog (ModestWindow *win,
2501                        GtkWidget *folder_view,
2502                        GtkWidget **tree_view)
2503 {
2504         GtkWidget *dialog, *scroll;
2505
2506         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2507                                               GTK_WINDOW (win),
2508                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2509                                               GTK_STOCK_OK,
2510                                               GTK_RESPONSE_ACCEPT,
2511                                               GTK_STOCK_CANCEL,
2512                                               GTK_RESPONSE_REJECT,
2513                                               NULL);
2514
2515         /* Create scrolled window */
2516         scroll = gtk_scrolled_window_new (NULL, NULL);
2517         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
2518                                          GTK_POLICY_AUTOMATIC,
2519                                          GTK_POLICY_AUTOMATIC);
2520
2521         /* Create folder view */
2522         *tree_view = modest_folder_view_new (NULL);
2523
2524         /* It could happen that we're trying to move a message from a
2525            window (msg window for example) after the main window was
2526            closed, so we can not just get the model of the folder
2527            view */
2528         if (MODEST_IS_FOLDER_VIEW (folder_view))
2529                 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2530                                          gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2531         else
2532                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
2533                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2534
2535         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2536
2537         /* Add scroll to dialog */
2538         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
2539                             scroll, FALSE, FALSE, 0);
2540
2541         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2542
2543         return dialog;
2544 }
2545
2546 /*
2547  * Returns TRUE if at least one of the headers of the list belongs to
2548  * a message that has been fully retrieved.
2549  */
2550 static gboolean
2551 has_retrieved_msgs (TnyList *list)
2552 {
2553         TnyIterator *iter;
2554         gboolean found = FALSE;
2555
2556         iter = tny_list_create_iterator (list);
2557         while (tny_iterator_is_done (iter) && !found) {
2558                 TnyHeader *header;
2559                 TnyHeaderFlags flags;
2560
2561                 header = TNY_HEADER (tny_iterator_get_current (iter));
2562                 flags = tny_header_get_flags (header);
2563                 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2564                         found = TRUE;
2565
2566                 if (!found)
2567                         tny_iterator_next (iter);
2568         }
2569         g_object_unref (iter);
2570
2571         return found;
2572 }
2573
2574 /*
2575  * Shows a confirmation dialog to the user when we're moving messages
2576  * from a remote server to the local storage. Returns the dialog
2577  * response. If it's other kind of movement the it always returns
2578  * GTK_RESPONSE_OK
2579  */
2580 static gint
2581 msgs_move_to_confirmation (GtkWindow *win,
2582                            TnyFolder *dest_folder,
2583                            TnyList *headers)
2584 {
2585         gint response = GTK_RESPONSE_OK;
2586
2587         /* If the destination is a local folder */
2588         if (modest_tny_folder_is_local_folder (dest_folder)) {
2589                 TnyFolder *src_folder;
2590                 TnyIterator *iter;
2591                 TnyHeader *header;
2592
2593                 /* Get source folder */
2594                 iter = tny_list_create_iterator (headers);
2595                 header = TNY_HEADER (tny_iterator_get_current (iter));
2596                 src_folder = tny_header_get_folder (header);
2597                 g_object_unref (header);
2598                 g_object_unref (iter);
2599
2600                 /* If the source is a remote folder */
2601                 if (!modest_tny_folder_is_local_folder (src_folder)) {
2602                         const gchar *message;
2603                         
2604                         if (tny_list_get_length (headers) == 1)
2605                                 if (has_retrieved_msgs (headers))
2606                                         message = _("mcen_nc_move_retrieve");
2607                                 else
2608                                         message = _("mcen_nc_move_header");
2609                         else
2610                                 if (has_retrieved_msgs (headers))
2611                                         message = _("mcen_nc_move_retrieves");
2612                                 else
2613                                         message = _("mcen_nc_move_headers");
2614                         
2615                         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2616                                                                             (const gchar *) message);
2617                 }
2618                 g_object_unref (src_folder);
2619         }
2620         return response;
2621 }
2622
2623
2624 static void
2625 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2626 {
2627         ModestMsgViewWindow *self = NULL;
2628         gboolean found = FALSE;
2629
2630         g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2631         self = MODEST_MSG_VIEW_WINDOW (object);
2632
2633         found = modest_msg_view_window_select_first_message (self);
2634         g_return_if_fail (found);
2635 }
2636
2637 void
2638 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
2639                                              gpointer user_data)
2640 {
2641         GObject *win = modest_mail_operation_get_source (mail_op);
2642
2643         /* TODO: show error message */
2644         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2645                                                 _("mail_in_ui_folder_move_target_error"));
2646 }
2647
2648 /*
2649  * UI handler for the "Move to" action when invoked from the
2650  * ModestMainWindow
2651  */
2652 static void 
2653 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
2654                                           ModestMainWindow *win)
2655 {
2656         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2657         GtkWidget *header_view = NULL;
2658         gint result;
2659         TnyFolderStore *folder_store = NULL;
2660         ModestMailOperation *mail_op = NULL;
2661
2662         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2663
2664         /* Get the folder view */
2665         folder_view = modest_main_window_get_child_widget (win,
2666                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2667
2668         /* Get header view */
2669         header_view = modest_main_window_get_child_widget (win,
2670                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2671
2672         /* Create and run the dialog */
2673         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2674         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2675         result = gtk_dialog_run (GTK_DIALOG(dialog));
2676         g_object_ref (tree_view);
2677
2678         /* We do this to save an indentation level ;-) */
2679         if (result != GTK_RESPONSE_ACCEPT)
2680                 goto end;
2681
2682         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2683
2684         if (TNY_IS_ACCOUNT (folder_store))
2685                 goto end;
2686
2687         /* Get folder or messages to transfer */
2688         if (gtk_widget_is_focus (folder_view)) {
2689                 TnyFolderStore *src_folder;
2690                 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2691
2692                 /* Clean folder on header view before moving it */
2693                 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL); 
2694
2695                 if (TNY_IS_FOLDER (src_folder)) {
2696                         mail_op = 
2697                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
2698                                                                                G_OBJECT(win),
2699                                                                                modest_ui_actions_move_folder_error_handler,
2700                                                                                NULL);
2701                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2702
2703                         modest_mail_operation_xfer_folder (mail_op, 
2704                                                            TNY_FOLDER (src_folder),
2705                                                            folder_store,
2706                                                            TRUE);
2707                         /* Unref mail operation */
2708                         g_object_unref (G_OBJECT (mail_op));
2709                 }
2710
2711                 /* Frees */
2712                 g_object_unref (G_OBJECT (src_folder));
2713         } else {
2714                 if (gtk_widget_is_focus (header_view)) {
2715                         TnyList *headers;
2716                         gint response;
2717
2718                         headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2719
2720                         /* Ask for user confirmation */
2721                         response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2722                                                               TNY_FOLDER (folder_store), 
2723                                                               headers);
2724
2725                         /* Transfer messages */
2726                         if (response == GTK_RESPONSE_OK) {
2727                                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2728                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2729                                                                  mail_op);
2730
2731                                 modest_mail_operation_xfer_msgs (mail_op, 
2732                                                                  headers,
2733                                                                  TNY_FOLDER (folder_store),
2734                                                                  TRUE,
2735                                                                  NULL,
2736                                                                  NULL);
2737
2738                                 g_object_unref (G_OBJECT (mail_op));
2739                         }
2740                         g_object_unref (headers);
2741                 }
2742         }
2743         g_object_unref (folder_store);
2744  end:
2745         gtk_widget_destroy (dialog);
2746 }
2747
2748
2749 /*
2750  * UI handler for the "Move to" action when invoked from the
2751  * ModestMsgViewWindow
2752  */
2753 static void 
2754 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
2755                                               ModestMsgViewWindow *win)
2756 {
2757         GtkWidget *dialog, *folder_view, *tree_view = NULL;
2758         gint result;
2759         ModestMainWindow *main_window;
2760         TnyHeader *header;
2761         TnyList *headers;
2762
2763         /* Get the folder view */
2764         main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2765         if (main_window)
2766                 folder_view = modest_main_window_get_child_widget (main_window,
2767                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
2768         else
2769                 folder_view = NULL;
2770
2771         /* Create and run the dialog */
2772         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);  
2773         result = gtk_dialog_run (GTK_DIALOG(dialog));
2774         g_object_ref (tree_view);
2775
2776         if (result == GTK_RESPONSE_ACCEPT) {
2777                 TnyFolderStore *folder_store;
2778                 gint response;
2779
2780                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2781
2782                 /* Create header list */
2783                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
2784                 headers = tny_simple_list_new ();
2785                 tny_list_prepend (headers, G_OBJECT (header));
2786                 g_object_unref (header);
2787
2788                 /* Ask user for confirmation. MSG-NOT404 */
2789                 response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2790                                                       TNY_FOLDER (folder_store), 
2791                                                       headers);
2792
2793                 /* Transfer current msg */
2794                 if (response == GTK_RESPONSE_OK) {
2795                         ModestMailOperation *mail_op;
2796
2797                         /* Create mail op */
2798                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2799                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2800                                                          mail_op);
2801                         
2802                         /* Transfer messages */
2803                         modest_mail_operation_xfer_msgs (mail_op, 
2804                                                          headers,
2805                                                          TNY_FOLDER (folder_store),
2806                                                          TRUE,
2807                                                          tranasfer_msgs_from_viewer_cb,
2808                                                          NULL);
2809                         g_object_unref (G_OBJECT (mail_op));
2810                 }
2811                 g_object_unref (headers);
2812                 g_object_unref (folder_store);
2813         }
2814         gtk_widget_destroy (dialog);
2815 }
2816
2817 void 
2818 modest_ui_actions_on_move_to (GtkAction *action, 
2819                               ModestWindow *win)
2820 {
2821         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2822                           MODEST_IS_MSG_VIEW_WINDOW (win));
2823
2824         if (MODEST_IS_MAIN_WINDOW (win)) 
2825                 modest_ui_actions_on_main_window_move_to (action, 
2826                                                           MODEST_MAIN_WINDOW (win));
2827         else
2828                 modest_ui_actions_on_msg_view_window_move_to (action, 
2829                                                               MODEST_MSG_VIEW_WINDOW (win));
2830 }
2831
2832 /*
2833  * Calls #HeadersFunc for each header already selected in the main
2834  * window or the message currently being shown in the msg view window
2835  */
2836 static void
2837 do_headers_action (ModestWindow *win, 
2838                    HeadersFunc func,
2839                    gpointer user_data)
2840 {
2841         TnyList *headers_list;
2842         TnyIterator *iter;
2843
2844         /* Get headers */
2845         headers_list = get_selected_headers (win);
2846         if (!headers_list)
2847                 return;
2848
2849         /* Call the function for each header */
2850         iter = tny_list_create_iterator (headers_list);
2851         while (!tny_iterator_is_done (iter)) {
2852                 TnyHeader *header;
2853
2854                 header = TNY_HEADER (tny_iterator_get_current (iter));
2855                 func (header, win, user_data);
2856                 g_object_unref (header);
2857                 tny_iterator_next (iter);
2858         }
2859         g_object_unref (iter);
2860         g_object_unref (headers_list);
2861 }
2862
2863 void 
2864 modest_ui_actions_view_attachment (GtkAction *action,
2865                                    ModestWindow *window)
2866 {
2867         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2868                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2869         } else {
2870                 /* not supported window for this action */
2871                 g_return_if_reached ();
2872         }
2873 }
2874
2875 void
2876 modest_ui_actions_save_attachments (GtkAction *action,
2877                                     ModestWindow *window)
2878 {
2879         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2880                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2881         } else {
2882                 /* not supported window for this action */
2883                 g_return_if_reached ();
2884         }
2885 }
2886
2887 void
2888 modest_ui_actions_remove_attachments (GtkAction *action,
2889                                       ModestWindow *window)
2890 {
2891         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2892                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2893         } else {
2894                 /* not supported window for this action */
2895                 g_return_if_reached ();
2896         }
2897 }
2898
2899 void 
2900 modest_ui_actions_on_settings (GtkAction *action, 
2901                                ModestWindow *win)
2902 {
2903         GtkWidget *dialog;
2904
2905         dialog = modest_platform_get_global_settings_dialog ();
2906         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2907         gtk_widget_show (dialog);
2908
2909         gtk_dialog_run (GTK_DIALOG (dialog));
2910
2911         gtk_widget_destroy (dialog);
2912 }
2913
2914 void 
2915 modest_ui_actions_on_help (GtkAction *action, 
2916                            ModestWindow *win)
2917 {
2918         const gchar *help_id = NULL;
2919
2920         if (MODEST_IS_MAIN_WINDOW (win)) {
2921                 const gchar *action_name;
2922                 action_name = gtk_action_get_name (action);
2923
2924                 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2925                     !strcmp (action_name, "HeaderViewCSMHelp")) {
2926                         GtkWidget *folder_view;
2927                         TnyFolderStore *folder_store;
2928                         /* Get selected folder */
2929                         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2930                                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2931                         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2932
2933                         /* Switch help_id */
2934                         if (TNY_IS_FOLDER (folder_store)) {
2935                                 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2936                                 case TNY_FOLDER_TYPE_NORMAL:
2937                                         help_id = "applications_email_userfolder";
2938                                         break;
2939                                 case TNY_FOLDER_TYPE_INBOX:
2940                                         help_id = "applications_email_inbox";
2941                                         break;
2942                                 case TNY_FOLDER_TYPE_OUTBOX:
2943                                         help_id = "applications_email_outbox";
2944                                         break;
2945                                 case TNY_FOLDER_TYPE_SENT:
2946                                         help_id = "applications_email_sent";
2947                                         break;
2948                                 case TNY_FOLDER_TYPE_DRAFTS:
2949                                         help_id = "applications_email_drafts";
2950                                         break;
2951                                 case TNY_FOLDER_TYPE_ARCHIVE:
2952                                         help_id = "applications_email_archive";
2953                                         break;
2954                                 default:
2955                                         help_id = NULL;
2956                                 }
2957                         }
2958                 } else {
2959                         help_id = "applications_email_mainview";        
2960                 }
2961         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2962                 help_id = "applications_email_viewer";
2963         } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2964                 help_id = "applications_email_editor";
2965
2966         modest_platform_show_help (GTK_WINDOW (win), help_id);
2967 }
2968
2969 void 
2970 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2971                                             ModestWindow *window)
2972 {
2973         ModestMailOperation *mail_op;
2974         TnyList *headers;
2975
2976         /* Get headers */
2977         headers = get_selected_headers (window);
2978         if (!headers)
2979                 return;
2980
2981         /* Create mail operation */
2982         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
2983                                                                  G_OBJECT (window),
2984                                                                  modest_ui_actions_get_msgs_full_error_handler, 
2985                                                                  NULL);
2986         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2987         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2988
2989         /* Frees */
2990         g_object_unref (headers);
2991         g_object_unref (mail_op);
2992 }
2993
2994 void
2995 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2996                                           ModestWindow *window)
2997 {
2998         g_return_if_fail (MODEST_IS_WINDOW (window));
2999
3000         /* Update dimmed */     
3001         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3002 }
3003
3004 void
3005 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3006                                           ModestWindow *window)
3007 {
3008         g_return_if_fail (MODEST_IS_WINDOW (window));
3009
3010         /* Update dimmed */     
3011         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3012 }
3013
3014 void
3015 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3016                                                  ModestWindow *window)
3017 {
3018         g_return_if_fail (MODEST_IS_WINDOW (window));
3019
3020         /* Update dimmed */     
3021         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3022 }
3023
3024 void
3025 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3026                                                      ModestWindow *window)
3027 {
3028         g_return_if_fail (MODEST_IS_WINDOW (window));
3029
3030         /* Update dimmed */     
3031         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3032 }
3033
3034 void
3035 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3036                                                      ModestWindow *window)
3037 {
3038         g_return_if_fail (MODEST_IS_WINDOW (window));
3039
3040         /* Update dimmed */     
3041         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3042 }
3043
3044 void
3045 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3046 {
3047         g_return_if_fail (MODEST_IS_WINDOW (window));
3048
3049         /* Update dimmed */     
3050         modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");  
3051 }
3052
3053 void
3054 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3055 {
3056         g_return_if_fail (MODEST_IS_WINDOW (window));
3057
3058         modest_platform_show_search_messages (GTK_WINDOW (window));
3059 }
3060
3061 void     
3062 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3063 {
3064         g_return_if_fail (MODEST_IS_WINDOW (win));
3065         modest_platform_show_addressbook (GTK_WINDOW (win));
3066 }
3067
3068
3069 void
3070 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3071                                           ModestWindow *window)
3072 {
3073         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3074
3075         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3076 }
3077
3078 static void 
3079 _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
3080                                    ModestMailOperationState *state,
3081                                    gpointer user_data)
3082 {
3083         g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3084
3085         /* Set send/receive operation finished */       
3086         if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3087                 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
3088         
3089 }