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