41aa482f4c7c5b353a26e408e3c6acad2a194667
[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 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
51
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
57
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
70
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
74
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
81
82 #include <gtkhtml/gtkhtml.h>
83
84 typedef struct _GetMsgAsyncHelper {     
85         ModestWindow *window;
86         ModestMailOperation *mail_op;
87         TnyIterator *iter;
88         guint num_ops;
89         GFunc func;     
90         gpointer user_data;
91 } GetMsgAsyncHelper;
92
93 typedef enum _ReplyForwardAction {
94         ACTION_REPLY,
95         ACTION_REPLY_TO_ALL,
96         ACTION_FORWARD
97 } ReplyForwardAction;
98
99 typedef struct _ReplyForwardHelper {
100         guint reply_forward_type;
101         ReplyForwardAction action;
102         gchar *account_name;
103         GtkWidget *parent_window;
104 } ReplyForwardHelper;
105
106 typedef struct _PasteAsAttachmentHelper {
107         ModestMsgEditWindow *window;
108         GtkWidget *banner;
109 } PasteAsAttachmentHelper;
110
111
112 /*
113  * The do_headers_action uses this kind of functions to perform some
114  * action to each member of a list of headers
115  */
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
117
118 static void     do_headers_action     (ModestWindow *win, 
119                                        HeadersFunc func,
120                                        gpointer user_data);
121
122 static void     open_msg_cb            (ModestMailOperation *mail_op, 
123                                         TnyHeader *header, 
124                                         TnyMsg *msg,
125                                         gpointer user_data);
126
127 static void     reply_forward_cb       (ModestMailOperation *mail_op, 
128                                         TnyHeader *header, 
129                                         TnyMsg *msg,
130                                         gpointer user_data);
131
132 static void     reply_forward          (ReplyForwardAction action, ModestWindow *win);
133
134 static void     folder_refreshed_cb    (ModestMailOperation *mail_op, 
135                                         TnyFolder *folder, 
136                                         gpointer user_data);
137
138 static void     _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
139                                                    ModestMailOperationState *state,
140                                                    gpointer user_data);
141
142 static gboolean
143 download_uncached_messages (TnyList *header_list, GtkWindow *win,
144                             gboolean reply_fwd);
145
146
147 static gint
148 msgs_move_to_confirmation (GtkWindow *win,
149                            TnyFolder *dest_folder,
150                            gboolean delete,
151                            TnyList *headers);
152
153
154 static void
155 run_account_setup_wizard (ModestWindow *win)
156 {
157         ModestEasysetupWizardDialog *wizard;
158         
159         g_return_if_fail (MODEST_IS_WINDOW(win));
160         
161         wizard = modest_easysetup_wizard_dialog_new ();
162         gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
163         
164         /* Don't make this a modal window, because secondary windows will then 
165          * be unusable, freezing the UI: */
166         /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
167         
168         gtk_dialog_run (GTK_DIALOG (wizard));
169         gtk_widget_destroy (GTK_WIDGET (wizard));
170 }
171
172
173 void   
174 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
175 {
176         GtkWidget *about;
177         const gchar *authors[] = {
178                 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
179                 NULL
180         };
181         about = gtk_about_dialog_new ();
182         gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
183         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
184         gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
185                                         _("Copyright (c) 2006, Nokia Corporation\n"
186                                           "All rights reserved."));
187         gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
188                                        _("a modest e-mail client\n\n"
189                                          "design and implementation: Dirk-Jan C. Binnema\n"
190                                          "contributions from the fine people at KC and Ig\n"
191                                          "uses the tinymail email framework written by Philip van Hoof"));
192         gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
193         gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
194         gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
195         gtk_window_set_modal (GTK_WINDOW (about), TRUE);
196         
197         gtk_dialog_run (GTK_DIALOG (about));
198         gtk_widget_destroy(about);
199 }
200
201 /*
202  * Gets the list of currently selected messages. If the win is the
203  * main window, then it returns a newly allocated list of the headers
204  * selected in the header view. If win is the msg view window, then
205  * the value returned is a list with just a single header.
206  *
207  * The caller of this funcion must free the list.
208  */
209 static TnyList *
210 get_selected_headers (ModestWindow *win)
211 {
212         if (MODEST_IS_MAIN_WINDOW(win)) {
213                 GtkWidget *header_view;         
214                 
215                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
216                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
217                 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
218                 
219         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
220                 /* for MsgViewWindows, we simply return a list with one element */
221                 TnyHeader *header;
222                 TnyList *list = NULL;
223                 
224                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
225                 if (header != NULL) {
226                         list = tny_simple_list_new ();
227                         tny_list_prepend (list, G_OBJECT(header));
228                         g_object_unref (G_OBJECT(header));
229                 }
230
231                 return list;
232
233         } else
234                 return NULL;
235 }
236
237 static void
238 headers_action_mark_as_read (TnyHeader *header,
239                              ModestWindow *win,
240                              gpointer user_data)
241 {
242         TnyHeaderFlags flags;
243
244         g_return_if_fail (TNY_IS_HEADER(header));
245
246         flags = tny_header_get_flags (header);
247         if (flags & TNY_HEADER_FLAG_SEEN) return;
248         tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
249 }
250
251 static void
252 headers_action_mark_as_unread (TnyHeader *header,
253                                ModestWindow *win,
254                                gpointer user_data)
255 {
256         TnyHeaderFlags flags;
257
258         g_return_if_fail (TNY_IS_HEADER(header));
259
260         flags = tny_header_get_flags (header);
261         if (flags & TNY_HEADER_FLAG_SEEN)  {
262                 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
263         }
264 }
265
266 /** A convenience method, because deleting a message is 
267  * otherwise complicated, and it's best to change it in one place 
268  * when we change it.
269  */
270 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
271 {
272         ModestMailOperation *mail_op = NULL;
273         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, 
274                 win ? G_OBJECT(win) : NULL);
275         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
276                                          mail_op);
277         
278         /* Always delete. TODO: Move to trash still not supported */
279         modest_mail_operation_remove_msg (mail_op, header, FALSE);
280         g_object_unref (G_OBJECT (mail_op));
281 }
282
283 static void
284 headers_action_delete (TnyHeader *header,
285                        ModestWindow *win,
286                        gpointer user_data)
287 {
288         modest_do_message_delete (header, win);
289 }
290
291 /** After deleing a message that is currently visible in a window, 
292  * show the next message from the list, or close the window if there are no more messages.
293  **/
294 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
295 {
296         /* Close msg view window or select next */
297         if (modest_msg_view_window_last_message_selected (win) &&
298                 modest_msg_view_window_first_message_selected (win)) {
299                 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
300         } else {
301                 if (!modest_msg_view_window_select_next_message (win)) {
302                         gboolean ret_value;
303                         g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
304                 }
305         }
306 }
307
308 void
309 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
310 {
311         TnyList *header_list = NULL;
312         TnyIterator *iter = NULL;
313         TnyHeader *header = NULL;
314         gchar *message = NULL;
315         gchar *desc = NULL;
316         gint response;
317         ModestWindowMgr *mgr;
318         GtkWidget *header_view = NULL;
319
320         g_return_if_fail (MODEST_IS_WINDOW(win));
321         
322         /* Check first if the header view has the focus */
323         if (MODEST_IS_MAIN_WINDOW (win)) {
324                 header_view = 
325                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
326                                                              MODEST_WIDGET_TYPE_HEADER_VIEW);
327                 if (!gtk_widget_is_focus (header_view))
328                         return;
329         }
330         
331         /* Get the headers, either from the header view (if win is the main window),
332          * or from the message view window: */
333         header_list = get_selected_headers (win);
334         if (!header_list) return;
335                         
336         /* Check if any of the headers are already opened, or in the process of being opened */
337         if (MODEST_IS_MAIN_WINDOW (win)) {
338                 gboolean found;
339                 iter = tny_list_create_iterator (header_list);
340                 found = FALSE;
341                 mgr = modest_runtime_get_window_mgr ();
342                 while (!tny_iterator_is_done (iter) && !found) {
343                         header = TNY_HEADER (tny_iterator_get_current (iter));
344                         if (header) {
345                                 found =  modest_window_mgr_find_registered_header (mgr, header, NULL);
346                                 g_object_unref (header);
347                         }
348
349                         tny_iterator_next (iter);
350                 }
351                 g_object_unref (iter);
352
353                 if (found) {
354                         gchar *num, *msg;
355
356                         num = g_strdup_printf ("%d", tny_list_get_length (header_list));
357                         msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
358
359                         modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
360                         
361                         g_free (msg);
362                         g_free (num);
363                         g_object_unref (header_list);
364                         return;
365                 }
366         }
367
368         /* Select message */
369         if (tny_list_get_length(header_list) == 1) {
370                 iter = tny_list_create_iterator (header_list);
371                 header = TNY_HEADER (tny_iterator_get_current (iter));
372                 if (header) {
373                         desc = g_strdup_printf ("%s", tny_header_get_subject (header)); 
374                         g_object_unref (header);
375                 }
376
377                 g_object_unref (iter);
378         }
379         message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages", 
380                                            tny_list_get_length(header_list)), desc);
381
382         /* Confirmation dialog */
383         printf("DEBUG: %s\n", __FUNCTION__);    
384         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
385                                                             message);
386         
387
388         if (response == GTK_RESPONSE_OK) {      
389                 ModestWindow *main_window = NULL;
390                 ModestWindowMgr *mgr = NULL;
391                 GtkTreeModel *model = NULL;
392                 GtkTreeSelection *sel = NULL;
393                 GList *sel_list = NULL, *tmp = NULL;
394                 GtkTreeRowReference *row_reference = NULL;
395                 GtkTreePath *next_path = NULL;
396                 TnyFolder *folder = NULL;
397                 GError *err = NULL;
398
399                 /* Find last selected row */                    
400                 if (MODEST_IS_MAIN_WINDOW (win)) {
401                         model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
402                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
403                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
404                         for (tmp=sel_list; tmp; tmp=tmp->next) {
405                                 if (tmp->next == NULL) {
406                                         next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
407                                         gtk_tree_path_next (next_path);
408                                         row_reference = gtk_tree_row_reference_new (model, next_path);
409                                         gtk_tree_path_free (next_path);
410                                 }
411                         }
412                 }
413                 
414                 /* Remove each header. If it's a view window header_view == NULL */
415                 do_headers_action (win, headers_action_delete, header_view);
416
417                 /* refresh the header view (removing marked-as-deleted)*/
418                 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view)); 
419                 
420                 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
421                         modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
422                         
423                         /* Get main window */
424                         mgr = modest_runtime_get_window_mgr ();
425                         main_window = modest_window_mgr_get_main_window (mgr);
426                 }
427                 else {                  
428                         /* Move cursor to next row */
429                         main_window = win; 
430
431                         /* Select next row */
432                         if (gtk_tree_row_reference_valid (row_reference)) {
433                                 next_path = gtk_tree_row_reference_get_path (row_reference);
434                                 gtk_tree_selection_select_path (sel, next_path);
435                                 gtk_tree_path_free (next_path);
436                         }
437                         if (row_reference != NULL)
438                                 gtk_tree_row_reference_free (row_reference);
439                 }
440
441                 /* Get folder from first header and sync it */
442                 iter = tny_list_create_iterator (header_list);
443                 header = TNY_HEADER (tny_iterator_get_current (iter));
444                 folder = tny_header_get_folder (header);
445                 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
446 /*                      tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
447                         tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
448 /*              else if (TNY_IS_CAMEL_POP_FOLDER (folder)) */
449 /*                      tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
450 /*                      tny_folder_sync (folder, TRUE, &err); /\* TRUE --> expunge *\/ */
451                 else
452                         /* local folders */
453 /*                      tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
454                         tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
455
456                 if (err != NULL) {
457                         printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
458                         g_error_free(err);
459                 }
460
461                 g_object_unref (header);
462                 g_object_unref (iter);
463                 g_object_unref (folder);
464                 
465                 /* Update toolbar dimming state */
466                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
467
468                 /* Free */
469                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
470                 g_list_free (sel_list);
471         }
472
473         /* Free*/
474         g_free(message);
475         g_free(desc);
476         g_object_unref (header_list);
477 }
478
479
480
481
482 /* delete either message or folder, based on where we are */
483 void
484 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
485 {
486         g_return_if_fail (MODEST_IS_WINDOW(win));
487         
488         /* Check first if the header view has the focus */
489         if (MODEST_IS_MAIN_WINDOW (win)) {
490                 GtkWidget *w;
491                 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
492                                                          MODEST_WIDGET_TYPE_FOLDER_VIEW);
493                 if (gtk_widget_is_focus (w)) {
494                         modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
495                         return;
496                 }
497         }
498         modest_ui_actions_on_delete_message (action, win);
499 }
500
501
502
503 void
504 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
505 {
506 #ifdef MODEST_PLATFORM_MAEMO
507         modest_osso_save_state();
508 #endif /* MODEST_PLATFORM_MAEMO */
509
510         g_debug ("closing down, clearing %d item(s) from operation queue",
511                  modest_mail_operation_queue_num_elements
512                  (modest_runtime_get_mail_operation_queue()));
513
514         /* cancel all outstanding operations */
515         modest_mail_operation_queue_cancel_all 
516                 (modest_runtime_get_mail_operation_queue());
517         
518         g_debug ("queue has been cleared");
519
520         /* note: when modest-tny-account-store is finalized,
521            it will automatically set all network connections
522            to offline */
523
524         gtk_main_quit ();
525 }
526
527 void
528 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
529 {
530         gboolean ret_value;
531
532         g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
533
534 /*      if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
535 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
536 /*      } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
537 /*              gboolean ret_value; */
538 /*              g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
539 /*      } else if (MODEST_IS_WINDOW (win)) { */
540 /*              gtk_widget_destroy (GTK_WIDGET (win)); */
541 /*      } else { */
542 /*              g_return_if_reached (); */
543 /*      } */
544 }
545
546 void
547 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
548 {
549         GtkClipboard *clipboard = NULL;
550         gchar *selection = NULL;
551
552         clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
553         selection = gtk_clipboard_wait_for_text (clipboard);
554
555         /* Question: why is the clipboard being used here? 
556          * It doesn't really make a lot of sense. */
557
558         if (selection)
559         {
560                 modest_address_book_add_address (selection);
561                 g_free (selection);
562         }
563 }
564
565 void
566 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
567 {
568         /* This is currently only implemented for Maemo */
569 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
570         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
571                 run_account_setup_wizard (win);
572                 return;
573         } else  {
574                 /* Show the list of accounts: */
575                 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
576                 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
577                 
578                 /* Don't make this a modal window, because secondary windows will then 
579                  * be unusable, freezing the UI: */
580                 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
581                 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win); 
582         }
583 #else
584         GtkWidget *dialog, *label;
585         
586         /* Create the widgets */
587         
588         dialog = gtk_dialog_new_with_buttons ("Message",
589                                               GTK_WINDOW(win),
590                                               GTK_DIALOG_DESTROY_WITH_PARENT,
591                                               GTK_STOCK_OK,
592                                               GTK_RESPONSE_NONE,
593                                               NULL);
594         label = gtk_label_new ("Hello World!");
595         
596         /* Ensure that the dialog box is destroyed when the user responds. */
597         
598         g_signal_connect_swapped (dialog, "response", 
599                                   G_CALLBACK (gtk_widget_destroy),
600                                   dialog);
601         
602         /* Add the label, and show everything we've added to the dialog. */
603         
604         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
605                            label);
606         gtk_widget_show_all (dialog);
607 #endif /* MODEST_PLATFORM_MAEMO */
608 }
609
610 static void
611 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
612 {
613         ModestWindow *main_window = MODEST_WINDOW (user_data);
614         
615         /* Save any changes. */
616         modest_connection_specific_smtp_window_save_server_accounts (
617                         MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window), 
618                         modest_window_get_active_account (main_window));
619         gtk_widget_destroy (GTK_WIDGET (window));
620 }
621
622
623
624 void
625 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
626 {
627         /* This is currently only implemented for Maemo,
628          * because it requires an API (libconic) to detect different connection 
629          * possiblities.
630          */
631 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
632         
633         /* Create the window if necessary: */
634         const gchar *active_account_name = modest_window_get_active_account (win);
635         
636         /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
637          * or show the default account?
638          * If we show the default account then the account name should be shown in 
639          * the window when we show it. */
640         if (!active_account_name) {
641                 g_warning ("%s: No account is active.", __FUNCTION__);
642                 return;
643         }
644                 
645         GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
646         modest_connection_specific_smtp_window_fill_with_connections (
647                 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), 
648                 modest_runtime_get_account_mgr(), 
649                 active_account_name);
650
651         /* Show the window: */  
652         gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
653         gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
654         gtk_widget_show (specific_window);
655     
656         /* Save changes when the window is hidden: */
657         g_signal_connect (specific_window, "hide", 
658                 G_CALLBACK (on_smtp_servers_window_hide), win);
659 #endif /* MODEST_PLATFORM_MAEMO */
660 }
661
662 void
663 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
664 {
665         ModestWindow *msg_win = NULL;
666         TnyMsg *msg = NULL;
667         TnyFolder *folder = NULL;
668         gchar *account_name = NULL;
669         gchar *from_str = NULL;
670 /*      GError *err = NULL; */
671         TnyAccount *account = NULL;
672         ModestWindowMgr *mgr;
673         gchar *signature = NULL, *blank_and_signature = NULL;
674
675         /* if there are no accounts yet, just show the wizard */
676         if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
677                         run_account_setup_wizard (win);
678                         return;
679         }
680         
681         account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
682         if (!account_name)
683                 account_name = g_strdup (modest_window_get_active_account (win));
684         if (!account_name) {
685                 g_printerr ("modest: no account found\n");
686                 goto cleanup;
687         }
688         
689         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
690                                                                        account_name,
691                                                                        TNY_ACCOUNT_TYPE_STORE);
692         if (!account) {
693                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
694                 goto cleanup;
695         }
696
697         from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
698         if (!from_str) {
699                 g_printerr ("modest: failed get from string for '%s'\n", account_name);
700                 goto cleanup;
701         }
702
703         if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
704                                          MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
705                 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
706                                                            MODEST_ACCOUNT_SIGNATURE, FALSE);
707                 blank_and_signature = g_strconcat ("\n", signature, NULL);
708                 g_free (signature);
709         } else {
710                 blank_and_signature = g_strdup ("");
711         }
712
713         msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
714         if (!msg) {
715                 g_printerr ("modest: failed to create new msg\n");
716                 goto cleanup;
717         }
718         
719         folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
720         if (!folder) {
721                 g_printerr ("modest: failed to find Drafts folder\n");
722                 goto cleanup;
723         }
724         
725
726         /* Create and register edit window */
727         /* This is destroyed by TOOD. */
728         msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
729         mgr = modest_runtime_get_window_mgr ();
730         modest_window_mgr_register_window (mgr, msg_win);
731
732         if (win)
733                 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
734                                               GTK_WINDOW (win));        
735         gtk_widget_show_all (GTK_WIDGET (msg_win));
736
737 cleanup:
738         g_free (account_name);
739         g_free (from_str);
740         g_free (blank_and_signature);
741         if (msg_win)
742                 g_object_unref (msg_win);
743         if (account)
744                 g_object_unref (G_OBJECT(account));
745         if (msg)
746                 g_object_unref (G_OBJECT(msg));
747         if (folder)
748                 g_object_unref (G_OBJECT(folder));
749 }
750
751 gboolean 
752 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
753                                        TnyHeader *header,
754                                        TnyMsg *msg)
755 {
756         ModestMailOperationStatus status;
757
758         /* If there is no message or the operation was not successful */
759         status = modest_mail_operation_get_status (mail_op);
760         if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
761
762                 /* Remove the header from the preregistered uids */
763                 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),  
764                                                      header);
765
766                 return FALSE;
767         }
768
769         return TRUE;
770 }
771
772 static void
773 open_msg_cb (ModestMailOperation *mail_op, 
774              TnyHeader *header, 
775              TnyMsg *msg, 
776              gpointer user_data)
777 {
778         ModestWindowMgr *mgr = NULL;
779         ModestWindow *parent_win = NULL;
780         ModestWindow *win = NULL;
781         TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
782         gchar *account = NULL;
783         TnyFolder *folder;
784         
785         /* Do nothing if there was any problem with the mail
786            operation. The error will be shown by the error_handler of
787            the mail operation */
788         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
789                 return;
790         }
791
792         parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
793         folder = tny_header_get_folder (header);
794
795         /* Mark header as read */
796         headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
797
798         /* Get account */
799         account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
800         if (!account)
801                 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
802         
803         /* Gets folder type (OUTBOX headers will be opened in edit window */
804         if (modest_tny_folder_is_local_folder (folder))
805                 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
806
807         /* If the header is in the drafts folder then open the editor,
808            else the message view window */
809         if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
810             (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
811                 /* we cannot edit without a valid account... */
812                 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
813                         run_account_setup_wizard(parent_win);
814                         goto cleanup;
815                 }
816                 win = modest_msg_edit_window_new (msg, account, TRUE);
817                 
818         } else {
819                 gchar *uid = modest_tny_folder_get_header_unique_id (header);
820                 
821                 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
822                         GtkWidget *header_view;
823                         GtkTreeSelection *sel;
824                         GList *sel_list = NULL;
825                         GtkTreeModel *model;
826                         
827                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
828                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
829
830                         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
831                         sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
832
833                         if (sel_list != NULL) {
834                                 GtkTreeRowReference *row_reference;
835
836                                 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
837                                 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
838                                 g_list_free (sel_list);
839                                 
840                                 win = modest_msg_view_window_new_with_header_model (msg, 
841                                                                                     account,
842                                                                                     (const gchar*) uid,
843                                                                                     model, 
844                                                                                     row_reference);
845                                 gtk_tree_row_reference_free (row_reference);
846                         } else {
847                                 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
848                         }
849                 } else {
850                         win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
851                 }
852                 g_free (uid);
853         }
854         
855         /* Register and show new window */
856         if (win != NULL) {
857                 mgr = modest_runtime_get_window_mgr ();
858                 modest_window_mgr_register_window (mgr, win);
859                 g_object_unref (win);
860                 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
861                 gtk_widget_show_all (GTK_WIDGET(win));
862         }
863
864         /* Update toolbar dimming state */
865         if (MODEST_IS_MAIN_WINDOW (parent_win)) {
866                 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
867         }
868
869 cleanup:
870         /* Free */
871         g_free(account);
872         g_object_unref (parent_win);
873         g_object_unref (folder);
874 }
875
876 void
877 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
878                                                gpointer user_data)
879 {
880         const GError *error;
881         GObject *win = modest_mail_operation_get_source (mail_op);
882
883         error = modest_mail_operation_get_error (mail_op);
884         printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
885  
886         if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
887
888                 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
889                                                         error->message);
890         } else {
891                 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
892                                                         _("mail_ni_ui_folder_get_msg_folder_error"));
893         }
894
895         if (win)
896                 g_object_unref (win);
897 }
898
899 /*
900  * This function is used by both modest_ui_actions_on_open and
901  * modest_ui_actions_on_header_activated. This way we always do the
902  * same when trying to open messages.
903  */
904 static void
905 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
906 {
907         ModestWindowMgr *mgr = NULL;
908         TnyIterator *iter = NULL;
909         ModestMailOperation *mail_op = NULL;
910         TnyList *not_opened_headers = NULL;
911         TnyHeaderFlags flags = 0;
912                 
913         /* Look if we already have a message view for each header. If
914            true, then remove the header from the list of headers to
915            open */
916         mgr = modest_runtime_get_window_mgr ();
917         iter = tny_list_create_iterator (headers);
918         not_opened_headers = tny_simple_list_new ();
919
920         while (!tny_iterator_is_done (iter)) {
921
922                 ModestWindow *window = NULL;
923                 TnyHeader *header = NULL;
924                 gboolean found = FALSE;
925                 
926                 header = TNY_HEADER (tny_iterator_get_current (iter));
927                 if (header)
928                         flags = tny_header_get_flags (header);
929
930                 window = NULL;
931                 found = modest_window_mgr_find_registered_header (mgr, header, &window);
932                 
933                 /* Do not open again the message and present the
934                    window to the user */
935                 if (found) {
936                         if (window)
937                                 gtk_window_present (GTK_WINDOW (window));
938                         else
939                                 /* the header has been registered already, we don't do
940                                  * anything but wait for the window to come up*/
941                                 g_debug ("header %p already registered, waiting for window", header);
942                 } else {
943                         tny_list_append (not_opened_headers, G_OBJECT (header));
944                 }
945
946                 if (header)
947                         g_object_unref (header);
948
949                 tny_iterator_next (iter);
950         }
951         g_object_unref (iter);
952         iter = NULL;
953         
954         /* If some messages would have to be downloaded, ask the user to 
955          * make a connection. It's generally easier to do this here (in the mainloop) 
956          * than later in a thread:
957          */
958         if (tny_list_get_length (not_opened_headers) > 0) {
959                 TnyIterator *iter;
960                 gboolean found = FALSE;
961
962                 iter = tny_list_create_iterator (not_opened_headers);
963                 while (!tny_iterator_is_done (iter) && !found) {
964                         TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
965                         if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
966                                 found = TRUE;
967                         else
968                                 tny_iterator_next (iter);
969
970                         g_object_unref (header);
971                 }
972                 g_object_unref (iter);
973
974                 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
975                         g_object_unref (not_opened_headers);
976                         return;                 
977                 }
978         }
979         
980         /* Register the headers before actually creating the windows: */
981         TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
982         while (!tny_iterator_is_done (iter_not_opened)) {
983                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
984                 if (header) {
985                         modest_window_mgr_register_header (mgr, header);
986                         g_object_unref (header);
987                 }
988                 
989                 tny_iterator_next (iter_not_opened);
990         }
991         g_object_unref (iter_not_opened);
992         iter_not_opened = NULL;
993         
994         /* Open each message */
995         if (tny_list_get_length (not_opened_headers) > 0) {
996                 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
997                                                                          G_OBJECT (win), 
998                                                                          modest_ui_actions_get_msgs_full_error_handler, 
999                                                                          NULL);
1000                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1001                 if (tny_list_get_length (not_opened_headers) > 1) {
1002                         modest_mail_operation_get_msgs_full (mail_op, 
1003                                                              not_opened_headers, 
1004                                                              open_msg_cb, 
1005                                                              NULL, 
1006                                                              NULL);
1007                 } else {
1008                         TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1009                         TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1010                         modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1011                         g_object_unref (header);
1012                         g_object_unref (iter);
1013                 }
1014                 g_object_unref (mail_op);
1015         }
1016
1017         /* Clean */
1018         if (not_opened_headers != NULL)
1019                 g_object_unref (not_opened_headers);
1020 }
1021
1022 void
1023 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1024 {
1025         TnyList *headers;
1026
1027         /* Get headers */
1028         headers = get_selected_headers (win);
1029         if (!headers)
1030                 return;
1031
1032         /* Open them */
1033         _modest_ui_actions_open (headers, win);
1034
1035         g_object_unref(headers);
1036 }
1037
1038
1039 static void
1040 free_reply_forward_helper (gpointer data)
1041 {
1042         ReplyForwardHelper *helper;
1043
1044         helper = (ReplyForwardHelper *) data;
1045         g_free (helper->account_name);
1046         g_slice_free (ReplyForwardHelper, helper);
1047 }
1048
1049 static void
1050 reply_forward_cb (ModestMailOperation *mail_op, 
1051                   TnyHeader *header, 
1052                   TnyMsg *msg,
1053                   gpointer user_data)
1054 {
1055         TnyMsg *new_msg;
1056         ReplyForwardHelper *rf_helper;
1057         ModestWindow *msg_win = NULL;
1058         ModestEditType edit_type;
1059         gchar *from = NULL;
1060         TnyAccount *account = NULL;
1061         ModestWindowMgr *mgr = NULL;
1062         gchar *signature = NULL;
1063
1064         /* If there was any error. The mail operation could be NULL,
1065            this means that we already have the message downloaded and
1066            that we didn't do a mail operation to retrieve it */
1067         if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1068                 return;
1069                         
1070         g_return_if_fail (user_data != NULL);
1071         rf_helper = (ReplyForwardHelper *) user_data;
1072
1073         from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1074                                                    rf_helper->account_name);
1075         if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1076                                          rf_helper->account_name,
1077                                          MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1078                 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1079                                                            rf_helper->account_name,
1080                                                            MODEST_ACCOUNT_SIGNATURE, FALSE);
1081         }
1082
1083         /* Create reply mail */
1084         switch (rf_helper->action) {
1085         case ACTION_REPLY:
1086                 new_msg = 
1087                         modest_tny_msg_create_reply_msg (msg, header, from, signature,
1088                                                          rf_helper->reply_forward_type,
1089                                                          MODEST_TNY_MSG_REPLY_MODE_SENDER);
1090                 break;
1091         case ACTION_REPLY_TO_ALL:
1092                 new_msg = 
1093                         modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1094                                                          MODEST_TNY_MSG_REPLY_MODE_ALL);
1095                 edit_type = MODEST_EDIT_TYPE_REPLY;
1096                 break;
1097         case ACTION_FORWARD:
1098                 new_msg = 
1099                         modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1100                 edit_type = MODEST_EDIT_TYPE_FORWARD;
1101                 break;
1102         default:
1103                 g_return_if_reached ();
1104                 return;
1105         }
1106
1107         g_free (signature);
1108
1109         if (!new_msg) {
1110                 g_printerr ("modest: failed to create message\n");
1111                 goto cleanup;
1112         }
1113
1114         account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1115                                                                        rf_helper->account_name,
1116                                                                        TNY_ACCOUNT_TYPE_STORE);
1117         if (!account) {
1118                 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1119                 goto cleanup;
1120         }
1121
1122         /* Create and register the windows */
1123         msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1124         mgr = modest_runtime_get_window_mgr ();
1125         modest_window_mgr_register_window (mgr, msg_win);
1126
1127         if (rf_helper->parent_window != NULL) {
1128                 gdouble parent_zoom;
1129
1130                 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1131                 modest_window_set_zoom (msg_win, parent_zoom);
1132         }
1133
1134         /* Show edit window */
1135         gtk_widget_show_all (GTK_WIDGET (msg_win));
1136
1137 cleanup:
1138         if (msg_win)
1139                 g_object_unref (msg_win);
1140         if (new_msg)
1141                 g_object_unref (G_OBJECT (new_msg));
1142         if (account)
1143                 g_object_unref (G_OBJECT (account));
1144 /*      g_object_unref (msg); */
1145         free_reply_forward_helper (rf_helper);
1146 }
1147
1148 /*
1149  * Checks a list of headers. If any of them are not currently
1150  * downloaded (CACHED) then it asks the user for permission to
1151  * download them.
1152  *
1153  * Returns FALSE if the user does not want to download the
1154  * messages. Returns TRUE if the user allowed the download or if all
1155  * of them are currently downloaded
1156  */
1157 static gboolean
1158 download_uncached_messages (TnyList *header_list, 
1159                             GtkWindow *win,
1160                             gboolean reply_fwd)
1161 {
1162         TnyIterator *iter;
1163         gboolean retval;
1164         gint uncached_messages = 0;
1165
1166         iter = tny_list_create_iterator (header_list);
1167         while (!tny_iterator_is_done (iter)) {
1168                 TnyHeader *header;
1169
1170                 header = TNY_HEADER (tny_iterator_get_current (iter));
1171                 if (header) {
1172                         if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1173                                 uncached_messages ++;
1174                         g_object_unref (header);
1175                 }
1176
1177                 tny_iterator_next (iter);
1178         }
1179         g_object_unref (iter);
1180
1181         /* Ask for user permission to download the messages */
1182         retval = TRUE;
1183         if (uncached_messages > 0) {
1184                 GtkResponseType response;
1185                 if (reply_fwd)
1186                         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1187                                                                             _("emev_nc_include_original"));
1188                 else
1189                         response =
1190                                 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1191                                                                          ngettext("mcen_nc_get_msg",
1192                                                                                   "mcen_nc_get_msgs",
1193                                                                                   uncached_messages));
1194                 if (response == GTK_RESPONSE_CANCEL)
1195                         retval = FALSE;
1196                 else {
1197                         /* If a download will be necessary, make sure that we have a connection: */
1198                         retval = modest_platform_connect_and_wait(win, NULL);   
1199                 }
1200         }
1201         return retval;
1202 }
1203
1204
1205 /*
1206  * Common code for the reply and forward actions
1207  */
1208 static void
1209 reply_forward (ReplyForwardAction action, ModestWindow *win)
1210 {
1211         ModestMailOperation *mail_op = NULL;
1212         TnyList *header_list = NULL;
1213         ReplyForwardHelper *rf_helper = NULL;
1214         guint reply_forward_type;
1215         gboolean continue_download = TRUE;
1216         gboolean do_retrieve = TRUE;
1217         
1218         g_return_if_fail (MODEST_IS_WINDOW(win));
1219
1220         /* we need an account when editing */
1221         if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1222                 run_account_setup_wizard (win);
1223                 return;
1224         }
1225         
1226         header_list = get_selected_headers (win);
1227         if (!header_list)
1228                 return;
1229
1230         reply_forward_type = 
1231                 modest_conf_get_int (modest_runtime_get_conf (),
1232                                      (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1233                                      NULL);
1234
1235         /* Check that the messages have been previously downloaded */
1236         do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1237         if (do_retrieve)
1238                 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1239         if (!continue_download) {
1240                 g_object_unref (header_list);
1241                 return;
1242         }
1243         
1244         /* We assume that we can only select messages of the
1245            same folder and that we reply all of them from the
1246            same account. In fact the interface currently only
1247            allows single selection */
1248         
1249         /* Fill helpers */
1250         rf_helper = g_slice_new0 (ReplyForwardHelper);
1251         rf_helper->reply_forward_type = reply_forward_type;
1252         rf_helper->action = action;
1253         rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1254         
1255         if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1256                 rf_helper->parent_window = GTK_WIDGET (win);
1257         if (!rf_helper->account_name)
1258                 rf_helper->account_name =
1259                         modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1260
1261         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1262                 TnyMsg *msg;
1263                 TnyHeader *header;
1264                 /* Get header and message. Do not free them here, the
1265                    reply_forward_cb must do it */
1266                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1267                 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1268                 if (!msg || !header) {
1269                         if (msg)
1270                                 g_object_unref (msg);
1271                         g_printerr ("modest: no message found\n");
1272                         return;
1273                 } else {
1274                         reply_forward_cb (NULL, header, msg, rf_helper);
1275                 }
1276                 if (header)
1277                         g_object_unref (header);
1278         } else {
1279                 TnyHeader *header;
1280                 TnyIterator *iter;
1281
1282                 /* Only reply/forward to one message */
1283                 iter = tny_list_create_iterator (header_list);
1284                 header = TNY_HEADER (tny_iterator_get_current (iter));
1285                 g_object_unref (iter);
1286
1287                 if (header) {
1288                         /* Retrieve messages */
1289                         if (do_retrieve) {
1290                                 mail_op = modest_mail_operation_new_with_error_handling (
1291                                         MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
1292                                         G_OBJECT(win),
1293                                         modest_ui_actions_get_msgs_full_error_handler, 
1294                                         NULL);
1295                                 modest_mail_operation_queue_add (
1296                                         modest_runtime_get_mail_operation_queue (), mail_op);
1297                                 
1298                                 modest_mail_operation_get_msg (mail_op,
1299                                                                header,
1300                                                                reply_forward_cb,
1301                                                                rf_helper);
1302                                 /* Clean */
1303                                 g_object_unref(mail_op);
1304                         } else {
1305                                 /* we put a ref here to prevent double unref as the reply
1306                                  * forward callback unrefs the header at its end */
1307                                 reply_forward_cb (NULL, header, NULL, rf_helper);
1308                         }
1309
1310
1311                         g_object_unref (header);
1312                 }
1313
1314         }
1315
1316         /* Free */
1317         g_object_unref (header_list);
1318 }
1319
1320 void
1321 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1322 {
1323         g_return_if_fail (MODEST_IS_WINDOW(win));
1324
1325         reply_forward (ACTION_REPLY, win);
1326 }
1327
1328 void
1329 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1330 {
1331         g_return_if_fail (MODEST_IS_WINDOW(win));
1332
1333         reply_forward (ACTION_FORWARD, win);
1334 }
1335
1336 void
1337 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1338 {
1339         g_return_if_fail (MODEST_IS_WINDOW(win));
1340
1341         reply_forward (ACTION_REPLY_TO_ALL, win);
1342 }
1343
1344 void 
1345 modest_ui_actions_on_next (GtkAction *action, 
1346                            ModestWindow *window)
1347 {
1348         if (MODEST_IS_MAIN_WINDOW (window)) {
1349                 GtkWidget *header_view;
1350
1351                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1352                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1353                 if (!header_view)
1354                         return;
1355         
1356                 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); 
1357         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1358                 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1359         } else {
1360                 g_return_if_reached ();
1361         }
1362 }
1363
1364 void 
1365 modest_ui_actions_on_prev (GtkAction *action, 
1366                            ModestWindow *window)
1367 {
1368         g_return_if_fail (MODEST_IS_WINDOW(window));
1369
1370         if (MODEST_IS_MAIN_WINDOW (window)) {
1371                 GtkWidget *header_view;
1372                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1373                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1374                 if (!header_view)
1375                         return;
1376                 
1377                 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); 
1378         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1379                 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1380         } else {
1381                 g_return_if_reached ();
1382         }
1383 }
1384
1385 void 
1386 modest_ui_actions_on_sort (GtkAction *action, 
1387                            ModestWindow *window)
1388 {
1389         g_return_if_fail (MODEST_IS_WINDOW(window));
1390
1391         if (MODEST_IS_MAIN_WINDOW (window)) {
1392                 GtkWidget *header_view;
1393                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1394                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
1395                 if (!header_view) {
1396                         modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1397
1398                         return;
1399                 }
1400
1401                 /* Show sorting dialog */
1402                 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);     
1403         }
1404 }
1405
1406 static void
1407 new_messages_arrived (ModestMailOperation *self, 
1408                       gint new_messages,
1409                       gpointer user_data)
1410 {
1411         if (new_messages == 0)
1412                 return;
1413
1414         modest_platform_on_new_msg ();
1415 }
1416
1417 /*
1418  * This function performs the send & receive required actions. The
1419  * window is used to create the mail operation. Typically it should
1420  * always be the main window, but we pass it as argument in order to
1421  * be more flexible.
1422  */
1423 void
1424 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1425 {
1426         gchar *acc_name = NULL;
1427         ModestMailOperation *mail_op;
1428
1429         /* If no account name was provided then get the current account, and if
1430            there is no current account then pick the default one: */
1431         if (!account_name) {
1432                 acc_name = g_strdup (modest_window_get_active_account(win));
1433                 if (!acc_name)
1434                         acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1435                 if (!acc_name) {
1436                         g_printerr ("modest: cannot get default account\n");
1437                         return;
1438                 }
1439         } else {
1440                 acc_name = g_strdup (account_name);
1441         }
1442
1443         /* Set send/receive operation in progress */    
1444         modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1445
1446         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1447                                                                  G_OBJECT (win),
1448                                                                  modest_ui_actions_send_receive_error_handler,
1449                                                                  NULL);
1450
1451         g_signal_connect (G_OBJECT(mail_op), "progress-changed", 
1452                           G_CALLBACK (_on_send_receive_progress_changed), 
1453                           win);
1454
1455         /* Send & receive. */
1456         /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1457         /* Receive and then send. The operation is tagged initially as
1458            a receive operation because the account update performs a
1459            receive and then a send. The operation changes its type
1460            internally, so the progress objects will receive the proper
1461            progress information */
1462         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1463         modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1464         g_object_unref (G_OBJECT (mail_op));
1465         
1466         /* Free */
1467         g_free (acc_name);
1468 }
1469
1470
1471 static void
1472 modest_ui_actions_do_cancel_send (const gchar *account_name,  
1473                                   ModestWindow *win)
1474 {
1475         TnyTransportAccount *transport_account;
1476         TnySendQueue *send_queue = NULL;
1477         GError *error = NULL;
1478
1479         /* Get transport account */
1480         transport_account =
1481                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1482                                       (modest_runtime_get_account_store(),
1483                                        account_name,
1484                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1485         if (!transport_account) {
1486                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1487                 goto frees;
1488         }
1489
1490         /* Get send queue*/
1491         send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1492         if (!TNY_IS_SEND_QUEUE(send_queue)) {
1493                 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1494                              MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1495                              "modest: could not find send queue for account\n");
1496         } else {
1497                 /* Keeep messages in outbox folder */
1498                 tny_send_queue_cancel (send_queue, FALSE, &error);
1499         }       
1500
1501  frees:
1502         if (transport_account != NULL) 
1503                 g_object_unref (G_OBJECT (transport_account));
1504 }
1505
1506 static void
1507 modest_ui_actions_cancel_send_all (ModestWindow *win) 
1508 {
1509         GSList *account_names, *iter;
1510
1511         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1512                                                           TRUE);
1513
1514         iter = account_names;
1515         while (iter) {                  
1516                 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1517                 iter = g_slist_next (iter);
1518         }
1519
1520         modest_account_mgr_free_account_names (account_names);
1521         account_names = NULL;
1522 }
1523
1524 void
1525 modest_ui_actions_cancel_send (GtkAction *action,  ModestWindow *win)
1526
1527 {
1528         /* Check if accounts exist */
1529         gboolean accounts_exist = 
1530                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1531         
1532         /* If not, allow the user to create an account before trying to send/receive. */
1533         if (!accounts_exist)
1534                 modest_ui_actions_on_accounts (NULL, win);
1535         
1536         /* Cancel all sending operaitons */     
1537         modest_ui_actions_cancel_send_all (win);
1538 }
1539
1540 /*
1541  * Refreshes all accounts. This function will be used by automatic
1542  * updates
1543  */
1544 void
1545 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1546 {
1547         GSList *account_names, *iter;
1548
1549         account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), 
1550                                                           TRUE);
1551
1552         iter = account_names;
1553         while (iter) {                  
1554                 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1555                 iter = g_slist_next (iter);
1556         }
1557
1558         modest_account_mgr_free_account_names (account_names);
1559         account_names = NULL;
1560 }
1561
1562 void 
1563 modest_do_refresh_current_folder(ModestWindow *win)
1564 {
1565         /* Refresh currently selected folder. Note that if we only
1566            want to retreive the headers, then the refresh only will
1567            invoke a poke_status over all folders, i.e., only the
1568            total/unread count will be updated */
1569         if (MODEST_IS_MAIN_WINDOW (win)) {
1570                 GtkWidget *header_view, *folder_view;
1571                 TnyFolderStore *folder_store;
1572
1573                 /* Get folder and header view */
1574                 folder_view = 
1575                         modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), 
1576                                                              MODEST_WIDGET_TYPE_FOLDER_VIEW);
1577
1578                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1579
1580                 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1581                         header_view = 
1582                                 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1583                                                                      MODEST_WIDGET_TYPE_HEADER_VIEW);
1584                 
1585                         /* We do not need to set the contents style
1586                            because it hasn't changed. We also do not
1587                            need to save the widget status. Just force
1588                            a refresh */
1589                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1590                                                        TNY_FOLDER (folder_store),
1591                                                        folder_refreshed_cb,
1592                                                        MODEST_MAIN_WINDOW (win));
1593                 }
1594                 
1595                 if (folder_store)
1596                         g_object_unref (folder_store);
1597         }
1598 }
1599
1600
1601 /*
1602  * Handler of the click on Send&Receive button in the main toolbar
1603  */
1604 void
1605 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1606 {
1607         /* Check if accounts exist */
1608         gboolean accounts_exist = 
1609                 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1610         
1611         /* If not, allow the user to create an account before trying to send/receive. */
1612         if (!accounts_exist)
1613                 modest_ui_actions_on_accounts (NULL, win);
1614
1615         modest_do_refresh_current_folder (win);
1616         
1617         /* Refresh the active account */
1618         modest_ui_actions_do_send_receive (NULL, win);
1619 }
1620
1621
1622 void
1623 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1624 {
1625         ModestConf *conf;
1626         GtkWidget *header_view;
1627         
1628         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1629
1630         header_view = modest_main_window_get_child_widget (main_window,
1631                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
1632         if (!header_view)
1633                 return;
1634
1635         conf = modest_runtime_get_conf ();
1636         
1637         /* what is saved/restored is depending on the style; thus; we save with
1638          * old style, then update the style, and restore for this new style
1639          */
1640         modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1641         
1642         if (modest_header_view_get_style
1643             (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1644                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1645                                               MODEST_HEADER_VIEW_STYLE_TWOLINES);
1646         else
1647                 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1648                                               MODEST_HEADER_VIEW_STYLE_DETAILS);
1649
1650         modest_widget_memory_restore (conf, G_OBJECT(header_view),
1651                                       MODEST_CONF_HEADER_VIEW_KEY);
1652 }
1653
1654
1655 void 
1656 modest_ui_actions_on_header_selected (ModestHeaderView *header_view, 
1657                                       TnyHeader *header,
1658                                       ModestMainWindow *main_window)
1659 {
1660         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1661         g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1662         
1663         /* in the case the folder is empty, show the empty folder message and focus
1664          * folder view */
1665         if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1666                 if (modest_header_view_is_empty (header_view)) {
1667                         TnyFolder *folder = modest_header_view_get_folder (header_view);
1668                         GtkWidget *folder_view = 
1669                                 modest_main_window_get_child_widget (main_window,
1670                                                                      MODEST_WIDGET_TYPE_FOLDER_VIEW);
1671                         if (folder != NULL) 
1672                                 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1673                         gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1674                         return;
1675                 }
1676         }
1677         /* If no header has been selected then exit */
1678         if (!header)
1679                 return;
1680
1681         /* Update focus */
1682         if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1683             gtk_widget_grab_focus (GTK_WIDGET(header_view));
1684
1685         /* Update Main window title */
1686         if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1687                 const gchar *subject = tny_header_get_subject (header);
1688                 if (subject && strlen(subject) > 0)
1689                         gtk_window_set_title (GTK_WINDOW (main_window), subject);
1690                 else
1691                         gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1692         }
1693
1694         /* Update toolbar dimming state */
1695         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1696 }
1697
1698 void
1699 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1700                                        TnyHeader *header,
1701                                        ModestMainWindow *main_window)
1702 {
1703         TnyList *headers;
1704
1705         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1706         
1707         if (!header)
1708                 return;
1709
1710         headers = tny_simple_list_new ();
1711         tny_list_prepend (headers, G_OBJECT (header));
1712
1713         _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1714
1715         g_object_unref (headers);
1716 }
1717
1718 static void
1719 set_active_account_from_tny_account (TnyAccount *account,
1720                                      ModestWindow *window)
1721 {
1722         const gchar *server_acc_name = tny_account_get_id (account);
1723         
1724         /* We need the TnyAccount provided by the
1725            account store because that is the one that
1726            knows the name of the Modest account */
1727         TnyAccount *modest_server_account = modest_server_account = 
1728                 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1729                                                              MODEST_TNY_ACCOUNT_STORE_QUERY_ID, 
1730                                                              server_acc_name);
1731         
1732         const gchar *modest_acc_name = 
1733                 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1734         modest_window_set_active_account (window, modest_acc_name);
1735         g_object_unref (modest_server_account);
1736 }
1737
1738
1739 static void
1740 folder_refreshed_cb (ModestMailOperation *mail_op, 
1741                      TnyFolder *folder, 
1742                      gpointer user_data)
1743 {
1744         ModestMainWindow *win = NULL;
1745         GtkWidget *header_view;
1746         TnyFolder *current_folder;
1747
1748         g_return_if_fail (TNY_IS_FOLDER (folder));
1749
1750         win = MODEST_MAIN_WINDOW (user_data);
1751         header_view = 
1752                 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1753
1754         if (header_view) {
1755                 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1756                 if (current_folder != NULL && folder != current_folder) {
1757                         return;
1758                 }
1759         }
1760
1761         /* Check if folder is empty and set headers view contents style */
1762         if (tny_folder_get_all_count (folder) == 0) {
1763         printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1764                 modest_main_window_set_contents_style (win,
1765                                                        MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1766         } else {
1767                 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1768         }
1769 }
1770
1771 void 
1772 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1773                                                TnyFolderStore *folder_store, 
1774                                                gboolean selected,
1775                                                ModestMainWindow *main_window)
1776 {
1777         ModestConf *conf;
1778         GtkWidget *header_view;
1779
1780         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1781
1782         header_view = modest_main_window_get_child_widget(main_window,
1783                                                           MODEST_WIDGET_TYPE_HEADER_VIEW);
1784         if (!header_view)
1785                 return;
1786         
1787         conf = modest_runtime_get_conf ();
1788
1789         if (TNY_IS_ACCOUNT (folder_store)) {
1790                 if (selected) {
1791                         /* Update active account */
1792                         set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1793                         /* Show account details */
1794                         modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1795                 }
1796         } else {
1797                 if (TNY_IS_FOLDER (folder_store) && selected) {
1798                         
1799                         /* Update the active account */
1800                         TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1801                         if (account) {
1802                                 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1803                                 g_object_unref (account);
1804                                 account = NULL;
1805                         }
1806
1807                         /* Set the header style by default, it could
1808                            be changed later by the refresh callback to
1809                            empty */
1810                         modest_main_window_set_contents_style (main_window, 
1811                                                                MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1812
1813                         /* Set folder on header view. This function
1814                            will call tny_folder_refresh_async so we
1815                            pass a callback that will be called when
1816                            finished. We use that callback to set the
1817                            empty view if there are no messages */
1818                         modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1819                                                        TNY_FOLDER (folder_store),
1820                                                        folder_refreshed_cb,
1821                                                        main_window);
1822                         
1823                         /* Restore configuration. We need to do this
1824                            *after* the set_folder because the widget
1825                            memory asks the header view about its
1826                            folder  */
1827                         modest_widget_memory_restore (modest_runtime_get_conf (), 
1828                                                       G_OBJECT(header_view),
1829                                                       MODEST_CONF_HEADER_VIEW_KEY);
1830                 } else {
1831                         /* Update the active account */
1832                         modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1833                         /* Save only if we're seeing headers */
1834                         if (modest_main_window_get_contents_style (main_window) ==
1835                             MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1836                                 modest_widget_memory_save (conf, G_OBJECT (header_view), 
1837                                                            MODEST_CONF_HEADER_VIEW_KEY);
1838                         modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1839                 }
1840         }
1841
1842         /* Update toolbar dimming state */
1843         modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1844 }
1845
1846 void 
1847 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1848                                      ModestWindow *win)
1849 {
1850         GtkWidget *dialog;
1851         gchar *txt, *item;
1852         gboolean online;
1853
1854         item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1855         
1856         online = tny_device_is_online (modest_runtime_get_device());
1857
1858         if (online) {
1859                 /* already online -- the item is simply not there... */
1860                 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1861                                                  GTK_DIALOG_MODAL,
1862                                                  GTK_MESSAGE_WARNING,
1863                                                  GTK_BUTTONS_OK,
1864                                                  _("The %s you selected cannot be found"),
1865                                                  item);
1866                 gtk_dialog_run (GTK_DIALOG(dialog));
1867         } else {
1868                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1869                                                       GTK_WINDOW (win),
1870                                                       GTK_DIALOG_MODAL,
1871                                                       GTK_STOCK_CANCEL,
1872                                                       GTK_RESPONSE_REJECT,
1873                                                       GTK_STOCK_OK,
1874                                                       GTK_RESPONSE_ACCEPT,
1875                                                       NULL);
1876                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1877                                          "Do you want to get online?"), item);
1878                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
1879                                     gtk_label_new (txt), FALSE, FALSE, 0);
1880                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1881                 g_free (txt);
1882
1883                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1884                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1885                         /* TODO: Comment about why is this commented out: */
1886                         /* modest_platform_connect_and_wait (); */
1887                 }
1888         }
1889         gtk_widget_destroy (dialog);
1890 }
1891
1892 void
1893 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1894                                      ModestWindow *win)
1895 {
1896         /* g_message ("%s %s", __FUNCTION__, link); */
1897 }       
1898
1899
1900 void
1901 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1902                                         ModestWindow *win)
1903 {
1904         modest_platform_activate_uri (link);
1905 }
1906
1907 void
1908 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1909                                           ModestWindow *win)
1910 {
1911         modest_platform_show_uri_popup (link);
1912 }
1913
1914 void
1915 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1916                                              ModestWindow *win)
1917 {
1918         modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1919 }
1920
1921 void
1922 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1923                                           const gchar *address,
1924                                           ModestWindow *win)
1925 {
1926         /* g_message ("%s %s", __FUNCTION__, address); */
1927 }
1928
1929 void
1930 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1931 {
1932         TnyTransportAccount *transport_account;
1933         ModestMailOperation *mail_operation;
1934         MsgData *data;
1935         gchar *account_name, *from;
1936         ModestAccountMgr *account_mgr;
1937         gchar *info_text = NULL;
1938
1939         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1940         
1941         data = modest_msg_edit_window_get_msg_data (edit_window);
1942
1943         account_mgr = modest_runtime_get_account_mgr();
1944         account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1945         if (!account_name) 
1946                 account_name = modest_account_mgr_get_default_account (account_mgr);
1947         if (!account_name) {
1948                 g_printerr ("modest: no account found\n");
1949                 modest_msg_edit_window_free_msg_data (edit_window, data);
1950                 return;
1951         }
1952
1953         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1954                 account_name = g_strdup (data->account_name);
1955         }
1956
1957         transport_account =
1958                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1959                                       (modest_runtime_get_account_store(),
1960                                        account_name,
1961                                        TNY_ACCOUNT_TYPE_TRANSPORT));
1962         if (!transport_account) {
1963                 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1964                 g_free (account_name);
1965                 modest_msg_edit_window_free_msg_data (edit_window, data);
1966                 return;
1967         }
1968         from = modest_account_mgr_get_from_string (account_mgr, account_name);
1969
1970         /* Create the mail operation */         
1971         mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1972         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1973
1974         modest_mail_operation_save_to_drafts (mail_operation,
1975                                               transport_account,
1976                                               data->draft_msg,
1977                                               edit_window,
1978                                               from,
1979                                               data->to, 
1980                                               data->cc, 
1981                                               data->bcc,
1982                                               data->subject, 
1983                                               data->plain_body, 
1984                                               data->html_body,
1985                                               data->attachments,
1986                                               data->priority_flags);
1987         /* Frees */
1988         g_free (from);
1989         g_free (account_name);
1990         g_object_unref (G_OBJECT (transport_account));
1991         g_object_unref (G_OBJECT (mail_operation));
1992
1993         modest_msg_edit_window_free_msg_data (edit_window, data);
1994
1995         info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1996         modest_platform_information_banner (NULL, NULL, info_text);
1997         g_free (info_text);
1998 }
1999
2000 /* For instance, when clicking the Send toolbar button when editing a message: */
2001 void
2002 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2003 {
2004         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2005
2006         if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2007                 return;
2008         
2009         /* Offer the connection dialog, if necessary: */        
2010         if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2011                 return;
2012         
2013         /* FIXME: Code added just for testing. The final version will
2014            use the send queue provided by tinymail and some
2015            classifier */
2016         ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2017         gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2018         if (!account_name) 
2019                 account_name = modest_account_mgr_get_default_account (account_mgr);
2020                 
2021         if (!account_name) {
2022                 /* Run account setup wizard */
2023                 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2024                 return;
2025         }
2026         
2027         MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2028
2029         if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2030                 account_name = g_strdup (data->account_name);
2031         }
2032         
2033         /* Get the currently-active transport account for this modest account: */
2034         TnyTransportAccount *transport_account =
2035                 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2036                                       (modest_runtime_get_account_store(),
2037                                        account_name));
2038         if (!transport_account) {
2039                 /* Run account setup wizard */
2040                 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2041                 return;
2042         }
2043         
2044         gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2045
2046         /* mail content checks and dialogs */
2047         if (data->subject == NULL || data->subject[0] == '\0') {
2048                 GtkResponseType response;
2049                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2050                                                                     _("mcen_nc_subject_is_empty_send"));
2051                 if (response == GTK_RESPONSE_CANCEL) {
2052                         g_free (account_name);
2053                         return;
2054                 }
2055         }
2056
2057         if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2058                 GtkResponseType response;
2059                 gchar *note_message;
2060                 gchar *note_subject = data->subject;
2061                 if (note_subject == NULL || note_subject[0] == '\0')
2062                         note_subject = _("mail_va_no_subject");
2063                 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2064                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2065                                                                     note_message);
2066                 g_free (note_message);
2067                 if (response == GTK_RESPONSE_CANCEL) {
2068                         g_free (account_name);
2069                         return;
2070                 }
2071         }
2072
2073         modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2074
2075         /* Create the mail operation */
2076         ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2077         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2078
2079         modest_mail_operation_send_new_mail (mail_operation,
2080                                              transport_account,
2081                                              data->draft_msg,
2082                                              from,
2083                                              data->to, 
2084                                              data->cc, 
2085                                              data->bcc,
2086                                              data->subject, 
2087                                              data->plain_body, 
2088                                              data->html_body,
2089                                              data->attachments,
2090                                              data->priority_flags);
2091                                              
2092         /* Free data: */
2093         g_free (from);
2094         g_free (account_name);
2095         g_object_unref (G_OBJECT (transport_account));
2096         g_object_unref (G_OBJECT (mail_operation));
2097
2098         modest_msg_edit_window_free_msg_data (edit_window, data);
2099         modest_msg_edit_window_set_sent (edit_window, TRUE);
2100
2101         /* Save settings and close the window: */
2102         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2103 }
2104
2105 void 
2106 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2107                                   ModestMsgEditWindow *window)
2108 {
2109         ModestMsgEditFormatState *format_state = NULL;
2110
2111         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2112         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2113
2114         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2115                 return;
2116
2117         format_state = modest_msg_edit_window_get_format_state (window);
2118         g_return_if_fail (format_state != NULL);
2119
2120         format_state->bold = gtk_toggle_action_get_active (action);
2121         modest_msg_edit_window_set_format_state (window, format_state);
2122         g_free (format_state);
2123         
2124 }
2125
2126 void 
2127 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2128                                      ModestMsgEditWindow *window)
2129 {
2130         ModestMsgEditFormatState *format_state = NULL;
2131
2132         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2133         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2134
2135         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2136                 return;
2137
2138         format_state = modest_msg_edit_window_get_format_state (window);
2139         g_return_if_fail (format_state != NULL);
2140
2141         format_state->italics = gtk_toggle_action_get_active (action);
2142         modest_msg_edit_window_set_format_state (window, format_state);
2143         g_free (format_state);
2144         
2145 }
2146
2147 void 
2148 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2149                                      ModestMsgEditWindow *window)
2150 {
2151         ModestMsgEditFormatState *format_state = NULL;
2152
2153         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2154         g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2155
2156         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2157                 return;
2158
2159         format_state = modest_msg_edit_window_get_format_state (window);
2160         g_return_if_fail (format_state != NULL);
2161
2162         format_state->bullet = gtk_toggle_action_get_active (action);
2163         modest_msg_edit_window_set_format_state (window, format_state);
2164         g_free (format_state);
2165         
2166 }
2167
2168 void 
2169 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2170                                      GtkRadioAction *selected,
2171                                      ModestMsgEditWindow *window)
2172 {
2173         ModestMsgEditFormatState *format_state = NULL;
2174         GtkJustification value;
2175
2176         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2177
2178         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2179                 return;
2180
2181         value = gtk_radio_action_get_current_value (selected);
2182
2183         format_state = modest_msg_edit_window_get_format_state (window);
2184         g_return_if_fail (format_state != NULL);
2185
2186         format_state->justification = value;
2187         modest_msg_edit_window_set_format_state (window, format_state);
2188         g_free (format_state);
2189 }
2190
2191 void 
2192 modest_ui_actions_on_select_editor_color (GtkAction *action,
2193                                           ModestMsgEditWindow *window)
2194 {
2195         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2196         g_return_if_fail (GTK_IS_ACTION (action));
2197
2198         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2199                 return;
2200
2201         modest_msg_edit_window_select_color (window);
2202 }
2203
2204 void 
2205 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2206                                                      ModestMsgEditWindow *window)
2207 {
2208         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2209         g_return_if_fail (GTK_IS_ACTION (action));
2210
2211         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2212                 return;
2213
2214         modest_msg_edit_window_select_background_color (window);
2215 }
2216
2217 void 
2218 modest_ui_actions_on_insert_image (GtkAction *action,
2219                                    ModestMsgEditWindow *window)
2220 {
2221         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2222         g_return_if_fail (GTK_IS_ACTION (action));
2223
2224         if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2225                 return;
2226
2227         modest_msg_edit_window_insert_image (window);
2228 }
2229
2230 void 
2231 modest_ui_actions_on_attach_file (GtkAction *action,
2232                                   ModestMsgEditWindow *window)
2233 {
2234         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2235         g_return_if_fail (GTK_IS_ACTION (action));
2236
2237         modest_msg_edit_window_offer_attach_file (window);
2238 }
2239
2240 void 
2241 modest_ui_actions_on_remove_attachments (GtkAction *action,
2242                                          ModestMsgEditWindow *window)
2243 {
2244         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2245         g_return_if_fail (GTK_IS_ACTION (action));
2246
2247         modest_msg_edit_window_remove_attachments (window, NULL);
2248 }
2249
2250 static void
2251 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2252                                             gpointer user_data)
2253 {
2254         ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2255         const GError *error = modest_mail_operation_get_error (mail_op);
2256
2257         if(error)
2258         {
2259                 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2260                                                     modest_mail_operation_get_error (mail_op)->message);
2261         }
2262 }
2263
2264 static void
2265 modest_ui_actions_create_folder(GtkWidget *parent_window,
2266                                 GtkWidget *folder_view)
2267 {
2268         TnyFolderStore *parent_folder;
2269
2270         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2271         
2272         if (parent_folder) {
2273                 gboolean finished = FALSE;
2274                 gint result;
2275                 gchar *folder_name = NULL, *suggested_name = NULL;
2276                 const gchar *proto_str = NULL;
2277                 TnyAccount *account;
2278
2279                 if (TNY_IS_ACCOUNT (parent_folder))
2280                         account = g_object_ref (parent_folder);
2281                 else
2282                         account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2283                 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2284
2285                 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2286                     MODEST_PROTOCOL_STORE_POP) {
2287                         finished = TRUE;
2288                         hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2289                 }
2290                 g_object_unref (account);
2291
2292                 /* Run the new folder dialog */
2293                 while (!finished) {
2294                         result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2295                                                                         parent_folder,
2296                                                                         suggested_name,
2297                                                                         &folder_name);
2298
2299                         g_free (suggested_name);
2300                         suggested_name = NULL;
2301
2302                         if (result == GTK_RESPONSE_REJECT) {
2303                                 finished = TRUE;
2304                         } else {
2305                                 ModestMailOperation *mail_op;
2306                                 TnyFolder *new_folder = NULL;
2307
2308                                 mail_op  = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2309                                                                                           G_OBJECT(parent_window),
2310                                                                                           modest_ui_actions_new_folder_error_handler,
2311                                                                                           parent_window);
2312
2313                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
2314                                                                  mail_op);
2315                                 new_folder = modest_mail_operation_create_folder (mail_op,
2316                                                                                   parent_folder,
2317                                                                                   (const gchar *) folder_name);
2318                                 if (new_folder) {
2319                                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), 
2320                                                                           new_folder, TRUE);
2321
2322                                         g_object_unref (new_folder);
2323                                         finished = TRUE;
2324                                 }
2325                                 g_object_unref (mail_op);
2326                         }
2327
2328                         suggested_name = folder_name;
2329                         folder_name = NULL;
2330                 }
2331
2332                 g_object_unref (parent_folder);
2333         }
2334 }
2335
2336 void 
2337 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2338 {
2339         GtkWidget *folder_view;
2340         
2341         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2342
2343         folder_view = modest_main_window_get_child_widget (main_window,
2344                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2345         if (!folder_view)
2346                 return;
2347
2348         modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2349 }
2350
2351 static void
2352 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2353                                                gpointer user_data)
2354 {
2355         GObject *win = modest_mail_operation_get_source (mail_op);
2356         const GError *error = NULL;
2357         const gchar *message = NULL;
2358         
2359         /* Get error message */
2360         error = modest_mail_operation_get_error (mail_op);
2361         if (error != NULL && error->message != NULL) {
2362                 message = error->message;
2363         } else {
2364                 message = _("!!! FIXME: Unable to rename");
2365         }
2366         
2367         /* Show notification dialog */
2368         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2369         g_object_unref (win);
2370 }
2371
2372 void 
2373 modest_ui_actions_on_rename_folder (GtkAction *action,
2374                                      ModestMainWindow *main_window)
2375 {
2376         TnyFolderStore *folder;
2377         GtkWidget *folder_view;
2378         GtkWidget *header_view; 
2379
2380         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2381
2382         folder_view = modest_main_window_get_child_widget (main_window,
2383                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2384         if (!folder_view)
2385                 return;
2386
2387         header_view = modest_main_window_get_child_widget (main_window,
2388                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
2389         
2390         if (!header_view)
2391                 return;
2392
2393         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2394         if (!folder)
2395                 return;
2396
2397         /* Offer the connection dialog if necessary: */
2398         if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2399                 g_object_unref (G_OBJECT (folder));
2400                 return;
2401         }
2402
2403         
2404         if (TNY_IS_FOLDER (folder)) {
2405                 gchar *folder_name;
2406                 gint response;
2407                 const gchar *current_name;
2408
2409                 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2410                 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2411                                                                      current_name, &folder_name);
2412
2413                 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2414                         ModestMailOperation *mail_op;
2415
2416                         mail_op = 
2417                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO, 
2418                                                                                G_OBJECT(main_window),
2419                                                                                modest_ui_actions_rename_folder_error_handler,
2420                                                                                NULL);
2421
2422
2423                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2424                                                          mail_op);
2425
2426                         modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2427                         
2428                         modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2429                                                           TNY_FOLDER(folder), TRUE);
2430
2431
2432                         modest_header_view_clear ((ModestHeaderView *) header_view);
2433  
2434                         modest_mail_operation_rename_folder (mail_op,
2435                                                              TNY_FOLDER (folder),
2436                                                              (const gchar *) folder_name);
2437
2438                         g_object_unref (mail_op);
2439                         g_free (folder_name);
2440                 }
2441         }
2442         g_object_unref (folder);
2443 }
2444
2445 static void
2446 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2447                                                gpointer user_data)
2448 {
2449         GObject *win = modest_mail_operation_get_source (mail_op);
2450
2451         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2452                                                 _("mail_in_ui_folder_delete_error"));
2453         g_object_unref (win);
2454 }
2455
2456 static void
2457 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) 
2458 {
2459         TnyFolderStore *folder;
2460         GtkWidget *folder_view;
2461         gint response;
2462         gchar *message;
2463         
2464         g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2465
2466         folder_view = modest_main_window_get_child_widget (main_window,
2467                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2468         if (!folder_view)
2469                 return;
2470
2471         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2472
2473         /* Show an error if it's an account */
2474         if (!TNY_IS_FOLDER (folder)) {
2475                 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2476                                                         _("mail_in_ui_folder_delete_error"));
2477                 g_object_unref (G_OBJECT (folder));
2478                 return ;
2479         }
2480
2481         /* Offer the connection dialog if necessary: */
2482         if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2483                 g_object_unref (G_OBJECT (folder));
2484                 return;
2485         }
2486
2487         /* Ask the user */      
2488         message =  g_strdup_printf (_("mcen_nc_delete_folder_text"), 
2489                                     tny_folder_get_name (TNY_FOLDER (folder)));
2490         response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2491                                                             (const gchar *) message);
2492         g_free (message);
2493
2494         if (response == GTK_RESPONSE_OK) {
2495                 ModestMailOperation *mail_op = 
2496                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, 
2497                                                                        G_OBJECT(main_window),
2498                                                                        modest_ui_actions_delete_folder_error_handler,
2499                                                                        NULL);
2500
2501                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2502                                                  mail_op);
2503                 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2504                 g_object_unref (G_OBJECT (mail_op));
2505         }
2506
2507         g_object_unref (G_OBJECT (folder));
2508 }
2509
2510 void 
2511 modest_ui_actions_on_delete_folder (GtkAction *action,
2512                                      ModestMainWindow *main_window)
2513 {
2514         GtkWidget *folder_view;
2515         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2516
2517         delete_folder (main_window, FALSE);
2518         folder_view = modest_main_window_get_child_widget (main_window,
2519                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
2520         if (!folder_view)
2521                 return;
2522         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2523 }
2524
2525 void 
2526 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2527 {
2528         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2529         
2530         delete_folder (main_window, TRUE);
2531 }
2532
2533
2534 static void
2535 show_error (GtkWidget *parent_widget, const gchar* text)
2536 {
2537         hildon_banner_show_information(parent_widget, NULL, text);
2538         
2539 #if 0
2540         GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2541         /*
2542           GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2543           (GtkDialogFlags)0,
2544           GTK_MESSAGE_ERROR,
2545           GTK_BUTTONS_OK,
2546           text ));
2547         */
2548                  
2549         gtk_dialog_run (dialog);
2550         gtk_widget_destroy (GTK_WIDGET (dialog));
2551 #endif
2552 }
2553
2554 void
2555 modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 
2556                                          const gchar* server_account_name,
2557                                          gchar **username,
2558                                          gchar **password, 
2559                                          gboolean *cancel, 
2560                                          gboolean *remember,
2561                                          ModestMainWindow *main_window)
2562 {
2563         g_return_if_fail(server_account_name);
2564         /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2565         
2566         /* Initalize output parameters: */
2567         if (cancel)
2568                 *cancel = FALSE;
2569                 
2570         if (remember)
2571                 *remember = TRUE;
2572                 
2573 #ifdef MODEST_PLATFORM_MAEMO
2574         /* Maemo uses a different (awkward) button order,
2575          * It should probably just use gtk_alternative_dialog_button_order ().
2576          */
2577         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2578                                               NULL,
2579                                               GTK_DIALOG_MODAL,
2580                                               GTK_STOCK_OK,
2581                                               GTK_RESPONSE_ACCEPT,
2582                                               GTK_STOCK_CANCEL,
2583                                               GTK_RESPONSE_REJECT,
2584                                               NULL);
2585 #else
2586         GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2587                                               NULL,
2588                                               GTK_DIALOG_MODAL,
2589                                               GTK_STOCK_CANCEL,
2590                                               GTK_RESPONSE_REJECT,
2591                                               GTK_STOCK_OK,
2592                                               GTK_RESPONSE_ACCEPT,
2593                                               NULL);
2594 #endif /* MODEST_PLATFORM_MAEMO */
2595
2596         gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2597         
2598         gchar *server_name = modest_server_account_get_hostname (
2599                 modest_runtime_get_account_mgr(), server_account_name);
2600         if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2601                 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2602                 *cancel = TRUE;
2603                 return;
2604         }
2605         
2606         /* This causes a warning because the logical ID has no %s in it, 
2607          * though the translation does, but there is not much we can do about that: */
2608         gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2609         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2610                             FALSE, FALSE, 0);
2611         g_free (txt);
2612         g_free (server_name);
2613         server_name = NULL;
2614
2615         /* username: */
2616         gchar *initial_username = modest_server_account_get_username (
2617                 modest_runtime_get_account_mgr(), server_account_name);
2618         
2619         GtkWidget *entry_username = gtk_entry_new ();
2620         if (initial_username)
2621                 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2622         /* Dim this if a connection has ever succeeded with this username,
2623          * as per the UI spec: */
2624         const gboolean username_known = 
2625                 modest_server_account_get_username_has_succeeded(
2626                         modest_runtime_get_account_mgr(), server_account_name);
2627         gtk_widget_set_sensitive (entry_username, !username_known);
2628         
2629 #ifdef MODEST_PLATFORM_MAEMO
2630         /* Auto-capitalization is the default, so let's turn it off: */
2631         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2632         
2633         /* Create a size group to be used by all captions.
2634          * Note that HildonCaption does not create a default size group if we do not specify one.
2635          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2636         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2637         
2638         GtkWidget *caption = hildon_caption_new (sizegroup, 
2639                 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2640         gtk_widget_show (entry_username);
2641         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2642                 FALSE, FALSE, MODEST_MARGIN_HALF);
2643         gtk_widget_show (caption);
2644 #else 
2645         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2646                             TRUE, FALSE, 0);
2647 #endif /* MODEST_PLATFORM_MAEMO */      
2648                             
2649         /* password: */
2650         GtkWidget *entry_password = gtk_entry_new ();
2651         gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2652         /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2653         
2654 #ifdef MODEST_PLATFORM_MAEMO
2655         /* Auto-capitalization is the default, so let's turn it off: */
2656         hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), 
2657                 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2658         
2659         caption = hildon_caption_new (sizegroup, 
2660                 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2661         gtk_widget_show (entry_password);
2662         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, 
2663                 FALSE, FALSE, MODEST_MARGIN_HALF);
2664         gtk_widget_show (caption);
2665         g_object_unref (sizegroup);
2666 #else 
2667         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2668                             TRUE, FALSE, 0);
2669 #endif /* MODEST_PLATFORM_MAEMO */      
2670                                 
2671 /* This is not in the Maemo UI spec:
2672         remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2673         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2674                             TRUE, FALSE, 0);
2675 */
2676
2677         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2678         
2679         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2680                 if (username) {
2681                         *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2682                         
2683                         modest_server_account_set_username (
2684                                  modest_runtime_get_account_mgr(), server_account_name, 
2685                                  *username);
2686                                  
2687                         const gboolean username_was_changed = 
2688                                 (strcmp (*username, initial_username) != 0);
2689                         if (username_was_changed) {
2690                                 g_warning ("%s: tinymail does not yet support changing the "
2691                                         "username in the get_password() callback.\n", __FUNCTION__);
2692                         }
2693                 }
2694                         
2695                 if (password) {
2696                         *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2697                         
2698                         /* We do not save the password in the configuration, 
2699                          * because this function is only called for passwords that should 
2700                          * not be remembered:
2701                         modest_server_account_set_password (
2702                                  modest_runtime_get_account_mgr(), server_account_name, 
2703                                  *password);
2704                         */
2705                 }
2706                 
2707                 if (cancel)
2708                         *cancel   = FALSE;
2709                         
2710         } else {
2711                 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2712                 
2713                 if (username)
2714                         *username = NULL;
2715                         
2716                 if (password)
2717                         *password = NULL;
2718                         
2719                 if (cancel)
2720                         *cancel   = TRUE;
2721         }
2722
2723 /* This is not in the Maemo UI spec:
2724         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2725                 *remember = TRUE;
2726         else
2727                 *remember = FALSE;
2728 */
2729
2730         gtk_widget_destroy (dialog);
2731         
2732         /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2733 }
2734
2735 void
2736 modest_ui_actions_on_cut (GtkAction *action,
2737                           ModestWindow *window)
2738 {
2739         GtkWidget *focused_widget;
2740         GtkClipboard *clipboard;
2741
2742         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2743         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2744         if (GTK_IS_EDITABLE (focused_widget)) {
2745                 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2746                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2747                 gtk_clipboard_store (clipboard);
2748         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2749                 GtkTextBuffer *buffer;
2750
2751                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2752                 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2753                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2754                 gtk_clipboard_store (clipboard);
2755         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2756                 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2757         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2758                 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2759         }
2760 }
2761
2762 void
2763 modest_ui_actions_on_copy (GtkAction *action,
2764                            ModestWindow *window)
2765 {
2766         GtkClipboard *clipboard;
2767         GtkWidget *focused_widget;
2768
2769         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2770         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2771
2772         if (GTK_IS_LABEL (focused_widget)) {
2773                 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2774                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2775                 gtk_clipboard_store (clipboard);
2776         } else if (GTK_IS_EDITABLE (focused_widget)) {
2777                 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2778                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2779                 gtk_clipboard_store (clipboard);
2780         } else if (GTK_IS_HTML (focused_widget)) {
2781                 gtk_html_copy (GTK_HTML (focused_widget));
2782                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2783                 gtk_clipboard_store (clipboard);
2784         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2785                 GtkTextBuffer *buffer;
2786                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2787                 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2788                 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2789                 gtk_clipboard_store (clipboard);
2790         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2791                 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2792                 TnyIterator *iter = tny_list_create_iterator (header_list);
2793                 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2794                 
2795                 gboolean ask = FALSE;
2796                 if (header) {
2797                         TnyFolder *folder = tny_header_get_folder (header);
2798                         TnyAccount *account = tny_folder_get_account (folder);
2799                         const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2800                         /* If it's POP then ask */
2801                         ask = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
2802                                 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2803                         g_object_unref (account);
2804                         g_object_unref (folder);
2805                         g_object_unref (header);
2806                 }
2807
2808                 g_object_unref (iter);
2809                 
2810                 /* Check that the messages have been previously downloaded */
2811                 gboolean continue_download = TRUE;
2812                 if (ask)
2813                         continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2814                 if (continue_download)
2815                         modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2816                 g_object_unref (header_list);
2817         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2818                 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2819         }    
2820
2821         /* Show information banner */
2822         modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2823         
2824 }
2825
2826 void
2827 modest_ui_actions_on_undo (GtkAction *action,
2828                            ModestWindow *window)
2829 {
2830         ModestEmailClipboard *clipboard = NULL;
2831
2832         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2833                 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2834         } else if (MODEST_IS_MAIN_WINDOW (window)) {
2835                 /* Clear clipboard source */
2836                 clipboard = modest_runtime_get_email_clipboard ();
2837                 modest_email_clipboard_clear (clipboard);               
2838         }
2839         else {
2840                 g_return_if_reached ();
2841         }
2842 }
2843
2844 void
2845 modest_ui_actions_on_redo (GtkAction *action,
2846                            ModestWindow *window)
2847 {
2848         if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2849                 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2850         }
2851         else {
2852                 g_return_if_reached ();
2853         }
2854 }
2855
2856
2857 static void
2858 paste_msgs_cb (const GObject *object, gpointer user_data)
2859 {
2860         g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2861         g_return_if_fail (GTK_IS_WIDGET (user_data));
2862         
2863         /* destroy information note */
2864         gtk_widget_destroy (GTK_WIDGET(user_data));
2865 }
2866
2867 static void
2868 paste_as_attachment_free (gpointer data)
2869 {
2870         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2871
2872         gtk_widget_destroy (helper->banner);
2873         g_object_unref (helper->banner);
2874         g_free (helper);
2875 }
2876
2877 static void
2878 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2879                             TnyHeader *header,
2880                             TnyMsg *msg,
2881                             gpointer userdata)
2882 {
2883         PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2884         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2885
2886         if (msg == NULL)
2887                 return;
2888
2889         modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2890         
2891 }
2892
2893 void
2894 modest_ui_actions_on_paste (GtkAction *action,
2895                             ModestWindow *window)
2896 {
2897         GtkWidget *focused_widget = NULL;
2898         GtkWidget *inf_note = NULL;
2899         ModestMailOperation *mail_op = NULL;
2900
2901         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2902         if (GTK_IS_EDITABLE (focused_widget)) {
2903                 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2904         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2905                 ModestEmailClipboard *e_clipboard = NULL;
2906                 e_clipboard = modest_runtime_get_email_clipboard ();
2907                 if (modest_email_clipboard_cleared (e_clipboard)) {
2908                         GtkTextBuffer *buffer;
2909                         GtkClipboard *clipboard;
2910
2911                         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2912                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2913                         gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2914                 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2915                         ModestMailOperation *mail_op;
2916                         TnyFolder *src_folder;
2917                         TnyList *data;
2918                         gboolean delete;
2919                         PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2920                         helper->window = MODEST_MSG_EDIT_WINDOW (window);
2921                         helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2922                                                                            _CS("ckct_nw_pasting"));
2923                         modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2924                         mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
2925                                                              G_OBJECT (window));
2926                         if (helper->banner != NULL) {
2927                                 g_object_ref (G_OBJECT (helper->banner));
2928                                 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2929                                 gtk_widget_show (GTK_WIDGET (helper->banner));
2930                         }
2931
2932                         if (data != NULL) {
2933                                 modest_mail_operation_get_msgs_full (mail_op, 
2934                                                                      data,
2935                                                                      (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2936                                                                      helper,
2937                                                                      paste_as_attachment_free);
2938                         }
2939                 }
2940         } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2941                 ModestEmailClipboard *clipboard = NULL;
2942                 TnyFolder *src_folder = NULL;
2943                 TnyFolderStore *folder_store = NULL;
2944                 TnyList *data = NULL;           
2945                 gboolean delete = FALSE;
2946                 
2947                 /* Check clipboard source */
2948                 clipboard = modest_runtime_get_email_clipboard ();
2949                 if (modest_email_clipboard_cleared (clipboard)) 
2950                         return;
2951                 
2952                 /* Get elements to paste */
2953                 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2954
2955                 /* Create a new mail operation */
2956                 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2957                 
2958                 /* Get destination folder */
2959                 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2960
2961                 /* transfer messages  */
2962                 if (data != NULL) {
2963                         gint response = 0;
2964
2965                         /* Ask for user confirmation */
2966                         response = msgs_move_to_confirmation (GTK_WINDOW (window), 
2967                                                               TNY_FOLDER (folder_store), 
2968                                                               delete,
2969                                                               data);
2970                         
2971                         if (response == GTK_RESPONSE_OK) {
2972                                 /* Launch notification */
2973                                 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
2974                                                                              _CS("ckct_nw_pasting"));
2975                                 if (inf_note != NULL)  {
2976                                         gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2977                                         gtk_widget_show (GTK_WIDGET(inf_note));
2978                                 }
2979
2980                                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2981                                 modest_mail_operation_xfer_msgs (mail_op, 
2982                                                                  data,
2983                                                                  TNY_FOLDER (folder_store),
2984                                                                  delete,
2985                                                                  paste_msgs_cb,
2986                                                                  inf_note);                             
2987                         } else {
2988                                 g_object_unref (mail_op);
2989                         }
2990                         
2991                 } else if (src_folder != NULL) {                        
2992                         /* Launch notification */
2993                         inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL, 
2994                                                                      _CS("ckct_nw_pasting"));
2995                         if (inf_note != NULL)  {
2996                                 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2997                                 gtk_widget_show (GTK_WIDGET(inf_note));
2998                         }
2999                         
3000                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3001                         modest_mail_operation_xfer_folder (mail_op, 
3002                                                            src_folder,
3003                                                            folder_store,
3004                                                            delete,
3005                                                            paste_msgs_cb,
3006                                                            inf_note);
3007                 }
3008
3009                 /* Free */
3010                 if (data != NULL) 
3011                         g_object_unref (data);
3012                 if (src_folder != NULL) 
3013                         g_object_unref (src_folder);
3014                 if (folder_store != NULL) 
3015                         g_object_unref (folder_store);
3016         }
3017 }
3018
3019
3020 void
3021 modest_ui_actions_on_select_all (GtkAction *action,
3022                                  ModestWindow *window)
3023 {
3024         GtkWidget *focused_widget;
3025
3026         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3027         if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3028                 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3029         } else if (GTK_IS_LABEL (focused_widget)) {
3030                 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3031         } else if (GTK_IS_EDITABLE (focused_widget)) {
3032                 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3033         } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3034                 GtkTextBuffer *buffer;
3035                 GtkTextIter start, end;
3036
3037                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3038                 gtk_text_buffer_get_start_iter (buffer, &start);
3039                 gtk_text_buffer_get_end_iter (buffer, &end);
3040                 gtk_text_buffer_select_range (buffer, &start, &end);
3041         } else if (GTK_IS_HTML (focused_widget)) {
3042                 gtk_html_select_all (GTK_HTML (focused_widget));
3043         } else if (MODEST_IS_MAIN_WINDOW (window)) {
3044                 GtkWidget *header_view = focused_widget;
3045                 GtkTreeSelection *selection = NULL;
3046                 
3047                 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3048                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3049                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
3050                                 
3051                 /* Select all messages */
3052                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3053                 gtk_tree_selection_select_all (selection);
3054
3055                 /* Set focuse on header view */
3056                 gtk_widget_grab_focus (header_view);
3057         }
3058
3059 }
3060
3061 void
3062 modest_ui_actions_on_mark_as_read (GtkAction *action,
3063                                    ModestWindow *window)
3064 {       
3065         g_return_if_fail (MODEST_IS_WINDOW(window));
3066                 
3067         /* Mark each header as read */
3068         do_headers_action (window, headers_action_mark_as_read, NULL);
3069 }
3070
3071 void
3072 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3073                                      ModestWindow *window)
3074 {       
3075         g_return_if_fail (MODEST_IS_WINDOW(window));
3076                 
3077         /* Mark each header as read */
3078         do_headers_action (window, headers_action_mark_as_unread, NULL);
3079 }
3080
3081 void
3082 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3083                                   GtkRadioAction *selected,
3084                                   ModestWindow *window)
3085 {
3086         gint value;
3087
3088         value = gtk_radio_action_get_current_value (selected);
3089         if (MODEST_IS_WINDOW (window)) {
3090                 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3091         }
3092 }
3093
3094 void     modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3095                                                         GtkRadioAction *selected,
3096                                                         ModestWindow *window)
3097 {
3098         TnyHeaderFlags flags;
3099         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3100
3101         flags = gtk_radio_action_get_current_value (selected);
3102         modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3103 }
3104
3105 void     modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3106                                                            GtkRadioAction *selected,
3107                                                            ModestWindow *window)
3108 {
3109         gint file_format;
3110
3111         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3112
3113         file_format = gtk_radio_action_get_current_value (selected);
3114         modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3115 }
3116
3117
3118 void     
3119 modest_ui_actions_on_zoom_plus (GtkAction *action,
3120                                 ModestWindow *window)
3121 {
3122         g_return_if_fail (MODEST_IS_WINDOW (window));
3123
3124         modest_window_zoom_plus (MODEST_WINDOW (window));
3125 }
3126
3127 void     
3128 modest_ui_actions_on_zoom_minus (GtkAction *action,
3129                                  ModestWindow *window)
3130 {
3131         g_return_if_fail (MODEST_IS_WINDOW (window));
3132
3133         modest_window_zoom_minus (MODEST_WINDOW (window));
3134 }
3135
3136 void     
3137 modest_ui_actions_on_toggle_fullscreen    (GtkToggleAction *toggle,
3138                                            ModestWindow *window)
3139 {
3140         ModestWindowMgr *mgr;
3141         gboolean fullscreen, active;
3142         g_return_if_fail (MODEST_IS_WINDOW (window));
3143
3144         mgr = modest_runtime_get_window_mgr ();
3145
3146         active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3147         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3148
3149         if (active != fullscreen) {
3150                 modest_window_mgr_set_fullscreen_mode (mgr, active);
3151                 gtk_window_present (GTK_WINDOW (window));
3152         }
3153 }
3154
3155 void
3156 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3157                                         ModestWindow *window)
3158 {
3159         ModestWindowMgr *mgr;
3160         gboolean fullscreen;
3161
3162         g_return_if_fail (MODEST_IS_WINDOW (window));
3163
3164         mgr = modest_runtime_get_window_mgr ();
3165         fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3166         modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3167
3168         gtk_window_present (GTK_WINDOW (window));
3169 }
3170
3171 /* 
3172  * Used by modest_ui_actions_on_details to call do_headers_action 
3173  */
3174 static void
3175 headers_action_show_details (TnyHeader *header, 
3176                              ModestWindow *window,
3177                              gpointer user_data)
3178
3179 {
3180         GtkWidget *dialog;
3181         
3182         /* Create dialog */
3183         dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3184
3185         /* Run dialog */
3186         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3187         gtk_widget_show_all (dialog);
3188         gtk_dialog_run (GTK_DIALOG (dialog));
3189
3190         gtk_widget_destroy (dialog);
3191 }
3192
3193 /*
3194  * Show the folder details in a ModestDetailsDialog widget
3195  */
3196 static void
3197 show_folder_details (TnyFolder *folder, 
3198                      GtkWindow *window)
3199 {
3200         GtkWidget *dialog;
3201         
3202         /* Create dialog */
3203         dialog = modest_details_dialog_new_with_folder (window, folder);
3204
3205         /* Run dialog */
3206         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3207         gtk_widget_show_all (dialog);
3208         gtk_dialog_run (GTK_DIALOG (dialog));
3209
3210         gtk_widget_destroy (dialog);
3211 }
3212
3213 /*
3214  * Show the header details in a ModestDetailsDialog widget
3215  */
3216 void     
3217 modest_ui_actions_on_details (GtkAction *action, 
3218                               ModestWindow *win)
3219 {
3220         TnyList * headers_list;
3221         TnyIterator *iter;
3222         TnyHeader *header;              
3223
3224         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3225                 TnyMsg *msg;
3226
3227                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3228                 if (!msg)
3229                         return;
3230                 g_object_unref (msg);           
3231
3232                 headers_list = get_selected_headers (win);
3233                 if (!headers_list)
3234                         return;
3235
3236                 iter = tny_list_create_iterator (headers_list);
3237
3238                 header = TNY_HEADER (tny_iterator_get_current (iter));
3239                 if (header) {
3240                         headers_action_show_details (header, win, NULL);
3241                         g_object_unref (header);
3242                 }
3243
3244                 g_object_unref (iter);
3245                 g_object_unref (headers_list);
3246
3247         } else if (MODEST_IS_MAIN_WINDOW (win)) {
3248                 GtkWidget *folder_view, *header_view;
3249
3250                 /* Check which widget has the focus */
3251                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3252                                                                     MODEST_WIDGET_TYPE_FOLDER_VIEW);
3253                 if (gtk_widget_is_focus (folder_view)) {
3254                         TnyFolderStore *folder_store
3255                                 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3256                         if (!folder_store) {
3257                                 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3258                                 return; 
3259                         }
3260                         /* Show only when it's a folder */
3261                         /* This function should not be called for account items, 
3262                          * because we dim the menu item for them. */
3263                         if (TNY_IS_FOLDER (folder_store)) {
3264                                 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3265                         }
3266
3267                         g_object_unref (folder_store);
3268
3269                 } else {
3270                         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3271                                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
3272                         /* Show details of each header */
3273                         do_headers_action (win, headers_action_show_details, header_view);
3274                 }
3275         }
3276 }
3277
3278 void     
3279 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3280                                      ModestMsgEditWindow *window)
3281 {
3282         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3283
3284         modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3285 }
3286
3287 void     
3288 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3289                                       ModestMsgEditWindow *window)
3290 {
3291         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3292
3293         modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3294 }
3295
3296 void
3297 modest_ui_actions_toggle_folders_view (GtkAction *action, 
3298                                        ModestMainWindow *main_window)
3299 {
3300         g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3301
3302         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3303                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3304         else
3305                 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3306 }
3307
3308 void 
3309 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle, 
3310                                      ModestWindow *window)
3311 {
3312         gboolean active, fullscreen = FALSE;
3313         ModestWindowMgr *mgr;
3314
3315         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3316
3317         /* Check if we want to toggle the toolbar vuew in fullscreen
3318            or normal mode */
3319         if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)), 
3320                      "ViewShowToolbarFullScreen")) {
3321                 fullscreen = TRUE;
3322         }
3323
3324         /* Toggle toolbar */
3325         mgr = modest_runtime_get_window_mgr ();
3326         modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3327 }
3328
3329 void     
3330 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3331                                            ModestMsgEditWindow *window)
3332 {
3333         modest_msg_edit_window_select_font (window);
3334 }
3335
3336 void
3337 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3338                                                   const gchar *display_name,
3339                                                   GtkWindow *window)
3340 {
3341         /* Do not change the application name if the widget has not
3342            the focus. This callback could be called even if the folder
3343            view has not the focus, because the handled signal could be
3344            emitted when the folder view is redrawn */
3345         if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3346                 if (display_name)
3347                         gtk_window_set_title (window, display_name);
3348                 else
3349                         gtk_window_set_title (window, " ");
3350         }
3351 }
3352
3353 void
3354 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3355 {
3356         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3357         modest_msg_edit_window_select_contacts (window);
3358 }
3359
3360 void
3361 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3362 {
3363         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3364         modest_msg_edit_window_check_names (window, FALSE);
3365 }
3366
3367 static void
3368 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3369 {
3370         modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3371                                          GTK_WIDGET (user_data));
3372 }
3373
3374 static GtkWidget*
3375 create_move_to_dialog (GtkWindow *win,
3376                        GtkWidget *folder_view,
3377                        GtkWidget **tree_view)
3378 {
3379         GtkWidget *dialog, *scroll;
3380         GtkWidget *new_button;
3381
3382         dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3383                                               GTK_WINDOW (win),
3384                                               GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3385                                               NULL);
3386
3387         gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3388         /* We do this manually so GTK+ does not associate a response ID for
3389          * the button. */
3390         new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3391         gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3392         gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3393
3394         /* Create scrolled window */
3395         scroll = gtk_scrolled_window_new (NULL, NULL);
3396         gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroll),
3397                                          GTK_POLICY_AUTOMATIC,
3398                                          GTK_POLICY_AUTOMATIC);
3399
3400         /* Create folder view */
3401         *tree_view = modest_platform_create_folder_view (NULL);
3402
3403         g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3404
3405         /* It could happen that we're trying to move a message from a
3406            window (msg window for example) after the main window was
3407            closed, so we can not just get the model of the folder
3408            view */
3409         if (MODEST_IS_FOLDER_VIEW (folder_view))
3410                 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3411                                          gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3412         else
3413                 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), 
3414                                                  TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3415
3416         modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3417         
3418         gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3419
3420         /* Add scroll to dialog */
3421         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
3422                             scroll, TRUE, TRUE, 0);
3423
3424         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3425         gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3426
3427         return dialog;
3428 }
3429
3430 /*
3431  * Returns TRUE if at least one of the headers of the list belongs to
3432  * a message that has been fully retrieved.
3433  */
3434 static gboolean
3435 has_retrieved_msgs (TnyList *list)
3436 {
3437         TnyIterator *iter;
3438         gboolean found = FALSE;
3439
3440         iter = tny_list_create_iterator (list);
3441         while (!tny_iterator_is_done (iter) && !found) {
3442                 TnyHeader *header;
3443                 TnyHeaderFlags flags = 0;
3444
3445                 header = TNY_HEADER (tny_iterator_get_current (iter));
3446                 if (header) {
3447                         flags = tny_header_get_flags (header);
3448                         if (flags & TNY_HEADER_FLAG_CACHED)
3449 /*                      if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3450                                 found = TRUE;
3451
3452                         g_object_unref (header);
3453                 }
3454
3455                 if (!found)
3456                         tny_iterator_next (iter);
3457         }
3458         g_object_unref (iter);
3459
3460         return found;
3461 }
3462
3463 /*
3464  * Shows a confirmation dialog to the user when we're moving messages
3465  * from a remote server to the local storage. Returns the dialog
3466  * response. If it's other kind of movement the it always returns
3467  * GTK_RESPONSE_OK
3468  */
3469 static gint
3470 msgs_move_to_confirmation (GtkWindow *win,
3471                            TnyFolder *dest_folder,
3472                            gboolean delete,
3473                            TnyList *headers)
3474 {
3475         gint response = GTK_RESPONSE_OK;
3476
3477         /* If the destination is a local folder (or MMC folder )*/
3478         if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3479 /*      if (modest_tny_folder_is_local_folder (dest_folder)) { */
3480                 TnyFolder *src_folder = NULL;
3481                 TnyIterator *iter = NULL;
3482                 TnyHeader *header = NULL;
3483
3484                 /* Get source folder */
3485                 iter = tny_list_create_iterator (headers);
3486                 header = TNY_HEADER (tny_iterator_get_current (iter));
3487                 if (header) {
3488                         src_folder = tny_header_get_folder (header);
3489                         g_object_unref (header);
3490                 }
3491
3492                 g_object_unref (iter);
3493
3494                 /* if no src_folder, message may be an attahcment */
3495                 if (src_folder == NULL) 
3496                         return GTK_RESPONSE_CANCEL;
3497
3498                 /* If the source is a remote folder */
3499 /*              if (!modest_tny_folder_is_local_folder (src_folder)) { */
3500                 if (modest_tny_folder_is_remote_folder (src_folder)) {
3501                         const gchar *message = NULL;
3502                         gboolean cached = has_retrieved_msgs (headers);
3503                         if (cached) 
3504                                 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3505                                                     tny_list_get_length (headers));
3506                         else 
3507                                 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3508                                                     tny_list_get_length (headers));
3509                         
3510                         if (cached && !delete)  
3511                                 response = GTK_RESPONSE_OK;
3512                         else
3513                                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3514                                                                                     (const gchar *) message);
3515                 }
3516                 
3517                 g_object_unref (src_folder);
3518         }
3519         
3520         return response;
3521 }
3522
3523
3524
3525 static void
3526 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3527 {
3528         ModestMsgViewWindow *self = NULL;
3529
3530         g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3531         self = MODEST_MSG_VIEW_WINDOW (object);
3532         
3533         if (!modest_msg_view_window_select_next_message (self))
3534                 if (!modest_msg_view_window_select_previous_message (self))
3535                         /* No more messages to view, so close this window */
3536                         modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3537 }
3538
3539 void
3540 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, 
3541                                              gpointer user_data)
3542 {
3543         GObject *win = modest_mail_operation_get_source (mail_op);
3544         const GError *error = NULL;
3545         const gchar *message = NULL;
3546         
3547         /* Get error message */
3548         error = modest_mail_operation_get_error (mail_op);
3549         if (error != NULL && error->message != NULL) {
3550                 message = error->message;
3551         } else {
3552                 message = _("mail_in_ui_folder_move_target_error");
3553         }
3554         
3555         /* Show notification dialog */
3556         modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3557         g_object_unref (win);
3558 }
3559
3560 void
3561 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op, 
3562                                               gpointer user_data)
3563 {
3564         GObject *win = modest_mail_operation_get_source (mail_op);
3565         const GError *error = modest_mail_operation_get_error (mail_op);
3566
3567         g_return_if_fail (error != NULL);
3568         if (error->message != NULL)             
3569                 g_printerr ("modest: %s\n", error->message);
3570         else
3571                 g_printerr ("modest: unkonw error on send&receive operation");
3572
3573         /* Show error message */
3574 /*      if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3575 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3576 /*                                                      _CS("sfil_ib_unable_to_receive")); */
3577 /*      else  */
3578 /*              modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3579 /*                                                      _CS("sfil_ib_unable_to_send")); */
3580         g_object_unref (win);
3581 }
3582
3583 static void
3584 open_msg_for_purge_cb (ModestMailOperation *mail_op, 
3585                        TnyHeader *header, 
3586                        TnyMsg *msg, 
3587                        gpointer user_data)
3588 {
3589         TnyList *parts;
3590         TnyIterator *iter;
3591         gint pending_purges = 0;
3592         gboolean some_purged = FALSE;
3593         ModestWindow *win = MODEST_WINDOW (user_data);
3594         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3595
3596         /* If there was any error */
3597         if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3598                 modest_window_mgr_unregister_header (mgr, header);
3599                 return;
3600         }
3601
3602         /* Once the message has been retrieved for purging, we check if
3603          * it's all ok for purging */
3604
3605         parts = tny_simple_list_new ();
3606         tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3607         iter = tny_list_create_iterator (parts);
3608
3609         while (!tny_iterator_is_done (iter)) {
3610                 TnyMimePart *part;
3611                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3612                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3613                         if (tny_mime_part_is_purged (part))
3614                                 some_purged = TRUE;
3615                         else
3616                                 pending_purges++;
3617                 }
3618
3619                 if (part)
3620                         g_object_unref (part);
3621
3622                 tny_iterator_next (iter);
3623         }
3624
3625         if (pending_purges>0) {
3626                 gint response;
3627                 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3628
3629                 if (response == GTK_RESPONSE_OK) {
3630                         modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3631                         tny_iterator_first (iter);
3632                         while (!tny_iterator_is_done (iter)) {
3633                                 TnyMimePart *part;
3634                                 
3635                                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3636                                 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3637                                         tny_mime_part_set_purged (part);
3638
3639                                 if (part)
3640                                         g_object_unref (part);
3641
3642                                 tny_iterator_next (iter);
3643                         }
3644                         
3645                         tny_msg_rewrite_cache (msg);
3646                 }
3647         } else {
3648                 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3649         }
3650
3651         /* remove attachments */
3652         tny_iterator_first (iter);
3653         while (!tny_iterator_is_done (iter)) {
3654                 TnyMimePart *part;
3655                         
3656                 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3657                 if (part) {
3658                         /* One for the reference given by tny_iterator_get_current(): */
3659                         g_object_unref (part);
3660
3661                         /* TODO: Is this meant to remove the attachment by doing another unref()? 
3662                          * Otherwise, this seems useless. */
3663                 }
3664
3665                 tny_iterator_next (iter);
3666         }
3667         modest_window_mgr_unregister_header (mgr, header);
3668
3669         g_object_unref (iter);
3670         g_object_unref (parts);
3671 }
3672
3673 static void
3674 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3675                                                      ModestMainWindow *win)
3676 {
3677         GtkWidget *header_view;
3678         TnyList *header_list;
3679         TnyIterator *iter;
3680         TnyHeader *header;
3681         TnyHeaderFlags flags;
3682         ModestWindow *msg_view_window =  NULL;
3683         gboolean found;
3684
3685         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3686
3687         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3688                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
3689
3690         header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3691
3692         if (tny_list_get_length (header_list) == 1) {
3693                 iter = tny_list_create_iterator (header_list);
3694                 header = TNY_HEADER (tny_iterator_get_current (iter));
3695                 g_object_unref (iter);
3696         } else {
3697                 return;
3698         }
3699
3700         found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3701                                                           header, &msg_view_window);
3702         flags = tny_header_get_flags (header);
3703         if (!(flags & TNY_HEADER_FLAG_CACHED))
3704                 return;
3705         if (found) {
3706                 if (msg_view_window != NULL) 
3707                         modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3708                 else {
3709                         /* do nothing; uid was registered before, so window is probably on it's way */
3710                         g_warning ("debug: header %p has already been registered", header);
3711                 }
3712         } else {
3713                 ModestMailOperation *mail_op = NULL;
3714                 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3715                 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3716                                                                          G_OBJECT (win),
3717                                                                          modest_ui_actions_get_msgs_full_error_handler,
3718                                                                          NULL);
3719                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3720                 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3721                 
3722                 g_object_unref (mail_op);
3723         }
3724         if (header)
3725                 g_object_unref (header);
3726         if (header_list)
3727                 g_object_unref (header_list);
3728 }
3729
3730 /**
3731  * Utility function that transfer messages from both the main window
3732  * and the msg view window when using the "Move to" dialog
3733  */
3734 static void
3735 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3736                                               ModestWindow *win)
3737 {
3738         TnyList *headers = NULL;
3739         gint response = 0;
3740         TnyAccount *dst_account = NULL;
3741         const gchar *proto_str = NULL;
3742         gboolean dst_is_pop = FALSE;
3743
3744         if (!TNY_IS_FOLDER (dst_folder)) {
3745                 modest_platform_information_banner (GTK_WIDGET (win),
3746                                                     NULL,
3747                                                     _CS("ckdg_ib_unable_to_move_to_current_location"));
3748                 return;
3749         }
3750
3751         dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3752         proto_str = tny_account_get_proto (dst_account);
3753         dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
3754                       MODEST_PROTOCOL_STORE_POP);
3755         g_object_unref (dst_account);
3756
3757         /* Get selected headers */
3758         headers = get_selected_headers (MODEST_WINDOW (win));
3759
3760         if (dst_is_pop) {
3761                 modest_platform_information_banner (GTK_WIDGET (win),
3762                                                     NULL,
3763                                                     ngettext("mail_in_ui_folder_move_target_error",
3764                                                              "mail_in_ui_folder_move_targets_error",
3765                                                              tny_list_get_length (headers)));
3766                 g_object_unref (headers);
3767                 return;
3768         }
3769
3770         /* Ask for user confirmation */
3771         response = msgs_move_to_confirmation (GTK_WINDOW (win), 
3772                                               TNY_FOLDER (dst_folder), 
3773                                               TRUE,
3774                                               headers);
3775
3776         /* Transfer messages */
3777         if (response == GTK_RESPONSE_OK) {
3778                 ModestMailOperation *mail_op = 
3779                         modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3780                                                                        G_OBJECT(win),
3781                                                                        modest_ui_actions_move_folder_error_handler,
3782                                                                        NULL);
3783                 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
3784                                                  mail_op);
3785
3786                 modest_mail_operation_xfer_msgs (mail_op, 
3787                                                  headers,
3788                                                  TNY_FOLDER (dst_folder),
3789                                                  TRUE,
3790                                                  (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3791                                                  NULL);
3792
3793                 g_object_unref (G_OBJECT (mail_op));
3794         }
3795         g_object_unref (headers);
3796 }
3797
3798
3799 /*
3800  * UI handler for the "Move to" action when invoked from the
3801  * ModestMainWindow
3802  */
3803 static void 
3804 modest_ui_actions_on_main_window_move_to (GtkAction *action, 
3805                                           GtkWidget *folder_view,
3806                                           TnyFolderStore *dst_folder,
3807                                           ModestMainWindow *win)
3808 {
3809         GtkWidget *header_view = NULL;
3810         ModestMailOperation *mail_op = NULL;
3811         TnyFolderStore *src_folder;
3812
3813         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3814
3815         /* Get the source folder */
3816         src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3817         
3818         /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3819         if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), 
3820                                                                       src_folder))
3821                 goto end;
3822
3823         /* Get header view */
3824         header_view = 
3825                 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3826
3827         /* Get folder or messages to transfer */
3828         if (gtk_widget_is_focus (folder_view)) {
3829
3830                 /* Allow only to transfer folders to the local root folder */
3831                 if (TNY_IS_ACCOUNT (dst_folder) && 
3832                     !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3833                         goto end;
3834                 
3835                 /* Clean folder on header view before moving it */
3836                 modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); 
3837
3838                 if (TNY_IS_FOLDER (src_folder)) {
3839                         mail_op = 
3840                                 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
3841                                                                                G_OBJECT(win),
3842                                                                                modest_ui_actions_move_folder_error_handler,
3843                                                                                NULL);
3844                         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), 
3845                                                          mail_op);
3846
3847                         modest_mail_operation_xfer_folder (mail_op, 
3848                                                            TNY_FOLDER (src_folder),
3849                                                            dst_folder,
3850                                                            TRUE, NULL, NULL);
3851                         /* Unref mail operation */
3852                         g_object_unref (G_OBJECT (mail_op));
3853                 } else {
3854                         g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);       
3855                 }
3856         } else if (gtk_widget_is_focus (header_view)) {
3857                 /* Transfer messages */
3858                 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3859         }
3860         
3861  end:
3862     if (src_folder)
3863         g_object_unref (src_folder);
3864 }
3865
3866
3867 /*
3868  * UI handler for the "Move to" action when invoked from the
3869  * ModestMsgViewWindow
3870  */
3871 static void 
3872 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, 
3873                                               TnyFolderStore *dst_folder,
3874                                               ModestMsgViewWindow *win)
3875 {
3876         TnyHeader *header = NULL;
3877         TnyFolder *src_folder;
3878
3879         /* Create header list */
3880         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));              
3881         src_folder = tny_header_get_folder(header);
3882         g_object_unref (header);
3883
3884         /* Transfer the message */
3885         if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3886                 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3887
3888         g_object_unref (src_folder);
3889 }
3890
3891 void 
3892 modest_ui_actions_on_move_to (GtkAction *action, 
3893                               ModestWindow *win)
3894 {
3895         GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3896         gint result = 0;
3897         TnyFolderStore *dst_folder = NULL;
3898         ModestMainWindow *main_window;
3899
3900         g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3901                           MODEST_IS_MSG_VIEW_WINDOW (win));
3902
3903         /* Get the main window if exists */
3904         if (MODEST_IS_MAIN_WINDOW (win))
3905                 main_window = MODEST_MAIN_WINDOW (win);
3906         else
3907                 main_window = 
3908                         MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3909
3910         /* Get the folder view widget if exists */
3911         if (main_window)
3912                 folder_view = modest_main_window_get_child_widget (main_window,
3913                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
3914         else
3915                 folder_view = NULL;
3916
3917         /* Create and run the dialog */
3918         dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3919         modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3920         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3921         result = gtk_dialog_run (GTK_DIALOG(dialog));
3922         g_object_ref (tree_view);
3923         gtk_widget_destroy (dialog);
3924
3925         if (result != GTK_RESPONSE_ACCEPT)
3926                 return;
3927
3928         dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3929         /* Offer the connection dialog if necessary: */
3930         if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), 
3931                                                                       dst_folder)) {
3932
3933                 /* Do window specific stuff */
3934                 if (MODEST_IS_MAIN_WINDOW (win))
3935                         modest_ui_actions_on_main_window_move_to (action,
3936                                                                   folder_view,
3937                                                                   dst_folder,
3938                                                                   MODEST_MAIN_WINDOW (win));
3939                 else
3940                         modest_ui_actions_on_msg_view_window_move_to (action,
3941                                                                       dst_folder,
3942                                                                       MODEST_MSG_VIEW_WINDOW (win));
3943         }
3944         if (dst_folder)
3945                 g_object_unref (dst_folder);
3946 }
3947
3948 /*
3949  * Calls #HeadersFunc for each header already selected in the main
3950  * window or the message currently being shown in the msg view window
3951  */
3952 static void
3953 do_headers_action (ModestWindow *win, 
3954                    HeadersFunc func,
3955                    gpointer user_data)
3956 {
3957         TnyList *headers_list = NULL;
3958         TnyIterator *iter = NULL;
3959         TnyHeader *header = NULL;
3960         TnyFolder *folder = NULL;
3961
3962         /* Get headers */
3963         headers_list = get_selected_headers (win);
3964         if (!headers_list)
3965                 return;
3966
3967         /* Get the folder */
3968         iter = tny_list_create_iterator (headers_list);
3969         header = TNY_HEADER (tny_iterator_get_current (iter));
3970         if (header) {
3971                 folder = tny_header_get_folder (header);
3972                 g_object_unref (header);
3973         }
3974
3975         /* Call the function for each header */
3976         while (!tny_iterator_is_done (iter)) {
3977                 header = TNY_HEADER (tny_iterator_get_current (iter));
3978                 func (header, win, user_data);
3979                 g_object_unref (header);
3980                 tny_iterator_next (iter);
3981         }
3982
3983         /* Trick: do a poke status in order to speed up the signaling
3984            of observers */
3985         tny_folder_poke_status (folder);
3986
3987         /* Frees */
3988         g_object_unref (folder);
3989         g_object_unref (iter);
3990         g_object_unref (headers_list);
3991 }
3992
3993 void 
3994 modest_ui_actions_view_attachment (GtkAction *action,
3995                                    ModestWindow *window)
3996 {
3997         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3998                 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3999         } else {
4000                 /* not supported window for this action */
4001                 g_return_if_reached ();
4002         }
4003 }
4004
4005 void
4006 modest_ui_actions_save_attachments (GtkAction *action,
4007                                     ModestWindow *window)
4008 {
4009         if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4010                 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4011         } else {
4012                 /* not supported window for this action */
4013                 g_return_if_reached ();
4014         }
4015 }
4016
4017 void
4018 modest_ui_actions_remove_attachments (GtkAction *action,
4019                                       ModestWindow *window)
4020 {
4021         if (MODEST_IS_MAIN_WINDOW (window)) {
4022                 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4023         } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4024                 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4025         } else {
4026                 /* not supported window for this action */
4027                 g_return_if_reached ();
4028         }
4029 }
4030
4031 void 
4032 modest_ui_actions_on_settings (GtkAction *action, 
4033                                ModestWindow *win)
4034 {
4035         GtkWidget *dialog;
4036
4037         dialog = modest_platform_get_global_settings_dialog ();
4038         gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4039         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4040         gtk_widget_show_all (dialog);
4041
4042         gtk_dialog_run (GTK_DIALOG (dialog));
4043
4044         gtk_widget_destroy (dialog);
4045 }
4046
4047 void 
4048 modest_ui_actions_on_help (GtkAction *action, 
4049                            ModestWindow *win)
4050 {
4051         const gchar *help_id = NULL;
4052
4053         if (MODEST_IS_MAIN_WINDOW (win)) {
4054                 const gchar *action_name;
4055                 action_name = gtk_action_get_name (action);
4056
4057                 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4058                     !strcmp (action_name, "HeaderViewCSMHelp")) {
4059                         GtkWidget *folder_view;
4060                         TnyFolderStore *folder_store;
4061                         /* Get selected folder */
4062                         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4063                                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
4064                         folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4065
4066                         /* Switch help_id */
4067                         if (TNY_IS_FOLDER (folder_store)) {
4068                                 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4069                                 case TNY_FOLDER_TYPE_NORMAL:
4070                                         help_id = "applications_email_managefolders";
4071                                         break;
4072                                 case TNY_FOLDER_TYPE_INBOX:
4073                                         help_id = "applications_email_inbox";
4074                                         break;
4075                                 case TNY_FOLDER_TYPE_OUTBOX:
4076                                         help_id = "applications_email_outbox";
4077                                         break;
4078                                 case TNY_FOLDER_TYPE_SENT:
4079                                         help_id = "applications_email_sent";
4080                                         break;
4081                                 case TNY_FOLDER_TYPE_DRAFTS:
4082                                         help_id = "applications_email_drafts";
4083                                         break;
4084                                 case TNY_FOLDER_TYPE_ARCHIVE:
4085                                         help_id = "applications_email_managefolders";
4086                                         break;
4087                                 default:
4088                                         help_id = "applications_email_managefolders";
4089                                 }
4090                         } else {
4091                                 help_id = "applications_email_mainview";        
4092                         }
4093                         g_object_unref (folder_store);
4094                 } else {
4095                         help_id = "applications_email_mainview";        
4096                 }
4097         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4098                 help_id = "applications_email_viewer";
4099         } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4100                 help_id = "applications_email_editor";
4101
4102         modest_platform_show_help (GTK_WINDOW (win), help_id);
4103 }
4104
4105 void 
4106 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4107                                             ModestWindow *window)
4108 {
4109         ModestMailOperation *mail_op;
4110         TnyList *headers;
4111
4112         /* Get headers */
4113         headers = get_selected_headers (window);
4114         if (!headers)
4115                 return;
4116
4117         /* Create mail operation */
4118         mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
4119                                                                  G_OBJECT (window),
4120                                                                  modest_ui_actions_get_msgs_full_error_handler, 
4121                                                                  NULL);
4122         modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4123         modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4124
4125         /* Frees */
4126         g_object_unref (headers);
4127         g_object_unref (mail_op);
4128 }
4129
4130 void
4131 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4132                                           ModestWindow *window)
4133 {
4134         g_return_if_fail (MODEST_IS_WINDOW (window));
4135         
4136         /* Update dimmed */     
4137         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4138 }
4139
4140 void
4141 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4142                                           ModestWindow *window)
4143 {
4144         g_return_if_fail (MODEST_IS_WINDOW (window));
4145
4146         /* Update dimmed */     
4147         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4148 }
4149
4150 void
4151 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4152                                           ModestWindow *window)
4153 {
4154         g_return_if_fail (MODEST_IS_WINDOW (window));
4155
4156         /* Update dimmed */     
4157         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4158 }
4159
4160 void
4161 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4162                                           ModestWindow *window)
4163 {
4164         g_return_if_fail (MODEST_IS_WINDOW (window));
4165
4166         /* Update dimmed */     
4167         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4168 }
4169
4170 void
4171 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4172                                           ModestWindow *window)
4173 {
4174         g_return_if_fail (MODEST_IS_WINDOW (window));
4175
4176         /* Update dimmed */     
4177         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4178 }
4179
4180 void
4181 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4182                                                  ModestWindow *window)
4183 {
4184         g_return_if_fail (MODEST_IS_WINDOW (window));
4185
4186         /* Update dimmed */     
4187         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4188 }
4189
4190 void
4191 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4192                                                      ModestWindow *window)
4193 {
4194         g_return_if_fail (MODEST_IS_WINDOW (window));
4195
4196         /* Update dimmed */     
4197         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4198 }
4199
4200 void
4201 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4202                                                      ModestWindow *window)
4203 {
4204         g_return_if_fail (MODEST_IS_WINDOW (window));
4205
4206         /* Update dimmed */     
4207         modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");     
4208 }
4209
4210 void
4211 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4212 {
4213         g_return_if_fail (MODEST_IS_WINDOW (window));
4214
4215         /* Update dimmed */     
4216         modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");  
4217 }
4218
4219 void
4220 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4221 {
4222         g_return_if_fail (MODEST_IS_WINDOW (window));
4223
4224         modest_platform_show_search_messages (GTK_WINDOW (window));
4225 }
4226
4227 void     
4228 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4229 {
4230         g_return_if_fail (MODEST_IS_WINDOW (win));
4231         modest_platform_show_addressbook (GTK_WINDOW (win));
4232 }
4233
4234
4235 void
4236 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4237                                           ModestWindow *window)
4238 {
4239         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4240
4241         modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4242 }
4243
4244 static void 
4245 _on_send_receive_progress_changed (ModestMailOperation  *mail_op, 
4246                                    ModestMailOperationState *state,
4247                                    gpointer user_data)
4248 {
4249         g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4250
4251         /* Set send/receive operation finished */       
4252         if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4253                 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4254         
4255 }
4256
4257