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