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