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