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