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