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