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