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