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