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