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