98748fa7b87404bc9260ef07729d6b6382ce54b3
[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 focus */
1232         if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1233             gtk_widget_grab_focus (GTK_WIDGET(header_view));
1234
1235         /* Update Main window title */
1236         if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1237                 const gchar *subject = tny_header_get_subject (header);
1238                 if (subject && strlen(subject) > 0)
1239                         gtk_window_set_title (GTK_WINDOW (main_window), subject);
1240                 else
1241                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1242         }
1243
1244         /* Update toolbar dimming state */
1245         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1246 }
1247
1248 void
1249 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1250                                        TnyHeader *header,
1251                                        ModestMainWindow *main_window)
1252 {
1253         TnyList *headers;
1254
1255         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1256         
1257         if (!header)
1258                 return;
1259
1260         headers = tny_simple_list_new ();
1261         tny_list_prepend (headers, G_OBJECT (header));
1262
1263         _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1264
1265         g_object_unref (headers);
1266 }
1267
1268 static void
1269 set_active_account_from_tny_account (TnyAccount *account,
1270                                      ModestWindow *window)
1271 {
1272         const gchar *server_acc_name = tny_account_get_id (account);
1273         
1274         /* We need the TnyAccount provided by the
1275            account store because that is the one that
1276            knows the name of the Modest account */
1277         TnyAccount *modest_server_account = modest_server_account = 
1278                 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1279                                                              MODEST_TNY_ACCOUNT_STORE_QUERY_ID, 
1280                                                              server_acc_name);
1281         
1282         const gchar *modest_acc_name = 
1283                 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1284         modest_window_set_active_account (window, modest_acc_name);
1285         g_object_unref (modest_server_account);
1286 }
1287
1288
1289 static void
1290 folder_refreshed_cb (const GObject *obj, 
1291                      TnyFolder *folder, 
1292                      gpointer user_data)
1293 {
1294         ModestMainWindow *win = NULL;
1295         GtkWidget *header_view;
1296
1297         g_return_if_fail (TNY_IS_FOLDER (folder));
1298
1299         win = MODEST_MAIN_WINDOW (user_data);
1300         header_view = 
1301                 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1302
1303         /* Check if folder is empty and set headers view contents style */
1304         if (tny_folder_get_all_count (folder) == 0) {
1305         printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1306                 modest_main_window_set_contents_style (win,
1307                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1308         } else {
1309                 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1310         }
1311 }
1312
1313 void 
1314 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1315                                                TnyFolderStore *folder_store, 
1316                                                gboolean selected,
1317                                                ModestMainWindow *main_window)
1318 {
1319         ModestConf *conf;
1320         GtkWidget *header_view;
1321
1322         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1323
1324         header_view = modest_main_window_get_child_widget(main_window,
1325                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
1326         if (!header_view)
1327                 return;
1328         
1329         conf = modest_runtime_get_conf ();
1330
1331         if (TNY_IS_ACCOUNT (folder_store)) {
1332                 if (selected) {
1333                         /* Update active account */
1334                         set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1335                         /* Show account details */
1336                         modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1337                 }
1338         } else {
1339                 if (TNY_IS_FOLDER (folder_store) && selected) {
1340                         
1341                         /* Update the active account */
1342                         TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1343                         if (account) {
1344                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1345                                 g_object_unref (account);
1346                                 account = NULL;
1347                         }
1348
1349                         /* Set the header style by default, it could
1350                            be changed later by the refresh callback to
1351                            empty */
1352                         modest_main_window_set_contents_style (main_window, 
1353                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1354
1355                         /* Set folder on header view. This function
1356                            will call tny_folder_refresh_async so we
1357                            pass a callback that will be called when
1358                            finished. We use that callback to set the
1359                            empty view if there are no messages */
1360                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1361                                                        TNY_FOLDER (folder_store),
1362                                                        folder_refreshed_cb,
1363                                                        main_window);
1364                         
1365                         /* Restore configuration. We need to do this
1366                            *after* the set_folder because the widget
1367                            memory asks the header view about its
1368                            folder  */
1369                         modest_widget_memory_restore (modest_runtime_get_conf (), 
1370                                                       G_OBJECT(header_view),
1371                                                       MODEST_CONF_HEADER_VIEW_KEY);
1372                 } else {
1373                         /* Update the active account */
1374                         modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1375                         /* Save only if we're seeing headers */
1376                         if (modest_main_window_get_contents_style (main_window) ==
1377                             MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1378                                 modest_widget_memory_save (conf, G_OBJECT (header_view), 
1379                                                            MODEST_CONF_HEADER_VIEW_KEY);
1380                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1381                 }
1382         }
1383
1384         /* Update toolbar dimming state */
1385         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1386 }
1387
1388 void 
1389 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1390                                      ModestWindow *win)
1391 {
1392         GtkWidget *dialog;
1393         gchar *txt, *item;
1394         gboolean online;
1395
1396         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1397         
1398         if (g_main_depth > 0)   
1399                 gdk_threads_enter ();
1400         online = tny_device_is_online (modest_runtime_get_device());
1401
1402         if (online) {
1403                 /* already online -- the item is simply not there... */
1404                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1405                                                  GTK_DIALOG_MODAL,
1406                                                  GTK_MESSAGE_WARNING,
1407                                                  GTK_BUTTONS_OK,
1408                                                  _("The %s you selected cannot be found"),
1409                                                  item);
1410                 gtk_dialog_run (GTK_DIALOG(dialog));
1411         } else {
1412                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1413                                                       GTK_WINDOW (win),
1414                                                       GTK_DIALOG_MODAL,
1415                                                       GTK_STOCK_CANCEL,
1416                                                       GTK_RESPONSE_REJECT,
1417                                                       GTK_STOCK_OK,
1418                                                       GTK_RESPONSE_ACCEPT,
1419                                                       NULL);
1420                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1421                                          "Do you want to get online?"), item);
1422                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1423                                     gtk_label_new (txt), FALSE, FALSE, 0);
1424                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1425                 g_free (txt);
1426
1427                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1428                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1429 //                      modest_platform_connect_and_wait ();
1430                 }
1431         }
1432         gtk_widget_destroy (dialog);
1433         if (g_main_depth > 0)   
1434                 gdk_threads_leave ();
1435 }
1436
1437 void
1438 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1439                                      ModestWindow *win)
1440 {
1441         /* g_message ("%s %s", __FUNCTION__, link); */
1442 }       
1443
1444
1445 void
1446 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1447                                         ModestWindow *win)
1448 {
1449         modest_platform_activate_uri (link);
1450 }
1451
1452 void
1453 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1454                                           ModestWindow *win)
1455 {
1456         modest_platform_show_uri_popup (link);
1457 }
1458
1459 void
1460 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1461                                              ModestWindow *win)
1462 {
1463         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1464 }
1465
1466 void
1467 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1468                                           const gchar *address,
1469                                           ModestWindow *win)
1470 {
1471         /* g_message ("%s %s", __FUNCTION__, address); */
1472 }
1473
1474 void
1475 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1476 {
1477         TnyTransportAccount *transport_account;
1478         ModestMailOperation *mail_operation;
1479         MsgData *data;
1480         gchar *account_name, *from;
1481         ModestAccountMgr *account_mgr;
1482         gchar *info_text = NULL;
1483
1484         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1485         
1486         data = modest_msg_edit_window_get_msg_data (edit_window);
1487
1488         account_mgr = modest_runtime_get_account_mgr();
1489         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1490         if (!account_name) 
1491                 account_name = modest_account_mgr_get_default_account (account_mgr);
1492         if (!account_name) {
1493                 g_printerr ("modest: no account found\n");
1494                 modest_msg_edit_window_free_msg_data (edit_window, data);
1495                 return;
1496         }
1497
1498         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1499                 account_name = g_strdup (data->account_name);
1500         }
1501
1502         transport_account =
1503                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1504                                       (modest_runtime_get_account_store(),
1505                                        account_name,
1506                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1507         if (!transport_account) {
1508                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1509                 g_free (account_name);
1510                 modest_msg_edit_window_free_msg_data (edit_window, data);
1511                 return;
1512         }
1513         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1514
1515         /* Create the mail operation */         
1516         mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1517         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1518
1519         modest_mail_operation_save_to_drafts (mail_operation,
1520                                               transport_account,
1521                                               data->draft_msg,
1522                                               from,
1523                                               data->to, 
1524                                               data->cc, 
1525                                               data->bcc,
1526                                               data->subject, 
1527                                               data->plain_body, 
1528                                               data->html_body,
1529                                               data->attachments,
1530                                               data->priority_flags);
1531         /* Frees */
1532         g_free (from);
1533         g_free (account_name);
1534         g_object_unref (G_OBJECT (transport_account));
1535         g_object_unref (G_OBJECT (mail_operation));
1536
1537         modest_msg_edit_window_free_msg_data (edit_window, data);
1538
1539         info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1540         modest_platform_information_banner (NULL, NULL, info_text);
1541         g_free (info_text);
1542
1543         /* Save settings and close the window */
1544         gtk_widget_destroy (GTK_WIDGET (edit_window));
1545 }
1546
1547 /* For instance, when clicking the Send toolbar button when editing a message: */
1548 void
1549 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1550 {
1551         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1552
1553         if (!modest_msg_edit_window_check_names (edit_window))
1554                 return;
1555         
1556         /* FIXME: Code added just for testing. The final version will
1557            use the send queue provided by tinymail and some
1558            classifier */
1559         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1560         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1561         if (!account_name) 
1562                 account_name = modest_account_mgr_get_default_account (account_mgr);
1563                 
1564         if (!account_name) {
1565                 g_printerr ("modest: no account found\n");
1566                 return;
1567         }
1568         
1569         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1570
1571         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1572                 account_name = g_strdup (data->account_name);
1573         }
1574         
1575         /* Get the currently-active transport account for this modest account: */
1576         TnyTransportAccount *transport_account =
1577                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1578                                       (modest_runtime_get_account_store(),
1579                                        account_name));
1580         if (!transport_account) {
1581                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1582                 g_free (account_name);
1583                 modest_msg_edit_window_free_msg_data (edit_window, data);
1584                 return;
1585         }
1586         
1587         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1588
1589         /* mail content checks and dialogs */
1590         if (data->subject == NULL || data->subject[0] == '\0') {
1591                 GtkResponseType response;
1592                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1593                                                                     _("mcen_nc_subject_is_empty_send"));
1594                 if (response == GTK_RESPONSE_CANCEL) {
1595                         g_free (account_name);
1596                         return;
1597                 }
1598         }
1599
1600         if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1601                 GtkResponseType response;
1602                 gchar *note_message;
1603                 gchar *note_subject = data->subject;
1604                 if (note_subject == NULL || note_subject[0] == '\0')
1605                         note_subject = _("mail_va_no_subject");
1606                 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1607                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1608                                                                     note_message);
1609                 g_free (note_message);
1610                 if (response == GTK_RESPONSE_CANCEL) {
1611                         g_free (account_name);
1612                         return;
1613                 }
1614         }
1615
1616         modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1617
1618         /* Create the mail operation */
1619         ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1620         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1621
1622         modest_mail_operation_send_new_mail (mail_operation,
1623                                              transport_account,
1624                                              data->draft_msg,
1625                                              from,
1626                                              data->to, 
1627                                              data->cc, 
1628                                              data->bcc,
1629                                              data->subject, 
1630                                              data->plain_body, 
1631                                              data->html_body,
1632                                              data->attachments,
1633                                              data->priority_flags);
1634                                              
1635         /* Free data: */
1636         g_free (from);
1637         g_free (account_name);
1638         g_object_unref (G_OBJECT (transport_account));
1639         g_object_unref (G_OBJECT (mail_operation));
1640
1641         modest_msg_edit_window_free_msg_data (edit_window, data);
1642
1643         /* Save settings and close the window: */
1644         gtk_widget_destroy (GTK_WIDGET (edit_window));
1645 }
1646
1647 void 
1648 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1649                                   ModestMsgEditWindow *window)
1650 {
1651         ModestMsgEditFormatState *format_state = NULL;
1652
1653         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1654         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1655
1656         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1657                 return;
1658
1659         format_state = modest_msg_edit_window_get_format_state (window);
1660         g_return_if_fail (format_state != NULL);
1661
1662         format_state->bold = gtk_toggle_action_get_active (action);
1663         modest_msg_edit_window_set_format_state (window, format_state);
1664         g_free (format_state);
1665         
1666 }
1667
1668 void 
1669 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1670                                      ModestMsgEditWindow *window)
1671 {
1672         ModestMsgEditFormatState *format_state = NULL;
1673
1674         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1675         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1676
1677         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1678                 return;
1679
1680         format_state = modest_msg_edit_window_get_format_state (window);
1681         g_return_if_fail (format_state != NULL);
1682
1683         format_state->italics = gtk_toggle_action_get_active (action);
1684         modest_msg_edit_window_set_format_state (window, format_state);
1685         g_free (format_state);
1686         
1687 }
1688
1689 void 
1690 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1691                                      ModestMsgEditWindow *window)
1692 {
1693         ModestMsgEditFormatState *format_state = NULL;
1694
1695         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1696         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1697
1698         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1699                 return;
1700
1701         format_state = modest_msg_edit_window_get_format_state (window);
1702         g_return_if_fail (format_state != NULL);
1703
1704         format_state->bullet = gtk_toggle_action_get_active (action);
1705         modest_msg_edit_window_set_format_state (window, format_state);
1706         g_free (format_state);
1707         
1708 }
1709
1710 void 
1711 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1712                                      GtkRadioAction *selected,
1713                                      ModestMsgEditWindow *window)
1714 {
1715         ModestMsgEditFormatState *format_state = NULL;
1716         GtkJustification value;
1717
1718         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1719
1720         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1721                 return;
1722
1723         value = gtk_radio_action_get_current_value (selected);
1724
1725         format_state = modest_msg_edit_window_get_format_state (window);
1726         g_return_if_fail (format_state != NULL);
1727
1728         format_state->justification = value;
1729         modest_msg_edit_window_set_format_state (window, format_state);
1730         g_free (format_state);
1731 }
1732
1733 void 
1734 modest_ui_actions_on_select_editor_color (GtkAction *action,
1735                                           ModestMsgEditWindow *window)
1736 {
1737         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1738         g_return_if_fail (GTK_IS_ACTION (action));
1739
1740         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1741                 return;
1742
1743         modest_msg_edit_window_select_color (window);
1744 }
1745
1746 void 
1747 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1748                                                      ModestMsgEditWindow *window)
1749 {
1750         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1751         g_return_if_fail (GTK_IS_ACTION (action));
1752
1753         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1754                 return;
1755
1756         modest_msg_edit_window_select_background_color (window);
1757 }
1758
1759 void 
1760 modest_ui_actions_on_insert_image (GtkAction *action,
1761                                    ModestMsgEditWindow *window)
1762 {
1763         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1764         g_return_if_fail (GTK_IS_ACTION (action));
1765
1766         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1767                 return;
1768
1769         modest_msg_edit_window_insert_image (window);
1770 }
1771
1772 void 
1773 modest_ui_actions_on_attach_file (GtkAction *action,
1774                                   ModestMsgEditWindow *window)
1775 {
1776         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1777         g_return_if_fail (GTK_IS_ACTION (action));
1778
1779         modest_msg_edit_window_attach_file (window);
1780 }
1781
1782 void 
1783 modest_ui_actions_on_remove_attachments (GtkAction *action,
1784                                          ModestMsgEditWindow *window)
1785 {
1786         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1787         g_return_if_fail (GTK_IS_ACTION (action));
1788
1789         modest_msg_edit_window_remove_attachments (window, NULL);
1790 }
1791
1792 void 
1793 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1794 {
1795         TnyFolderStore *parent_folder;
1796         GtkWidget *folder_view;
1797         
1798         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1799
1800         folder_view = modest_main_window_get_child_widget (main_window,
1801                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1802         if (!folder_view)
1803                 return;
1804
1805         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1806         
1807         if (parent_folder) {
1808                 gboolean finished = FALSE;
1809                 gint result;
1810                 gchar *folder_name = NULL, *suggested_name = NULL;
1811
1812                 /* Run the new folder dialog */
1813                 while (!finished) {
1814                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1815                                                                         parent_folder,
1816                                                                         suggested_name,
1817                                                                         &folder_name);
1818
1819                         if (result == GTK_RESPONSE_REJECT) {
1820                                 finished = TRUE;
1821                         } else {
1822                                 ModestMailOperation *mail_op;
1823                                 TnyFolder *new_folder = NULL;
1824
1825                                 mail_op  = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, 
1826                                                                       G_OBJECT(main_window));
1827                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
1828                                                                  mail_op);
1829                                 new_folder = modest_mail_operation_create_folder (mail_op,
1830                                                                                   parent_folder,
1831                                                                                   (const gchar *) folder_name);
1832                                 if (new_folder) {
1833                                         g_object_unref (new_folder);
1834                                         finished = TRUE;
1835                                 }
1836                                 g_object_unref (mail_op);
1837                         }
1838                         g_free (folder_name);
1839                         folder_name = NULL;
1840                 }
1841
1842                 g_object_unref (parent_folder);
1843         }
1844 }
1845
1846 void 
1847 modest_ui_actions_on_rename_folder (GtkAction *action,
1848                                      ModestMainWindow *main_window)
1849 {
1850         TnyFolderStore *folder;
1851         GtkWidget *folder_view;
1852         GtkWidget *header_view; 
1853
1854         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1855
1856         folder_view = modest_main_window_get_child_widget (main_window,
1857                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1858         if (!folder_view)
1859                 return;
1860
1861         header_view = modest_main_window_get_child_widget (main_window,
1862                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1863         
1864         if (!header_view)
1865                 return;
1866
1867         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1868         
1869         if (folder && TNY_IS_FOLDER (folder)) {
1870                 gchar *folder_name;
1871                 gint response;
1872                 const gchar *current_name;
1873
1874                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1875                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
1876                                                                      current_name, &folder_name);
1877
1878                 if (response == GTK_RESPONSE_OK && strlen (folder_name) > 0) {
1879                         ModestMailOperation *mail_op;
1880
1881                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1882                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1883                                                          mail_op);
1884
1885                         modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1886
1887                         modest_mail_operation_rename_folder (mail_op,
1888                                                              TNY_FOLDER (folder),
1889                                                              (const gchar *) folder_name);
1890
1891                         g_object_unref (mail_op);
1892                         g_free (folder_name);
1893                 }
1894                 g_object_unref (folder);
1895         }
1896 }
1897
1898 static void
1899 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1900                                                gpointer user_data)
1901 {
1902         GObject *win = modest_mail_operation_get_source (mail_op);
1903
1904         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1905                                                 _("mail_in_ui_folder_delete_error"));
1906         g_object_unref (win);
1907 }
1908
1909 static void
1910 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
1911 {
1912         TnyFolderStore *folder;
1913         GtkWidget *folder_view;
1914         gint response;
1915         gchar *message;
1916         
1917         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1918
1919         folder_view = modest_main_window_get_child_widget (main_window,
1920                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1921         if (!folder_view)
1922                 return;
1923
1924         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1925
1926         /* Show an error if it's an account */
1927         if (!TNY_IS_FOLDER (folder)) {
1928                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1929                                                         _("mail_in_ui_folder_delete_error"));
1930                 return ;
1931         }
1932
1933         /* Ask the user */      
1934         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
1935                                     tny_folder_get_name (TNY_FOLDER (folder)));
1936         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window), 
1937                                                             (const gchar *) message);
1938         g_free (message);
1939
1940         if (response == GTK_RESPONSE_OK) {
1941                 ModestMailOperation *mail_op = 
1942                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, 
1943                                                                        G_OBJECT(main_window),
1944                                                                        modest_ui_actions_delete_folder_error_handler,
1945                                                                        NULL);
1946
1947                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1948                                                  mail_op);
1949                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1950                 g_object_unref (G_OBJECT (mail_op));
1951         }
1952
1953         g_object_unref (G_OBJECT (folder));
1954 }
1955
1956 void 
1957 modest_ui_actions_on_delete_folder (GtkAction *action,
1958                                      ModestMainWindow *main_window)
1959 {
1960         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1961
1962         delete_folder (main_window, FALSE);
1963 }
1964
1965 void 
1966 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1967 {
1968         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1969         
1970         delete_folder (main_window, TRUE);
1971 }
1972
1973 void
1974 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
1975                                          const gchar* server_account_name,
1976                                          gchar **username,
1977                                          gchar **password, 
1978                                          gboolean *cancel, 
1979                                          gboolean *remember,
1980                                          ModestMainWindow *main_window)
1981 {
1982         g_return_if_fail(server_account_name);
1983         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1984         
1985         /* Initalize output parameters: */
1986         if (cancel)
1987                 *cancel = FALSE;
1988                 
1989         if (remember)
1990                 *remember = TRUE;
1991                 
1992 #ifdef MODEST_PLATFORM_MAEMO
1993         /* Maemo uses a different (awkward) button order,
1994          * It should probably just use gtk_alternative_dialog_button_order ().
1995          */
1996         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1997                                               NULL,
1998                                               GTK_DIALOG_MODAL,
1999                                               GTK_STOCK_OK,
2000                                               GTK_RESPONSE_ACCEPT,
2001                                               GTK_STOCK_CANCEL,
2002                                               GTK_RESPONSE_REJECT,
2003                                               NULL);
2004 #else
2005         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2006                                               NULL,
2007                                               GTK_DIALOG_MODAL,
2008                                               GTK_STOCK_CANCEL,
2009                                               GTK_RESPONSE_REJECT,
2010                                               GTK_STOCK_OK,
2011                                               GTK_RESPONSE_ACCEPT,
2012                                               NULL);
2013 #endif /* MODEST_PLATFORM_MAEMO */
2014
2015         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2016         
2017         gchar *server_name = modest_server_account_get_hostname (
2018                 modest_runtime_get_account_mgr(), server_account_name);
2019         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2020                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2021                 *cancel = TRUE;
2022                 return;
2023         }
2024         
2025         /* This causes a warning because the logical ID has no %s in it, 
2026          * though the translation does, but there is not much we can do about that: */
2027         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2028         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2029                             FALSE, FALSE, 0);
2030         g_free (txt);
2031         g_free (server_name);
2032         server_name = NULL;
2033
2034         /* username: */
2035         gchar *initial_username = modest_server_account_get_username (
2036                 modest_runtime_get_account_mgr(), server_account_name);
2037         
2038         GtkWidget *entry_username = gtk_entry_new ();
2039         if (initial_username)
2040                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2041         /* Dim this if a connection has ever succeeded with this username,
2042          * as per the UI spec: */
2043         const gboolean username_known = 
2044                 modest_server_account_get_username_has_succeeded(
2045                         modest_runtime_get_account_mgr(), server_account_name);
2046         gtk_widget_set_sensitive (entry_username, !username_known);
2047         
2048 #ifdef MODEST_PLATFORM_MAEMO
2049         /* Auto-capitalization is the default, so let's turn it off: */
2050         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2051         
2052         /* Create a size group to be used by all captions.
2053          * Note that HildonCaption does not create a default size group if we do not specify one.
2054          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2055         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2056         
2057         GtkWidget *caption = hildon_caption_new (sizegroup, 
2058                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2059         gtk_widget_show (entry_username);
2060         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2061                 FALSE, FALSE, MODEST_MARGIN_HALF);
2062         gtk_widget_show (caption);
2063 #else 
2064         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2065                             TRUE, FALSE, 0);
2066 #endif /* MODEST_PLATFORM_MAEMO */      
2067                             
2068         /* password: */
2069         GtkWidget *entry_password = gtk_entry_new ();
2070         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2071         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2072         
2073 #ifdef MODEST_PLATFORM_MAEMO
2074         /* Auto-capitalization is the default, so let's turn it off: */
2075         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2076                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2077         
2078         caption = hildon_caption_new (sizegroup, 
2079                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2080         gtk_widget_show (entry_password);
2081         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2082                 FALSE, FALSE, MODEST_MARGIN_HALF);
2083         gtk_widget_show (caption);
2084         g_object_unref (sizegroup);
2085 #else 
2086         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2087                             TRUE, FALSE, 0);
2088 #endif /* MODEST_PLATFORM_MAEMO */      
2089                                 
2090 /* This is not in the Maemo UI spec:
2091         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2092         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2093                             TRUE, FALSE, 0);
2094 */
2095
2096         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2097         
2098         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2099                 if (username) {
2100                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2101                         
2102                         modest_server_account_set_username (
2103                                  modest_runtime_get_account_mgr(), server_account_name, 
2104                                  *username);
2105                                  
2106                         const gboolean username_was_changed = 
2107                                 (strcmp (*username, initial_username) != 0);
2108                         if (username_was_changed) {
2109                                 g_warning ("%s: tinymail does not yet support changing the "
2110                                         "username in the get_password() callback.\n", __FUNCTION__);
2111                         }
2112                 }
2113                         
2114                 if (password) {
2115                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2116                         
2117                         /* We do not save the password in the configuration, 
2118                          * because this function is only called for passwords that should 
2119                          * not be remembered:
2120                         modest_server_account_set_password (
2121                                  modest_runtime_get_account_mgr(), server_account_name, 
2122                                  *password);
2123                         */
2124                 }
2125                 
2126                 if (cancel)
2127                         *cancel   = FALSE;
2128                         
2129         } else {
2130                 if (username)
2131                         *username = NULL;
2132                         
2133                 if (password)
2134                         *password = NULL;
2135                         
2136                 if (cancel)
2137                         *cancel   = TRUE;
2138         }
2139
2140 /* This is not in the Maemo UI spec:
2141         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2142                 *remember = TRUE;
2143         else
2144                 *remember = FALSE;
2145 */
2146
2147         gtk_widget_destroy (dialog);
2148         
2149         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2150 }
2151
2152 void
2153 modest_ui_actions_on_cut (GtkAction *action,
2154                           ModestWindow *window)
2155 {
2156         GtkWidget *focused_widget;
2157
2158         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2159         if (GTK_IS_EDITABLE (focused_widget)) {
2160                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2161         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2162                 GtkTextBuffer *buffer;
2163                 GtkClipboard *clipboard;
2164
2165                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2166                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2167                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2168         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2169                 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2170         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2171                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2172         }
2173 }
2174
2175 void
2176 modest_ui_actions_on_copy (GtkAction *action,
2177                            ModestWindow *window)
2178 {
2179         GtkClipboard *clipboard;
2180         GtkWidget *focused_widget;
2181
2182         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2183         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2184
2185         if (GTK_IS_LABEL (focused_widget)) {
2186                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2187         } else if (GTK_IS_EDITABLE (focused_widget)) {
2188                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2189         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2190                 GtkTextBuffer *buffer;
2191                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2192                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2193                 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2194         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2195                 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2196                 TnyIterator *iter = tny_list_create_iterator (header_list);
2197                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2198                 TnyFolder *folder = tny_header_get_folder (header);
2199                 TnyAccount *account = tny_folder_get_account (folder);
2200                 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2201                 /* If it's POP then ask */
2202                 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
2203                        MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2204                 g_object_unref (account);
2205                 g_object_unref (folder);
2206                 g_object_unref (header);
2207                 g_object_unref (iter);
2208                 
2209                 /* Check that the messages have been previously downloaded */
2210                 gboolean continue_download = TRUE;
2211                 if (ask)
2212                         continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2213                 if (continue_download)
2214                         modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2215                 g_object_unref (header_list);
2216         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2217                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2218         }    
2219
2220         /* Show information banner */
2221         modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2222         
2223 }
2224
2225 void
2226 modest_ui_actions_on_undo (GtkAction *action,
2227                            ModestWindow *window)
2228 {
2229         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2230                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2231         } else {
2232                 g_return_if_reached ();
2233         }
2234 }
2235
2236 void
2237 modest_ui_actions_on_paste (GtkAction *action,
2238                             ModestWindow *window)
2239 {
2240         GtkWidget *focused_widget;
2241         ModestMailOperation *mail_op = NULL;
2242
2243         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2244         if (GTK_IS_EDITABLE (focused_widget)) {
2245                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2246         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2247                 GtkTextBuffer *buffer;
2248                 GtkClipboard *clipboard;
2249
2250                 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2251                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2252                 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2253         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2254                 ModestEmailClipboard *clipboard = NULL;
2255                 TnyFolder *src_folder = NULL;
2256                 TnyFolderStore *folder_store = NULL;
2257                 TnyList *data = NULL;           
2258                 gboolean delete = FALSE;
2259                 
2260                 /* Check clipboard source */
2261                 clipboard = modest_runtime_get_email_clipboard ();
2262                 if (modest_email_clipboard_cleared (clipboard)) 
2263                         return;
2264                 
2265                 /* Get elements to paste */
2266                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2267
2268                 /* Create a new mail operation */
2269                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2270                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2271                                                  mail_op);
2272                 
2273                 /* Get destination folder */
2274                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2275
2276                 /* transfer messages  */
2277                 if (data != NULL) {
2278                         modest_mail_operation_xfer_msgs (mail_op, 
2279                                                          data,
2280                                                          TNY_FOLDER (folder_store),
2281                                                          delete,
2282                                                          NULL,
2283                                                          NULL);
2284                         
2285                 } else if (src_folder != NULL) {                        
2286                         modest_mail_operation_xfer_folder (mail_op, 
2287                                                            src_folder,
2288                                                            folder_store,
2289                                                            delete);
2290                 }
2291
2292                 /* Free */
2293                 if (data != NULL) 
2294                         g_object_unref (data);
2295                 if (src_folder != NULL) 
2296                         g_object_unref (src_folder);
2297                 if (folder_store != NULL) 
2298                         g_object_unref (folder_store);
2299         }
2300 }
2301
2302 void
2303 modest_ui_actions_on_select_all (GtkAction *action,
2304                                  ModestWindow *window)
2305 {
2306         GtkWidget *focused_widget;
2307
2308         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2309         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2310                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2311         } else if (GTK_IS_LABEL (focused_widget)) {
2312                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2313         } else if (GTK_IS_EDITABLE (focused_widget)) {
2314                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2315         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2316                 GtkTextBuffer *buffer;
2317                 GtkTextIter start, end;
2318
2319                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2320                 gtk_text_buffer_get_start_iter (buffer, &start);
2321                 gtk_text_buffer_get_end_iter (buffer, &end);
2322                 gtk_text_buffer_select_range (buffer, &start, &end);
2323         }
2324         else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2325                  (MODEST_IS_HEADER_VIEW (focused_widget))) {
2326                 
2327                 GtkTreeSelection *selection = NULL;
2328
2329                 /* Get header view */           
2330                 GtkWidget *header_view = focused_widget;
2331                 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2332                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2333                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2334
2335                 /* Select all messages */
2336                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2337                 gtk_tree_selection_select_all (selection);
2338
2339                 /* Set focuse on header view */
2340                 gtk_widget_grab_focus (header_view);
2341
2342         } else if (GTK_IS_HTML (focused_widget)) {
2343                 gtk_html_select_all (GTK_HTML (focused_widget));
2344         }
2345 }
2346
2347 void
2348 modest_ui_actions_on_mark_as_read (GtkAction *action,
2349                                    ModestWindow *window)
2350 {       
2351         g_return_if_fail (MODEST_IS_WINDOW(window));
2352                 
2353         /* Mark each header as read */
2354         do_headers_action (window, headers_action_mark_as_read, NULL);
2355 }
2356
2357 void
2358 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2359                                      ModestWindow *window)
2360 {       
2361         g_return_if_fail (MODEST_IS_WINDOW(window));
2362                 
2363         /* Mark each header as read */
2364         do_headers_action (window, headers_action_mark_as_unread, NULL);
2365 }
2366
2367 void
2368 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2369                                   GtkRadioAction *selected,
2370                                   ModestWindow *window)
2371 {
2372         gint value;
2373
2374         value = gtk_radio_action_get_current_value (selected);
2375         if (MODEST_IS_WINDOW (window)) {
2376                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2377         }
2378 }
2379
2380 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2381                                                         GtkRadioAction *selected,
2382                                                         ModestWindow *window)
2383 {
2384         TnyHeaderFlags flags;
2385         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2386
2387         flags = gtk_radio_action_get_current_value (selected);
2388         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2389 }
2390
2391 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2392                                                            GtkRadioAction *selected,
2393                                                            ModestWindow *window)
2394 {
2395         gint file_format;
2396
2397         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2398
2399         file_format = gtk_radio_action_get_current_value (selected);
2400         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2401 }
2402
2403
2404 void     
2405 modest_ui_actions_on_zoom_plus (GtkAction *action,
2406                                 ModestWindow *window)
2407 {
2408         g_return_if_fail (MODEST_IS_WINDOW (window));
2409
2410         modest_window_zoom_plus (MODEST_WINDOW (window));
2411 }
2412
2413 void     
2414 modest_ui_actions_on_zoom_minus (GtkAction *action,
2415                                  ModestWindow *window)
2416 {
2417         g_return_if_fail (MODEST_IS_WINDOW (window));
2418
2419         modest_window_zoom_minus (MODEST_WINDOW (window));
2420 }
2421
2422 void     
2423 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
2424                                            ModestWindow *window)
2425 {
2426         ModestWindowMgr *mgr;
2427         gboolean fullscreen, active;
2428         g_return_if_fail (MODEST_IS_WINDOW (window));
2429
2430         mgr = modest_runtime_get_window_mgr ();
2431
2432         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2433         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2434
2435         if (active != fullscreen) {
2436                 modest_window_mgr_set_fullscreen_mode (mgr, active);
2437                 gtk_window_present (GTK_WINDOW (window));
2438         }
2439 }
2440
2441 void
2442 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2443                                         ModestWindow *window)
2444 {
2445         ModestWindowMgr *mgr;
2446         gboolean fullscreen;
2447
2448         g_return_if_fail (MODEST_IS_WINDOW (window));
2449
2450         mgr = modest_runtime_get_window_mgr ();
2451         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2452         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2453
2454         gtk_window_present (GTK_WINDOW (window));
2455 }
2456
2457 /* 
2458  * Used by modest_ui_actions_on_details to call do_headers_action 
2459  */
2460 static void
2461 headers_action_show_details (TnyHeader *header, 
2462                              ModestWindow *window,
2463                              gpointer user_data)
2464
2465 {
2466         GtkWidget *dialog;
2467         
2468         /* Create dialog */
2469         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2470
2471         /* Run dialog */
2472         gtk_widget_show_all (dialog);
2473         gtk_dialog_run (GTK_DIALOG (dialog));
2474
2475         gtk_widget_destroy (dialog);
2476 }
2477
2478 /*
2479  * Show the folder details in a ModestDetailsDialog widget
2480  */
2481 static void
2482 show_folder_details (TnyFolder *folder, 
2483                      GtkWindow *window)
2484 {
2485         GtkWidget *dialog;
2486         
2487         /* Create dialog */
2488         dialog = modest_details_dialog_new_with_folder (window, folder);
2489
2490         /* Run dialog */
2491         gtk_widget_show_all (dialog);
2492         gtk_dialog_run (GTK_DIALOG (dialog));
2493
2494         gtk_widget_destroy (dialog);
2495 }
2496
2497 /*
2498  * Show the header details in a ModestDetailsDialog widget
2499  */
2500 void     
2501 modest_ui_actions_on_details (GtkAction *action, 
2502                               ModestWindow *win)
2503 {
2504         TnyList * headers_list;
2505         TnyIterator *iter;
2506         TnyHeader *header;              
2507
2508         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2509                 TnyMsg *msg;
2510
2511                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2512                 if (!msg)
2513                         return;
2514                 g_object_unref (msg);           
2515
2516                 headers_list = get_selected_headers (win);
2517                 if (!headers_list)
2518                         return;
2519
2520                 iter = tny_list_create_iterator (headers_list);
2521
2522                 header = TNY_HEADER (tny_iterator_get_current (iter));
2523                 headers_action_show_details (header, win, NULL);
2524                 g_object_unref (header);
2525
2526                 g_object_unref (iter);
2527                 g_object_unref (headers_list);
2528
2529         } else if (MODEST_IS_MAIN_WINDOW (win)) {
2530                 GtkWidget *folder_view, *header_view;
2531
2532                 /* Check which widget has the focus */
2533                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2534                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
2535                 if (gtk_widget_is_focus (folder_view)) {
2536                         TnyFolderStore *folder_store
2537                                 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2538                         if (!folder_store) {
2539                                 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2540                                 return; 
2541                         }
2542                         /* Show only when it's a folder */
2543                         /* This function should not be called for account items, 
2544                          * because we dim the menu item for them. */
2545                         if (TNY_IS_FOLDER (folder_store)) {
2546                                 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2547                         }
2548
2549                         g_object_unref (folder_store);
2550
2551                 } else {
2552                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2553                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2554                         /* Show details of each header */
2555                         do_headers_action (win, headers_action_show_details, header_view);
2556                 }
2557         }
2558 }
2559
2560 void     
2561 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2562                                      ModestMsgEditWindow *window)
2563 {
2564         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2565
2566         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2567 }
2568
2569 void     
2570 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2571                                       ModestMsgEditWindow *window)
2572 {
2573         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2574
2575         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2576 }
2577
2578 void
2579 modest_ui_actions_toggle_folders_view (GtkAction *action, 
2580                                        ModestMainWindow *main_window)
2581 {
2582         ModestConf *conf;
2583         
2584         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2585
2586         conf = modest_runtime_get_conf ();
2587         
2588         if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2589                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2590         else
2591                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2592 }
2593
2594 void 
2595 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
2596                                      ModestWindow *window)
2597 {
2598         gboolean active, fullscreen = FALSE;
2599         ModestWindowMgr *mgr;
2600
2601         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2602
2603         /* Check if we want to toggle the toolbar vuew in fullscreen
2604            or normal mode */
2605         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
2606                      "ViewShowToolbarFullScreen")) {
2607                 fullscreen = TRUE;
2608         }
2609
2610         /* Toggle toolbar */
2611         mgr = modest_runtime_get_window_mgr ();
2612         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2613 }
2614
2615 void     
2616 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2617                                            ModestMsgEditWindow *window)
2618 {
2619         modest_msg_edit_window_select_font (window);
2620 }
2621
2622 void
2623 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2624                                                   const gchar *display_name,
2625                                                   GtkWindow *window)
2626 {
2627         /* Do not change the application name if the widget has not
2628            the focus. This callback could be called even if the folder
2629            view has not the focus, because the handled signal could be
2630            emitted when the folder view is redrawn */
2631         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2632                 if (display_name)
2633                         gtk_window_set_title (window, display_name);
2634                 else
2635                         gtk_window_set_title (window, " ");
2636         }
2637 }
2638
2639 void
2640 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2641 {
2642         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2643         modest_msg_edit_window_select_contacts (window);
2644 }
2645
2646 void
2647 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2648 {
2649         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2650         modest_msg_edit_window_check_names (window);
2651 }
2652
2653
2654 static GtkWidget*
2655 create_move_to_dialog (ModestWindow *win,
2656                        GtkWidget *folder_view,
2657                        GtkWidget **tree_view)
2658 {
2659         GtkWidget *dialog, *scroll;
2660
2661         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2662                                               GTK_WINDOW (win),
2663                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2664                                               GTK_STOCK_OK,
2665                                               GTK_RESPONSE_ACCEPT,
2666                                               GTK_STOCK_CANCEL,
2667                                               GTK_RESPONSE_REJECT,
2668                                               NULL);
2669
2670         /* Create scrolled window */
2671         scroll = gtk_scrolled_window_new (NULL, NULL);
2672         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
2673                                          GTK_POLICY_AUTOMATIC,
2674                                          GTK_POLICY_AUTOMATIC);
2675
2676         /* Create folder view */
2677         *tree_view = modest_platform_create_folder_view (NULL);
2678
2679         /* It could happen that we're trying to move a message from a
2680            window (msg window for example) after the main window was
2681            closed, so we can not just get the model of the folder
2682            view */
2683         if (MODEST_IS_FOLDER_VIEW (folder_view))
2684                 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2685                                          gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2686         else
2687                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
2688                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2689
2690         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2691
2692         /* Add scroll to dialog */
2693         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
2694                             scroll, FALSE, FALSE, 0);
2695
2696         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2697
2698         /* Select INBOX or local account */
2699         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2700
2701         return dialog;
2702 }
2703
2704 /*
2705  * Returns TRUE if at least one of the headers of the list belongs to
2706  * a message that has been fully retrieved.
2707  */
2708 static gboolean
2709 has_retrieved_msgs (TnyList *list)
2710 {
2711         TnyIterator *iter;
2712         gboolean found = FALSE;
2713
2714         iter = tny_list_create_iterator (list);
2715         while (tny_iterator_is_done (iter) && !found) {
2716                 TnyHeader *header;
2717                 TnyHeaderFlags flags;
2718
2719                 header = TNY_HEADER (tny_iterator_get_current (iter));
2720                 flags = tny_header_get_flags (header);
2721                 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2722                         found = TRUE;
2723
2724                 if (!found)
2725                         tny_iterator_next (iter);
2726         }
2727         g_object_unref (iter);
2728
2729         return found;
2730 }
2731
2732 /*
2733  * Shows a confirmation dialog to the user when we're moving messages
2734  * from a remote server to the local storage. Returns the dialog
2735  * response. If it's other kind of movement the it always returns
2736  * GTK_RESPONSE_OK
2737  */
2738 static gint
2739 msgs_move_to_confirmation (GtkWindow *win,
2740                            TnyFolder *dest_folder,
2741                            TnyList *headers)
2742 {
2743         gint response = GTK_RESPONSE_OK;
2744
2745         /* If the destination is a local folder */
2746         if (modest_tny_folder_is_local_folder (dest_folder)) {
2747                 TnyFolder *src_folder;
2748                 TnyIterator *iter;
2749                 TnyHeader *header;
2750
2751                 /* Get source folder */
2752                 iter = tny_list_create_iterator (headers);
2753                 header = TNY_HEADER (tny_iterator_get_current (iter));
2754                 src_folder = tny_header_get_folder (header);
2755                 g_object_unref (header);
2756                 g_object_unref (iter);
2757
2758                 /* If the source is a remote folder */
2759                 if (!modest_tny_folder_is_local_folder (src_folder)) {
2760                         const gchar *message;
2761                         
2762                         if (has_retrieved_msgs (headers))
2763                                 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2764                                                     tny_list_get_length (headers));
2765                         else 
2766                                 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2767                                                     tny_list_get_length (headers));
2768
2769                         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2770                                                                             (const gchar *) message);
2771                 }
2772                 g_object_unref (src_folder);
2773         }
2774         return response;
2775 }
2776
2777
2778 static void
2779 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2780 {
2781         ModestMsgViewWindow *self = NULL;
2782
2783         g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2784         self = MODEST_MSG_VIEW_WINDOW (object);
2785
2786         /* If there are not more messages don't do anything. The
2787            viewer will show the same message */
2788         if (!modest_msg_view_window_select_first_message (self))
2789             return;
2790 }
2791
2792 void
2793 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
2794                                              gpointer user_data)
2795 {
2796         GObject *win = modest_mail_operation_get_source (mail_op);
2797
2798         /* TODO: show error message */
2799         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2800                                                 _("mail_in_ui_folder_move_target_error"));
2801         g_object_unref (win);
2802 }
2803
2804 /*
2805  * UI handler for the "Move to" action when invoked from the
2806  * ModestMainWindow
2807  */
2808 static void 
2809 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
2810                                           ModestMainWindow *win)
2811 {
2812         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2813         GtkWidget *header_view = NULL;
2814         gint result;
2815         TnyFolderStore *folder_store = NULL;
2816         ModestMailOperation *mail_op = NULL;
2817
2818         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2819
2820         /* Get the folder view */
2821         folder_view = modest_main_window_get_child_widget (win,
2822                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2823
2824         /* Get header view */
2825         header_view = modest_main_window_get_child_widget (win,
2826                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2827
2828         /* Create and run the dialog */
2829         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2830         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2831         result = gtk_dialog_run (GTK_DIALOG(dialog));
2832         g_object_ref (tree_view);
2833
2834         /* We do this to save an indentation level ;-) */
2835         if (result != GTK_RESPONSE_ACCEPT)
2836                 goto end;
2837
2838         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2839
2840         if (TNY_IS_ACCOUNT (folder_store))
2841                 goto end;
2842
2843         /* Get folder or messages to transfer */
2844         if (gtk_widget_is_focus (folder_view)) {
2845                 TnyFolderStore *src_folder;
2846                 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2847
2848                 /* Clean folder on header view before moving it */
2849                 modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); 
2850
2851                 if (TNY_IS_FOLDER (src_folder)) {
2852                         mail_op = 
2853                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
2854                                                                                G_OBJECT(win),
2855                                                                                modest_ui_actions_move_folder_error_handler,
2856                                                                                NULL);
2857                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2858
2859                         modest_mail_operation_xfer_folder (mail_op, 
2860                                                            TNY_FOLDER (src_folder),
2861                                                            folder_store,
2862                                                            TRUE);
2863                         /* Unref mail operation */
2864                         g_object_unref (G_OBJECT (mail_op));
2865                 }
2866
2867                 /* Frees */
2868                 g_object_unref (G_OBJECT (src_folder));
2869         } else {
2870                 if (gtk_widget_is_focus (header_view)) {
2871                         TnyList *headers;
2872                         gint response;
2873
2874                         headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2875
2876                         /* Ask for user confirmation */
2877                         response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2878                                                               TNY_FOLDER (folder_store), 
2879                                                               headers);
2880
2881                         /* Transfer messages */
2882                         if (response == GTK_RESPONSE_OK) {
2883                                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2884                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2885                                                                  mail_op);
2886
2887                                 modest_mail_operation_xfer_msgs (mail_op, 
2888                                                                  headers,
2889                                                                  TNY_FOLDER (folder_store),
2890                                                                  TRUE,
2891                                                                  NULL,
2892                                                                  NULL);
2893
2894                                 g_object_unref (G_OBJECT (mail_op));
2895                         }
2896                         g_object_unref (headers);
2897                 }
2898         }
2899  end:
2900         if (folder_store != NULL)
2901                 g_object_unref (folder_store);
2902         gtk_widget_destroy (dialog);
2903 }
2904
2905
2906 /*
2907  * UI handler for the "Move to" action when invoked from the
2908  * ModestMsgViewWindow
2909  */
2910 static void 
2911 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
2912                                               ModestMsgViewWindow *win)
2913 {
2914         GtkWidget *dialog, *folder_view, *tree_view = NULL;
2915         gint result;
2916         ModestMainWindow *main_window;
2917         TnyHeader *header;
2918         TnyList *headers;
2919
2920         /* Get the folder view */
2921         main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2922         if (main_window)
2923                 folder_view = modest_main_window_get_child_widget (main_window,
2924                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
2925         else
2926                 folder_view = NULL;
2927
2928         /* Create and run the dialog */
2929         dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);  
2930         result = gtk_dialog_run (GTK_DIALOG(dialog));
2931         g_object_ref (tree_view);
2932
2933         if (result == GTK_RESPONSE_ACCEPT) {
2934                 TnyFolderStore *folder_store;
2935                 gint response;
2936
2937                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2938
2939                 /* Create header list */
2940                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
2941                 headers = tny_simple_list_new ();
2942                 tny_list_prepend (headers, G_OBJECT (header));
2943                 g_object_unref (header);
2944
2945                 /* Ask user for confirmation. MSG-NOT404 */
2946                 response = msgs_move_to_confirmation (GTK_WINDOW (win), 
2947                                                       TNY_FOLDER (folder_store), 
2948                                                       headers);
2949
2950                 /* Transfer current msg */
2951                 if (response == GTK_RESPONSE_OK) {
2952                         ModestMailOperation *mail_op;
2953
2954                         /* Create mail op */
2955                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2956                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2957                                                          mail_op);
2958                         
2959                         /* Transfer messages */
2960                         modest_mail_operation_xfer_msgs (mail_op, 
2961                                                          headers,
2962                                                          TNY_FOLDER (folder_store),
2963                                                          TRUE,
2964                                                          transfer_msgs_from_viewer_cb,
2965                                                          NULL);
2966                         g_object_unref (G_OBJECT (mail_op));
2967                 }
2968                 g_object_unref (headers);
2969                 g_object_unref (folder_store);
2970         }
2971         gtk_widget_destroy (dialog);
2972 }
2973
2974 void 
2975 modest_ui_actions_on_move_to (GtkAction *action, 
2976                               ModestWindow *win)
2977 {
2978         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2979                           MODEST_IS_MSG_VIEW_WINDOW (win));
2980
2981         if (MODEST_IS_MAIN_WINDOW (win)) 
2982                 modest_ui_actions_on_main_window_move_to (action, 
2983                                                           MODEST_MAIN_WINDOW (win));
2984         else
2985                 modest_ui_actions_on_msg_view_window_move_to (action, 
2986                                                               MODEST_MSG_VIEW_WINDOW (win));
2987 }
2988
2989 /*
2990  * Calls #HeadersFunc for each header already selected in the main
2991  * window or the message currently being shown in the msg view window
2992  */
2993 static void
2994 do_headers_action (ModestWindow *win, 
2995                    HeadersFunc func,
2996                    gpointer user_data)
2997 {
2998         TnyList *headers_list;
2999         TnyIterator *iter;
3000         TnyHeader *header;
3001         TnyFolder *folder;
3002
3003         /* Get headers */
3004         headers_list = get_selected_headers (win);
3005         if (!headers_list)
3006                 return;
3007
3008         /* Get the folder */
3009         iter = tny_list_create_iterator (headers_list);
3010         header = TNY_HEADER (tny_iterator_get_current (iter));
3011         folder = tny_header_get_folder (header);
3012         g_object_unref (header);
3013
3014         /* Call the function for each header */
3015         while (!tny_iterator_is_done (iter)) {
3016                 header = TNY_HEADER (tny_iterator_get_current (iter));
3017                 func (header, win, user_data);
3018                 g_object_unref (header);
3019                 tny_iterator_next (iter);
3020         }
3021
3022         /* Trick: do a poke status in order to speed up the signaling
3023            of observers */
3024         tny_folder_poke_status (folder);
3025
3026         /* Frees */
3027         g_object_unref (folder);
3028         g_object_unref (iter);
3029         g_object_unref (headers_list);
3030 }
3031
3032 void 
3033 modest_ui_actions_view_attachment (GtkAction *action,
3034                                    ModestWindow *window)
3035 {
3036         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3037                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3038         } else {
3039                 /* not supported window for this action */
3040                 g_return_if_reached ();
3041         }
3042 }
3043
3044 void
3045 modest_ui_actions_save_attachments (GtkAction *action,
3046                                     ModestWindow *window)
3047 {
3048         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3049                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3050         } else {
3051                 /* not supported window for this action */
3052                 g_return_if_reached ();
3053         }
3054 }
3055
3056 void
3057 modest_ui_actions_remove_attachments (GtkAction *action,
3058                                       ModestWindow *window)
3059 {
3060         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3061                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window));
3062         } else {
3063                 /* not supported window for this action */
3064                 g_return_if_reached ();
3065         }
3066 }
3067
3068 void 
3069 modest_ui_actions_on_settings (GtkAction *action, 
3070                                ModestWindow *win)
3071 {
3072         GtkWidget *dialog;
3073
3074         dialog = modest_platform_get_global_settings_dialog ();
3075         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3076         gtk_widget_show (dialog);
3077
3078         gtk_dialog_run (GTK_DIALOG (dialog));
3079
3080         gtk_widget_destroy (dialog);
3081 }
3082
3083 void 
3084 modest_ui_actions_on_help (GtkAction *action, 
3085                            ModestWindow *win)
3086 {
3087         const gchar *help_id = NULL;
3088
3089         if (MODEST_IS_MAIN_WINDOW (win)) {
3090                 const gchar *action_name;
3091                 action_name = gtk_action_get_name (action);
3092
3093                 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3094                     !strcmp (action_name, "HeaderViewCSMHelp")) {
3095                         GtkWidget *folder_view;
3096                         TnyFolderStore *folder_store;
3097                         /* Get selected folder */
3098                         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3099                                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
3100                         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3101
3102                         /* Switch help_id */
3103                         if (TNY_IS_FOLDER (folder_store)) {
3104                                 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3105                                 case TNY_FOLDER_TYPE_NORMAL:
3106                                         help_id = "applications_email_userfolder";
3107                                         break;
3108                                 case TNY_FOLDER_TYPE_INBOX:
3109                                         help_id = "applications_email_inbox";
3110                                         break;
3111                                 case TNY_FOLDER_TYPE_OUTBOX:
3112                                         help_id = "applications_email_outbox";
3113                                         break;
3114                                 case TNY_FOLDER_TYPE_SENT:
3115                                         help_id = "applications_email_sent";
3116                                         break;
3117                                 case TNY_FOLDER_TYPE_DRAFTS:
3118                                         help_id = "applications_email_drafts";
3119                                         break;
3120                                 case TNY_FOLDER_TYPE_ARCHIVE:
3121                                         help_id = "applications_email_archive";
3122                                         break;
3123                                 default:
3124                                         help_id = NULL;
3125                                 }
3126                         }
3127                         g_object_unref (folder_store);
3128                 } else {
3129                         help_id = "applications_email_mainview";        
3130                 }
3131         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3132                 help_id = "applications_email_viewer";
3133         } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3134                 help_id = "applications_email_editor";
3135
3136         modest_platform_show_help (GTK_WINDOW (win), help_id);
3137 }
3138
3139 void 
3140 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3141                                             ModestWindow *window)
3142 {
3143         ModestMailOperation *mail_op;
3144         TnyList *headers;
3145
3146         /* Get headers */
3147         headers = get_selected_headers (window);
3148         if (!headers)
3149                 return;
3150
3151         /* Create mail operation */
3152         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3153                                                                  G_OBJECT (window),
3154                                                                  modest_ui_actions_get_msgs_full_error_handler, 
3155                                                                  NULL);
3156         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3157         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3158
3159         /* Frees */
3160         g_object_unref (headers);
3161         g_object_unref (mail_op);
3162 }
3163
3164 void
3165 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3166                                           ModestWindow *window)
3167 {
3168         g_return_if_fail (MODEST_IS_WINDOW (window));
3169
3170         /* Update dimmed */     
3171         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3172 }
3173
3174 void
3175 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3176                                           ModestWindow *window)
3177 {
3178         g_return_if_fail (MODEST_IS_WINDOW (window));
3179
3180         /* Update dimmed */     
3181         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3182 }
3183
3184 void
3185 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3186                                           ModestWindow *window)
3187 {
3188         g_return_if_fail (MODEST_IS_WINDOW (window));
3189
3190         /* Update dimmed */     
3191         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3192 }
3193
3194 void
3195 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3196                                           ModestWindow *window)
3197 {
3198         g_return_if_fail (MODEST_IS_WINDOW (window));
3199
3200         /* Update dimmed */     
3201         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3202 }
3203
3204 void
3205 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3206                                           ModestWindow *window)
3207 {
3208         g_return_if_fail (MODEST_IS_WINDOW (window));
3209
3210         /* Update dimmed */     
3211         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3212 }
3213
3214 void
3215 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3216                                                  ModestWindow *window)
3217 {
3218         g_return_if_fail (MODEST_IS_WINDOW (window));
3219
3220         /* Update dimmed */     
3221         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3222 }
3223
3224 void
3225 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3226                                                      ModestWindow *window)
3227 {
3228         g_return_if_fail (MODEST_IS_WINDOW (window));
3229
3230         /* Update dimmed */     
3231         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3232 }
3233
3234 void
3235 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3236                                                      ModestWindow *window)
3237 {
3238         g_return_if_fail (MODEST_IS_WINDOW (window));
3239
3240         /* Update dimmed */     
3241         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
3242 }
3243
3244 void
3245 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3246 {
3247         g_return_if_fail (MODEST_IS_WINDOW (window));
3248
3249         /* Update dimmed */     
3250         modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");  
3251 }
3252
3253 void
3254 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3255 {
3256         g_return_if_fail (MODEST_IS_WINDOW (window));
3257
3258         modest_platform_show_search_messages (GTK_WINDOW (window));
3259 }
3260
3261 void     
3262 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3263 {
3264         g_return_if_fail (MODEST_IS_WINDOW (win));
3265         modest_platform_show_addressbook (GTK_WINDOW (win));
3266 }
3267
3268
3269 void
3270 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3271                                           ModestWindow *window)
3272 {
3273         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3274
3275         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3276 }
3277
3278 static void 
3279 _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
3280                                    ModestMailOperationState *state,
3281                                    gpointer user_data)
3282 {
3283         g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3284
3285         /* Set send/receive operation finished */       
3286         if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3287                 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
3288         
3289 }
3290
3291