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